#!/usr/bin/perl -w
# nf_conntrack.pl - a simple web interface to the /proc/net/nf_conntrack system file
# released under GPL by paul mansfield
#
# wack this in your firewall/router's web server cgi-bin directory and make it executable.
#
# add this to your /etc/sudoers file:
#	wwwrun  ALL= NOPASSWD: /bin/cat /proc/net/nf_conntrack
# wwwrun might need to be changed to nobody, httpd or whatever the username your
# web server runs as

use strict;
use CGI;
use FileHandle;

my $TIMEOUT = 30;
my $NFC='/proc/net/nf_conntrack';

my %tcpColours = (
		  'CLOSE'	=> '#d0d0d0'
		, 'TIME_WAIT'	=> '#b0b0df'
		, 'ESTABLISHED'	=> '#d0d0ff'
		, 'SYN_SENT'	=> '#e0e0ef'
		);

# minimise delays writing to the browser
$| = 1;
STDERR->autoflush;          # already unbuffered in stdio

print "Content-type: text/html\n\n<html><head><title>nf_conntrack</title>\n<meta http-equiv=\"refresh\" content=\"$TIMEOUT\">\n</head>\n<body>\n";

my $cgiQuery = new CGI;
my $filterString = '';
$filterString = $cgiQuery->param('filterString') if (defined $cgiQuery->param('filterString'));
print "<form method=\"get\" action=\"\">\n\tFilter: <input type=\"text\" name=\"filterString\" value=\"" . $filterString . "\" />\n</form>\n";

if (open(H, "/usr/bin/sudo cat $NFC|"))
{
	print "<table border=\"1\">\n<tr>\n<th>Ver</th><th>?</th><th>proto</th><th>?</th><th>?</th><th>tcp state</th><th>src ip:port</th><th>dst ip:port</th>\n<th>packets</th><th>bytes</th></tr>\n";
# ipv4 2 udp 17 88 src=127.0.0.1 dst=127.0.0.1 sport=40157 dport=123 packets=6 bytes=240 src=127.0.0.1 dst=127.0.0.1 sport=123 dport=40157 packets=11 bytes=3504 [ASSURED] mark=0 secmark=0 use=1 
	my $outputLine = '';
	while (<H>)
	{
		chomp;
		$outputLine = '';
		# UDP unpacked
		if ($_ =~ /^ipv(\d+)\s+(\d+)\s+udp\s+(\d+)\s+(\d+)\s+src=(\d+\.\d+\.\d+\.\d+)\s+dst=(\d+\.\d+\.\d+\.\d+)\s+sport=(\d+)\s+dport=(\d+)\s+packets=(\d+)\s+bytes=(\d+)\s+(.*)$/)
		{
			$outputLine = "<tr bgcolor=\"#d0ffd0\"><td>$1</td><td>$2</td><td>udp</td><td>$3</td><td>$4</td><td>&nbsp;</td><td>$5:$7</td><td>$6:$8</td><td>$9</td><td>$10</td></tr>\n";
		}
		# TCP unpacked
		elsif ($_ =~ /^ipv(\d+)\s+(\d+)\s+tcp\s+(\d+)\s+(\d+)\s+(\w+)\s+src=(\d+\.\d+\.\d+\.\d+)\s+dst=(\d+\.\d+\.\d+\.\d+)\s+sport=(\d+)\s+dport=(\d+)\s+packets=(\d+)\s+bytes=(\d+)\s+(.*)$/)
		{
			$outputLine = "<tr bgcolor=\"" . $tcpColours{$5} . "\"><td>$1</td><td>$2</td><td>tcp</td><td>$3</td><td>$4</td><td>$5</td><td>$6:$8</td><td>$7:$9</td><td>$10</td><td>$11</td></tr>\n";
		}
		else
		{
			$outputLine = "<tr><td colspan=\"5\">UF: $_</td></tr>\n";
		}
		print $outputLine  if (($outputLine ne '') && (! defined($filterString)) || ($filterString eq '') || ($outputLine =~ /$filterString/));

	}
	print "</table>\n";
	close(H);
}
else
{
	print "<p>Error, failed to open $NFC for reading\n</p>\n";
}



print "</body>\n</html>\n";

