#!/usr/local/bin/perl 
#
# fwtable.pl ver 1.0
#
# Created by Lance Spitzner, lance@spitzner.net
# July 3, 1999
#
# Distributed under the terms of this General Public License
# http://www.gnu.org/copyleft/gpl.html
#
# Converts FW-1 Connections table to readable format
#
# The purpose of this PERL script is to help you gain a better 
# understanding of Check Point FW-1's stateful inspection table.  This 
# table is where FW-1 maintains all concurrent connections.  When 
# marketing is talking about "stateful inspection", this table is 
# the heart of that.  Check Point provides a tool to look at this 
# table, unfortunately it is extremelly cyptic, as it is in hex.
# This script makes it easier to read by converting the hex to decimal.  
# The script also allows you to convert connections tables from remote 
# FWs, or tables you have already outputed to a file.
#
#  Output has 9 columns, described as follows:
#
#  NOTE:  This script was written for FW-1, ver 4.0.  Only the first 5 columns are
#         valid for ver 3.0.  
#
# Src_IP 	= Source IP address
# Src_Prt 	= Source Port
# Dst_IP 	= Destination IP address
# Dst_Prt 	= Destination Port
# IP_prot 	= IP protocol (6 is TCP, 17 is UDP)
# Kbuf 		= I THINK this means Kernel buffer memory used for this connection ??
# Type 		= I don't know
# Flags 	= I don't know, maybe header flags?
# Timeout 	= how much time is left / how much the total Timeout value is



#############################################################
#			SCRIPT BEGINS			    #
#############################################################
  

### Set variables
$FWDIR="/etc/fw";
chomp($thispl = `basename $0`);

### Table definitions for connections
### Taken from $FWDIR/lib/table.def
# <src,sport,dst,dport,ip_p;kbuf,type,flags>


#############################################################
#		Get options from user  			    #
#############################################################

use Getopt::Std;
getopts('hc:i:t:');

### Usage
if ($opt_h) {
	&usage;
	exit(5);
}

### How many connections user wants to query
if      (defined($opt_c))  {$max = $opt_c;}
else                       {$max = "500";}

### Which target user wants to query
if      (defined($opt_t))  {$target = $opt_t;}
else                       {$target = "localhost";}

### Get connections tabe from FW or an existing file.
if (defined($opt_i)) { 
	$fwfile="$opt_i";
	open(INFILE, $fwfile) or die "FW file could not be found\n";
}
else {
	open(INFILE, "$FWDIR/bin/fw tab -t connections -max $max $target | ");
}


#############################################################
# Actual program.  Converts <INFILE> data from hex to 	    #
# easy to read decimal.					    #
#############################################################


$LineCount=0;

print "\n\t\t\t\t ---- FW-1 CONNECTIONS TABLE ---\n\n\n";
print "Src_IP   \tSrc_Prt\tDst_IP   \tDst_Prt\tIP_prot\tKbuf\tType\tFlags   \tTimeout\n\n";

while(<INFILE>) {

### Skip first four lines
	if($LineCount <= "3") { 
		$LineCount +=1;
		next };

### Grab a line, and start munging the data.
 	$TheLine = $_;
	chomp($TheLine);

### Uncomment this if you want to see the raw data also.
#	print "$TheLine\n";

### Set variables for each column.
	$src = substr($TheLine,1,8);
	$sport = hex(substr($TheLine,11,8));
	$dst = substr($TheLine,21,8);
	$dport = hex(substr($TheLine,31,8));
	$ip_p = hex(substr($TheLine,41,8));
	$kbuf = hex(substr($TheLine,51,8));
	$type = hex(substr($TheLine,61,8));
	$flags = substr($TheLine,71,8);
	$timeout = substr($TheLine,81,9);
	$timeout =~ s/>//;                  # remove trailing >

### Print out each column, per line.
	&convert($src);
	print "$sport\t";
	&convert($dst);
	print "$dport\t";
	print "$ip_p\t";
	print "$kbuf\t";
	print "$type\t";
	print "$flags\t";
	print "$timeout\n";
}



#############################################################
#			Sub-routines		 	    #		
#############################################################

### routine to convert ip_address from hex to dec
### Big thanks to DEAN Ivan <ivan.dean@dewrsb.gov.au>,
### who sent me this routine, and gave me the idea for
### this PERL script!

sub convert {
my ($source) = @_;

  $octet1 = substr($source,0,2);
  $octet2 = substr($source,2,2);
  $octet3 = substr($source,4,2);
  $octet4 = substr($source,6,2);
  $dec1 = hex($octet1);
  $dec2 = hex($octet2);
  $dec3 = hex($octet3);
  $dec4 = hex($octet4);

  print "$dec1.$dec2.$dec3.$dec4\t";
}

### You figure this one out :)
sub usage {
    print  <<EOT;

$thispl by Lance Spitzner <lance\@spitzner.net>
Usage: $thispl -c <# of connections> -i <infput file> -t <target>

	$thispl converts a FireWall-1 connections table to readable
	format. It can be ran without any options.  By default, 
	$thispl queries the local machine for the FireWall-1 
	connections table, and converts the first 500 connections.  
	This information is then sent to STDOUT.  You have the 
	following options.

	-c: Number of connections you want to query from the
	    Firewall.  The default is 500. This option dos NOT work
	    with the '-i' option.

	-i: Instead of querying a Firewall for the connections
	    table, convert an existing file <input file>.

	-t: Query a remote Firewall for the connections table.

EOT
    ;
}

#############################################################
#			SCRIPT ENDS			    #
#############################################################
