$! ................... Cut between dotted lines and save. ................... $!........................................................................... $! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989. $! $! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from $! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au). $! $! To unpack, simply save, concatinate all parts into one file and $! execute (@) that file. $! $! This archive was created by user PHILIPPE $! on 12-JUL-1989 17:50:32.20. $! $! It contains the following 12 files: $! AAAREADME.TXT $! BUILD_ETHERMON.COM $! COMMAND_LINE.PAS $! DISPLAY.PAS $! ETHERMON.CLD $! ETHERMON.OPT $! ETHERMON.PAS $! ETHERMONLET.PAS $! ETHERMON_SETUP.COM $! INITIALIZE.PAS $! NODE_NAMES.DAT $! PROCESS_DATA.PAS $! $!============================================================================ $ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL ) $ VERSION = F$GETSYI( "VERSION" ) $ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK $ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", - "VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher." $ EXIT 44 ! SS$_ABORT $VERSION_OK: $ GOTO START $! $UNPACK_FILE: $ WRITE SYS$OUTPUT "Creating ''FILE_IS'" $ DEFINE/USER_MODE SYS$OUTPUT NL: $ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION - VMS_SHARE_DUMMY.DUMMY b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) ) ; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE , b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors := 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN & "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION ( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail & LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP ; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK ( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 ) ; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF ; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ) ; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ) ; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF ; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE ; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1 ; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF ; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors := i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT ( "The following line could not be unpacked properly:" ); SPLIT_LINE ; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL ( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH ( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1 ); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP ; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION ( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO ( "The following !UL errors were detected while unpacking !AS", i_errors , s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" ) ; ENDIF; EXIT; $ DELETE VMS_SHARE_DUMMY.DUMMY;* $ CHECKSUM 'FILE_IS $ WRITE SYS$OUTPUT " CHECKSUM ", - F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." ) $ RETURN $! $START: $ FILE_IS = "AAAREADME.TXT" $ CHECKSUM_IS = 593131449 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY XETHERMON is a demonstration program to give you some general idea about XEthernet traffic. It will show you information on which nodes are top senders Xand receivers, how much data is seen, and how many packets are captured. XPrivilege to be promiscuous is required. X XIt is not intended to be a serious networking diagnostic tool. We know, for Xexample, that is does not see every single packet that goes by (on the other Xhand, neither do similar tools that you pay for). It was not written for the Vgeneral case, but we have tried to make it as general as possible. It has bee Xn Xtested successfully on the following configurations: X X`009VAX 8550`009`009DEBNA`009`009VAX/VMS A5.0-1 X`009VAXStation II/GPX`009DEQNA`009`009VAX/VMS V5.0-1 X VThis program was originally written for VMS 4.x and has had just a few change Xs Vfor V5. If you need to make it work on V4, it shouldn't be more than massagin Xg Xa few run-time library calls. X X***********************`009`009To use it:`009****************************** X V1) Modify the ETHERMON_SETUP.COM file, changing the lines marked site specifi Xc Vto reflect the location of these files, and the controller type of the Ethern Xet Xcontroller. Execute this setup file. X X2) Edit the file NODE_NAMES.DAT to catalog your node names and Ethernet Xaddresses. X X3) Now, you can invoke it with X X`009$ ETHERMON [/INTERVAL=update_interval] X X***********************`009`009To build it:`009****************************** X XIf you need to / want to make changes, you need to edit BUILD_ETHERMON.COM to Vchange the site-specific lines. This command procedure can be used to build i Xt. X X XAgain, this program wasn't written for the general case. If you need to make Vchanges to make it work for you, or if you have any suggestions, please get i Xn Vtouch with us so we can get a better version ready to submit to the SIG tape X in XAtlanta. X`009`009`009`009`009`009Kevin Angley or Dave Moore X`009`009`009`009`009`009Memorex Telex X`009`009`009`009`009`0093301 Terminal Drive X`009`009`009`009`009`009Raleigh, N.C. 27610 X`009`009`009`009`009`009(919) 890-1416 or X`009`009`009`009`009`009(800) 334-4380 ext. 416. $ GOSUB UNPACK_FILE $ FILE_IS = "BUILD_ETHERMON.COM" $ CHECKSUM_IS = 1058151643 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY V$ assign/nolog disk$pageswapper:[us114246.ethermon] ethermon_directory`009! S Xite specific X$ debug_compile_switch := "" X$ debug_link_switch := "" X$ if p1 .nes. "" then debug_compile_switch := "/DEBUG/NOOPTIMIZE" X$ if p1 .nes. "" then debug_link_switch := "/DEBUG" X$ set default ethermon_directory X$ pas/env ethermonlet 'debug_compile_switch' X$ pas command_line 'debug_compile_switch' X$ pas display 'debug_compile_switch' X$ pas ethermon 'debug_compile_switch' X$ pas initialize 'debug_compile_switch' X$ pas process_data 'debug_compile_switch' X$ link ethermon/opt 'debug_link_switch' $ GOSUB UNPACK_FILE $ FILE_IS = "COMMAND_LINE.PAS" $ CHECKSUM_IS = 1829722760 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X[INHERIT ('SYS$LIBRARY:STARLET.PEN', X`009 'ethermon_directory:ETHERMONLET.PEN')] XMODULE Parse_Line(OUTPUT); X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Parse_Command_Line; X XVAR X`009Stat`009`009: INTEGER; X`009Interval_String`009: VARYING [133] OF CHAR; X XBEGIN X X IF (CLI$PRESENT('INTERVAL') = CLI$_ABSENT) THEN X Interval := 3.0 X ELSE X BEGIN X Stat := CLI$GET_VALUE('INTERVAL',Interval_String); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X READV(Interval_String,Interval); X IF (Interval < 0.3) THEN Interval := 0.3; X END; X XEND; X V`123************************************************************************* X*********************************************************`125 X XEND. $ GOSUB UNPACK_FILE $ FILE_IS = "DISPLAY.PAS" $ CHECKSUM_IS = 190998497 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X[INHERIT ('SYS$LIBRARY:STARLET.PEN', X`009 'ethermon_directory:ETHERMONLET.PEN')] XMODULE Ethernet_Display(OUTPUT); `032 X V`123************************************************************************* X*********************************************************`125 X V[GLOBAL] FUNCTION Get_Node_Name_From_Address(Ethernet_Address`009: Ethernet_A Xddress_Type): String_6; X XVAR X`009Ptr`009`009: Node_Name_Ptr; X `009Found`009`009: BOOLEAN; X`009Work_String`009: VARYING [6] OF CHAR; X`009I`009`009: INTEGER; X XBEGIN X X Found := FALSE; X Ptr := Node_Name_List; X WHILE (NOT Found) AND (Ptr`094.Next_Node <> NIL) DO X BEGIN X Ptr := Ptr`094.Next_Node; X IF (Ethernet_Address = Ptr`094.Ethernet_Address) THEN X`009BEGIN X`009 Found := TRUE; X`009 Get_Node_Name_From_Address := Ptr`094.Node_Name; X`009END; X END; X V IF (NOT Found) THEN`009`009`009`009`009`009`009`123 If you can't find it in X the node list return the`009`125 V BEGIN`009`009`009`009`009`009`009`009`123 first six characters of the Eth Xernet address.`009`009`125 X Work_String := ''; X FOR I := 1 TO 3 DO X`009Work_String := Work_String + HEX(ORD(Ethernet_Address[I]),2); X Get_Node_Name_From_Address := Work_String; X END; X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Display_Counts; X XVAR X`009Time_String`009`009: PACKED ARRAY [1..11] OF CHAR; X`009Date_String`009`009: PACKED ARRAY [1..11] OF CHAR; X`009Node_Name_String`009: VARYING [6] OF CHAR; X`009Number_String`009`009: VARYING [20] OF CHAR; X`009Graph_String`009`009: VARYING [25] OF CHAR; X`009Stat`009`009`009: INTEGER; X X`009Ptr`009`009`009: List_Ptr; X`009Rec_Count_Array`009`009: ARRAY [1..8] OF Count_Type; X`009Xmit_Count_Array`009: ARRAY [1..8] OF Count_Type; X`009I`009`009`009: INTEGER; X`009J`009`009`009: INTEGER; X`009Inserted`009`009: BOOLEAN; X XBEGIN X X DATE(Date_String); X TIME(Time_String); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Date_String + ' ' + SUBSTR(Time_String,1,8), X`009`009`009START_ROW`009:= 3, X`009`009`009START_COLUMN`009:= 30); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Packets_Per_Second:7:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 7, X`009`009`009START_COLUMN`009:= 27); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Packet_Average:7:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 7, X`009`009`009START_COLUMN`009:= 41); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Min_Packets:7:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 7, X`009`009`009START_COLUMN`009:= 55); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Max_Packets:7:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 7, X`009`009`009START_COLUMN`009:= 69); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Bytes_Per_Second:10:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 8, X`009`009`009START_COLUMN`009:= 24); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Byte_Average:10:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 8, X`009`009`009START_COLUMN`009:= 38); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Min_Bytes:10:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 8, X`009`009`009START_COLUMN`009:= 52); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X WRITEV(Number_String, Max_Bytes:10:2); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Number_String, X`009`009`009START_ROW`009:= 8, X`009`009`009START_COLUMN`009:= 66); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X V FOR I := 1 TO 8 DO Xmit_Count_Array[I].Count := 0;`009`009`009`009`123 figu Xre out the top 8 transmitters `125 X Ptr := Transmit_List; X WHILE (Ptr`094.Next_Element <> NIL) DO X BEGIN X Ptr := Ptr`094.Next_Element; X Inserted := FALSE; X I := 1; X WHILE (NOT Inserted) AND (I <= 8) DO X`009BEGIN X`009 IF (Ptr`094.Count > Xmit_Count_Array[I].Count) THEN X`009 BEGIN X`009 FOR J := 8 DOWNTO I+1 DO X`009`009BEGIN V`009`009 Xmit_Count_Array[J].Ethernet_Address := Xmit_Count_Array[J-1].Ether Xnet_Address; X`009`009 Xmit_Count_Array[J].Count := Xmit_Count_Array[J-1].Count; X`009`009END; X`009 Xmit_Count_Array[I].Ethernet_Address := Ptr`094.Ethernet_Address; X`009 Xmit_Count_Array[I].Count := Ptr`094.Count; X`009 Inserted := TRUE; X`009 END; X`009 I := I + 1; X`009END; X END; X V FOR I := 1 TO 8 DO Rec_Count_Array[I].Count := 0;`009`009`009`009`009`123 f Xigure out the top 8 receivers `125 X Ptr := Receive_List; X WHILE (Ptr`094.Next_Element <> NIL) DO X BEGIN X Ptr := Ptr`094.Next_Element; X Inserted := FALSE; X I := 1; X WHILE (NOT Inserted) AND (I <= 8) DO X`009BEGIN X`009 IF (Ptr`094.Count > Rec_Count_Array[I].Count) THEN X`009 BEGIN X`009 FOR J := 8 DOWNTO I+1 DO X`009`009BEGIN V`009`009 Rec_Count_Array[J].Ethernet_Address := Rec_Count_Array[J-1].Etherne Xt_Address; X`009`009 Rec_Count_Array[J].Count := Rec_Count_Array[J-1].Count; X`009`009END; X`009 Rec_Count_Array[I].Ethernet_Address := Ptr`094.Ethernet_Address; X`009 Rec_Count_Array[I].Count := Ptr`094.Count; X`009 Inserted := TRUE; X`009 END; X`009 I := I + 1; X`009END; X END; X V FOR I := 1 TO 8 DO`009`009`009`009`009`009`009`009`123 display the top eigh Xt transmitters `125 X BEGIN X IF (Xmit_Count_Array[I].Count > 0) THEN X`009BEGIN X`009 WRITEV(Number_String,Xmit_Count_Array[I].Count:5); V`009 IF (Xmit_Count_Array[I].Count > 96) THEN Xmit_Count_Array[I].Count := 9 X6; V`009 Graph_String := PAD(PAD('',CHR(97),(Xmit_Count_Array[I].Count DIV 4) + X 1),' ',25); V`009 Node_Name_String := Get_Node_Name_From_Address(Xmit_Count_Array[I].Ethe Xrnet_Address); X`009END X ELSE X`009BEGIN X`009 Node_Name_String := ' '; X`009 Number_String := ' '; X`009 Graph_String := ' '; X`009END; X Stat := SMG$PUT_CHARS(DISPLAY_ID`009`009:= Display_ID, X`009`009`009 TEXT`009`009:= Node_Name_String, X`009`009`009 START_ROW`009`009:= I + 13, X`009`009`009 START_COLUMN`009:= 1); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009`009:= Display_ID, X`009`009`009 TEXT`009`009:= Number_String, X`009`009`009 START_ROW`009`009:= I + 13, X`009`009`009 START_COLUMN`009:= 7); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009`009:= Display_ID, X`009`009`009 TEXT`009`009:= Graph_String, X`009`009`009 START_ROW`009`009:= I + 13, X`009`009`009 START_COLUMN`009:= 13, X`009`009`009 CHARACTER_SET`009:= SMG$C_SPEC_GRAPHICS); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X END; X V FOR I := 1 TO 8 DO`009`009`009`009`009`009`009`009`123 display the top eigh Xt receviers `125 X BEGIN X IF (Rec_Count_Array[I].Count > 0) THEN X`009BEGIN X`009 WRITEV(Number_String,Rec_Count_Array[I].Count:5); X`009 IF (Rec_Count_Array[I].Count > 96) THEN Rec_Count_Array[I].Count := 96; V`009 Graph_String := PAD(PAD('',CHR(97),(Rec_Count_Array[I].Count DIV 4) + 1 X),' ',25); V`009 Node_Name_String := Get_Node_Name_From_Address(Rec_Count_Array[I].Ether Xnet_Address); X`009END X ELSE X`009BEGIN X`009 Node_Name_String := ' '; X`009 Number_String := ' '; X`009 Graph_String := ' '; X`009END; X Stat := SMG$PUT_CHARS(DISPLAY_ID`009`009:= Display_ID, X`009`009`009 TEXT`009`009:= Node_Name_String, X`009`009`009 START_ROW`009`009:= I + 13, X`009`009`009 START_COLUMN`009:= 41); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009`009:= Display_ID, X`009`009`009 TEXT`009`009:= Number_String, X`009`009`009 START_ROW`009`009:= I + 13, X`009`009`009 START_COLUMN`009:= 48); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009`009:= Display_ID, X`009`009`009 TEXT`009`009:= Graph_String, X`009`009`009 START_ROW`009`009:= I + 13, X`009`009`009 START_COLUMN`009:= 54, X`009`009`009 CHARACTER_SET`009:= SMG$C_SPEC_GRAPHICS); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X END; X XEND; X V`123************************************************************************* X*********************************************************`125 X XEND. $ GOSUB UNPACK_FILE $ FILE_IS = "ETHERMON.CLD" $ CHECKSUM_IS = 1782871846 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X`009!`009CLD file for ETHERMON X `009! X`009define`009verb`009`009ETHERMON X`009`009image`009`009ethermon_directory:ETHERMON X`009! X`009qualifier`009`009INTERVAL,`032 X`009`009`009`009VALUE(TYPE=$NUMBER,DEFAULT=3), X`009`009`009`009NONNEGATABLE $ GOSUB UNPACK_FILE $ FILE_IS = "ETHERMON.OPT" $ CHECKSUM_IS = 1410402249 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY Xethermon, - X`009command_line,- X`009display, - X`009ethermonlet, - X`009initialize, - X`009process_data $ GOSUB UNPACK_FILE $ FILE_IS = "ETHERMON.PAS" $ CHECKSUM_IS = 2118144809 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X[INHERIT ('SYS$LIBRARY:STARLET.PEN', X`009 'ethermon_directory:ETHERMONLET.PEN')] XPROGRAM Ethernet_Monitor(OUTPUT); X V`123************************************************************************* X*********************************************************`125 X V`123 Ethermon is a utility which may be used for getting some idea of the nat Xure of the Ethernet traffic on your LAN. It sets the V Ethernet controller in promiscuous mode and then monitors the packets which X go by for size, source, and destination. Although V it does not necessarily see every packet that goes by on the wire, it doe Xs give you a general idea of which nodes on the net- X work are talking to whom. X V The code is not very well commented (I originally wrote Ethermon as an exer Xcise after hearing about promiscuous mode somewhere) V and as the code is probably not all that intuitively obvious I'll take a mo Xment here to give an overview of how it works. The V program starts by initializing a linked list of all the nodes and their Et Xhernet addresses found in the file NODE_NAMES.DAT so V it can translate Ethernet addresses into node names. (I didn't want to l Xook in the DECnet database for this info because I V also wanted to monitor nodes running non-DECnet protocols.) It then sets th Xe Ethernet controller in promiscuous mode and queues V a number of asynchronous reads (five, in this version) to the controller. X After queueing an asynchronous read to the terminal V looking for a Control-Z, it goes into an infinite loop of hibernating for X the interval specified on the command line (default V of three seconds), waking up and displaying the data collected since the X last iteration, and then re-initializing the packet X transmit and receive count lists to zero. X V The actual processing of the collected data is performed by an AST upon com Xpletion of the QIO read to the controller. This AST V extracts the source address, destination address, and size of the packet ju Xst read and increments the count for the appropriate V nodes in the transmit and receive lists. It then requeues the read to the X controller. The assumption is made that the AST will V complete and the read be requeued before the other outstanding reads comple Xte, i.e., that there will always be at least one QIO V pending on the controller. There is no guarantee that this is true. If X the network traffic is very heavy or the CPU bogged V down, packets might slip by. In this case, more reads may could queued at X once by increasing the constant Receive_Count (found V in ETHERMONLET.PAS) above its current value of 5, and then rebuilding the e Xxecutable. X X David Moore X Memorex Telex X 3301 Terminal Drive X Raleigh, NC 27604 X (919)890-1527 X X`125 X V`123************************************************************************* X*********************************************************`125 X XBEGIN X X Parse_Command_Line; X Init_Node_Name_List; X Init_Display; X Init_Counts; X Assign_Channels; X Start_Qios; X `032 X WHILE (TRUE) DO X BEGIN X LIB$WAIT(Interval); X Update_Counts; X Display_Counts; X Re_Init_Counts; X END; X XEND. $ GOSUB UNPACK_FILE $ FILE_IS = "ETHERMONLET.PAS" $ CHECKSUM_IS = 1847736033 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X[INHERIT ('SYS$LIBRARY:STARLET.PEN')] XMODULE Ethernet_Monitor_Environment; X XCONST X`009Revision_Level`009`009= '1.3'; X`009Receive_Count`009`009= 5; X V`123************************************************************************* X*********************************************************`125 X V`123 This version of Ethermonlet includes definitions copied from Telex_Starl Xet X so that Ethermon can be built from a simpler distribution. `125 X X`009CLI$_ABSENT`009= %X'000381F0'; X`009CLI$_PRESENT`009= %X'0003FD19'; X`009NMA$C_STATE_ON`009= 0; X`009NMA$C_PCLI_PRM`009= 2840; X XTYPE X X`009Unsigned_Byte`009= [BYTE] 0..255; X`009Signed_Byte`009= [BYTE] -128..127; X`009Unsigned_Word`009= [WORD] 0..65535; X`009Signed_Word`009= [WORD] -32768..32767; X`009Unsigned_Quadword = RECORD X`009`009`009 L0: UNSIGNED; X`009`009`009 L1: UNSIGNED; X`009`009`009 END; X`009Signed_Quadword = RECORD X`009`009`009 L0: UNSIGNED; X`009`009`009 L1: INTEGER; X`009`009`009 END; X V`009IOSB_Type`009= RECORD`009`009`009`009`009`123 Common types required by va Xrious system services`009`125 X`009`009`009 Condition_Value`009: Unsigned_Word; X`009`009`009 Transfer_Count`009: Unsigned_Word; X`009`009`009 Terminator`009`009: Unsigned_Word; X`009`009`009 Terminator_Size`009: Unsigned_Word; X`009`009`009 END; X X`009Ethermon_controller_IOSB_Type = RECORD X`009`009`009 Condition_Value`009: Unsigned_Word; X`009`009`009 Transfer_Count`009: Unsigned_Word; X`009`009`009 Unused_1`009`009: Unsigned_Byte; X`009`009`009 Unit_Status_Bits`009: Unsigned_Byte; X`009`009`009 Error_Summary_Bits`009: Unsigned_Byte; X`009`009`009 Unused_2`009`009: Unsigned_Byte; X`009`009`009 END; X`009String_6`009`009`009= VARYING [6] OF CHAR; X X`009Extended_Char_Block_Type`009= RECORD X`009`009`009`009`009 Parameter_ID`009: Unsigned_Word; X`009`009`009`009`009 Value`009`009: UNSIGNED; X`009`009`009`009`009 END; X X`009Extended_Char_Descr_Type`009= RECORD X`009`009`009`009`009 Length`009`009: UNSIGNED; X`009`009`009`009`009 Address`009`009: UNSIGNED; X`009`009`009`009`009 END; X X`009Ethernet_Address_Type`009`009= PACKED ARRAY [1..6] OF CHAR; X X`009P5_Buffer_Type`009`009`009= RECORD X`009`009`009`009`009 Destination_Address`009: Ethernet_Address_Type; X`009`009`009`009`009 Source_Address`009: Ethernet_Address_Type; X`009`009`009`009`009 Protocol_Type`009: Unsigned_Word; X`009`009`009`009`009 END; X X`009Qio_Data_Structure`009`009= RECORD X`009`009`009`009`009 IOSB`009`009: Ethermon_controller_Iosb_Type; X`009`009`009`009`009 Receive_Buffer`009: PACKED ARRAY [1..1500] OF CHAR; X`009`009`009`009`009 P5_Buffer`009`009: P5_Buffer_Type; X`009`009`009`009`009 END; X X`009List_Ptr`009`009`009= `094List_Element; X X`009List_Element`009`009`009= [VOLATILE] RECORD X`009`009`009`009`009 Ethernet_Address`009: Ethernet_Address_Type; X`009`009`009`009`009 Count`009`009: INTEGER; X`009`009`009`009`009 Next_Element`009: List_Ptr; X`009`009`009`009`009 END; X X `009Node_Name_Ptr`009`009`009= `094Node_Name_Type; X X`009Node_Name_Type`009`009`009= RECORD X`009`009`009`009`009 Ethernet_Address`009: Ethernet_Address_Type; X`009`009`009`009`009 Node_Name`009`009: String_6; X`009`009`009`009`009 Next_Node`009`009: Node_Name_Ptr; X`009`009`009`009`009 END; X X`009Count_Type`009`009`009= RECORD X`009`009`009`009`009 Ethernet_Address`009: Ethernet_Address_Type; X`009`009`009`009`009 Node_Name`009`009: String_6; X`009`009`009`009`009 Count`009`009: INTEGER; X`009`009`009`009`009 END; X V`123************************************************************************* X*********************************************************`125 X XVAR X`009Interval`009`009`009: [GLOBAL] REAL; X X`009Ethermon_Controller_Channel`009: [GLOBAL,VOLATILE] Unsigned_Word; X`009Terminal_Channel`009`009: [GLOBAL,VOLATILE] Unsigned_Word; X`009Terminal_IOSB`009`009`009: [GLOBAL,VOLATILE] IOSB_Type; X`009Terminal_Buffer`009`009`009: [GLOBAL,VOLATILE] VARYING [1] OF CHAR; X`009Stat`009`009`009`009: [GLOBAL,VOLATILE] INTEGER; X`009Extended_Characteristics`009: [GLOBAL] Extended_Char_Block_Type; X`009Extended_Char_Descriptor`009: [GLOBAL] Extended_Char_Descr_Type; X X`009Array_Index`009`009`009: [GLOBAL,VOLATILE] INTEGER; V`009Qio_Data`009`009`009: [GLOBAL,VOLATILE] ARRAY [1..Receive_Count] OF Qio_D Xata_Structure; X X`009Packet_Count`009`009`009: [GLOBAL,VOLATILE] INTEGER; X`009Total_Packets`009`009`009: [GLOBAL] INTEGER; X`009Packets_Per_Second`009`009: [GLOBAL] REAL; X`009Packet_Average`009`009`009: [GLOBAL] REAL; X`009Max_Packets`009`009`009: [GLOBAL] REAL; X`009Min_Packets`009`009`009: [GLOBAL] REAL; X X`009Byte_Count`009`009`009: [GLOBAL,VOLATILE] INTEGER; X`009Total_Bytes`009`009`009: [GLOBAL] INTEGER; X`009Bytes_Per_Second`009`009: [GLOBAL] REAL; X`009Byte_Average`009`009`009: [GLOBAL] REAL; X`009Max_Bytes`009`009`009: [GLOBAL] REAL; X`009Min_Bytes`009`009`009: [GLOBAL] REAL; X X`009Time_Collecting`009`009`009: [GLOBAL] REAL; X X`009Pasteboard_ID`009`009`009: [GLOBAL,VOLATILE] UNSIGNED; X`009Display_ID`009`009`009: [GLOBAL,VOLATILE] UNSIGNED; X X`009Transmit_List`009`009`009: [GLOBAL,VOLATILE] List_Ptr; X`009Receive_List`009`009`009: [GLOBAL,VOLATILE] List_Ptr; X`009Node_Name_List`009`009`009: [GLOBAL] Node_Name_Ptr; X V`123************************************************************************* X*********************************************************`125 X X[EXTERNAL] PROCEDURE Assign_Channels; EXTERN; X X[EXTERNAL] PROCEDURE Display_Counts; EXTERN; X V[EXTERNAL] FUNCTION Get_Node_Name_From_Address(Ethernet_Address`009: Ethernet X_Address_Type): String_6; EXTERN; X X[EXTERNAL] PROCEDURE Init_Counts; EXTERN; X X[EXTERNAL] PROCEDURE Init_Display; EXTERN; X X[EXTERNAL] PROCEDURE Init_Node_Name_List; EXTERN; X X[EXTERNAL] PROCEDURE Parse_Command_Line; EXTERN; X X[EXTERNAL,ASYNCHRONOUS,UNBOUND] PROCEDURE Process_Traffic; EXTERN; X X[EXTERNAL,ASYNCHRONOUS,UNBOUND] PROCEDURE Process_Terminal_Input; EXTERN; X X[EXTERNAL] PROCEDURE Re_Init_Counts; EXTERN; X X[EXTERNAL] PROCEDURE Start_Qios; EXTERN; X X[EXTERNAL] PROCEDURE Update_Counts; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION LIB$WAIT X`009`009`009(%REF Seconds`009`009: REAL): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL,ASYNCHRONOUS] FUNCTION CLI$GET_VALUE X`009`009`009(%DESCR Entity_Desc`009`009: VARYING [u] OF CHAR; X`009`009`009 %DESCR Retdesc `009`009: VARYING [v] OF CHAR; X`009`009`009 %REF Retlength `009`009: Unsigned_Word := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL,ASYNCHRONOUS] FUNCTION CLI$PRESENT X`009`009`009(%DESCR Entity_Desc`009`009: VARYING [u] OF CHAR): X`009`009`009INTEGER; EXTERN; X V(**************************************************************************** X******************************************************) X(*`009`009`009`009`009`009`009`009`009`009`009`009`009`009`009`009 *) V(*`009`009`009`009`009`009`009SMG$ Library Routines`009`009`009`009`009`009`0 X09 *) X(*`009`009`009`009`009`009`009`009`009`009`009`009`009`009`009`009 *) V(**************************************************************************** X******************************************************) X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$CREATE_PASTEBOARD X`009`009`009(%REF Pasteboard_ID `009`009`009: UNSIGNED; V`009`009`009 %DESCR Output_Device`009`009`009: VARYING [u] OF CHAR := %IMMED X 0; X`009`009`009 %REF Number_of_Pasteboard_Rows`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Number_of_Pasteboard_Columns`009: INTEGER := %IMMED 0; X`009`009`009 %REF Flags`009`009`009`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Type_of_Terminal`009`009`009: UNSIGNED := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$CREATE_VIRTUAL_DISPLAY X`009`009`009(%REF Number_of_Rows`009`009: INTEGER; X`009`009`009 %REF Number_of_Columns`009`009: INTEGER; X`009`009`009 %REF Display_Id`009`009: UNSIGNED; X`009`009`009 %REF Display_Attributes`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Video_Attributes`009`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Character_Set`009`009: UNSIGNED := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$DRAW_LINE X`009`009`009(%REF Display_ID`009`009: UNSIGNED; X`009`009`009 %REF Start_Row `009`009: INTEGER; X`009`009`009 %REF Start_Column`009`009: INTEGER; X`009`009`009 %REF End_Row`009`009`009: INTEGER; X`009`009`009 %REF End_Column`009`009: INTEGER; X`009`009`009 %REF Rendition_Set`009`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Rendition_Complement`009: UNSIGNED := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$PASTE_VIRTUAL_DISPLAY X`009`009`009(%REF Display_ID`009`009: UNSIGNED; X`009`009`009 %REF Pasteboard_ID`009`009: UNSIGNED; X`009`009`009 %REF Pasteboard_Row`009`009: INTEGER; X`009`009`009 %REF Pasteboard_Column `009: INTEGER; X`009`009`009 %REF Top_Display_ID`009`009: UNSIGNED := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$PUT_CHARS X`009`009`009(%REF Display_ID`009`009: UNSIGNED; X`009`009`009 %DESCR Text`009`009`009: VARYING [u] OF CHAR; X`009`009`009 %REF Start_Row`009`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Start_Column`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Flags`009`009`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Rendition_Set`009`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Rendition_Complement`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Character_Set`009`009: UNSIGNED := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$SCROLL_DISPLAY_AREA X`009`009`009(%REF Display_ID`009`009: UNSIGNED; X`009`009`009 %REF Start_Row`009`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Start_Column`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Height`009`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Width`009`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Direction `009`009: UNSIGNED := %IMMED 0; X`009`009`009 %REF Count`009`009`009: INTEGER := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$SET_CURSOR_ABS X`009`009`009(%REF Display_ID`009`009: UNSIGNED; X`009`009`009 %REF Start_Row`009`009`009: INTEGER := %IMMED 0; X`009`009`009 %REF Start_Column`009`009: INTEGER := %IMMED 0): X`009`009`009INTEGER; EXTERN; X X[EXTERNAL, ASYNCHRONOUS] FUNCTION SMG$SET_CURSOR_MODE X`009`009`009(%REF Pasteboard_ID`009`009: UNSIGNED; X`009`009`009 %REF Flags`009`009`009: UNSIGNED): X`009`009`009INTEGER; EXTERN; X XEND. $ GOSUB UNPACK_FILE $ FILE_IS = "ETHERMON_SETUP.COM" $ CHECKSUM_IS = 1903320121 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$ assign/nolog decus$root:[ethermon] ethermon_directory`009! Site-specific X$ assign/nolog ET ethermon_controller`009`009`009`009! Site-specific X$ set command ethermon_directory:ethermon X$ exit $ GOSUB UNPACK_FILE $ FILE_IS = "INITIALIZE.PAS" $ CHECKSUM_IS = 1462334094 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X[INHERIT ('SYS$LIBRARY:STARLET.PEN', X`009 'ethermon_directory:ETHERMONLET.PEN')] XMODULE Ethernet_Initialize(OUTPUT); X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Re_Init_Counts; X XVAR X`009Ptr_1`009`009: List_Ptr; X`009Ptr_2`009`009: List_Ptr; X XBEGIN X X Packet_Count := 0; X Byte_Count := 0; X X Ptr_1 := Transmit_List`094.Next_Element; X WHILE (Ptr_1 <> NIL) DO X BEGIN X Ptr_2 := Ptr_1`094.Next_Element; X DISPOSE(Ptr_1); X Ptr_1 := Ptr_2; X END; X Transmit_List`094.Next_Element := NIL; X X Ptr_1 := Receive_List`094.Next_Element; X WHILE (Ptr_1 <> NIL) DO X BEGIN X Ptr_2 := Ptr_1`094.Next_Element; X DISPOSE(Ptr_1); X Ptr_1 := Ptr_2; X END; X Receive_List`094.Next_Element := NIL; X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Init_Display; X XVAR X `009Stat`009`009: INTEGER; X`009Date_String`009: PACKED ARRAY [1..11] OF CHAR; X`009Time_String`009: PACKED ARRAY [1..11] OF CHAR; X XBEGIN X X Stat := SMG$CREATE_PASTEBOARD(PASTEBOARD_ID`009:= Pasteboard_ID); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$SET_CURSOR_MODE(PASTEBOARD_ID`009:= Pasteboard_ID, X`009`009`009 FLAGS`009`009:= SMG$M_CURSOR_OFF); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$CREATE_VIRTUAL_DISPLAY(NUMBER_OF_ROWS`009:= 24, X`009`009`009`009 NUMBER_OF_COLUMNS`009:= 80, X`009`009`009`009 DISPLAY_ID`009`009:= Display_ID); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PASTE_VIRTUAL_DISPLAY(DISPLAY_ID`009`009:= Display_ID, X`009`009`009`009 PASTEBOARD_ID`009:= Pasteboard_ID, X`009`009`009`009 PASTEBOARD_ROW`009:= 1, X`009`009`009`009 PASTEBOARD_COLUMN`009:= 1); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'VAX/VMS Ethernet Monitor', X`009`009`009START_ROW`009:= 1, X`009`009`009START_COLUMN`009:= 28, X`009`009`009RENDITION_SET`009:= SMG$M_REVERSE); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'Version ' + Revision_Level, X`009`009`009START_ROW`009:= 2, X`009`009`009START_COLUMN`009:= 34); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X DATE(Date_String); X TIME(Time_String); X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= Date_String + ' ' + SUBSTR(Time_String,1,8), X`009`009`009START_ROW`009:= 3, X`009`009`009START_COLUMN`009:= 30); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'CUR', X`009`009`009START_ROW`009:= 5, X`009`009`009START_COLUMN`009:= 30, X`009`009`009RENDITION_SET`009:= SMG$M_UNDERLINE); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'AVE', X`009`009`009START_ROW`009:= 5, X`009`009`009START_COLUMN`009:= 44, X`009`009`009RENDITION_SET`009:= SMG$M_UNDERLINE); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'MIN', X`009`009`009START_ROW`009:= 5, X`009`009`009START_COLUMN`009:= 58, X`009`009`009RENDITION_SET`009:= SMG$M_UNDERLINE); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'MAX', X`009`009`009START_ROW`009:= 5, X`009`009`009START_COLUMN`009:= 72, X`009`009`009RENDITION_SET`009:= SMG$M_UNDERLINE); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, V`009`009`009TEXT`009`009:= 'Packets per Second 0.00 0.00 `032 X 0.00 0.00', X`009`009`009START_ROW`009:= 7, X`009`009`009START_COLUMN`009:= 5); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, V`009`009`009TEXT`009`009:= 'Bytes per Second 0.00 0.00 `032 X 0.00 0.00', X`009`009`009START_ROW`009:= 8, X`009`009`009START_COLUMN`009:= 5); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'Top Transmitting Nodes', X`009`009`009START_ROW`009:= 12, X`009`009`009START_COLUMN`009:= 9); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$DRAW_LINE(DISPLAY_ID`009:= Display_ID, X`009`009`009START_ROW`009:= 14, X`009`009`009START_COLUMN`009:= 12, X`009`009`009END_ROW`009`009:= 22, X`009`009`009END_COLUMN`009:= 12); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X `032 X Stat := SMG$DRAW_LINE(DISPLAY_ID`009:= Display_ID, X`009`009`009START_ROW`009:= 22, X`009`009`009START_COLUMN`009:= 12, X`009`009`009END_ROW`009`009:= 22, X`009`009`009END_COLUMN`009:= 38); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'Packets Transmitted', X`009`009`009START_ROW`009:= 24, X`009`009`009START_COLUMN`009:= 15); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'Top Receiving Nodes', X`009`009`009START_ROW`009:= 12, X`009`009`009START_COLUMN`009:= 51); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$DRAW_LINE(DISPLAY_ID`009:= Display_ID, X`009`009`009START_ROW`009:= 14, X`009`009`009START_COLUMN`009:= 53, X`009`009`009END_ROW`009`009:= 22, X`009`009`009END_COLUMN`009:= 53); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$DRAW_LINE(DISPLAY_ID`009:= Display_ID, X`009`009`009START_ROW`009:= 22, X`009`009`009START_COLUMN`009:= 53, X`009`009`009END_ROW`009`009:= 22, X`009`009`009END_COLUMN`009:= 79); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$PUT_CHARS(DISPLAY_ID`009:= Display_ID, X`009`009`009TEXT`009`009:= 'Packets Received', X`009`009`009START_ROW`009:= 24, X`009`009`009START_COLUMN`009:= 58); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Init_Counts; X XBEGIN X X Time_Collecting := 0.0; X X Packet_Count := 0; X Total_Packets := 0; X Max_Packets := 0; X Min_Packets := MAXINT; X X Byte_Count := 0; X Total_Bytes := 0; X Max_Bytes := 0; X Min_Bytes := MAXINT; X X Array_Index := 1; X X NEW(Transmit_List); X Transmit_List`094.Next_Element := NIL; X X NEW(Receive_List); X Receive_List`094.Next_Element := NIL; X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Init_Node_Name_List; X XVAR X`009Node_Name_File`009: TEXT; X`009Address_String`009: PACKED ARRAY [1..12] OF CHAR; X`009Node_Name`009: VARYING [6] OF CHAR; X`009Dummy_String`009: VARYING [1] OF CHAR; X`009List_Entry`009: Node_Name_Ptr; X X`009I`009`009: INTEGER; X XBEGIN X X NEW(Node_Name_List); X Node_Name_List`094.Next_Node := NIL; X X OPEN(Node_Name_File,'ethermon_directory:node_names.dat',OLD); X RESET(Node_Name_File); X X WHILE (NOT EOF(Node_Name_File)) DO X BEGIN X READLN(Node_Name_File,Address_String,Dummy_String,Node_Name); X NEW(List_Entry); X Node_Name := PAD(Node_Name,' ',6); X List_Entry`094.Node_Name := Node_Name; V FOR I := 1 TO 6 DO READV(SUBSTR(Address_String,2*(I-1)+1,2),List_Entry` X094.Ethernet_Address[I]::Unsigned_Byte:HEX); X List_Entry`094.Next_Node := Node_Name_List`094.Next_Node; X Node_Name_List`094.Next_Node := List_Entry; X END; `032 X X CLOSE(Node_Name_File); X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Assign_Channels; X XVAR X`009Stat`009`009: INTEGER; X XBEGIN X V Stat := $ASSIGN(DEVNAM`009:= 'Ethermon_Controller',`009`009`123 assign a ch Xannel to the ethermon_controller `125 X`009`009 CHAN`009`009:= Ethermon_controller_Channel); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X V Stat := $ASSIGN(DEVNAM`009:= 'SYS$INPUT',`009`009`009`123 assign a channel X to the terminal `125 X`009`009 CHAN`009`009:= Terminal_Channel); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Start_Qios; X XVAR X`009I`009`009: INTEGER; X`009Stat`009`009: INTEGER; X XBEGIN X V Extended_Characteristics.Parameter_ID := NMA$C_PCLI_PRM;`009`123 get promis Xcuous `125 X Extended_Characteristics.Value := NMA$C_STATE_ON; X Extended_Char_Descriptor.Length := 6; X Extended_Char_Descriptor.Address := IADDRESS(Extended_Characteristics); V Stat := $QIOW(CHAN`009`009:= Ethermon_controller_Channel,`009`009`009`009`0 X09`009`123 startup promiscuously `125 X`009`009FUNC`009`009:= IO$_SETMODE + IO$M_CTRL + IO$M_STARTUP, X`009`009IOSB`009`009:= Qio_Data[1].Iosb, X`009`009P2`009`009:= %REF Extended_Char_Descriptor); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); V IF (NOT ODD(Qio_Data[1].Iosb.Condition_Value)) THEN $EXIT(Qio_Data[1].Iosb. XCondition_Value); X V Stat := $QIO(CHAN`009`009:= Terminal_Channel,`009`009`009`009`009`009`123 l Xook for a control z `125 X`009 FUNC`009`009:= IO$_READVBLK + IO$M_NOECHO, X`009 IOSB`009`009:= Terminal_IOSB, X`009 ASTADR`009`009:= %IMMED Process_Terminal_Input, X`009 P1`009`009:= Terminal_Buffer, X`009 P2`009`009:= 1); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X FOR I := 1 TO Receive_Count DO X BEGIN X Stat := $QIO(CHAN`009`009:= Ethermon_controller_Channel, X`009`009 FUNC`009`009:= IO$_READVBLK, X`009`009 IOSB`009`009:= Qio_Data[I].Iosb, X`009`009 ASTADR`009:= %IMMED Process_Traffic, X`009`009 P1`009`009:= Qio_Data[I].Receive_Buffer, X`009`009 P2`009`009:= 1500, X`009`009 P5`009`009:= IADDRESS(Qio_Data[I].P5_Buffer)); X IF (NOT ODD(Stat)) THEN $EXIT; X END; X XEND; X V`123************************************************************************* X*********************************************************`125 X XEND. $ GOSUB UNPACK_FILE $ FILE_IS = "NODE_NAMES.DAT" $ CHECKSUM_IS = 1277885632 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY XAB0000010000 DmpLoa XAB0000020000 RemCon XAB0000030000 Router XAB0000040000 EndNod XAA0004000A04 Node1 XAA0004000604 Node2 XAA0004000304 Node3 XAA0004000804 Node4 X08002B044886 Serv1 X08002B03E1D0 Serv2 X080020007507 ForNod $ GOSUB UNPACK_FILE $ FILE_IS = "PROCESS_DATA.PAS" $ CHECKSUM_IS = 1766605577 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X[INHERIT ('SYS$LIBRARY:STARLET.PEN', X`009 'ethermon_directory:ETHERMONLET.PEN')] XMODULE Process_Data(OUTPUT); X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL,ASYNCHRONOUS,UNBOUND] PROCEDURE Process_Traffic; X XVAR X`009Stat`009`009: INTEGER; X`009I`009`009: INTEGER; X`009Ptr`009`009: List_Ptr; X`009New_Ptr`009`009: List_Ptr; X`009Added_to_List`009: BOOLEAN; X XBEGIN X V IF (NOT ODD(Qio_Data[Array_Index].Iosb.Condition_Value)) THEN $EXIT(Qio_Dat Xa[Array_Index].Iosb.Condition_Value); X X IF (Qio_Data[Array_Index].P5_Buffer.Protocol_Type = 6) THEN V Qio_Data[Array_Index].Iosb.Transfer_Count := ORD(Qio_Data[Array_Index].Re Xceive_Buffer[2]) + V`009`009`009`009`009`009 (256 * ORD(Qio_Data[Array_Index].Receive_Buffer[3])) X; X X Packet_Count := Packet_Count + 1; V Byte_Count := Byte_Count + MAX(Qio_Data[Array_Index].Iosb.Transfer_Count,46 X); X X Added_to_List := FALSE; X Ptr := Transmit_List; X WHILE (Ptr`094.Next_Element <> NIL) AND (NOT Added_to_List) DO X BEGIN X Ptr := Ptr`094.Next_Element; V IF (Ptr`094.Ethernet_Address = Qio_Data[Array_Index].P5_Buffer.Source_A Xddress) THEN X`009BEGIN X`009 Ptr`094.Count := Ptr`094.Count + 1; X`009 Added_to_List := TRUE; X`009END; X END; X IF (NOT Added_to_List) THEN X BEGIN X NEW(New_Ptr); V New_Ptr`094.Ethernet_Address := Qio_Data[Array_Index].P5_Buffer.Source_ XAddress; X New_Ptr`094.Count := 1; X New_Ptr`094.Next_Element := NIL; X Ptr`094.Next_Element := New_Ptr; X END; X X Added_to_List := FALSE; X Ptr := Receive_List; X WHILE (Ptr`094.Next_Element <> NIL) AND (NOT Added_to_List) DO X BEGIN X Ptr := Ptr`094.Next_Element; V IF (Ptr`094.Ethernet_Address = Qio_Data[Array_Index].P5_Buffer.Destinat Xion_Address) THEN X`009BEGIN X`009 Ptr`094.Count := Ptr`094.Count + 1; X`009 Added_to_List := TRUE; X`009END; X END; X IF (NOT Added_to_List) THEN X BEGIN X NEW(New_Ptr); V New_Ptr`094.Ethernet_Address := Qio_Data[Array_Index].P5_Buffer.Destina Xtion_Address; X New_Ptr`094.Count := 1; X New_Ptr`094.Next_Element := NIL; X Ptr`094.Next_Element := New_Ptr; X END; X X Stat := $QIO(CHAN`009`009:= Ethermon_Controller_Channel, X`009 FUNC`009`009:= IO$_READVBLK, X`009 IOSB`009`009:= Qio_Data[Array_Index].Iosb, X`009 ASTADR`009`009:= %IMMED Process_Traffic, X`009 P1`009`009:= Qio_Data[Array_Index].Receive_Buffer, X`009 P2`009`009:= 1500, X`009 P5`009`009:= IADDRESS(Qio_Data[Array_Index].P5_Buffer)); X IF (NOT ODD(Stat)) THEN $EXIT; X V IF (Array_Index = 5) THEN Array_Index := 1 ELSE Array_Index := Array_Index X + 1; X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL,ASYNCHRONOUS,UNBOUND] PROCEDURE Process_Terminal_Input; X XVAR X`009Stat`009`009: INTEGER; X XBEGIN X V IF (NOT ODD(Terminal_IOSB.Condition_Value)) THEN $EXIT(Terminal_IOSB.Condit Xion_Value); X `032 X IF (Terminal_IOSB.Terminator <> 26) THEN X BEGIN X Stat := $QIO(CHAN`009`009:= Terminal_Channel, X`009`009 FUNC`009`009:= IO$_READVBLK + IO$M_NOECHO, X`009`009 IOSB`009`009:= Terminal_IOSB, X`009`009 ASTADR`009:= %IMMED Process_Terminal_Input, X`009`009 P1`009`009:= Terminal_Buffer, X`009`009 P2`009`009:= 1); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X END X ELSE X BEGIN X Stat := $QIOW(CHAN`009`009:= Ethermon_Controller_Channel, X`009`009 FUNC`009`009:= IO$_SETMODE + IO$M_CTRL + IO$M_SHUTDOWN, X`009`009 IOSB`009`009:= Qio_Data[1].Iosb); X`123 IF (NOT ODD(Stat)) THEN $EXIT(Stat); V IF (NOT ODD(Qio_Data[1].Iosb.Condition_Value)) THEN $EXIT(Qio_Data[1].I Xosb.Condition_Value); X`125 V Stat := SMG$SET_CURSOR_MODE(PASTEBOARD_ID`009:= Pasteboard_ID,`009`123 X turn the cursor back on `125 X`009`009`009`009 FLAGS`009`009:= SMG$M_CURSOR_ON); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$SET_CURSOR_ABS(DISPLAY_ID`009:= Display_ID, X`009`009`009`009 START_ROW`009:= 24, X`009`009`009`009 START_COLUMN`009:= 1); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := SMG$SCROLL_DISPLAY_AREA(DISPLAY_ID`009:= Display_ID); X IF (NOT ODD(Stat)) THEN $EXIT(Stat); X X Stat := $DASSGN(CHAN`009`009:= Ethermon_Controller_Channel);`009`009 X`123 deassign the ethermon_Controller channel `125 X X X X $EXIT(Stat);`009`009`009`009`009`009`009`123 we're all done `125 X X END; X XEND; X V`123************************************************************************* X*********************************************************`125 X X[GLOBAL] PROCEDURE Update_Counts; X XBEGIN X X Time_Collecting := Time_Collecting + Interval; X X Total_Packets := Total_Packets + Packet_Count; X Packets_Per_Second := Packet_Count / Interval; X Packet_Average := Total_Packets / Time_Collecting; X V IF (Packets_Per_Second > Max_Packets) THEN Max_Packets := Packets_Per_Secon Xd; V IF (Packets_Per_Second < Min_Packets) THEN Min_Packets := Packets_Per_Secon Xd; X X Total_Bytes := Total_Bytes + Byte_Count; X Bytes_Per_Second := Byte_Count / Interval; X Byte_Average := Total_Bytes / Time_Collecting; X X IF (Bytes_Per_Second > Max_Bytes) THEN Max_Bytes := Bytes_Per_Second; X IF (Bytes_Per_Second < Min_Bytes) THEN Min_Bytes := Bytes_Per_Second; X XEND; X V`123************************************************************************* X*********************************************************`125 X XEND. $ GOSUB UNPACK_FILE $ EXIT