#!/afs/athena/contrib/perl/perl
# Usage:  netwatch.pl [<sleep time>]

# Default sleep time is 30 seconds.

# Welcome to the new version of netwatch.pl, the perl script for the paranoid
# Note the changes of the zephyr class that this sends the messages to
# change your subs accordingly

#This is the new & improved version desogned to not hose your machine 
# as much as the original.  Other features include giving you the 
# full machine name of hosts with long machine names.

# Thanks to all that made this an intelligent (well sort of) script...
# (bert, rjbarbal, mosquito, ckclark, & marc)

# send bug reports to mhbraun@mit.edu

#                      Matt

if (@ARGV) {
    $sleep_time = shift(@ARGV);
}
else {
    $sleep_time = 30;
}

# Hash all the services
setservent("");
while ( ($name,$aliases,$port,$prot) = getservent() ) {
    $service{$port} = $name;
}
endservent();

chop ($hosttype = `machtype`);

if ($hosttype =~ /^sun/) {
    $skip_regexp = "^$|^TCP|^   Local|^---";
}
else {
    $skip_regexp = "^Active|^Proto";
}

print "NetWatch2, sleep = $sleep_time\n";

# We may find a better way to do this sometime..

while (`users` =~ /$ENV{'USER'}/) { # exit upon logout

    # Get new information from netstat
    open (NETSTAT, "/usr/ucb/netstat -n -f inet |");

    while (<NETSTAT>) {
	if (! /$skip_regexp/) {   # kill first 2 lines, chop&split the rest
	    chop;
            if ($hosttype =~ /^sun/) {
		($local,$foreign,$swind,$sq,$rwind,$rq,$state) = split(/[ \t]+/);
	    }
	    else {
		($prot,$rq,$sq,$local,$foreign,$state) = split(/[ \t]+/);
	    } 
	    $netstat = $_ ;
	
	    if (($foreign ne "18.72.0.214.2051") && ($foreign ne "127.0.0.1.53") && ($local ne "127.0.0.1.53")) {

		     if ($foreign =~ /^\*\.(.*)$/) {
		         $fname="*";
		         $fport=$1;
		     }
		else {
		    @faddr = split(/\./,$foreign);
		    $fip = pack ('C4', @faddr[0..3]);
		    $fname = ($host{$fip}
			|| ($host{$fip} = ( ((gethostbyaddr($fip,2))[0])
					 || ($fname= join(".",@faddr[0..3])) )));

		    $fport = $faddr[4];
		}

		$fport_name = ( $service{$fport} || $fport );

#		if ($local =~ /^(.+\.)([0-9]+)$/) {
#		    $locp = $1 . ( $service{$2} || $2 );
#		}
#		else {
#		    $locp = $local;
#		}
		     if ($local =~ /^\*\.(.*)$/) {
		         $lname="*";
		         $lport=$1;
		     }
		else {
		    @laddr = split(/\./,$local);
		    $lip = pack ('C4', @laddr[0..3]);
		    $lname = ($host{$lip}
			|| ($host{$lip} = ( ((gethostbyaddr($lip,2))[0])
					 || ($lname= join(".",@laddr[0..3])) )));

		    $lport = $laddr[4];
		}

		$lport_name = ( $service{$lport} || $lport );

		$netstat = sprintf("%3s  %1d  %1d     %-30s  %-30s  %s",
				$prot,$rq,$sq,"$lname.$lport_name","$fname.$fport_name",$state);

		if ($old{"$local:$foreign"} ne "x".$status) {
		    $zephyr[$n++] = $netstat;
		}
		$new{"$local:$foreign"}="x".$status;
	    }
	}
    }

    %old = %new;
    %new = 0;

    close (NETSTAT);

    # Send new information via zephyr
    if ($n > 0) {
	open (ZEPHYR, "| zwrite -c netstat -n -q \$USER");
	print ZEPHYR "\n".join("\n",@zephyr)."\n";
	close (ZEPHYR);
	$#zephyr = 0;
	$n = 0;
    }

    sleep ($sleep_time);
}
