.TITLE ETHERMON_PARSE Parser and Accessories for Ethernet Monitor .IDENT /V1.0/ ; ; define funny system symbols used by this program ; .LIBRARY /SYS$LIBRARY:LIB/ $NMADEF GLOBAL .IF NE NMA$C_STATE_ON .WARN 0 ; inconsistency in FORTRAN code, fix it!!!!! .ENDC $TPADEF .SBTTL FORTRAN COMMON's .PSECT LCV_EXIT,NOEXE,RD,WRT,GBL,SHR,OVR,PIC,LONG LCV_EXIT: .BLKB 1 ; flag to indicate EXIT command entered .PSECT PARSE_ARG2,NOEXE,RD,WRT,GBL,SHR,OVR,PIC,LONG slomode: .blkl 1 ; if zero run in slow mode, if >0 fast mode. .PSECT PARSE_ARGS,NOEXE,RD,WRT,GBL,SHR,OVR,PIC,LONG ICVPRS_NUMBER: .BLKL 1 ; generic parsed number BCVPRS_ADDRNUM: .BLKB 6 ; parsed address number BCVPRS_PROTNUM: .BLKB 2 ; parsed protocol number BCVPRS_DSTADR: .BLKB 6 ; parsed address for destination BCVPRS_SRCADR: .BLKB 6 ; parsed address for source ;*** next three bytes must remain in this order *** BCVPRS_DSTMOD: .BLKB 1 ; filter mode for destination addr (1=EXCLUDE, 2=ONLY) BCVPRS_SRCMOD: .BLKB 1 ; filter mode for source addr (1=EXCLUDE, 2=ONLY) BCVPRS_PRTMOD: .BLKB 1 ; filter mode for protocol (1=EXCLUDE, 2=ONLY) ;*** previous three bytes must remain in this order *** BCVPRS_FLTMOD: .BLKB 1 ; overall filter mode (1=ENABLE, 2=DISABLE) NCVPRS_FILESPECLEN: .BLKW 1 ; length of used filespec buffer CCVPRS_FILESPEC: .BLKB 128 ; file specification buffer .PSECT $LOCAL,NOEXE,RD,WRT,NOSHR,LCL,PIC,LONG BLV_SAVE_FLT_ENA: .BLKB 1 ; place to save filter EXCLUDE/ONLY flag .SBTTL Command Line Parse State Table COMMA = ^X2C $INIT_STATE CMDLIN_STATE,CMDLIN_KEY $STATE $TRAN !ENDLIN,TPA$_EXIT $TRAN 'ADD',STATE_ADD $TRAN 'CLEAR',STATE_CLEAR $TRAN 'DISPLAY',STATE_DISPLAY $TRAN 'EXIT',TPA$_EXIT,EXIT_COMMAND $TRAN 'HELP',STATE_HELP $TRAN 'SET',STATE_SET $TRAN 'SHOW',STATE_SHOW $TRAN 'TRACE',STATE_TRACE $TRAN 'SPEED',STATE_SLOFST $STATE ENDLIN $TRAN TPA$_EOS,TPA$_EXIT $TRAN '!',TPA$_EXIT $STATE STATE_SLOFST $TRAN 'SLOW',STATE_SLOW $TRAN 'FAST',STATE_FAST $STATE STATE_SLOW $TRAN !$ENDLIN,TPA$_EXIT,SETSLO $STATE STATE_FAST $TRAN !$ENDLIN,TPA$_EXIT,SETFAST $STATE $TRAN !ENDLIN,TPA$_EXIT $STATE STATE_ADD $TRAN 'FILTER',STATE_ADD_FILTER $STATE STATE_ADD_FILTER $TRAN !FILTER_quals,STATE_ADD_FILTER $TRAN !ENDLIN,TPA$_EXIT,ADD_FILTER $STATE STATE_CLEAR $TRAN 'FILTER',STATE_CLEAR_FILTER $TRAN 'PROTOCOL_NAME',STATE_CLEAR_PROTNAM $STATE STATE_CLEAR_FILTER $TRAN !ALL_qual,STATE_CLEAR_FILTER_2,,,,-1 $TRAN TPA$_DECIMAL,STATE_CLEAR_FILTER_2,,,,1 $STATE STATE_CLEAR_FILTER_2 $TRAN !ENDLIN,TPA$_EXIT,CLEAR_FILTER $STATE STATE_CLEAR_PROTNAM $TRAN !ALL_qual,STATE_CLEAR_PROTNAM_2 $TRAN !protocol_num,STATE_CLEAR_PROTNAM_2 $STATE STATE_CLEAR_PROTNAM_2 $TRAN !ENDLIN,TPA$_EXIT $STATE STATE_DISPLAY $TRAN 'DESTINATION',,,,,1 $TRAN 'PROTOCOL',,,,,2 $TRAN 'SIZE',,,,,3 $TRAN 'SOURCE',,,,,4 $TRAN 'STATISTICS',,,,,5 $STATE $TRAN !ENDLIN,TPA$_EXIT,DISPLAY $TRAN '/' $STATE $TRAN 'ALL_STATISTICS',,,1,ICVPRS_NUMBER $STATE $TRAN !ENDLIN,TPA$_EXIT,DISPLAY $STATE STATE_HELP $TRAN !skip_to_end,TPA$_EXIT,HELP $STATE STATE_SET $TRAN 'ADDRESS_NAME',STATE_SET_ADDRNAM $TRAN 'FILTER',STATE_SET_FILTER $TRAN 'INTERVAL',STATE_SET_INTERVAL $TRAN 'LENGTH',STATE_SET_LENGTH $TRAN 'PROTOCOL_NAME',STATE_SET_PROTNAM $STATE STATE_SET_ADDRNAM $TRAN !AUTO_qual,STATE_SET_ADDRNAM_AUTO $TRAN !address_num $STATE $TRAN TPA$_SYMBOL,,save_filespec $TRAN !quoted_string,,save_filespec $STATE $TRAN !ENDLIN,TPA$_EXIT,SET_ADDRNAM $STATE STATE_SET_ADDRNAM_AUTO $TRAN !ENDLIN,TPA$_EXIT,SET_ADDRNAM_AUTO $STATE STATE_SET_FILTER $TRAN TPA$_DECIMAL,,save_number $STATE STATE_SET_FILTER_2 $TRAN !FILTER_quals,STATE_SET_FILTER_2 $TRAN !ENDLIN,TPA$_EXIT,SET_FILTER $STATE STATE_SET_INTERVAL $TRAN TPA$_DECIMAL $STATE $TRAN !ENDLIN,TPA$_EXIT,SET_INTERVAL $STATE STATE_SET_LENGTH $TRAN TPA$_DECIMAL,,VALIDATE_MSGLEN $STATE $TRAN !ENDLIN,TPA$_EXIT,SET_LENGTH $STATE STATE_SET_PROTNAM $TRAN !protocol_num $STATE $TRAN TPA$_SYMBOL,,save_filespec $TRAN !quoted_string,,save_filespec $STATE $TRAN !ENDLIN,TPA$_EXIT,SET_PROTNAM $STATE STATE_SHOW $TRAN 'ADDRESS_NAMES',STATE_SHOW_ADDRESS $TRAN 'FILTER',STATE_SHOW_FILTER $TRAN 'PORT_STATUS',STATE_SHOW_PORT $TRAN 'PROTOCOL_NAMES',STATE_SHOW_PROTOCOL $STATE STATE_SHOW_ADDRESS $TRAN !ENDLIN,TPA$_EXIT,SHOW_ADDRESS_NAMES $STATE STATE_SHOW_FILTER $TRAN !ENDLIN,TPA$_EXIT,SHOW_FILTER $STATE STATE_SHOW_PORT $TRAN !ZERO_qual,,,-1,ICVPRS_NUMBER $TRAN TPA$_LAMBDA $STATE $TRAN !ENDLIN,TPA$_EXIT,SHOW_PORT_STATUS $STATE STATE_SHOW_PROTOCOL $TRAN !ENDLIN,TPA$_EXIT,SHOW_PROTOCOL_NAMES $STATE STATE_TRACE $TRAN !ENDLIN,TPA$_EXIT,TRACE $TRAN '/' $STATE $TRAN 'ASCII',STATE_TRACE,,1,BCVPRS_PROTNUM $TRAN 'BINARY',STATE_TRACE,,2,BCVPRS_PROTNUM $TRAN 'INTERVAL',STATE_TRACE_INTERVAL,,8,BCVPRS_PROTNUM $TRAN 'OUTPUT',STATE_TRACE_OUTPUT,,4,BCVPRS_PROTNUM $STATE STATE_TRACE_INTERVAL $TRAN '=' $STATE $TRAN !delta_time,STATE_TRACE,get_delta_time $STATE STATE_TRACE_OUTPUT $TRAN '=' $STATE $TRAN TPA$_FILESPEC,STATE_TRACE,save_filespec $STATE ALL_qual $TRAN '/' $STATE $TRAN 'ALL',TPA$_EXIT $STATE address_num $TRAN TPA$_HEX,,VALIDATE_ADDRNUM,,,0 $STATE $TRAN '-' $STATE $TRAN TPA$_HEX,,VALIDATE_ADDRNUM,,,1 $STATE $TRAN '-' $STATE $TRAN TPA$_HEX,,VALIDATE_ADDRNUM,,,2 $STATE $TRAN '-' $STATE $TRAN TPA$_HEX,,VALIDATE_ADDRNUM,,,3 $STATE $TRAN '-' $STATE $TRAN TPA$_HEX,,VALIDATE_ADDRNUM,,,4 $STATE $TRAN '-' $STATE $TRAN TPA$_HEX,TPA$_EXIT,VALIDATE_ADDRNUM,,,5 $STATE AUTO_qual $TRAN '/' $STATE $TRAN 'AUTOMATIC',TPA$_EXIT,,-1,ICVPRS_NUMBER $TRAN 'NOAUTOMATIC',TPA$_EXIT $STATE delta_time $TRAN TPA$_DECIMAL,,validate_time,,,23 $TRAN TPA$_LAMBDA $STATE $TRAN ':' $TRAN TPA$_LAMBDA,TPA$_EXIT $STATE $TRAN TPA$_DECIMAL,,validate_time,,,59 $TRAN TPA$_LAMBDA $STATE $TRAN ':' $TRAN TPA$_LAMBDA,TPA$_EXIT $STATE $TRAN TPA$_DECIMAL,,validate_time,,,59 $TRAN TPA$_LAMBDA $STATE $TRAN '.' $TRAN TPA$_LAMBDA,TPA$_EXIT $STATE $TRAN TPA$_DECIMAL,TPA$_EXIT,validate_time,,,99 $STATE FILTER_quals $TRAN '/' $STATE $TRAN 'DISABLE',TPA$_EXIT,save_filter_mode,,,2 $TRAN 'ENABLE',TPA$_EXIT,save_filter_mode,,,1 $TRAN 'EXCLUDE',,save_filter_switch,,,1 $TRAN 'NODESTINATION',TPA$_EXIT,mark_filter_switch,,,0 $TRAN 'NOPROTOCOL',TPA$_EXIT,mark_filter_switch,,,2 $TRAN 'NOSOURCE',TPA$_EXIT,mark_filter_switch,,,1 $TRAN 'ONLY',,save_filter_switch,,,2 $STATE $TRAN '=' $STATE $TRAN '(' $TRAN !FILTER_qual_subqual,TPA$_EXIT $STATE FILTER_qual_2 $TRAN !FILTER_qual_subqual $STATE $TRAN COMMA,FILTER_qual_2 $TRAN ')',TPA$_EXIT $STATE FILTER_qual_subqual $TRAN 'DESTINATION',FILTER_qual_subqual_DST $TRAN 'PROTOCOL',FILTER_qual_subqual_PRO $TRAN 'SOURCE',FILTER_qual_subqual_SRC $STATE FILTER_qual_subqual_DST $TRAN '=' $STATE $TRAN !address_num,TPA$_EXIT,save_addr_as_dst $STATE FILTER_qual_subqual_PRO $TRAN '=' $STATE $TRAN !protocol_num,TPA$_EXIT,save_protocol_mode $STATE FILTER_qual_subqual_SRC $TRAN '=' $STATE $TRAN !address_num,TPA$_EXIT,save_addr_as_src $STATE protocol_num $TRAN TPA$_HEX,,VALIDATE_PROTNUM,,,0 $STATE $TRAN '-' $STATE $TRAN TPA$_HEX,TPA$_EXIT,VALIDATE_PROTNUM,,,1 $STATE quoted_string $TRAN '"' $STATE quoted_string_2 $TRAN '"',TPA$_EXIT $TRAN TPA$_ANY,quoted_string_2 $STATE skip_to_end $TRAN !ENDLIN,TPA$_EXIT $TRAN TPA$_ANY,skip_to_end $STATE ZERO_qual $TRAN '/' $STATE $TRAN 'ZERO',TPA$_EXIT $END_STATE .SBTTL Command Parsing Subroutine .PSECT $CODE,EXE,RD,NOWRT,LCL,SHR,PIC,LONG .ENTRY EVALUATE_COMMAND,^M CLRL ICVPRS_NUMBER ; clear any variables related to filters, CLRW BCVPRS_PROTNUM CLRL BCVPRS_SRCADR CLRW BCVPRS_SRCADR+4 CLRL BCVPRS_DSTADR CLRW BCVPRS_DSTADR+4 CLRB BCVPRS_DSTMOD CLRB BCVPRS_SRCMOD CLRB BCVPRS_PRTMOD CLRB BCVPRS_FLTMOD CLRW NCVPRS_FILESPECLEN CLRB BLV_SAVE_FLT_ENA SUBL2 #TPA$K_LENGTH0,SP ; build TPARSE argblk on stack, MOVC5 #0,(SP),#0,#TPA$K_LENGTH0,(SP) ; clear block, MOVL #TPA$K_COUNT0,TPA$L_COUNT(SP) ; fill in the block, MOVL #TPA$M_ABBREV,TPA$L_OPTIONS(SP) MOVAQ @4(AP),R0 MOVZWL (R0),TPA$L_STRINGCNT(SP) MOVAB @4(R0),TPA$L_STRINGPTR(SP) PUSHAB CMDLIN_KEY ; call the parser, PUSHAB CMDLIN_STATE PUSHAL 8(SP) CALLS #3,G^LIB$TPARSE BLBS R0,99$ ; exit if successful, CMPL R0,#LIB$_SYNTAXERR ; else test what type of error it was, BNEQ 90$ ; not a syntax error, continue. BBC #TPA$V_AMBIG,TPA$L_OPTIONS(SP),90$ ; skip if not ambiguous error, MOVL #CLI$_ABVERB,R0 ; else change error status, 90$: PUSHL R0 ; build message vector on stack, PUSHL #1 $PUTMSG_S MSGVEC=12(SP) ; report error, 99$: RET ; return. .SBTTL Command Execution Support Subroutines .ENTRY EXIT_COMMAND,^M<> MNEGB #1,LCV_EXIT ; flag EXIT command as entered, RET ; return. .ENTRY VALIDATE_MSGLEN,^M<> MOVL TPA$L_NUMBER(AP),ICVPRS_NUMBER ; save number value, CMPL TPA$L_NUMBER(AP),#1500 ; test if number is too large, BLEQU 99$ ; skip if OK, MOVL #ETH__MSGTOOLNG,R0 ; else report error. 99$: RET .ENTRY validate_time,^M<> CMPL TPA$L_NUMBER(AP),- ; check if number in range, TPA$L_PARAM(AP) BLEQU 99$ ; skip out if OK, MOVZWL #SS$_IVTIME,R0 ; else report error. 99$: RET day_prolog: .ASCID "0 " .ENTRY get_delta_time,^M<> CLRQ -(SP) ; make an empty dynamic string descriptor, MOVW #^X020E,2(SP) PUSHAQ day_prolog ; build properly formatted time string, PUSHAQ 4(SP) CALLS #2,G^STR$APPEND PUSHAQ TPA$L_TOKENCNT(AP) PUSHAQ 4(SP) CALLS #2,G^STR$APPEND $BINTIM_S TIMBUF=4(SP),- ; attempt to translate time, TIMADR=BCVPRS_DSTADR PUSHR #^M ; preserve $BINTIM status, PUSHAQ 4(SP) ; release the dynamic string, CALLS #1,G^STR$FREE1_DX POPR #^M ; restore $BINTIM status, RET ; return w/results (whatever they are). .ENTRY save_number,^M<> MOVL TPA$L_NUMBER(AP),ICVPRS_NUMBER ; copy number from argblk to COMMON, RET ; exit. .ENTRY save_filter_mode,^M<> MOVB TPA$L_PARAM(AP),BCVPRS_FLTMOD ; save filter mode, RET ; exit. .ENTRY mark_filter_switch,^M<> MOVL TPA$L_PARAM(AP),R1 ; get number of desired target, MNEGB #1,BCVPRS_DSTMOD[R1] ; mark filter mode as "clear it", RET ; exit. .ENTRY SETFAST,^M<> MOVL #1,SLOMODE RET .ENTRY SETSLO,^M<> CLRL SLOMODE RET .ENTRY save_filter_switch,^M<> MOVB TPA$L_PARAM(AP),BLV_SAVE_FLT_ENA ; save filter EXCLUDE/ONLY switch, RET ; exit. .ENTRY VALIDATE_ADDRNUM,^M<> MOVL TPA$L_PARAM(AP),R1 ; get index into buffer array, MOVB TPA$L_NUMBER(AP),BCVPRS_ADDRNUM[R1] ; copy value into buffer, CMPL TPA$L_TOKENCNT(AP),#2 ; test if number too long, BGTRU 98$ ; bomb if too long, CMPL TPA$L_NUMBER(AP),#^XFF ; is number in range? BLSSU 99$ ; skip out if so, 98$: MOVL #ETH__BADADDRNUM,R0 ; else report syntax error. 99$: RET .ENTRY VALIDATE_PROTNUM,^M<> MOVL TPA$L_PARAM(AP),R1 ; get index into buffer array, MOVB TPA$L_NUMBER(AP),BCVPRS_PROTNUM[R1] ; copy value into buffer, CMPL TPA$L_TOKENCNT(AP),#2 ; test if number too long, BGTRU 98$ ; bomb if too long, CMPL TPA$L_NUMBER(AP),#^XFF ; is number in range? BLSSU 99$ ; skip out if so, 98$: MOVL #ETH__BADPROTNUM,R0 ; else report syntax error. 99$: RET .ENTRY save_addr_as_dst,^M<> MOVL BCVPRS_ADDRNUM,BCVPRS_DSTADR ; copy 1st part of address, MOVW BCVPRS_ADDRNUM+4,BCVPRS_DSTADR+4 ; copy rest of address, MOVB BLV_SAVE_FLT_ENA,BCVPRS_DSTMOD ; save mode of address, RET ; exit. .ENTRY save_addr_as_src,^M<> MOVL BCVPRS_ADDRNUM,BCVPRS_SRCADR ; copy 1st part of address, MOVW BCVPRS_ADDRNUM+4,BCVPRS_SRCADR+4 ; copy rest of address, MOVB BLV_SAVE_FLT_ENA,BCVPRS_SRCMOD ; save mode of address, RET ; exit. .ENTRY save_protocol_mode,^M<> MOVB BLV_SAVE_FLT_ENA,BCVPRS_PRTMOD ; save mode of protocol, RET ; exit. .ENTRY save_filespec,^M PUSHR #^M ; preserve success status, MOVC5 TPA$L_TOKENCNT(AP),- ; copy string to COMMON buffer, @TPA$L_TOKENPTR(AP),#^A/ /,#128,CCVPRS_FILESPEC MOVW TPA$L_TOKENCNT(AP),NCVPRS_FILESPECLEN ; save string length, CMPW TPA$L_TOKENCNT(AP),#128 BLEQU 90$ MOVW #128,NCVPRS_FILESPECLEN ; adjust if string truncated, 90$: POPR #^M ; restore success status, RET ; exit. .END