Files
bpfire/html/cgi-bin/logs.cgi/firewalllogcountry.dat
Peter Müller 66c3619872 Early spring clean: Remove trailing whitespaces, and correct licence headers
Bumping across one of our scripts with very long trailing whitespaces, I
thought it might be a good idea to clean these up. Doing so, some
missing or inconsistent licence headers were fixed.

There is no need in shipping all these files en bloc, as their
functionality won't change.

Signed-off-by: Peter Müller <peter.mueller@ipfire.org>
2022-02-18 23:54:57 +00:00

547 lines
14 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 Getopt::Std;
# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/location-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 country'}, 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', $Lang::tr{'firewall graph country'});
print "<p><b>$Lang::tr{'firewall hits'} $longmonthstr $daystr: $lines</b></p>";
my $red_interface = &General::get_red_interface();
my $linesjc = 0;
my %tabjc;
if ($pienumber == -1 || $pienumber > $lines || $sortcolumn == 2) { $pienumber = $lines; };
$lines = 0;
foreach $_ (@log)
{
# If ipv6 uses bridge, use PHYSIN for iface, otherwise IN
if (/^... (..) (..:..:..) [\w\-]+ kernel:(.*)(PHYSIN=.*)$/) {}
elsif (/^... (..) (..:..:..) [\w\-]+ kernel:(.*)(IN=.*)$/) {}
my $packet = $4;
my $iface = '';
if ($packet =~ /PHYSIN=(\w+)/) { $iface = $1; } elsif ($packet =~ /IN=(\w+)/) { $iface = $1; }
if ( $1 =~ /2./ ) { $iface=''; }
my $srcaddr = '';
# Find ipv4 and ipv6 addresses
if ($packet =~ /SRC\=(([\d]{1,3})(\.([\d]{1,3})){3})/) { $srcaddr = $1; }
elsif ($packet =~ /SRC\=(([0-9a-fA-F]{0,4})(\:([0-9a-fA-F]{0,4})){2,7})/) { $srcaddr = $1; }
if($iface eq $red_interface) {
# Traffic from red
if($srcaddr ne '') {
# srcaddr is set
my $ccode = &Location::Functions::lookup_country_code($srcaddr);
if ($ccode eq '') {
$ccode = 'unknown';
}
$tabjc{$ccode} = $tabjc{$ccode} + 1;
if(($tabjc{$ccode} == 1) && ($lines < $pienumber)) { $lines = $lines + 1; }
$linesjc++;
}
}
else {
# Traffic not from red
if($iface ne '') {
$tabjc{$iface} = $tabjc{$iface} + 1 ;
if(($tabjc{$iface} == 1) && ($lines < $pienumber)) { $lines = $lines + 1; }
$linesjc++;
}
else {
# What to do with empty iface lines?
# This probably is traffic from ipfire itself (IN= OUT=XY)?
}
}
}
$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/ipfire/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-country*.png");
unlink(@filenames);
my $imagerandom = rand(1000000);
my $imagename = "/srv/web/ipfire/html/graphs/fwlog-country$imagerandom.png";
open(FILE,">$imagename");
print FILE $myimage->png;
close(FILE);
#####################################################
print "<div style='text-align:center;'>";
print "<img src='/graphs/fwlog-country$imagerandom.png'>";
print "</div>";
}
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];
# colors are numbered 1 to 10
my $colorIndex = ($color % 10) + 1;
$col="bgcolor='$color{\"color$colorIndex\"}'";
$color++;
print "<tr>";
print "<td align='center' $col>";
# Dont show details button for "unknown" location.
if ($key[$s] ne 'unknown') {
print"<form method='post' action='showrequestfromcountry.dat'>";
print"<input type='hidden' name='MONTH' value='$cgiparams{'MONTH'}'>";
print"<input type='hidden' name='DAY' value='$cgiparams{'DAY'}'>";
print"<input type='hidden' name='country' value='$key[$s]'>";
print"<input type='submit' value='$Lang::tr{'details'}'></form>";
}
elsif ($key[$s] eq 'unknown') {
print "unknown";
}
# Looks dangerous to use hardcoded interface names here. Probably needs fixing.
if ($key[$s] eq 'blue0' || $key[$s] eq 'green0' || $key[$s] eq 'orange0' ) {
print "<td align='center' $col>$key[$s]</td>";
}
else {
my $fcode = lc($key[$s]);
# Get flag icon for of the country.
my $flag_icon = &Location::Functions::get_flag_icon($fcode);
if($flag_icon) {
print "<td align='center' $col><a href='/cgi-bin/country.cgi#$fcode'><img src='$flag_icon' border='0' align='absmiddle' alt='$key[$s]' title='$key[$s]'></a></td>";
} else {
print "<td align='center' $col>$key[$s]</td>";
}
}
print "<td align='center' $col>$value[$s]</td>";
print "<td align='center' $col>$percent</td>";
print "</tr>";
}
if($cgiparams{'otherspie'} == 2 ){}
else{
# colors are numbered 1 to 10
my $colorIndex = ($color % 10) + 1;
$col="bgcolor='$color{\"color$colorIndex\"}'";
print "<tr>";
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";
}