Article Listing 1 Listing 2 jun2007.tar

Listing 1 The parseND.pl Perl script

#!/usr/bin/perl -w
#
# Filename: parseND.pl
# Programmer: Mihalis Tsoukalos
#
# Date: Wednesday 14 February 2007
#
# This Perl script parses tcpshow data
# and extracts the information we want
# which is the following:
#    1) Time 
#    2) dt (time difference)
#    3) sp (source port)
#    4) dp (destination port)
#
# This Perl script is for demonstration only
# Do not use it in a production system without changes

use strict;

# The input filename
my $filename = "";
# The line that we read from the input file
my $line = "";
# Hold the data for each packet
my @record = ();

die <<Thanatos unless @ARGV;
    usage:
        $0 inputData
Thanatos

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

$filename = shift @ARGV || "filename";

open (INPUT, "< $filename")
        || die "Cannot open $filename: $!\n";

my $j=0;

#
# Start reading the input file
#
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);
        # Initialize the @record variable.
        @record = ();
    }
    else
    {
        # Add line to @record variable
        push(@record, $line);
    }
    
}

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

print "Records processed: $j"."\n";

exit 0;

# 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
#
#
# * * * 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>
# -----------------------------------------------------------------------
#
#
sub parse_record
{
    my $sourcePort = "";
    my $destinationPort = "";
    my $time = "";
    my $dt = "";
    my $LINE = "";

    foreach $LINE (@record)
    {
    
        if ( $LINE =~ /^TIME/ )
        {
            my @time = split(/:/, $LINE);
            # Remove spaces
            $time[1] =~ s/ //g;
            #
            # Convert time to minutes
            #
            $time = $time[1]*60 + $time[2];
            # find dt
            $dt = $time[3];
            # remove the left (
            $dt =~ s/\(//g;
            # remove the right )
            $dt =~ s/\)//g;
            # split it
            my @data = split(/ /, $dt);
            $dt = $data[1];
            $time += $data[0];
        }
        elsif ( $LINE =~ /^\s+TCP/ )
        {        
            # Find the source and destination ports.
            if ( $LINE =~ /port/ )
            {
                my @words = split(/\s/,$LINE);
                $sourcePort = $words[6];
                $destinationPort = $words[8];
                
                print $time." ";
                print $dt." ";
                print port_name_to_number($sourcePort)." ";
                print port_name_to_number($destinationPort);
                print "\n";
            }
        }
        else
        {
            # do nothing
        }
    }
}


#
# This subroutine gets a port name (smtp, http, etc.)
# and converts it to its respective port number
#
sub port_name_to_number
{
    my $portName = shift;
    
    # This hash table holds the port name -> number pairs
    # You can change it according to your settings.
    my %PN2N = (
        "http", "80",
        "telnet", "23",
        "ftp", "21",
        "ssh", "22",
        "DNS", "53",
        "smtp", "25",
        "pop3", "110",
        "squid", "3128"
        );
    
    if ( defined($PN2N{$portName}) )
    {
        return $PN2N{$portName};
    }
    else
    {
        return $portName;
    }
}