#!/usr/bin/perl

#    =====================================================================
#    |                   SPALEWARE LICENSE (Revision 0.1)                |
#    |-------------------------------------------------------------------|
#    | This is a little script called "Netstat-bot" and is               |
#    | licensed under SPALEWARE. You may freely modify and distribute    |
#    | this package or parts of it. But you MUST keep the SPALWARE       |
#    | license in it!                                                    |
#    |                                                                   |
#    =====================================================================

use IO::Socket;

$|=1;
$localaddr  = "127.0.0.1";
$serverip   = "127.0.0.1";
$serverport = "9000";
$serverpass = "i line password";

# $$ is the PID, might be usefull to use it in the nickname for randomness
$perlnick   = "nmc$$";
$operuser   = "username";
$operpass   = "password";
$channel    = '&geneva';
$interfaces = 'eth0 eth1';
$update_time = 60;
$boldlevel  = '9999';

print "Loading $perlnick from $localaddr to $serverip\n";
$remote = IO::Socket::INET->new(
        Proto      => "tcp",
        PeerAddr   => "$serverip",
        PeerPort   => "$serverport",
        LocalAddr  => "$localaddr",
        ) or die "$serverip port $serverport : Connection refused";

while(1) {
	vec($wdata,fileno($remote),1) = 1;
	if ( select($wdata, undef, undef, 0.2) ) {
		$line = <$remote>;
		$line =~ s/(\r|\n)+$//;
		$time = time;

		print "<- $line\n";

	        if ( $onlyone eq "" ) {
	                srvsend("USER $perlnick $perlnick $perlnick :Network Monitor");
	                srvsend("PASS $serverpass");
	                srvsend("NICK $perlnick");
	                $onlyone ="toolate";
	        }
	        if ( $line =~ /^PING/ ) { $line =~ s/PING/PONG/; srvsend("$line"); }
		if ( $line =~ / 001 / ) {
			srvsend("MODE $perlnick +i");
			srvsend("OPER $operpass");
			srvsend("MODE $perlnick -s");
			srvsend("JOIN $channel OVERRIDE");
			srvsend("MODE $channel +o $perlnick");
		}
	}

	if ( $time - $lnetstat >= $update_time ) {
		$result = netstat();
		if ( $result ) { srvsend("NOTICE \@$channel :$result"); }
		$lnetstat = time;
	}
}

print "Died $perlnick\n";

sub srvsend {
        $print = shift;
	print "-> $print\n";
        print $remote "$print\n";
}

sub netstat {
	undef $return;
	foreach $int (  split ( / /,$interfaces ) ) {
		($bi{$int},$bo{$int}) = split(/ /,getdata($int));
		if ( $lbi{$int} && $lbo{$int} ) {
			if ( $bi{$int} < $lbi{$int} ) {
				$di{$int} = $bi{$int} + (2**32/8) - $lbi{$int};
			} else {
				$di{$int} = $bi{$int} - $lbi{$int};
			}
			if ( $bo{$int} < $lbo{$int} ) {
				$do{$int} = $bo{$int} + (2**32/8) - $lbo{$int};
			} else {
				$do{$int} = $bo{$int} - $lbo{$int};
			}
			$ti = int( $di{$int} / $update_time * 8 / 1024 );
			$to = int( $do{$int} / $update_time * 8 / 1024 );
			if ( $ti > $boldlevel || $to > $boldlevel ) { $bold = ''; } else { undef $bold; }
			$return .= "$bold$int: ";
			$return .= sprintf ( "%5s", $ti );
			$return .= "kbps in ";
			$return .= sprintf ( "%5s", $to );
			$return .= "kbps out $bold";
		}
		$lbi{$int} = $bi{$int};
		$lbo{$int} = $bo{$int};
	}
	return $return;
}

sub getdata {
	$ifint = (shift);
	undef $getdata;
	foreach(`ifconfig $ifint`) {
		s/(\r|\n)+$//;
		if ( /RX bytes.*TX bytes:/ ) {
			s/.*RX bytes:([0-9]+) .* TX bytes:([0-9]+) .*/$1 $2/;
			$getdata = $_;
		}
	}
	return $getdata;
}
