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