mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-09 18:45:54 +02:00
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>
456 lines
13 KiB
Perl
456 lines
13 KiB
Perl
#!/usr/bin/perl
|
|
#
|
|
# SmoothWall CGIs
|
|
#
|
|
# This code is distributed under the terms of the GPL
|
|
#
|
|
# (c) The SmoothWall Team
|
|
#
|
|
# $Id: firewalllog.dat,v 1.4.2.18 2005/08/23 12:01:50 eoberlander Exp $
|
|
#
|
|
# July 28, 2003 - Darren Critchley - darren@kdi.ca
|
|
# - added source mac adapter to layout
|
|
#
|
|
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";
|
|
|
|
my %color = ();
|
|
my %mainsettings = ();
|
|
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
|
|
&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
|
|
|
|
use POSIX();
|
|
|
|
#workaround to suppress a warning when a variable is used only once
|
|
my @dummy = ( ${Header::table2colour} );
|
|
undef (@dummy);
|
|
|
|
my %cgiparams=();
|
|
my %logsettings=();
|
|
my $errormessage = '';
|
|
|
|
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'} = '';
|
|
|
|
&Header::getcgihash(\%cgiparams);
|
|
$logsettings{'LOGVIEW_REVERSE'} = 'off';
|
|
&General::readhash("${General::swroot}/logging/settings", \%logsettings);
|
|
${Header::viewsize} = defined ($logsettings{'LOGVIEW_VIEWSIZE'}) ? $logsettings{'LOGVIEW_VIEWSIZE'} : 150;
|
|
|
|
my $start = ($logsettings{'LOGVIEW_REVERSE'} eq 'on') ? 0x7FFFF000 : 0; #index of firts line number to display
|
|
|
|
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'} =~ /^(0|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'};
|
|
if ($cgiparams{'DAY'}) {
|
|
@temp_then = localtime(POSIX::mktime(@temp_now) + 86400);
|
|
## Retrieve the same time on the next day +
|
|
## 86400 seconds in a day
|
|
} else {
|
|
$temp_now[3] = 1;
|
|
$temp_now[4] = ($temp_now[4]+1) %12;
|
|
@temp_then = localtime(POSIX::mktime(@temp_now) );
|
|
$temp_then[3] = 0;
|
|
}
|
|
$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'};
|
|
if ($cgiparams{'DAY'}) {
|
|
@temp_then = localtime(POSIX::mktime(@temp_now) - 86400);
|
|
## Retrieve the same time on the next day -
|
|
## 86400 seconds in a day
|
|
} else {
|
|
$temp_now[3] = 1;
|
|
$temp_now[4] = ($temp_now[4]-1) %12;
|
|
@temp_then = localtime(POSIX::mktime(@temp_now) );
|
|
$temp_then[3] = 0;
|
|
}
|
|
$cgiparams{'MONTH'} = $temp_then[4];
|
|
$cgiparams{'DAY'} = $temp_then[3];
|
|
}
|
|
|
|
# Find in which file.gz is the log. Can be calculated because WEEKLY ROTATING of access.log
|
|
my $gzindex;
|
|
my $date = $cgiparams{'DAY'} == 0 ? '' : $cgiparams{'DAY'} <= 9 ? "0$cgiparams{'DAY'}" : "$cgiparams{'DAY'}";
|
|
|
|
{
|
|
my $xday;
|
|
|
|
# Calculate time. If future date, calculate for past year !!!
|
|
if (( $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) ||
|
|
( $cgiparams{'MONTH'} > $now[4] ) ) {
|
|
$xday = POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1901 );
|
|
$date = "$longmonths[$cgiparams{'MONTH'}] $date, ". int($year-1);
|
|
} else {
|
|
$xday = POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1900 );
|
|
$date = "$longmonths[$cgiparams{'MONTH'}] $date, $year";
|
|
}
|
|
|
|
# calculate end of active week (saturday 23H59)
|
|
my @then = ();
|
|
@then = localtime(time());
|
|
my $sunday = POSIX::mktime( 0, 0, 0, @then[3], @then[4], @then[5]);
|
|
$sunday += (6-$then[6]) * 86400;
|
|
|
|
# Convert delta in second to full weeks
|
|
$gzindex = int (($sunday-$xday)/604800 );
|
|
}
|
|
|
|
my $monthstr = $shortmonths[$cgiparams{'MONTH'}];
|
|
my $daystr = $cgiparams{'DAY'} == 0 ? '..' : $cgiparams{'DAY'} <= 9 ? " $cgiparams{'DAY'}" : "$cgiparams{'DAY'}";
|
|
|
|
my $lines = 0;
|
|
my @log=();
|
|
|
|
my $loop = 1;
|
|
my $filestr = 0;
|
|
my $lastdatetime; # for debug
|
|
my $search_for_end = 0;
|
|
|
|
while ($gzindex >=0 && $loop) {
|
|
# calculate file name
|
|
if ($gzindex == 0) {
|
|
$filestr = "/var/log/messages";
|
|
} else {
|
|
$filestr = "/var/log/messages.$gzindex";
|
|
$filestr = "$filestr.gz" if -f "$filestr.gz";
|
|
}
|
|
# now read file if existing
|
|
if (open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr))) {
|
|
#&General::log("reading $filestr");
|
|
READ:while (<FILE>) {
|
|
my $line = $_;
|
|
if ($line =~ /^${monthstr} ${daystr} ..:..:.. [\w\-]+ kernel:.*IN=.*$/) {
|
|
# when standart viewing, just keep in memory the correct slice
|
|
# it starts a '$start' and size is $viewport
|
|
# If export, then keep all lines...
|
|
if ($cgiparams{'ACTION'} eq $Lang::tr{'export'}){
|
|
$log[$lines++] = "$line";
|
|
} else {
|
|
if ($lines++ < ($start + $Header::viewsize)) {
|
|
push(@log,"$line");
|
|
if (@log > $Header::viewsize) {
|
|
shift (@log);
|
|
}
|
|
#} else { dont do this optimisation, need to count lines !
|
|
# $datetime = $maxtime; # we have read viewsize lines, stop main loop
|
|
# last READ; # exit read file
|
|
}
|
|
}
|
|
$search_for_end = 1; # we find the start of slice, can look for end now
|
|
} else {
|
|
if ($search_for_end == 1) {
|
|
#finish read files when date is over (test month equality only)
|
|
$line =~ /^(...) (..) ..:..:..*$/;
|
|
$loop = 0 if ( ($1 ne $monthstr) || ( ($daystr ne '..') && ($daystr ne $2) ) );
|
|
}
|
|
}
|
|
}
|
|
close (FILE);
|
|
}
|
|
$gzindex--; # will try next gz file eg 40,39,38,.... because it may have holes when ipcop stopped
|
|
# for a long time
|
|
}# while
|
|
|
|
# $errormessage = "$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}";
|
|
|
|
if ($cgiparams{'ACTION'} eq $Lang::tr{'export'})
|
|
{
|
|
print "Content-type: text/plain\n\n";
|
|
print "IPFire firewall log\r\n";
|
|
print "$Lang::{'date'}: $date\r\n\r\n";
|
|
|
|
if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log = reverse @log; }
|
|
|
|
foreach $_ (@log)
|
|
{
|
|
/^... (..) (..:..:..) [\w\-]+ kernel:.*(IN=.*)$/;
|
|
my $day = $1;
|
|
$day =~ tr / /0/;
|
|
my $time = $cgiparams{'DAY'} ? "$2" : "$day/$2" ;
|
|
print "$time $3\r\n";
|
|
|
|
}
|
|
exit 0;
|
|
}
|
|
|
|
&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 </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'}: </td>
|
|
<td width='10%'>
|
|
<select name='MONTH'>
|
|
END
|
|
;
|
|
for (my $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'> $Lang::tr{'day'}: </td>
|
|
<td width='40%'>
|
|
<select name='DAY'>
|
|
END
|
|
;
|
|
print "<option value='0'>$Lang::tr{'all'}</option>\n";
|
|
for (my $day = 1; $day <= 31; $day++)
|
|
{
|
|
print "\t<option ";
|
|
if ($day == $cgiparams{'DAY'}) {
|
|
print "selected='selected' ";
|
|
}
|
|
print "value='$day'>$day</option>\n";
|
|
}
|
|
print <<END
|
|
</select>
|
|
</td>
|
|
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day before'}' value='<<' /></td>
|
|
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day after'}' value='>>' /></td>
|
|
<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
|
|
<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'export'}' /></td>
|
|
</tr>
|
|
</table>
|
|
</form>
|
|
END
|
|
;
|
|
|
|
&Header::closebox();
|
|
|
|
&Header::openbox('100%', 'left', $Lang::tr{'log'});
|
|
print "<p><b>$Lang::tr{'firewall hits'} $date: $lines</b></p>";
|
|
|
|
my $lastPageIndex = $lines - ${Header::viewsize};
|
|
$start = $lastPageIndex if ($start >= $lastPageIndex);
|
|
$start = 0 if ($start < 0);
|
|
|
|
my $prev;
|
|
if ($start == 0) {
|
|
$prev = -1;
|
|
} else {
|
|
$prev = $start - ${Header::viewsize};
|
|
$prev = 0 if ( $prev < 0);
|
|
}
|
|
|
|
my $next;
|
|
if ($start == $lastPageIndex) {
|
|
$next = -1;
|
|
} else {
|
|
$next = $start + ${Header::viewsize};
|
|
$next = $lines - ${Header::viewsize} if ($next >= $lines - ${Header::viewsize});
|
|
}
|
|
|
|
if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log = reverse @log; }
|
|
if ($lines != 0) { &oldernewer(); }
|
|
|
|
print <<END
|
|
<table width='100%' class='tbl'>
|
|
<tr>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'time'}</b></th>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'chain'}</b></th>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'iface'}</b></th>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'proto'}</b></th>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'source'}<br/>$Lang::tr{'destination'}</b></th>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'src port'}<br />$Lang::tr{'dst port'}</b></th>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'country'}</b></th>
|
|
<th align='center' class='boldbase'><b>$Lang::tr{'mac address'}</b></th>
|
|
</tr>
|
|
END
|
|
;
|
|
|
|
# Generate hash to translate protocol numbers into protocol names.
|
|
my %protocols = &General::generateProtoTransHash();
|
|
|
|
$lines = 0;
|
|
foreach $_ (@log)
|
|
{
|
|
# If ipv6 uses a bridge, PHYSIN= contains the relevant iface information
|
|
# otherwise use IN=
|
|
my $packet = '';
|
|
if ($_ =~ /^... (..) (..:..:..) [\w\-]+ kernel:(.*)(IN=.*)(PHYSIN=.*)$/) { $packet = $5; }
|
|
elsif ($_ =~ /^... (..) (..:..:..) [\w\-]+ kernel:(.*)(IN=.*)$/) { $packet = $4; }
|
|
my $day = $1;
|
|
$day =~ tr / /0/;
|
|
my $time = $cgiparams{'DAY'} ? "$2" : "$day/$2" ;
|
|
my $chain = $3;
|
|
|
|
my ($iface, $srcaddr, $dstaddr, $macaddr, $proto, $srcport, $dstport);
|
|
if ($packet =~ /PHYSIN=(\w+)/) { $iface=$1; } elsif ($packet =~ /IN=(\w+)/) { $iface = $1; }
|
|
# Identify whether ipv4 or ipv6. Both are mutally exclusive.
|
|
if ($packet =~ /SRC\=(([\d]{1,3})(\.([\d]{1,3})){3})/) { $srcaddr=$1; }
|
|
if ($packet =~ /SRC\=(([0-9a-fA-F]{0,4})(\:([0-9a-fA-F]{0,4})){2,7})/) { $srcaddr=$1; }
|
|
if ($packet =~ /DST\=(([\d]{1,3})(\.([\d]{1,3})){3})/) { $dstaddr=$1; }
|
|
if ($packet =~ /DST\=(([0-9a-fA-F]{0,4})(\:([0-9a-fA-F]{0,4})){2,7})/) { $dstaddr=$1; }
|
|
$macaddr=$1 if $packet =~ /MAC=([\w+\:]+)/;
|
|
$proto=$1 if $packet =~ /PROTO=(\w+)/;
|
|
$srcport=$1 if $packet =~ /SPT=(\d+)/;
|
|
$dstport=$1 if $packet =~ /DPT=(\d+)/;
|
|
|
|
# Get the country code.
|
|
my $ccode = &Location::Functions::lookup_country_code($srcaddr);
|
|
|
|
# Lookup if the grabbed protocol is part of the protocols hash.
|
|
if (exists ($protocols{$proto})) {
|
|
# Translate protocol number into protocol name.
|
|
$proto = $protocols{$proto};
|
|
}
|
|
|
|
my $servi = uc(getservbyport($srcport, lc($proto)));
|
|
if ($servi ne '' && $srcport < 1024) {
|
|
$srcport = "$srcport($servi)";
|
|
}
|
|
$servi = uc(getservbyport($dstport, lc($proto)));
|
|
if ($servi ne '' && $dstport < 1024) {
|
|
$dstport = "$dstport($servi)";
|
|
}
|
|
my @mactemp = split(/:/,$macaddr);
|
|
$macaddr = "$mactemp[6]:$mactemp[7]:$mactemp[8]:$mactemp[9]:$mactemp[10]:$mactemp[11]";
|
|
my $col="";
|
|
if ($lines % 2) {
|
|
print "<tr>";
|
|
$col="bgcolor='$color{'color20'}'";
|
|
}
|
|
else {
|
|
print "<tr>";
|
|
$col="bgcolor='$color{'color22'}'";
|
|
}
|
|
print <<END
|
|
|
|
<td align='center' $col>$time</td>
|
|
<td align='center' $col>$chain</td>
|
|
<td align='center' $col>$iface</td>
|
|
<td align='center' $col>$proto</td>
|
|
<td align='center' $col><a href='/cgi-bin/ipinfo.cgi?ip=$srcaddr'>$srcaddr</a><br /><a href='/cgi-bin/ipinfo.cgi?ip=$dstaddr'>$dstaddr</a></td>
|
|
<td align='center' $col>$srcport<br/>$dstport</td>
|
|
END
|
|
;
|
|
# Get flag icon for of the country.
|
|
my $flag_icon = &Location::Functions::get_flag_icon($ccode);
|
|
|
|
if ( $flag_icon) {
|
|
print "<td align='center' $col><a href='../country.cgi#$ccode'><img src='$flag_icon' border='0' align='absmiddle' alt='$ccode'></a></td>";
|
|
} else {
|
|
print "<td align='center' $col></td>";
|
|
}
|
|
|
|
print <<END
|
|
<td align='center' $col>$macaddr</td>
|
|
</tr>
|
|
END
|
|
;
|
|
$lines++;
|
|
}
|
|
|
|
print "</table>";
|
|
|
|
&oldernewer();
|
|
|
|
&Header::closebox();
|
|
|
|
&Header::closebigbox();
|
|
|
|
&Header::closepage();
|
|
|
|
sub oldernewer
|
|
{
|
|
print <<END
|
|
<table width='100%'>
|
|
<tr>
|
|
END
|
|
;
|
|
|
|
print "<td align='center' width='50%'>";
|
|
if ($prev != -1) {
|
|
print "<a href='/cgi-bin/logs.cgi/firewalllog.dat?0,$cgiparams{'MONTH'},$cgiparams{'DAY'}'>$Lang::tr{'first'}</a> ";
|
|
print "<a href='/cgi-bin/logs.cgi/firewalllog.dat?$prev,$cgiparams{'MONTH'},$cgiparams{'DAY'}'>$Lang::tr{'older'}</a>";
|
|
}
|
|
else {
|
|
print "$Lang::tr{'first'} $Lang::tr{'older'}";
|
|
}
|
|
print "</td>\n";
|
|
|
|
print "<td align='center' width='50%'>";
|
|
if ($next >= 0) {
|
|
print "<a href='/cgi-bin/logs.cgi/firewalllog.dat?$next,$cgiparams{'MONTH'},$cgiparams{'DAY'}'>$Lang::tr{'newer'}</a> ";
|
|
print "<a href='/cgi-bin/logs.cgi/firewalllog.dat?$lastPageIndex,$cgiparams{'MONTH'},$cgiparams{'DAY'}'>$Lang::tr{'last'}</a>";
|
|
}
|
|
else {
|
|
print "$Lang::tr{'newer'} $Lang::tr{'last'} ";
|
|
}
|
|
print "</td>\n";
|
|
|
|
print <<END
|
|
</tr>
|
|
</table>
|
|
END
|
|
;
|
|
}
|
|
|