# Program Name : ETHER_STAT.PL # Original Author : J. LAURET # SUNY @ Stony Brook # Stony Brook NY 11790-3400 # # Date : 12-APR-1996 # Program Description : Uses ETHERWATCH with /COUNT and display network # : statistics. Instaneous or Cumulative mode # currently avaialable as well as a sorting by number # of packages or by bytes. # Require : ETHERWATCH to be defined as a symbol or installed. # lexical.pm available at # http://nuchm2.chem.sunysb.edu/pub/vms/lexical.html # ----------------------- : # Date of Revision : 17-APR-1996 # Change Author : NUCMGR # Purpose of Revision : Added the TYPES reading from a file pointed by # : logical ETHER_TYPES # Format of the TYPES file: # Comment are allowed using "!" # Each line should contain the TYPE (as XX-XX or XXXX) and a # string equivalent # Ex: # 60-01 MOPDUMP # 6002 MODCONSOLE ! This is valid as well use lexical ; # usage is printed if no argument is provided $version = "V01-100" ; print "ETHER_STAT $version\n" ; if( $#ARGV >= 0){ if ($ENV{ETHERWATCHER} eq ""){ print "You may define ETHERWATCHER to point on a NODELIST file.\n"; print "See documentation for detail.\n" ; } # Some initialization # A list of possible ethernet types you will encounter # Use default list $pad = " -----------------------" ; $type{"60-01"} = "MOPDUMP" ; $type{"60-02"} = "MOPCONSOLE" ; $type{"60-03"} = "DECNET" ; $type{"60-04"} = "LAT" ; $type{"60-05"} = "DIAGNOSTICS" ; $type{"60-07"} = "LAVC" ; $type{"80-38"} = "RBMS" ; $type{"80-3B"} = "VAXELN" ; $type{"80-3E"} = "DNS" ; $type{"80-40"} = "NETBIOS" ; $type{"80-41"} = "LAST" ; $sttime = f_time() ; $i = 0 ; $sum = 0 ; $loop = 0 ; $mode = 2 ; # Alternative : You may define the logical ETHER_TYPES # to point on a file containing # type string # i.e.: 60-01 MOPDUMP # 6001 MOPDUMP ! is also a valid format $file = $ENV{ETHER_TYPES} ; if ($file ne ""){ # Open the TYPES file and suck-it in if (open(FI,"$file") ){ $pad = " --------------------------------------------------"; print "Reading $file\n" ; @TYPES = ; close(FI) ; foreach $el (@TYPES){ $el = f_edit($el,"UNCOMMENT,COMPRESS,TRIM"); if($el ne ""){ $tmp = f_element(0," ",$el) ; $len = length($tmp) ; # Fix it as XX-XX if($len = 4){ $tmp = substr($tmp,0,2)."-". substr($tmp,2,2) ; } if(length($tmp) > 5){ print "Ignore $el - Invalid type\n"; } else { $what= substr($el,5,length($el)-5); $type{$tmp} = $what ; } } } } else { # TYPES will still be printed if defined in the # default list. print "Could not open TYPES file $file\n" ; } } # Now get some data (first pass) $val = $ARGV[0]*1 ; if($val == 0){ print "Reading data ...\n" ; open(FI,$ARGV[0]) || die "Could not open file $ARGV[0]\n"; @STAT = ; close(FI) ; } else { @STAT = &getdata($val) ; if( $#ARGV >= 1){ $loop = substr(uc($ARGV[1]),0,1) ; $mode = length($ARGV[1]) ; } if( $#ARGV == 2){ $elaps = $ARGV[2] ; } else { $elaps = 10 ; } } } else { &usage ; } STATIS: print chr(27),"[H",chr(27),"[2J" ; foreach $line (@STAT){ die "$line\n" if( substr($line,0,1) eq "%" ) ; if( uc(f_element(0," ",$line)) eq "FROM"){ $ether = f_element(1," ",$line) ; $node = f_element(2," ",$line) ; } if( uc(f_element(0," ",$line)) eq "PROTOCOL"){ $line = f_edit($line,"COMPRESS") ; $proto = f_element(1," ",$line) ; if( length($proto) == 5){ $bytes = f_element(4," ",$line) ; $i++ ; if (!defined($A_NODE{$ether})){ $A_NODE{$ether} = $node ; } # How many times we've seen it $ETHER_CNT{$ether} += 1 ; # Sum of the bytes transferred $ETHER_BYT{$ether} += $bytes ; $sum += $bytes ; # How many times this protocol is used $ETHER_PRT{$proto} += 1 ; } } } print "Statistics started at $sttime\n" if ($mode == 1) ; print "$i counts -- " ; print "Time is : ",f_time(),"\n" ; print "Cumulative mode " if ($mode == 1) ; print "Instantaneous mode" if ($mode == 2) ; if($loop eq "T"){ print " - Frequency sort\n\n" ; } else { print " - Bytes transferred sort\n\n" ; } printf " %60s\t%5s\n","Protocol Type","%tage" ; printf "%70.70s\n",$pad ; foreach $proto (sort{$ETHER_PRT{$b} <=> $ETHER_PRT{$a}}(keys %ETHER_PRT)){ if( defined($type{$proto}) ){ $str = $type{$proto} ; } else { $str = "[".$proto."]" ; } $prct1 = $ETHER_PRT{$proto}/$i*100 ; printf " %60s\t%5.2f%%\n",$str,$prct1 ; } printf "%70.70s\n\n",$pad ; printf " %17.17s %15s \t%5s \t%5s \n","Hyphen","Node","% Bytes","% Frequency"; print " ======================================================================\n"; if($loop eq "T"){ foreach $ether (sort{$ETHER_CNT{$b} <=> $ETHER_CNT{$a}} (keys %ETHER_CNT)){ $prct2 = $ETHER_CNT{$ether}*100.0/$i ; if( $prct2 > 0.2){ $prct1 = $ETHER_BYT{$ether}*100.0/$sum ; $node = $A_NODE{$ether} ; printf " %17s %15s \t%5.2f \t\t%5.2f \n" , $ether,$node,$prct1,$prct2 ; } } } else { foreach $ether (sort{$ETHER_BYT{$b} <=> $ETHER_BYT{$a}} (keys %ETHER_BYT)){ $prct1 = $ETHER_BYT{$ether}*100.0/$sum ; if( $prct1 > 0.2){ $prct2 = $ETHER_CNT{$ether}*100.0/$i ; $node = $A_NODE{$ether} ; printf " %17s %15s \t%5.2f \t\t%5.2f \n" , $ether,$node,$prct1,$prct2 ; } } } # Case loop is asked if(($loop eq "T") || ($loop eq "B")){ if($mode == 2){ $i = 0 ; $sum = 0 ; undef(%ETHER_CNT) ; undef(%ETHER_BYT) ; undef(%ETHER_PRT) ; } undef(@STAT) ; print "\n\n" ; print "Waiting $elaps seconds \n" ; sleep($elaps) ; @STAT = &getdata($val) ; goto STATIS ; } else { print "\n\n" ; } # ----------------------------------------------------------------------- sub usage { print " ----------------------------------------------------------------------\n"; print " Usage is \n" ; print " ETHER_STAT P1 [P2 P3]\n" ; print " P1 can be \n" ; print " a FileName from which the data will be read or\n" ; print " a number of counts to process\n" ; print " P2 is used only if P1 is a number of counts. Value : \n" ; print " T Sort by number of package \n" ; print " B Sort by bytes transferred\n" ; print " T* Same as T but instantaneous instead of cumulative\n"; print " B* instantaneous B mode \n" ; print " P3 A time to wait between loops\n" ; print " ----------------------------------------------------------------------\n"; exit ; } sub getdata { my($cnt) = pop(@_) ; local(@A) ; print "Getting data ...\n" ; `etherwatch/display=none/count=$cnt` ; }