From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP 29-SEP-1988 05:52
To:	ARISIA::EVERHART
Subj:	Ethernet prosmiscuous mode problems


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Wed, 28 SEP 88 10:59:17 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Wed, 28 Sep 88 10:59:21 PDT
Received: by ucbvax.Berkeley.EDU (5.59/1.31)
	id AA13774; Wed, 28 Sep 88 08:15:58 PDT
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 27 Sep 88 13:54:11 GMT
From: dogie!dorl%vms.macc.wisc.edu@speedy.cs.wisc.edu  (Michael Dorl - MACC)
Organization: University of Wisconsin Academic Computing Center
Subject: Ethernet prosmiscuous mode problems
Message-Id: <721@dogie.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

Some time ago, I posted a query on problems I had using
promiscuous mode on a Vax station 2000 with VMS 4.7A in
a Ethernet monitor program.

Thanks to the several folks who made valuable suggestions
to help isolate and correct the problem.  I had already
learned that various versions of VMS differ in requiring
or prohibiting a protocol type parameter when establishing
promiscous mode and the program tried it both ways.  The
problem with the Vax station 2000 with VMS 4.7A was that
it not only required a protocol parameter but it also
required that the parmeter be a legal value.  I fixed the
problem by specifying a protocol value of ffff.  The program
now works on

 8600			VMS 4.6
 Vax station 2000	VMS 4.7A VMS 5.0

Here's a updated version with the fix and several cosmetic changes.

	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   Pad             !  2 Padding option
	  Integer  *4   Pad_Value       !  4
	  Integer  *2   PTy             !  2 Protocol
          Integer  *4   Pty_Value       !  4

					! --
					! 30 bytes total length
         End Map

         Map
          Byte          All
         End Map
	 End Union

	End Structure

	Parameter Set_Lg = 30		! Try with PTy first

        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/
	 Union      
	  Map
          Byte        Destination(6)
	  Byte        Source(6)
	  EndMap
	  Map
	   Byte	      Addresses(6,2)
	  EndMap
	 EndUnion
	 Union
	  Map
           Integer *2 Protocol
	  End Map
	  Map
	   Byte       Protocol_Bytes(2)
	  End Map
	 End Union
        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_PCLI_Pad  = 2842
	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

	Integer *4	  DesdProtocolX
	Integer *2	  DesdProtocol
	Equivalence	  (DesdProtocol, DesdProtocolX)

	Integer *2 	  Channel

 	Record /IOSBDef/  IOSB

	Record /HeaderDef/ Header

	Byte 		  Buffer(1500)

        Byte              Address(6,NAddr)
        Integer           Source_Count(NAddr)
        Integer           Destination_Count(NAddr)
	Byte		  OneSource(6,NAddr)
	Integer		  OneProt(NAddr)

        Integer           XAddr
        Integer           Prot(NProt)
        Integer           Prot_Count(NProt)
        Integer		  Prot_Mlt_Count(NProt)

        Integer           XProt
	Character *4      Device
        Character *16     Func
        Integer		  J
	Integer		  Found
	Integer           NBuffers
	Integer   	  DS,DE,DN
	Logical		  PTY_Tried	! This is needed because DEC
					! changed PTY from a required
					! parameter in pre VMS 4.6
					! to one which is not allowed
					! with PRM in VMS 4.6

	Integer		  Max_Bytes	! Maximum number of bytes to dump
	Integer		  SD
	Integer		  Z

	Real		  Time

C	Begin

C Get Parameters

	Func = ' '
	Do While (Func .eq. ' ')
          Print '(A,$)', ' Function (trace)?  '
          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"'
	    Func = ' '
          EndIf
	End Do
	Print '(A,$)', ' Number of buffers (1000)?  '
	Read '(I)', NBuffers
	If (NBuffers .le. 0) Then 
	  NBuffers = 1000
	EndIf

        Print '(A,$)', ' Device (XEA0)?  '
        Read '(A)', Device
	If (Device .eq. ' ') Then
	  Device = 'XEA0'
	EndIf

	If (Func .eq. 'trace') Then
	Print '(A,$)', ' Protocol type, hex (all)  '
	Read '(Z)', DesdProtocolX

	Print '(A,$)', ' Maximum number of bytes to dump (10)?  '
	Read '(I)', Max_Bytes
	If (Max_Bytes .le. 0) Then
	  Max_Bytes = 10
	EndIf
	EndIf

C Initialize summary data

        XProt = 2			! 1 = overflow, 2 = 802.3
        Prot(1) = 0
        XAddr = 1			! Address(n,1) is default
        Do I = 1,6
          Address(I,1) = 0
        EndDo

C Open a channel to the DEUNA

	Status = Sys$Assign (Device, Channel,,)
	If (.not. Status) Then
          Print '(A,Z)', ' Assign channel failed, status = ', Status
	  Stop
	EndIf

C Set parameters and start Ethernet channel

	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 = 'ffff'X

	Set.Pad = NMA$C_PCLI_Pad	! Padding option
	Set.Pad_Value = NMA$C_State_Off

	PTY_Tried = .false.
	Set_Desc.Length = Set_Lg
	Set_Desc.Type = 0
	Set_Desc.Class = 0
	Set_Desc.Address = %Loc(Set.All)

7       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
	  If ((IOSB.Condition .eq. '14'x) .and. (.not. PTY_Tried)) Then
            Print '(A)', ' IOSB.Condition=14, retrying without PTY'
	    Set_Desc.Length = Set_Lg - 6
	    PTY_Tried = .true.
	    Goto 7
	  EndIf
  	  Print '(A,Z,A,Z)',
     $      ' SetMode and startup failed, IOSB.Condition = ',
     $ 	    IOSB.Condition,
     $      '  IOSB.Specific = ', IOSB.Specific
	  Stop
	EndIf

C Monitor the Ethernet

        If (Func .eq. 'trace') Then
          Print '(2(x,A12),x,A4,x,A4,x,A4,x,A4)',
     $      'Source      ',
     $      'Destination ',
     $      'Prot',
     $      'Lg. ',
     $      ' Off',
     $      'Data'
        EndIf

	N = 0

	Time = Secnds (0.0)

	Do While ((Status) .and. (N .lt. NBuffers))

          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
	    I = Header.Protocol_Bytes(1)
	    Header.Protocol_Bytes(1) = Header.Protocol_Bytes(2)
	    Header.Protocol_Bytes(2) = I
            If ((DesdProtocol .eq. 0) .or. 
     $	        (Header.Protocol .eq. DesdProtocol)
     $         ) Then
              If (Func .eq. 'trace') Then
	        DN = IOSB.Count
	        If (DN .gt. Max_Bytes) Then
		  DN = Max_Bytes
	 	EndIf
	        DS = 1
	        DE = DE + IOSB.Count - 1
	        If ((DE - DS + 1) .gt. 10) Then 
	          DE = DS + 9
	 	EndIf
    	        Print '(2(x,6Z2.2),x,Z4.4,x,Z4.4,x,A4,T42,10(x,z2.2))',
     $            (Header.Source(I), I=1,6),
     $            (Header.Destination(I), I=1,6),
     $            Header.Protocol,
     $            IOSB.Count,
     $            '   1',
     $            (Buffer(I), I=DS,DE)
		DN = DN - 10
	        Do While (DN .gt. 0)	
		  DS = DE + 1
	          DE = DS + DN - 1
	          If ((DE - DS +1) .gt. 10) Then
	            DE = DS + 9
	          EndIf
	          Print '(T38,z4,10(x,z2.2))', 
     $		    DS,
     $              (Buffer(I), I=DS,DE)
		  DN = DN - 10
	        End Do
              Else
	        Do SD = 1,2
                  Found = 0
		  I = 2
		  Do While ((.not. Found) .and. (I .le. XAddr))
                    Do J = 1,6
                      If (Address(J,I) .ne. Header.Addresses(J,SD)) Then
                        I = I + 1
			Goto 2
                      EndIf
                    EndDo
                    Found = 1
2                   Continue
		  EndDo
                  If (.not. Found) Then
                    If (I .le. NAddr) Then
                      XAddr = I
                      Do J = 1,6
                        Address(J,I) = Header.Addresses(J,SD)
                      EndDo
                    Else
                      I = 1
                    EndIf
                  EndIf
		  If (SD .eq. 1) Then
                    Destination_Count(I) = Destination_Count(I) + 1
		    Do Z=1,6
		      OneSource(Z,I) = Header.Source(Z)
		      OneProt(I) = Header.Protocol
		    EndDo
		  Else
                    Source_Count(I) = Source_Count(I) + 1
		  EndIf
		EndDo

C Record protocol

		If (
     $              (Header.Protocol .le. 1518) 
     $		    .and. 
     $              (Header.Protocol .gt. 0) 
     $             )
     $          Then ! 802.3 packet
		  Found = 1
		  I = 2
		Else
                  Found = 0
                  I = 3
                  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
		      Prot_Mlt_Count(XProt) = 0
                    EndIf
                  EndIf
		EndIf

	        If (IAnd(ZExt(Header.Destination(1)),1) .ne. 0) Then
		  Prot_Mlt_Count(I) = Prot_Mlt_Count(I) + 1
		Else
                  Prot_Count(I) = Prot_Count(I) + 1
		EndIf

              EndIf
	    EndIf
          Else
	    Print '(x,Z)', Status
	  EndIf

	EndDo

C Print summary if selected

	Time = Secnds (Time)

        If (Func .eq. 'summary') Then
	  Print '(A,F6.2,//)', ' Elapsed time = ', Time
	  Print '(A)',
     $      '      Address  # Source  Source/S    # Dest    Dest/S' //
     $      '   One Source Prot'
          Do I = 1, XAddr
            Print 
     $      '(x,6z2.2, I10, F10.1, I10, F10.1 ,x,6z2.2,x,z4.4)',
     $        (Address(J,I), J=1,6),
     $        Source_Count(I), Source_Count(I)/Time,
     $        Destination_Count(I), Destination_Count(I)/Time, 
     $        (OneSource(J,I),J=1,6),
     $        JIBits(OneProt(I),0,16)
          EndDo
	  Print '(A)', ' Prot     Count Count/Sec     Multi Multi/Sec'
	  Do I=1,XProt
            Print '(x,z4.4,2(i10,f10.1))',
     $       JIBits(Prot(I),0,16),
     $       Prot_Count(I),
     $       Prot_Count(I)/Time,
     $       Prot_Mlt_Count(I),
     $       Prot_Mlt_Count(I)/Time
	  EndDo
        EndIf

	End

Michael Dorl (608) 262-0466
dorl@vms.macc.wisc.edu
dorl@wiscmacc.bitnet

