Article Figure 1 Figure 2 Figure 3 Figure 4
Figure 5 Figure 6 Figure 7 Figure 8 Figure 9
Listing 1 Listing 2 jul2007.tar

Listing 1 The parse_tcpshow.pl Perl script

#!/usr/bin/perl -w

# $Id: parse_tcpshow.pl,v 1.8 2006/09/29 11:37:23 mtsouk Exp $
#
# Please note that this code is
# provided without and guarantees.
#
# Programmer: Mihalis Tsoukalos
# Date: Thursday 10 August 2006
#
# Summary: This Perl script parses tcpshow data.
#
#

use strict;
use Tie::IxHash;

# The input filename
my $input = "";
# A record structure that holds the data
my @record = ();
# The line that we read from the input file
my $line = "";

#
# The following variables hold the useful data
# They are used in function parse_record().
#
my %PACKET_TIME = ();
tie %PACKET_TIME, "Tie::IxHash";
my %TCP_PACKET_TIME = ();
tie %TCP_PACKET_TIME, "Tie::IxHash";
my %SOURCE_PORT_COUNT = ();
tie %SOURCE_PORT_COUNT, "Tie::IxHash";
my %DEST_PORT_COUNT = ();
tie %DEST_PORT_COUNT, "Tie::IxHash";
my %PACKET_TYPE_COUNT = ();
tie %PACKET_TYPE_COUNT, "Tie::IxHash";
my %SOURCE_PORT_TIME = ();
tie %SOURCE_PORT_TIME, "Tie::IxHash";
my %DEST_PORT_TIME = ();
tie %DEST_PORT_TIME, "Tie::IxHash";

die <<Thanatos unless @ARGV;
ussage:
    $0 filename
Thanatos

if ( @ARGV != 1 )
{
    die <<Thanatos
        ussage info:
            Please use exactly 1 argument!
Thanatos
}

# Get the input filename
$input = shift @ARGV;

# Open file for reading
open( INPUT, "< $input" )
 or die "Cannot open file $input: $!\n";

my $i=0;
my $j=0;

while ( defined ($line = <INPUT>) )
{
    chomp $line;

    # Skip lines with -
    if ( $line =~ /^(-)*$/ )
    {
        $j++;
        next;
    }
        
    #
    # A new packet denotes the end of the previous one!
    #
    if ( $line =~ /^Packet/ )
    {
        # Process the packet that has just ended.
        parse_record(@record);
        $i++;
        # Initialize the @record variable.
        @record = ();
    }
    else
    {
        # Add line to @record variable
        push(@record, $line);
    }
}

#
# Also parse the last package!
#
parse_record(@record);

# Close the file
close( INPUT )
 or die "Cannot close file INPUT: $!\n";

my $key = "";


# Open file for reading
open( OUTPUT, "> SOURCE_PORT_COUNT.data" )
 or die "Cannot open file $input: $!\n";
#
# Print the SOURCE_PORT_COUNT structure
#
print "* * * SOURCE_PORT_COUNT data\n";
foreach $key (sort keys %SOURCE_PORT_COUNT)
{
    print OUTPUT $key."\t".$SOURCE_PORT_COUNT{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";

# Open file for reading
open( OUTPUT, "> DEST_PORT_COUNT.data" )
 or die "Cannot open file $input: $!\n";
#
# Print the DEST_PORT_COUNT structure
#
print "* * * DEST_PORT_COUNT data\n";
foreach $key (sort keys %DEST_PORT_COUNT)
{
    print OUTPUT $key."\t".$DEST_PORT_COUNT{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";

# Open file for reading
open( OUTPUT, "> PACKET_TYPE_COUNT.data" )
 or die "Cannot open file $input: $!\n";
#
# Print the PACKET_TYPE_COUNT structure
#
print "* * * PACKET_TYPE_COUNT data\n";
foreach $key (sort keys %PACKET_TYPE_COUNT)
{
    print OUTPUT $key."\t".$PACKET_TYPE_COUNT{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";


# Open file for reading
open( OUTPUT, "> PACKET_TIME.data" )
 or die "Cannot open file $input: $!\n";
#
# Print the PACKET_TIME structure
#
print "* * * PACKET_TIME\n";
foreach $key (keys %PACKET_TIME)
{
    print OUTPUT $key."\t".$PACKET_TIME{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";


# Open file for reading
open( OUTPUT, "> TCP_PACKET_TIME.data" )
 or die "Cannot open file $input: $!\n";
#
# Print the TCP_PACKET_TIME structure
#
print "* * * TCP_PACKET_TIME\n";
foreach $key (keys %TCP_PACKET_TIME)
{
    print OUTPUT $key."\t".$TCP_PACKET_TIME{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";

# Open file for reading
open( OUTPUT, "> SOURCE_PORT_TIME.data" )
 or die "Cannot open file $input: $!\n";
#
# Print the SOURCE_PORT_TIME structure
#
print "* * * SOURCE_PORT_TIME\n";
print OUTPUT "Time\tSourcePort\n";
foreach $key (keys %SOURCE_PORT_TIME)
{
    print OUTPUT $PACKET_TIME{$key}."\t".$SOURCE_PORT_TIME{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";

# Open file for reading
open( OUTPUT, "> DEST_PORT_TIME.data" )
 or die "Cannot open file $input: $!\n";
#
# Print the DEST_PORT_TIME structure
#
print "* * * DEST_PORT_TIME\n";
print OUTPUT "Time\tDestPort\n";
foreach $key (keys %DEST_PORT_TIME)
{
    print OUTPUT $PACKET_TIME{$key}."\t".$DEST_PORT_TIME{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";

# Open file for reading
open( OUTPUT, "> SOURCE_DEST_PORT.data" )
 or die "Cannot open file $input: $!\n";
#
# Print from SOURCE_PORT_TIME and DEST_PORT_TIME structures
#
print "* * * SOURCE_DEST_PORT\n";
foreach $key (keys %SOURCE_PORT_TIME)
{
    print OUTPUT $SOURCE_PORT_TIME{$key}."\t".$DEST_PORT_TIME{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";


# Open file for reading
open( OUTPUT, "> SOURCE_DEST_TIME.data" )
 or die "Cannot open file $input: $!\n";
#
# Print from SOURCE_PORT_TIME, DEST_PORT_TIME and
# PACKET_TIME structure
#
print "* * * SOURCE_DEST_TIME\n";
print OUTPUT "Time\tSourcePort\tDestPort\n";
foreach $key (keys %SOURCE_PORT_TIME)
{
    print OUTPUT $PACKET_TIME{$key}."\t";
    print OUTPUT $SOURCE_PORT_TIME{$key}."\t";
    print OUTPUT $DEST_PORT_TIME{$key}."\n";
}
# Close the file
close( OUTPUT )
 or die "Cannot close file OUTPUT: $!\n";


print "Beggining of Record: $i"."\n";
print "Records processed: $j"."\n";

exit 0;

# Parse the input file
#
# # # #
# # # # Sample tcpshow data
# # # #
#
# -----------------------------------------------------------------------
# Packet 1
# TIME:    14:59:01.547498
# LINK:    08:00:09:61:AA:C9 -> 08:00:09:61:AA:C9 type=0028
#    <*** No decode support for encapsulated protocol ***>
# -----------------------------------------------------------------------
# Packet 2
# TIME:    14:59:02.108822 (0.561324)
# LINK:    00:C0:4F:A3:58:23 -> 00:00:0C:04:41:BC type=IP
#  IP:    192.168.1.10 -> AS-20144-has-not-REGISTERED-the-use-of-this-prefix
#   hlen=20 TOS=00 dgramlen=51 id=012E
#    MF/DF=0/0 frag=0 TTL=64 proto=UDP cksum=B1AD
# UDP:    port domain -> domain hdr=8 data=23
# DATA:    .*...........aesop.....
# -----------------------------------------------------------------------
# Packet 169
# TIME:   15:00:15.366830 (0.000364)
# LINK:   00:00:0C:04:41:BC -> 00:60:97:DE:54:36 type=IP
#   IP:   172.16.x.y -> 207.46.x.z hlen=20 TOS=00 dgramlen=40 id=007D
#         MF/DF=0/1 frag=0 TTL=63 proto=TCP cksum=C854
# TCP:    port 1024 -> http seq=3183900830 ack=1274940435
#         hlen=20 (data=0) UAPRSF=010000 wnd=32120 cksum=2C97 urg=0
# DATA:   <No data>
# -----------------------------------------------------------------------
#
# This function parses each record
# and prints out the useful data
# according to our wills.
#
# Notes: Each record is a netword packet
#        Not all records have the same amount
#        and kind of data
#
sub parse_record
{
    my $LINE = "";
    my $sourcePort = "";
    my $destinationPort = "";
    my $time = "";
    
    foreach $LINE (@record)
    {
        if ( $LINE =~ /^TIME/ )
        {
            my @time = split(/:/, $LINE);
            # Remove spaces
            $time[1] =~ s/ //g;
            # Only get hours and minutes from time.
            $time = $time[1].":".$time[2];
            #
            # Convert time to minutes
            #
            $time = $time[1]*60 + $time[2];
            $PACKET_TIME{$i} = $time;
        }
        elsif ( $LINE =~ /^\s+IP/ )
        {
            #
            #
            # This code is not used in this article
            # but is provided here in case you
            # want to use it elsewhere.
            #
            #
            # Find source and destination IPs
            # if ( $LINE =~ /(\d+\.\d+.\d+\.\d+) -> (\d+\.\d+.\d+\.\d+)/ )
            # {
            #    print $1."\t".$2."\n";
            # }
        }
        elsif ( $LINE =~ /^\s+UDP/ )
        {
            # count an UDP packet.
            if ( defined $PACKET_TYPE_COUNT{'UDP'} )
            {
                $PACKET_TYPE_COUNT{'UDP'} = $PACKET_TYPE_COUNT{'UDP'} + 1;
            }
            else
            {
                $PACKET_TYPE_COUNT{'UDP'} = 1;
            }
        }
        elsif ( $LINE =~ /^ICMP/ )
        {
            # count an ICMP packet.
            if ( defined $PACKET_TYPE_COUNT{'ICMP'} )
            {
                $PACKET_TYPE_COUNT{'ICMP'} = $PACKET_TYPE_COUNT{'ICMP'} + 1;
            }
            else
            {
                $PACKET_TYPE_COUNT{'ICMP'} = 1;
            }

        }
        elsif ( $LINE =~ /^ARP/ )
        {
            # count and ARP packet.
            if ( defined $PACKET_TYPE_COUNT{'ARP'} )
            {
                $PACKET_TYPE_COUNT{'ARP'} = $PACKET_TYPE_COUNT{'ARP'} + 1;
            }
            else
            {
                $PACKET_TYPE_COUNT{'ARP'} = 1;
            }
        }
        elsif ( $LINE =~ /^\s+TCP/ )
        {
            # count a TCP packet.
            if ( defined $PACKET_TYPE_COUNT{'TCP'} )
            {
                $PACKET_TYPE_COUNT{'TCP'} = $PACKET_TYPE_COUNT{'TCP'} + 1;
            }
            else
            {
                $PACKET_TYPE_COUNT{'TCP'} = 1;
            }
            
            #
            # Add an entry to TCP_PACKET_TIME
            #
            $TCP_PACKET_TIME{$i} = $time;
            
            # Find the source and destination ports data.
            if ( $LINE =~ /port/ )
            {
                my @words = split(/\s/,$LINE);
                $sourcePort = $words[6];
                $destinationPort = $words[8];
                
                $SOURCE_PORT_TIME{$i} = $sourcePort;
                $DEST_PORT_TIME{$i} = $destinationPort;

                if ( defined $SOURCE_PORT_COUNT{$sourcePort} )
                {
                    $SOURCE_PORT_COUNT{$sourcePort} =
                        $SOURCE_PORT_COUNT{$sourcePort} + 1;
                }
                else
                {
                    $SOURCE_PORT_COUNT{$sourcePort} = 1;                
                }
                
                if ( defined $DEST_PORT_COUNT{$destinationPort} )
                {
                    $DEST_PORT_COUNT{$destinationPort} =
                        $DEST_PORT_COUNT{$destinationPort} + 1;
                }
                else
                {
                    $DEST_PORT_COUNT{$destinationPort} = 1;
                }
            }
        }
    }
}