#!/usr/bin/perl -w # # Purpose: # # Quick jobber to do some parsing of the iptables connection # tracking from /proc and print it out a little nicer. # (and to make Godot quit bugging me, of course ) # # Options: # -P This enables port lookups (translating ports -> services [Should be fast]) # -p This disables port lookups # # You can set the defaults for both of these below, 1 == lookup, # 0 == don't. The commandline switches override defaults. # # Author: # # Brian Poole, http://www.cerias.purdue.edu/homes/rajak/ # # LICENSE: # # This is licensed under the BSD license, in other words # do what you will, I don't care, just don't blame me. # I assume no liability for any incompetent usage of this # script, nor of any poor coding (though of course there # none of THAT!). $PORT_LOOKUPS = 1; if (defined @ARGV and $#ARGV != 0){ &usage; } elsif (defined @ARGV){ if ($ARGV[0] eq "-p"){ $PORT_LOOKUPS = 0; } elsif ($ARGV[0] eq "-P"){ $PORT_LOOKUPS = 1; } else { &usage; } } # Hey! Who told you that you could read my code! GET OUTTA HERE!#%^!@# # First lets grab the data from the proc entry.. open INPUT, "){ push @{ $records{(split " ")[0]} }, $_; } close INPUT; if (defined %records){ print " Current connections being tracked by netfilter\n\nProt Src IP Src Port State Dst IP Dst Port\n\n"; foreach $key (keys %records) { $proto = uc $key; for $i (0 .. $#{ $records{$key} } ){ # Assigning that bad boy into a variable because I don't like having to type all that every time ;) my $log = $records{$key}[$i]; # Zero out the port vars (we can't guarantee we have replaces to match them since some protocols (ICMP)) # don't have ports. Then do a match and shove the vars into place as appropriate. ($dport, $sport ) = ("",""); if( $log =~ /^.*?src=(.*?) dst=(.*?) (?:sport=(\d{1,5}) dport=(\d{1,5}) )?/) { ($srcip, $dstip) = ($1,$2); ($sport, $dport) = ($3,$4) if (defined $3 and defined $4); } else { report($log); } # This is detection of what ip_conntrack state the particular item is in, base is <--NORM--> (just regular) # the others are done as detected. I have a special check that if more than one []'s found to die and # report just because I'm not completely sure if this is impossible and I need to know if not. $state = "<--NORM-->"; if ( $log =~ /\[ASSURED\]/ ){ $state = "<==ASRD==>"; } if ( $log =~ /\[UNREPLIED\]/ ){ report($log) if $state ne "<--NORM-->"; $state = " --UNRE-->"; } if ( $log =~ /\[UNCONFIRMED\]/ ){ report($log) if $state ne "<--NORM-->"; $state = "<--UNCO-- "; } if ($PORT_LOOKUPS and $sport ne "" and $dport ne ""){ my $name = (getservbyport $sport, $key)[0]; $sport = $name if defined $name; undef $name; $name = (getservbyport $dport, $key)[0]; $dport = $name if defined $name; } write; } print "\n"; } } else { # No tracked connections.. weird. print "\nNo connections currently being tracked.\n"; } exit; # All of those -- err, that one subroutine # -- Make that TWO! I'm all about efficiency baby. sub usage { die "IP connection tracker\n", "Written by Brian Poole \n", "\nUsage: $0 [-Pp]\n", "\n-P enables port -> service mappings\n", "-p disables port -> service mappings\n\n"; } sub report { die "Please mail the following log entry to raj\@cerias.purdue.edu for debugging purposes.\n\n$_[0]\n"; } # The format.. duh. format STDOUT = @<<< @>>>>>>>>>>>>>> @|||||||||||| @<<<<<<<<< @>>>>>>>>>>>>>> @|||||||||||| $proto, $srcip, $sport, $state, $dstip, $dport .