Files
bpfire/html/cgi-bin/logs.cgi/firewalllogcountry.dat
Alf Høgemark f424897557 firewalllogcountry.dat: Use language strings and add to menu
Add some language strings for the new firewalllogport.dat, and
include html fixes done in firewalllogip.dat, which this file
is based on.

Also try to add the menu item to the sub menu, but that is
currently not working.
2014-03-01 14:59:18 +01:00

520 lines
16 KiB
Perl

#!/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();
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 (<FILE>)
{
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 (<FILE>) {
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 "<font class='base'>$errormessage&nbsp;</font>\n";
&Header::closebox();
}
&Header::openbox('100%', 'left', "$Lang::tr{'settings'}");
print <<END
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
<table width='100%'>
<tr>
<td width='10%' class='base'>$Lang::tr{'month'}:&nbsp;</td>
<td width='10%'>
<select name='MONTH'>
END
;
my $month;
for ($month = 0; $month < 12; $month++)
{
print "\t<option ";
if ($month == $cgiparams{'MONTH'}) {
print "selected='selected' "; }
print "value='$month'>$longmonths[$month]</option>\n";
}
print <<END
</select>
</td>
<td width='10%' class='base' align='right'>&nbsp;$Lang::tr{'day'}:&nbsp;</td>
<td width='40%'>
<select name='DAY'>
END
;
for ($day = 1; $day <= 31; $day++)
{
print "\t<option ";
if ($day == $cgiparams{'DAY'}) {
print "selected='selected' "; }
print "value='$day'>$day</option>\n";
}
if( $cgiparams{'pienumber'} != 0){$pienumber=$cgiparams{'pienumber'};}
if( $cgiparams{'otherspie'} != 0){$otherspie=$cgiparams{'otherspie'};}
if( $cgiparams{'showpie'} != 0){$showpie=$cgiparams{'showpie'};}
if( $cgiparams{'sortcolumn'} != 0){$sortcolumn=$cgiparams{'sortcolumn'};}
print <<END
</select>
</td>
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day before'}' value='&lt;&lt;' /></td>
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day after'}' value='&gt;&gt;' /></td>
<td width='20%' align='right'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
</tr>
<tr>
<td colspan='3' align='left' valign="left">$Lang::tr{'Number of Countries for the pie chart'}:</td>
<td colspan='3' align='left' valign="center"><input type='text' name='pienumber' value='$pienumber' size='4'></td>
<td align='right'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>
</tr>
</table>
</form>
END
;
&Header::closebox();
&Header::openbox('100%', 'left', 'Firewall Logs');
print "<p><b>$Lang::tr{'firewall hits'} $longmonthstr $daystr: $lines</b></p>";
my $linesjc = 0;
my %tabjc;
my $gi = Geo::IP::PurePerl->new();
if ($pienumber == -1 || $pienumber > $lines || $sortcolumn == 2) { $pienumber = $lines; };
$lines = 0;
foreach $_ (@log)
{
if($_ =~ /SRC\=([\d\.]+)/){
my $srcaddr=$1;
my $ccode = $gi->country_code_by_name($srcaddr);
my $fcode;
# TODO: should local IP adresses be include as unknown, or excluded from the statistics totally ?
# TODO: it would be nice to be able to group local IPs into "red", "green", "blue" etc
if( $ccode eq "") {
$ccode = "unknown";
}
else {
$tabjc{$ccode} = $tabjc{$ccode} + 1 ;
if(($tabjc{$ccode} == 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 );
my $color=0;
my %color = ();
my %mainsettings = ();
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
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 => [ "$color{'color1'}" , "$color{'color2'}" , "$color{'color3'}" , "$color{'color4'}" , "$color{'color5'}" , "$color{'color6'}" , "$color{'color7'}" , "$color{'color8'}" , "$color{'color9'}" , "$color{'color10'}" ] );
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 "<table align='center'><tr><td>";
print "<img src='/graphs/fwlog-ip$imagerandom.png'>";
print "</td></tr></table>";
}
print <<END
<table width='100%' class='tbl'>
<tr>
<th width='10%' align='center' class='boldbase'></th>
<th width='30%' align='center' class='boldbase'><b>$Lang::tr{'country'}</b></th>
<th width='30%' align='center' class='boldbase'><b>Count</b></th>
<th width='30%' align='center' class='boldbase'><b>$Lang::tr{'percentage'}</b></th>
</tr>
END
;
my $total=0;
my $show=0;
my $s;
my $percent;
my $col="";
for($s=0;$s<$lines;$s++)
{
$show++;
$percent = $value[$s] * 100 / $linesjc;
$percent = sprintf("%.f", $percent);
$total = $total + $value[$s];
if ( ($color % 10) == 1 ){print "<tr>"; $col="bgcolor='$color{'color1'}'";}
if ( ($color % 10) == 2 ){print "<tr>"; $col="bgcolor='$color{'color2'}'";}
if ( ($color % 10) == 3 ){print "<tr>"; $col="bgcolor='$color{'color3'}'";}
if ( ($color % 10) == 4 ){print "<tr>"; $col="bgcolor='$color{'color4'}'";}
if ( ($color % 10) == 5 ){print "<tr>"; $col="bgcolor='$color{'color5'}'";}
if ( ($color % 10) == 6 ){print "<tr>"; $col="bgcolor='$color{'color6'}'";}
if ( ($color % 10) == 7 ){print "<tr>"; $col="bgcolor='$color{'color7'}'";}
if ( ($color % 10) == 8 ){print "<tr>"; $col="bgcolor='$color{'color8'}'";}
if ( ($color % 10) == 9 ){print "<tr>"; $col="bgcolor='$color{'color9'}'";}
if ( ($color % 10) == 0 ){print "<tr>"; $col="bgcolor='$color{'color10'}'";}
$color++;
print "<td align='center' $col><form method='post' action='showrequestfromcountry.dat'><input type='hidden' name='MONTH' value='$cgiparams{'MONTH'}'> <input type='hidden' name='DAY' value='$cgiparams{'DAY'}'> <input type='hidden' name='country' value='$key[$s]'> <input type='submit' value='details'></form></td>";
if ( $key[$s] ne "unknown" ){
my $fcode = lc($key[$s]);
print "<td align='center' $col><a href='/cgi-bin/country.cgi#$fcode'><img src='/images/flags/$fcode.png' border='0' align='absmiddle' alt='$key[$s]' title='$key[$s]'></a></TD>";}
else {
print "<td align='center' $col></td>";
}
print "<td align='center' $col>$value[$s]</td>";
print "<td align='center' $col>$percent</td>";
print "</tr>";
}
if($cgiparams{'otherspie'} == 2 ){}
else{
if ( ($color % 10) == 1 ){print "<tr>"; $col="bgcolor='$color{'color1'}'";}
if ( ($color % 10) == 2 ){print "<tr>"; $col="bgcolor='$color{'color2'}'";}
if ( ($color % 10) == 3 ){print "<tr>"; $col="bgcolor='$color{'color3'}'";}
if ( ($color % 10) == 4 ){print "<tr>"; $col="bgcolor='$color{'color4'}'";}
if ( ($color % 10) == 5 ){print "<tr>"; $col="bgcolor='$color{'color5'}'";}
if ( ($color % 10) == 6 ){print "<tr>"; $col="bgcolor='$color{'color6'}'";}
if ( ($color % 10) == 7 ){print "<tr>"; $col="bgcolor='$color{'color7'}'";}
if ( ($color % 10) == 8 ){print "<tr>"; $col="bgcolor='$color{'color8'}'";}
if ( ($color % 10) == 9 ){print "<tr>"; $col="bgcolor='$color{'color9'}'";}
if ( ($color % 10) == 0 ){print "<tr>"; $col="bgcolor='$color{'color10'}'";}
if ( $linesjc ne "0")
{
my $dif;
$dif = $linesjc - $total;
$percent = $dif * 100 / $linesjc;
$percent = sprintf("%.f", $percent);
print <<END
<td align='center' $col></TD>
<td align='center' $col>$Lang::tr{'other countries'}</td>
<td align='center' $col>$dif</TD>
<td align='center' $col>$percent</TD>
</tr>
END
;
}
}
print <<END
</TABLE>
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";
}