#!/usr/bin/perl # Written by Kjell Wooding # Placed into the Public Domain use Date::Manip; use Socket; # If not set, set TZ $ENV{TZ}="MST7MDT"; $host=`/bin/hostname`; chomp $host; # Patterns to match hosts we should exclude from the stats @excl=('\d+\.\d+\.\d+\.255'); $datefmt=shift or die("Usage: ipfsummary \n"); $filename=shift or die("Usage: ipfsummary \n"); if ($datefmt =~ "any") { $date=".*"; } else { $date=&UnixDate($datefmt,"%b %e"); } $logstr=SetLogString(); open (INFILE,$filename); while() { if (/$date/) { if ((($dt, $tm, $rep, $if,$gr,$rule,$pb,$line)=/$logstr/) != 8) { $ifgroup="Unmatched"; } else { $ifgroup="$if". (($pb eq 'p')?' Pass':' Block'); } $rulesbyif{$ifgroup}++; push @{$ifgroup},$_; } } print bannerstr("IPF Firewall log Summary for $date on $host"); print bannerstr("Overview"); foreach $if (sort keys %rulesbyif) { print "$if: $rulesbyif{$if}\n"; } $logstr = &SetLogString; $rulestr = &SetRuleString; print bannerstr("Detail"); foreach $if (sort keys %rulesbyif) { print bannerstr("$if: $rulesbyif{$if}"); for ($j = 0; $j < $rulesbyif{$if}; $j++) { $_ = $$if[$j]; ($dt, $tm, $rep, $ifc,$gr,$rule,$pb,$line) = /$logstr/; $_ = $line; if ((($sip,$sp,$dip,$dp,$proto,$opt) = /$rulestr/) == 6) { # Resolve names, if possible $excls=0; $excld=0; foreach $pat (@excl) { if ($sip =~ /$pat/) { $excls++; } if ($dip =~ /$pat/) { $excld++; } } # Lookup source ip, unless excluded unless ($excls) { if ($DNS{$sip}) { $sip=$DNS{$sip}; } else { $sip=&ResolveName($sip); $DNS{$sip}=$sip; } } # Lookup dest ip, unless excluded unless ($excld) { if ($DNS{$dip}) { $dip=$DNS{$dip}; } else { $dip=&ResolveName($dip); $DNS{$dip}=$dip; } } if (($proto eq "tcp") or ($proto eq "udp")) { print "$proto : $sip,$sp -> $dip,$dp [$opt] ($tm \@$gr.$rule)\n"; } else { print "$proto: $sip -> $dip [$opt] ($tm \@$gr.$rule)\n"; } } else { print "$line ($tm \@$gr.$rule)\n"; } } } sub bannerstr { my ($str) = @_; return "\n". "#" x length($str."####") . "\n# $str #\n". "#" x length($str. "####") . "\n\n"; } sub SetLogString { # 1: date # 2: time # 3: repetition (optional) # 3: iface # 4: group # 5: rule # 6: pass/block # 7: rest return q!^(\w+\s+\d+)\s+(\d+:\d+:\d+)\s+\w+\s+ipmon\[\d+\]\:\s+\d+\:\d+\:\d+\.\d+\s+(\d+x\s+)?(\w+)\s+@(\d+):(\d+)\s+([p|b])\s+(.*)!; } sub SetRuleString { # 1: src ip # 2: src port (optional for icmp) # 3: dst ip # 4: dst port (optional for icmp) # 5: proto # 6: rest return q!(\d+\.\d+\.\d+\.\d+),?(\d+)?\s+->\s+(\d+\.\d+\.\d+\.\d+),?(\d+)?\s+PR\s+(\w+)\s+(.*)!; } sub ResolveName { my ($ip) = @_; my $nip = inet_aton($ip); my $name = gethostbyaddr($nip,AF_INET); if ($name) { return $name; } else { return $ip; } }