#!/usr/local/bin/perl #=========================================================================# # Program: pfilter_report # # Author: Chad Kerner # #-------------------------------------------------------------------------# # Purpose: The purpose of this program is to process the logging info # # from pfilter and generate some basic reports about the # # connections that are being blocked. # #-------------------------------------------------------------------------# # Program Options: # # -help Display this help screen. # # -detail Prints the connection detail report. # # -ip Prints a summary by IP address. # # -port Prints a summary by port. # # -all Prints all three reports. # # -i Select an interface to scan on. Default: eth0 # # -host Select a specific IP address to scan on. # #-------------------------------------------------------------------------# # Modification History # # 20040608 Chad Kerner - Initial Coding # #=========================================================================# # Package Declarations use strict; use Getopt::Long; # Function Prototypes sub get_options(); sub print_help(); sub get_data(); sub print_detail(); sub print_ip(); sub print_port(); sub add_comma($); sub leading_zero($); sub del_leading_zero($); # Variable Declarations $main::msg_file = "/var/log/messages"; # Main routine { get_opts(); get_data(); if( $main::detail || $main::all ) { print_detail(); } if( $main::ip || $main::all ) { print_ip(); } if( $main::port || $main::all ) { print_port(); } } # End of the main() routine. #-------------------------------------------------------------------------# # This routine will print the help screen. # #-------------------------------------------------------------------------# sub print_help() { print "\n\n"; print "\tUsage: pfilter_report -detail | -ip | -port | -all "; print "-host \n"; print "\t -i \n"; print "\n"; print "\t-all \tPrint all report combinations. \n"; print "\t-detail\tPrint all host / port combinations.\n"; print "\t-ip \tPrint report with IP address detail.\n"; print "\t-port \tPrint report with port number detail.\n"; print "\t-host \tA specific IP address to scan for.\n"; print "\t-i \tThe interface to scan for if the host has multiple cards.\n"; print "\n\tExample: pfilter_report -all -host 141.142.4.4 -i eth1\n"; print "\n\n"; exit; } # End of the print_help() routine. #-------------------------------------------------------------------------# # This routine will read the command line options. # #-------------------------------------------------------------------------# sub get_opts() { if( scalar @ARGV == 0 ) { print_help(); } my $opts = GetOptions( "detail" => \$main::detail, "port" => \$main::port, "ip" => \$main::ip, "all" => \$main::all, "i=s" => \$main::interface, "host=s" => \$main::hostip, "help" => sub { print_help() }, ); if( $main::interface eq "" ) { $main::interface = "eth0"; } return; } # End of the get_opts() routine. #-------------------------------------------------------------------------# # This routine will get the data from the logfile and place it into the # # correct hashes. # #-------------------------------------------------------------------------# sub get_data() { my $ip; my $ipf; my $pt; my $key; my $a; my $b; my $c; my $d; open(INFIL,"$main::msg_file") || die("Unable To Open File: $main::msg_file\n"); foreach() { chomp; if( m/ DROPPED IN=$main::interface.*SRC=(\S+).*DPT=(\S+).*/ ) { $ip = $1; $pt = $2; if( $ip =~ m/(\S+)\.(\S+)\.(\S+)\.(\S+)/ ) { $a = leading_zero($1); $b = leading_zero($2); $c = leading_zero($3); $d = leading_zero($4); $ipf = "$a.$b.$c.$d"; } if( $main::hostip eq "" ) { $key = "$ipf\_$pt"; $main::val{$key} = $main::val{$key} + 1; $main::port{$pt} = $main::port{$pt} + 1; $main::ipa{$ipf} = $main::ipa{$ipf} + 1; } elsif( $main::hostip ne "" && $main::hostip eq $ip ) { $key = "$ipf\_$pt"; $main::val{$key} = $main::val{$key} + 1; $main::port{$pt} = $main::port{$pt} + 1; $main::ipa{$ipf} = $main::ipa{$ipf} + 1; } } } close(INFIL); return; } # End of the get_data routine. #-------------------------------------------------------------------------# # This routine will print the detailed report based on IP address and the # # port that was being probed. # #-------------------------------------------------------------------------# sub print_detail() { my $ip; my $pt; my $cnt; my $key; my $tot = 0; my @sorted = sort { $a <=> $b } ( keys %main::val ); print "\nDetail Report"; if( $main::hostip ne "" ) { print " For IP: $main::hostip"; } printf("\n\n%-15s \t %5s \t %8s\n","IP Address","Port","Count"); foreach $key ( @sorted ) { ($ip,$pt) = split(/_/,$key); $cnt = $main::val{$key}; printf("%-15s \t %5s \t %8s\n",del_leading_zero($ip),$pt,add_comma($cnt)); $tot = $tot + $cnt; } printf("%-15s \t %5s \t %8s\n","Total","",add_comma($tot)); return; } # End of the print_detail() routine. #-------------------------------------------------------------------------# # This routine will print the summary based on IP address. # #-------------------------------------------------------------------------# sub print_ip() { my $key; my $tot = 0; print "\nDetail Hits By IP Address"; if( $main::hostip ne "" ) { print " For IP: $main::hostip"; } printf("\n\n%-15s \t %8s\n","IP Address","Count"); foreach $key ( sort keys %main::ipa ) { printf("%-15s \t %8s \n",del_leading_zero($key),add_comma($main::ipa{$key})); $tot = $tot + $main::ipa{$key}; } printf("%-15s \t %8s\n","Total",add_comma($tot)); return; } # End of the print_ip() routine. #-------------------------------------------------------------------------# # This routine will print the data for the port level summary. # #-------------------------------------------------------------------------# sub print_port() { my $key; my $tot = 0; my @sorted = sort { $a <=> $b } ( keys %main::port ); print "\nDetail Hits By Port"; if( $main::hostip ne "" ) { print " For IP: $main::hostip"; } printf("\n\n%-5s \t %8s\n","Port","Count"); foreach $key ( @sorted ) { printf("%-5s \t %8s \n",$key,add_comma($main::port{$key})); $tot = $tot + $main::port{$key}; } printf("%-5s \t %8s\n","Total",add_comma($tot)); return; } # End of the print_port() routine. #-------------------------------------------------------------------------# # This routine will make numbers pretty. For example: 1234567 will be # # returned as 1,234,567. # #-------------------------------------------------------------------------# sub add_comma($) { $_ = $_[0]; 1 while s/(.*\d)(\d\d\d)/$1,$2/; return $_; } # End of the add_comma() routine. #-------------------------------------------------------------------------# # This routine will pad the octets of an ip address with leading zeros. # #-------------------------------------------------------------------------# sub leading_zero($) { $_ = $_[0]; s/^(\d)$/0$1/; s/^(\d\d)$/0$1/; return $_; } # End of the leading_zero() routine. #-------------------------------------------------------------------------# # This routine will remove the leading zero's from all octets in an ip # # address. # #-------------------------------------------------------------------------# sub del_leading_zero($) { $_ = $_[0]; 1 while s/^0(\S+)/$1/; 1 while s/^(\S+)\.0(\S+)/$1\.$2/; return $_; } # End of the del_leading_zero() routine.