#!/usr/bin/perl # # SmoothWall CGIs # # This code is distributed under the terms of the GPL # # JC HERITIER # page inspired from the initial firewalllog.dat # # Modified for IPFire by Christian Schmidt # and Michael Tremer (www.ipfire.org) use strict; use Geo::IP::PurePerl; use Getopt::Std; # enable only the following on debugging purpose #use warnings; #use CGI::Carp 'fatalsToBrowser'; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; use POSIX(); #workaround to suppress a warning when a variable is used only once my @dummy = ( ${Header::table2colour} ); undef (@dummy); my %cgiparams=(); my %settings=(); my $pienumber; my $otherspie; my $showpie; my $sortcolumn; my $errormessage = ''; $cgiparams{'pienumber'} = 10; $cgiparams{'otherspie'} = 1; $cgiparams{'showpie'} = 1; $cgiparams{'sortcolumn'} = 1; my @shortmonths = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ); my @longmonths = ( $Lang::tr{'january'}, $Lang::tr{'february'}, $Lang::tr{'march'}, $Lang::tr{'april'}, $Lang::tr{'may'}, $Lang::tr{'june'}, $Lang::tr{'july'}, $Lang::tr{'august'}, $Lang::tr{'september'}, $Lang::tr{'october'}, $Lang::tr{'november'}, $Lang::tr{'december'} ); my @now = localtime(); my $dow = $now[6]; my $doy = $now[7]; my $tdoy = $now[7]; my $year = $now[5]+1900; $cgiparams{'DAY'} = $now[3]; $cgiparams{'MONTH'} = $now[4]; $cgiparams{'ACTION'} = ''; &General::readhash("${General::swroot}/fwlogs/ipsettings", \%settings); if ($settings{'pienumber'} != 0) { $cgiparams{'pienumber'} = $settings{'pienumber'} }; if ($settings{'otherspie'} != 0) { $cgiparams{'otherspie'} = $settings{'otherspie'} }; if ($settings{'showpie'} != 0) { $cgiparams{'showpie'} = $settings{'showpie'} }; if ($settings{'sortcolumn'} != 0) { $cgiparams{'sortcolumn'} = $settings{'sortcolumn'} }; &Header::getcgihash(\%cgiparams); if ($cgiparams{'pienumber'} != 0) { $settings{'pienumber'} = $cgiparams{'pienumber'} }; if ($cgiparams{'otherspie'} != 0) { $settings{'otherspie'} = $cgiparams{'otherspie'} }; if ($cgiparams{'showpie'} != 0) { $settings{'showpie'} = $cgiparams{'showpie'} }; if ($cgiparams{'sortcolumn'} != 0) { $settings{'sortcolumn'} = $cgiparams{'sortcolumn'} }; if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { &General::writehash("${General::swroot}/fwlogs/ipsettings", \%settings); } my $start = -1; if ($ENV{'QUERY_STRING'} && $cgiparams{'ACTION'} ne $Lang::tr{'update'}) { my @temp = split(',',$ENV{'QUERY_STRING'}); $start = $temp[0]; $cgiparams{'MONTH'} = $temp[1]; $cgiparams{'DAY'} = $temp[2]; } if (!($cgiparams{'MONTH'} =~ /^(0|1|2|3|4|5|6|7|8|9|10|11)$/) || !($cgiparams{'DAY'} =~ /^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)$/)) { $cgiparams{'DAY'} = $now[3]; $cgiparams{'MONTH'} = $now[4]; } elsif($cgiparams{'ACTION'} eq '>>') { my @temp_then=(); my @temp_now = localtime(time); $temp_now[4] = $cgiparams{'MONTH'}; $temp_now[3] = $cgiparams{'DAY'}; @temp_then = localtime(POSIX::mktime(@temp_now) + 86400); ## Retrieve the same time on the next day - ## 86400 seconds in a day $cgiparams{'MONTH'} = $temp_then[4]; $cgiparams{'DAY'} = $temp_then[3]; } elsif($cgiparams{'ACTION'} eq '<<') { my @temp_then=(); my @temp_now = localtime(time); $temp_now[4] = $cgiparams{'MONTH'}; $temp_now[3] = $cgiparams{'DAY'}; @temp_then = localtime(POSIX::mktime(@temp_now) - 86400); ## Retrieve the same time on the previous day - ## 86400 seconds in a day $cgiparams{'MONTH'} = $temp_then[4]; $cgiparams{'DAY'} = $temp_then[3]; } if (($cgiparams{'DAY'} ne $now[3]) || ($cgiparams{'MONTH'} ne $now[4])) { my @then = (); if ( ( $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) || ( $cgiparams{'MONTH'} > $now[4] ) ) { @then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1901 )); } else { @then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1900 )); } $tdoy = $then[7]; my $lastleap=($year-1)%4; if ($tdoy>$doy) { if ($lastleap == 0 && $tdoy < 60) { $doy=$tdoy+366; } else { $doy=$doy+365; } } } my $datediff=0; my $dowd=0; my $multifile=0; if ($tdoy ne $doy) { $datediff=int(($doy-$tdoy)/7); $dowd=($doy-$tdoy)%7; if (($dow-$dowd)<1) { $datediff=$datediff+1; } if (($dow-$dowd)==0) { $multifile=1; } } my $monthstr = $shortmonths[$cgiparams{'MONTH'}]; my $longmonthstr = $longmonths[$cgiparams{'MONTH'}]; my $day = $cgiparams{'DAY'}; my $daystr=''; if ($day <= 9) { $daystr = " $day"; } else { $daystr = $day; } my $skip=0; my $filestr=''; if ($datediff==0) { $filestr="/var/log/messages"; } else { $filestr="/var/log/messages.$datediff"; $filestr = "$filestr.gz" if -f "$filestr.gz"; } if (!(open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) { $errormessage = "$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}"; $skip=1; # Note: This is in case the log does not exist for that date } my $lines = 0; my @log=(); if (!$skip) { while () { if (/(^${monthstr} ${daystr} ..:..:..) [\w\-]+ kernel:.*(IN=.*)$/) { $log[$lines] = $_; $lines++; } } close (FILE); } $skip=0; if ($multifile) { $datediff=$datediff-1; if ($datediff==0) { $filestr="/var/log/messages"; } else { $filestr="/var/log/messages.$datediff"; $filestr = "$filestr.gz" if -f "$filestr.gz"; } if (!(open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) { $errormessage="$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}"; $skip=1; } if (!$skip) { while () { if (/(^${monthstr} ${daystr} ..:..:..) [\w\-]+ kernel:.*(IN=.*)$/) { $log[$lines] = $_; $lines++; } } close (FILE); } } my $MODNAME="fwlogs"; &Header::showhttpheaders(); &Header::openpage($Lang::tr{'firewall log'}, 1, ''); &Header::openbigbox('100%', 'left', '', $errormessage); if ($errormessage) { &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); print "$errormessage \n"; &Header::closebox(); } &Header::openbox('100%', 'left', "$Lang::tr{'settings'}:"); print <
$Lang::tr{'month'}:   $Lang::tr{'day'}: 
$Lang::tr{'Number of IPs for the pie chart'}:
END ; &Header::closebox(); &Header::openbox('100%', 'left', 'Firewall Logs'); print "

$Lang::tr{'firewall hits'} $longmonthstr $daystr: $lines

"; my $linesjc = 0; my %tabjc; if ($pienumber == -1 || $pienumber > $lines || $sortcolumn == 2) { $pienumber = $lines; }; $lines = 0; foreach $_ (@log) { if($_ =~ /SRC\=([\d\.]+)/){ $tabjc{$1} = $tabjc{$1} + 1 ; if(($tabjc{$1} == 1) && ($lines < $pienumber)) { $lines = $lines + 1; } $linesjc++; } } $pienumber = $lines; my @keytabjc = keys %tabjc; my @slice; my $go; my $nblinejc; if( $cgiparams{'linejc'} eq 'all' ){ $nblinejc = $linesjc; $go=1; } if( ($cgiparams{'linejc'} != 0) && ($cgiparams{'linejc'} ne 'all') ){ $nblinejc = $cgiparams{'linejc'}; $go=1;} if( $go != 1){ $nblinejc = 1000; } my @key; my @value; my $indice=0; my @tabjc2; if ($sortcolumn == 1) { @tabjc2 = sort { $b <=> $a } values (%tabjc); } else { @tabjc2 = sort { $a <=> $b } keys (%tabjc); } my $colour=1; ############################################## #pie chart generation use GD::Graph::pie; use GD::Graph::colour; #ips sort by hits number my $v; if ($sortcolumn == 1) { for ($v=0;$v<$pienumber;$v++){ findkey($tabjc2[$v]); } } else { foreach $v (@tabjc2) { $key[$indice] = $v; $value[$indice] = $tabjc{$v}; $indice++; } } my @ips; my @numb; @ips = @key; @numb = @value; my $o; if($cgiparams{'otherspie'} == 2 ){} else{ my $numothers; for($o=0;$o<$pienumber;$o++){ $numothers = $numothers + $numb[$o]; } $numothers = $linesjc - $numothers; if ($numothers > 0) { $ips[$pienumber]="$Lang::tr{'otherip'}"; $numb[$pienumber] = $numothers; } } my @data = (\@ips,\@numb); use GD::Graph::colour qw( :files ); GD::Graph::colour::read_rgb( "/srv/web/ipfire/cgi-bin/logs.cgi/colours.txt" ); if ($showpie != 2 && $pienumber <= 50 && $pienumber != 0) { my $mygraph = GD::Graph::pie->new(500, 350); $mygraph->set( 'title' => '', 'pie_height' => 50, 'start_angle' => 89 ) or warn $mygraph->error; $mygraph->set_value_font(GD::gdMediumBoldFont); $mygraph->set( dclrs => [ "colour1" , "colour2" , "colour3" , "colour4" , "colour5" , "colour6" , "colour7" , "colour8" , "colour9" , "colour10" ] ); my $myimage = $mygraph->plot(\@data) or die $mygraph->error; my @filenames = glob("/srv/web/ipfire/html/graphs/fwlog-ip*.png"); unlink(@filenames); my $imagerandom = rand(1000000); my $imagename = "/srv/web/ipfire/html/graphs/fwlog-ip$imagerandom.png"; open(FILE,">$imagename"); print FILE $myimage->png; close(FILE); ##################################################### print "
"; print ""; print "
"; } print < IP Flag Count Percent END ; my $total=0; my $show=0; my @colour; my $colour1; my $colour2; my $colour3; my $colour4; my $colour5; my $colour6; my $colour7; my $colour8; my $colour9; my $colour10; @colour = GD::Graph::colour::_rgb("colour1"); $colour1 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour2"); $colour2 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour3"); $colour3 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour4"); $colour4 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour5"); $colour5 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour6"); $colour6 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour7"); $colour7 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour8"); $colour8 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour9"); $colour9 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); @colour = GD::Graph::colour::_rgb("colour10"); $colour10 = GD::Graph::colour::rgb2hex($colour[0], $colour[1], $colour[2]); my $s; my $percent; for($s=0;$s<$lines;$s++) { $show++; $percent = $value[$s] * 100 / $linesjc; $percent = sprintf("%.3f", $percent); $total = $total + $value[$s]; if ( ($colour % 10) == 1 ){print "\n";} if ( ($colour % 10) == 2 ){print "\n";} if ( ($colour % 10) == 3 ){print "\n";} if ( ($colour % 10) == 4 ){print "\n";} if ( ($colour % 10) == 5 ){print "\n";} if ( ($colour % 10) == 6 ){print "\n";} if ( ($colour % 10) == 7 ){print "\n";} if ( ($colour % 10) == 8 ){print "\n";} if ( ($colour % 10) == 9 ){print "\n";} if ( ($colour % 10) == 0 ){print "\n";} my $gi = Geo::IP::PurePerl->new(); my $ccode = $gi->country_code_by_name($key[$s]); my $fcode = lc($ccode); $colour++; print "
"; print "$key[$s]"; print "$ccode"; print "$value[$s]"; print "$percent"; print ""; } if($cgiparams{'otherspie'} == 2 ){} else{ if ( ($colour % 10) == 1 ){print "\n";} if ( ($colour % 10) == 2 ){print "\n";} if ( ($colour % 10) == 3 ){print "\n";} if ( ($colour % 10) == 4 ){print "\n";} if ( ($colour % 10) == 5 ){print "\n";} if ( ($colour % 10) == 6 ){print "\n";} if ( ($colour % 10) == 7 ){print "\n";} if ( ($colour % 10) == 8 ){print "\n";} if ( ($colour % 10) == 9 ){print "\n";} if ( ($colour % 10) == 0 ){print "\n";} my $dif; $dif = $linesjc - $total; $percent = $dif * 100 / $linesjc; $percent = sprintf("%.3f", $percent); print < $Lang::tr{'otherip'} $dif $percent END ; } print < END ; &Header::closebox(); &Header::closebigbox(); &Header::closepage(); sub findkey { my $v; foreach $v (@keytabjc) { if ($tabjc{$v} eq $_[0]) { delete $tabjc{$v}; $key[$indice] = "$v"; $value[$indice] = $_[0]; $indice++; last; } } }sub checkversion { #Automatic Updates is disabled return "0","0"; }