File: //usr/local/bandmin/htdocs/index.cgi
#!/usr/bin/perl -I/usr/local/bandmin
#
#****************************************
#Bandmin (c)1998-1999 J. Nick Koston (BlueDraco)
# - A simple Bandwidth Monitor
#****************************************
#
#To use this package you must have a OS that has either ipfwadm,ipchains,
#or ipfw
#
use POSIX;
POSIX::nice(19);
require 'bmversion.pl';
require 'bandmin.conf';
require 'services.conf';
if ($ENV{'QUERY_STRING'} ne "") {
@keys = split(/&/, $ENV{'QUERY_STRING'});
foreach $key (sort @keys) {
($name,$value) = split(/=/, $key);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
} else {
read(STDIN,$q,$ENV{'CONTENT_LENGTH'});
@pairs = split(/\&/, $q);
foreach $pair (sort @pairs) {
($name,$value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
}
my %REPLACEMENTS = (
"<" => "<",
">" => ">",
"&" => "&",
'"' => """,
"'" => "'",
);
foreach my $key (keys %FORM) {
$FORM{$key} =~ s/([<>&"'])/$REPLACEMENTS{$1}/g;
}
open(BANDDATA,"/var/log/bandwidth/current");
while(<BANDDATA>) {
s/\n//g;
($ip,$bytespersec) = split(/=/, $_);
$CURRENTBW{$ip} = $bytespersec;
}
close(BANDDATA);
if ($FORM{'displayall'}) {
$displayMin = 0;
}
open(IPADDRDB,"/var/log/bandwidth/ipmap");
while(<IPADDRDB>) {
s/\n//g;
($ip,$name) = split(/=/, $_);
$name =~ s/ /<br>/g;
$IPNAMEMAP{$ip} = $name;
}
close(IPADDRDB);
print "Content-type: text/html\r\n\r\n";
$now = localtime(time());
if ($FORM{'action'} eq "listmonths" || $FORM{'action'} eq "") {
opendir(BWMON,"/var/log/bandwidth");
@YEARS = readdir(BWMON);
closedir(BWMON);
@YEARS = grep(!/^\./, @YEARS);
print "<html>";
print "<head><link rel=\"stylesheet\" href=\"style.css\"></head>";
print "<body><center><table class=logo><tr><td>Bandmin 1.4</td></tr></table>";
print "<br><center></center><br></center><blockquote>";
foreach $year (@YEARS) {
next if (! -d "/var/log/bandwidth/$year");
opendir(BWMON,"/var/log/bandwidth/$year");
@MONTHS = readdir(BWMON);
closedir(BWMON);
@MONTHS = grep(!/^\./, @MONTHS);
print "$year<br><table><tr>";
$rc=0;
foreach $month (@MONTHS) {
next if (! -d "/var/log/bandwidth/$year/${month}");
$rc++;if ($rc % 2 == 0) {$tdclass = 'shadedk';}else{$tdclass='shadelg';}
print "<td class=$tdclass><a href=\"index.cgi?action=showmonth&year=$year&month=$month\">$month</a></td> \n";
}
print "</tr></table><br><br>\n";
}
print "</blockquote></html>\n";
} elsif ($FORM{'action'} eq "showmonth") {
my $year = $FORM{'year'};
my $month = $FORM{'month'};
$year =~ s/\.//g;
$month =~ s/\.//g;
loadbanddata($year,$month);
print "<html>";
print "<head><link rel=\"stylesheet\" href=\"style.css\"></head>";
print "<body>\n";
print "<center><table><tr><td class=logo>$month Summary</td></tr></table></center><h3><center>Last updated $now</center></h2>";
print "<center><table class=transtbl><tr>";
print "<td bgcolor=#000000 class=header><b>Day</b></td>\n";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
print "<td bgcolor=#000000 class=header><b>Transfer in $ABRV{$unit}</b></td>";
}
}
print "</tr>\n";
$rc=0;
foreach $day (sort keys %DAYBAND) {
$rc++;if ($rc % 2 == 0) {$tdclass = 'shadedk';}else{$tdclass='shadelg';}
print "<tr><td class=leftblk><b>$day</b></td>";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
$bw = &unsci($DAYBAND{$day} * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=${tdclass}>$bw</td>";
}
}
print "</tr>\n";
}
print "</table></center>";
print "<br><center>";
if ($displayMin > 0) {
my $mb = $displayMin/1024**2;
my $s = "s" unless $mb = 1;
print "<font size'-1'>Please note that only sites with bandwidth usage greater than $mb megabyte$s
are being displayed.<br>To display all sites, please <a
href=\"index.cgi?action=showmonth&month=${month}&year=${year}&displayall=1\">click
here</a>.</font>";
}
print "</center><br>";
print "<table class=transtbl><tr><td width=1></td><td class=header><b>";
print "Ip<b></td><td class=header><b>Possible Domain(s)<b></td>\n";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
print "<td class=header><b>Transfer in $ABRV{$unit}</b></td>";
}
}
foreach $unit (sort keys %UNITS) {
if ($SHOWPERSEC{$unit} == 1) {
print "<td class=header><b>Transfer in $ABRV{$unit}/s</b></td>";
}
}
$totalbytes = 0;
$totalbps = 0;
$rc = 0;
foreach $ip (sort keys %TOTALBAND) {
next if ($ip eq "all-all");
next if ($ip !~ /-all-in$/ && $ip !~ /-all-out$/ && $ip ne "broadcast");
$page = $ip;
$page =~ s/-all-\S+$//g;
$ip =~ /^(\d+\.\d+\.\d+\.\d+)/;
if ($IPNAMEMAP{$1} ne "") {
$name = $IPNAMEMAP{$1};
} else {
$name = $page;
}
if ($ip eq 'broadcast') { $name = ''; }
if (unsci($TOTALBAND{$ip}) < $displayMin) {
next;
}
print "<tr>\n";
$rc++;if ($rc % 2 == 0) {$tdclass = 'shadedk';}else{$tdclass='shadelg';}
my $tdclassreset = $tdclass;
foreach $color (sort { $DISPLAY{$a} <=> $DISPLAY{$b} } keys %DISPLAY) {
if (unsci($TOTALBAND{$ip}) > $DISPLAY{$color}) {
$tdclass = "shade$color";
}
}
if ($ip =~ /out/) { print "<td width=1 class=leftblk><img src=\"out.gif\"></td>";
} elsif ($ip =~ /in/) { print "<td width=1 class=leftblk><img src=\"in.gif\"></td>";
} else { print "<td width=1 class=leftblk></td>"; }
print "<td class=${tdclass}><b><a
href=\"index.cgi?action=showhost&month=${month}&year=${year}&host=${page}\">${page}</a></b></td>\n";
print "<td class=${tdclass}><b><a
href=\"index.cgi?action=showhost&month=${month}&year=${year}&host=${page}\">$name</a></b></td>\n";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
$bw = &unsci($TOTALBAND{$ip} * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=${tdclass}><span class=${tdclass}>$bw</span></td>\n";
}
}
foreach $unit (sort keys %UNITS) {
if ($SHOWPERSEC{$unit} == 1) {
$bw = &unsci($CURRENTBW{$ip} * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=${tdclass}><span class=${tdclass}>$bw</span></td>\n";
}
}
print "</tr>\n";
}
@PATHS = ('in','out','all');
foreach $path (@PATHS) {
$tdclass = $tdclassreset;
print "<tr><td width=1 class=leftblk><img src=\"total.gif\"></td><td
class=total>Total ${path}</td><td class=total></td>";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
$bw = &unsci($TOTALBAND{"all-$path"} * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=total>$bw</td>";
}
}
foreach $unit (sort keys %UNITS) {
if ($SHOWPERSEC{$unit} == 1) {
$bw = &unsci($CURRENTBW{"all-$path"} * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=total>$bw</td>";
}
}
print "</tr>\n";
}
print "</table><br><center></center>
<table class=legend><tr><td>
<b>Legend:</b>
<img src=out.gif> Outgoing Traffic
<img src=in.gif> Incoming Traffic
<img src=total.gif> Total Traffic
</td></tr></table>
<br></center></html>\n";
} elsif ($FORM{'action'} eq "showhost") {
my $year = $FORM{'year'};
my $month = $FORM{'month'};
my $host = $FORM{'host'};
$year =~ s/\.//g;
$month =~ s/\.//g;
$host =~ s/\.\.//g;
loadbanddata($year,$month);
if ($host ne "broadcast") {
$file = $host;
$file =~ s/-all-out$//g;
$host =~ /^(\d+\.\d+\.\d+\.\d+)/;
if ($IPNAMEMAP{$1} ne "") {
$name = $IPNAMEMAP{$1};
} else {
$name = $host;
}
} else {
$name = 'broadcast';
$file = 'broadcast';
}
$name =~ s/\n//g;
$name =~ s/-all-out$//g;
$totalbytes = 0;
print "<html>";
print "<head><link rel=\"stylesheet\" href=\"style.css\"></head>";
print "<body><center><table><tr><td class=logo>$month Daily Summary</td></tr></table><span class=hitext>$name</span><br><br>Last updated $now";
print "<table class=transtbl>";
print "<tr>";
print "<td></td><td class=header><b>Day</b></td>\n";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
print "<td class=header><b>Transfer in $ABRV{$unit}</b></td>";
}
}
print "</tr>\n";
if ($host ne "broadcast") {
@PATHS = ('in','out');
} else {
@PATHS = ('broadcast');
}
$totalbytes = 0;
foreach $path (@PATHS) {
$key = "${file}-all-${path}";
if ($path eq "broadcast") { $key = 'broadcast'; }
$rc=0;
foreach $day (sort keys %{$BANDWIDTH{$key}}) {
$rc++;if ($rc % 2 == 0) {$tdclass = 'shadedk';}else{$tdclass='shadelg';}
print "<tr>";
$bytes = $BANDWIDTH{$key}{$day};
print "<td class=leftblk><img src=\"${path}.gif\"></td><td class=$tdclass><b>
<a href=\"index.cgi?action=showdaily&year=${year}&month=${month}&host=${host}&day=${day}\">$day</a></b></td>";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
$bw = &unsci($bytes * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=$tdclass>$bw</td>";
}
}
$totalbytes = ($totalbytes + $bytes);
print "</tr>\n";
}
}
print "<tr><td class=leftblk><img src=\"total.gif\"></td><td class=total>Total</td>";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
$bw = &unsci($totalbytes * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=total>$bw</td>";
}
}
print "</tr></table></center></html>";
close();
} elsif ($FORM{'action'} eq "showdaily") {
my $year = $FORM{'year'};
my $month = $FORM{'month'};
my $host = $FORM{'host'};
my $day = $FORM{'day'};
$year =~ s/\.//g;
$month =~ s/\.//g;
$host =~ s/\.\.//g;
$day =~ s/\.//g;
loadbanddata($year,$month);
if ($host ne "broadcast") {
$file = $host;
$file =~ s/-all-out$//g;
$host =~ /^(\d+\.\d+\.\d+\.\d+)/;
if ($IPNAMEMAP{$1} ne "") {
$name = $IPNAMEMAP{$1};
} else {
$name = $host;
}
} else {
$name = 'broadcast';
$file = 'broadcast';
}
$name =~ s/\n//g;
$name =~ s/-all-out$//g;
$totalbytes = 0;
$day = sprintf("%02d",$day);
print "<html>";
print "<head><link rel=\"stylesheet\" href=\"style.css\"></head>";
print "<body><center><table><tr><td class=logo>Summary for $month $day</td></tr></table>";
print "<br><span class=hitext>$name</span>
<br><br>Last updated $now<br>";
@PROTOCOLS = ("all","tcp","udp","icmp");
foreach $service (@SERVICES) {
push(@PROTOCOLS,"tcp:$service");
}
foreach $protocol (@PROTOCOLS) {
$totalbytes = 0;
print "<br>\n";
$port = '';
print "<table width=100%><tr><td width=40%>";
if ($protocol =~ /:/) {
($protocol,$port) = split(/:/, $protocol);
$portname = $PORTDB{$port};
print "<table><tr><td class=logo>$protocol port $port ($portname)</td></tr></table>";
} else {
print "<table><tr><td class=logo>$protocol</td></tr></table>";
}
print "</td><td>";
print "<table class=transtbl><tr>";
print "<td></td>\n";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
print "<td class=header><b>Transfer in $ABRV{$unit}</b></td>";
}
}
print "</tr>\n";
@PATHS = ('in','out');
$rc=0;
foreach $path (@PATHS) {
if ($port eq "") {
$key = "${file}-${protocol}-${path}";
} else {
$key = "${file}-${protocol}-${path}-${port}";
}
$rc++;if ($rc % 2 == 0) {$tdclass = 'shadedk';}else{$tdclass='shadelg';}
print "<tr>";
$bytes = $BANDWIDTH{$key}{$day};
print "<td class=leftblk><img src=\"${path}.gif\"></td>";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
$bw = &unsci($bytes * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td class=$tdclass>$bw</td>";
}
}
$totalbytes = ($totalbytes + $bytes);
print "</tr>\n";
}
print "<tr><td class=leftblk><img src=\"total.gif\"></td></td></td>";
foreach $unit (sort keys %UNITS) {
if ($SHOW{$unit} == 1) {
$bw = &unsci($totalbytes * eval($UNITS{$unit}));
if ($ROUND{$unit} == 1) { $bw = &round($bw); }
print "<td>$bw</td>";
}
}
print "</tr></table>\n";
print "</tr></table>\n";
}
}
sub unsci {
my($number) = shift;
return sprintf("%f",$number);
}
sub round {
my($number) = shift;
return int($number + .5 * ($number <=> 0));
}
sub imagenumbers {
my($number) = @_;
my($imagehtml) = '';
my($x);
for($i=0;$i<length($number);$i++) {
$x = substr($number,$i,1);
$imagehtml = $imagehtml . "<img alt=\"$x\"
src=\"bandmin_${x}.gif\" border=0>";
}
return($imagehtml);
}
sub loadbanddata {
my($year,$month) = @_;
@DAYS = ();
opendir(BWDAY,"/var/log/bandwidth/$year/$month");
@DAYS = readdir(BWDAY);
closedir(BWDAY);
@DAYS = grep(!/^\./, @DAYS);
foreach $ip (sort keys %BANDWIDTH) {
delete @{$BANDWIDTH{$ip}}{keys %{$BANDWIDTH{$ip}}};
delete $BANDWIDTH{$ip};
}
delete @TOTALBAND{keys %TOTALBAND};
delete @DAYBAND{keys %DAYBAND};
foreach $day (@DAYS) {
$day =~ s/\n//g;
$daytotal = 0;
open(BANDDATA,"/var/log/bandwidth/$year/$month/$day");
while(<BANDDATA>) {
s/\n//g;
($ip,$bytes) = split(/=/, $_);
$BANDWIDTH{$ip}{$day} = $bytes;
$TOTALBAND{$ip} += $bytes;
if ($ip =~ /-all-in/) { $TOTALBAND{'all-in'} += $bytes; }
if ($ip =~ /-all-out/) { $TOTALBAND{'all-out'} += $bytes; }
if ($ip eq "all-all") {
$DAYBAND{$day} += $bytes;
}
}
close(BANDDATA);
}
}