dorl@vms.macc.wisc.edu (Michael (NMI) Dorl) (05/26/87)
I had occasion to write a small program to look at what's happening on
an Ethernet using VMS. The program assigns a channel to the Ethernet
controller and then receives either every packet or every packet with
a given protocol field going by on the network. The program works but
the machines crashes after a short time!
Has anyone had any similar experiences using promiscous mode on
VMS? Is there some resource in VMS that needs expanding? Any ideas
welcome.
The program follows. Note that you need physical IO priv to run it
so don't flame me for posting a program that crashes VMS.
My machine crashes if I specify a protocol type of zero or 6003 (hex)
which is DECNet. It does not crash if I specify some non-existant
protocol. It crashes if I specify a function of TRACE or SUMMARY.
TRACE prints every packet while SUMMARY prints some statistics after
receiving 1000 packets so I don't think it has anything to do with
the printing. I have no problem if I reduce the packet count to
some small number like 100..
-----------------------------------------------------------------------
Implicit None
Include '($IODef)'
External Sys$QIOW
Integer Sys$QIOW
External Sys$Assign
Integer Sys$Assign
Structure /SetDef/
Union
Map
Integer *2 BFN ! 2 Number of buffers
Integer *4 BFN_Value ! 4
Integer *2 BUS ! 2 Maximum receive size
Integer *4 BUS_Value ! 4
Integer *2 PRM ! 2 Promiscuous mode
Integer *4 PRM_Value ! 4
Integer *2 PTY ! 2 Protocol type
Integer *4 PTY_Value ! 4
! --
! 24 bytes total length
End Map
Map
Byte All
End Map
End Union
End Structure
Parameter Set_Lg = 24
Structure /DescDef/
Integer *2 Length
Byte Type
Byte Class
Integer *4 Address
End Structure
Structure /IOSBDef/
Integer *2 Condition
Integer *2 Count
Integer *4 Specific
End Structure
Structure /HeaderDef/
Byte Destination(6)
Byte Source(6)
Integer *2 Protocol
End Structure
C I can't find a $NMADEF anywhere so define the values I need
Parameter NMA$C_PCLI_BFN = 1105
Parameter NMA$C_PCLI_BUS = 2801
Parameter NMA$C_PCLI_PRM = 2840
Parameter NMA$C_PCLI_PTY = 2830
Parameter NMA$C_State_On = 0
Parameter NMA$C_State_Off = 1
C Parameter Definitions
Integer NAddr
Parameter (NAddr = 100)
Integer NProt
Parameter (NProt = 50)
C Local Definitions
Record /SetDef/ Set
Record /DescDef/ Set_Desc
Integer *4 Status, Function, I, N, DesdProtocol
Integer *2 Channel
Record /IOSBDef/ IOSB
Record /HeaderDef/ Header
Byte Buffer(1500)
Byte Address(6,NAddr)
Integer Source_Count(NAddr)
Integer Destination_Count(NAddr)
Integer XAddr
Integer Prot(NProt)
Integer Prot_Count(NProt)
Integer XProt
Character *16 Func
Integer J, Found
C Begin
Print '(A,$)', ' Protocol type (Hex) = '
Read '(Z)', DesdProtocol
Print '(A,Z3.3)', ' Protocol type = ', DesdProtocol
1 Print '(A,$)', ' Function = '
Read '(A)', Func
If (Func .eq. 'trace') Then
Else If (Func .eq. 'summary') Then
Else If (Func .eq. ' ') Then
Func = 'trace'
Else
Print '(A)', ' Illegal function, type "trace" or "summary"'
Goto 1
EndIf
XProt = 1
Prot(1) = 0
XAddr = 1 ! Address(n,1) is default
Do I = 1,6
Address(I,1) = 0
EndDo
Set.BFN = NMA$C_PCLI_BFN ! Number of preallocated
Set.BFN_Value = 4 ! receive buffers
Set.BUS = NMA$C_PCLI_BUS ! Maximum allowable
Set.BUS_Value = 1500 ! buffer length
Set.PRM = NMA$C_PCLI_PRM ! Set promiscuous (all packets)
Set.PRM_Value = NMA$C_State_On ! mode
Set.PTY = NMA$C_PCLI_PTY ! Set protocol type
Set.PTY_Value = 0
Set_Desc.Length = Set_Lg
Set_Desc.Type = 0
Set_Desc.Class = 0
Set_Desc.Address = %Loc(Set.All)
C Open a channel to the DEUNA
Status = Sys$Assign ('XEA0', Channel,,)
If (.not. Status) Then
Print '(A,Z)', ' Assign channel failed, status = ', Status
Stop
EndIf
C Set parameters and start Ethernet channel
Function = IO$_SetMode + IO$M_Ctrl + IO$M_StartUp
Status = Sys$QIOW
$ (, ! efn
$ %Val(Channel), ! chan
$ %Val(Function), ! func
$ IOSB, ! iosb
$ , ! astadr
$ , ! astprm
$ , ! p1
$ Set_Desc, ! p2
$ ,,, ! p3 - p6
$ )
If (.not. Status) Then
Print '(A,Z)', ' SetMode and startup failed, status = ',
$ Status
Stop
EndIf
If (.not. IOSB.Condition) Then
Print '(A,Z)',
$ ' SetMode and startup failed, IOSB.Condition = ',
$ IOSB.Condition
Stop
EndIf
C Monitor the Ethernet
If (Func .eq. 'trace') Then
Print '(2(x,A12),x,A4,x,A4,x,A)',
$ 'Source ',
$ 'Destination ',
$ 'Prot',
$ 'Lg. ',
$ 'Data'
EndIf
N = 0
Do While ((Status) .and. (N .lt. 1000))
N = N + 1
Function = IO$_ReadVBlk
Status = Sys$QIOW
$ (, ! efn
$ %Val(Channel), ! chan
$ %Val(Function), ! func
$ IOSB, ! iosb
$ , ! astadr
$ , ! astprm
$ Buffer, ! p1
$ %Val(1500), ! p2
$ , ! p3
$ , ! p4
$ Header, ! p5
$ ! p6
$ )
If (Status) Then
If ((DesdProtocol .eq. 0) .or.
$ (Header.Protocol .eq. DesdProtocol)
$ ) Then
If (Func .eq. 'trace') Then
Print '(2(x,6Z2.2),x,Z4.4,x,Z4.4,32(x,Z2.2))',
$ (Header.Source(I), I=6,1,-1),
$ (Header.Destination(I), I=6,1,-1),
$ Header.Protocol,
$ IOSB.Count,
$ (Buffer(I), I=1,15)
Else
c If (XAddr .gt. 1) Then
Found = 0
I = 2
Do While ((.not. Found) .and. (I .le. XAddr))
Do J = 1,6
If (Address(J,I) .ne. Header.Source(J)) Then
I = I + 1
Goto 2
EndIf
EndDo
Found = 1
2 Continue
EndDo
c Else
c Found = 0
c EndIf
If (.not. Found) Then
If (I .le. NAddr) Then
XAddr = I
Do J = 1,6
Address(J,I) = Header.Source(J)
EndDo
Else
I = 1
EndIf
EndIf
Source_Count(I) = Source_Count(I) + 1
C Record protocol
Found = 0
I = 2
Do While ((.not. Found) .and. (I .le. XProt))
If (Prot(I) .eq. Header.Protocol) Then
Found = 1
Else
I = I + 1
EndIf
End Do
If (.not. Found) Then
If (I .gt. NProt) Then
I = 1
Else
XProt = I
Prot(XProt) = Header.Protocol
Prot_Count(XProt) = 0
EndIf
EndIf
Prot_Count(I) = Prot_Count(I) + 1
EndIf
EndIf
Else
Print '(x,Z)', Status
EndIf
EndDo
C Print summary if selected
If (Func .eq. 'summary') Then
Do I = 1, XAddr
Print '(x,6(z2.2,x), I10, I10)',
$ (Address(J,I), J=1,6),
$ Source_Count(I), Destination_Count(I)
EndDo
Print '(x,z4.4,i10)', (Prot(I),Prot_Count(I),I=1,XProt)
EndIf
End