cotarelo has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks, I am very perl newbie, I am trying to do a perl script which takes the tcpdump log and counts the number of packets from one ip to another ip within the same port. Right now I have parsed the output of tcpdump and stored in an array. But I dont know how to make a hash to compare the positions in the different array of hashes and I am getting frustrated. My perl script is like this:
#!/usr/bin/perl #use strict; open(TEXT,"dump.txt")or die("Text not found"); while (<TEXT>) { if ( /IP\s+(\d+\.\d+\.\d+\.\d+)(\.(\d+))?\s+>\s+(\d+\.\d+\.\d+\.\d +++)(\.(\d+))?\:\s+(\w+)/ ) { my ($srcip, $srcport, $dstip, $dstport, $proto) = ($1, $3, $4 +, $6, $7); printf "%16s [%5d] --> %16s [%5d] (%s)\n", $srcip, $srcport, +$dstip, $dstport, lc($proto); } }

Replies are listed 'Best First'.
Re: array of arrays of hashes
by keszler (Priest) on Nov 16, 2009 at 13:29 UTC
    A starting point might be something like this:
    #!/usr/bin/perl use strict; use Sort::Key::IPv4 qw(ipv4sort); open(TEXT,"dump.txt")or die("Text not found"); my %packets; while (<TEXT>) { if ( /IP\s+(\d+\.\d+\.\d+\.\d+)(\.(\d+))?\s+>\s+(\d+\.\d+\.\d+\.\d++ +)(\.(\d+))?\:\s+(\w+)/ ) { my ($srcip, $srcport, $dstip, $dstport, $proto) = ($1, $3, $4, $6, + $7); printf "%16s [%5d] --> %16s [%5d] (%s)\n", $srcip, $srcport, $dsti +p, $dstport, lc($proto); if ($srcport == $dstport) { # one IP to another on the same port... $packets{$srcport}{$srcip}{$dstip}++ } } } foreach my $port (sort { $a <=> $b } keys %packets) { # ports sorted ascending foreach my $srcip ( ipv4sort keys %{$packets{$port}}) { # source IPs sorted ascending foreach my $dstip ( ipv4sort keys %{$packets{$port}{$srcip}}) { # dest IPs sorted ascending print "On port $port, from $srcip to $dstip, there were $packe +ts{$port}{$srcip}{$dstip} packets\n"; } } } }

    Also, you should read about the (?:pattern) in perlre - there's no need to capture in your regex anything you don't want.

      Thank you very much for your answer, it clarified me the method and also it make me think it is going to be complicated if I continue this way. I think I will better use pcap library.
Re: array of arrays of hashes
by apl (Monsignor) on Nov 16, 2009 at 12:58 UTC
    Reading this might help. Otherwise, Google will point you to these.
Re: array of arrays of hashes
by graff (Chancellor) on Nov 17, 2009 at 01:01 UTC
    Well, I think the first thing to do would be to finish defining what the task is, in terms of what specific sort of output(s) you really want; this will help to figure out what sort of data structure to use.

    What you've said so far about the task is:

    count the number of packets from one ip to another ip within the same port

    but I don't quite understand what that means. Based on the code you've posted, you apparently start with an input list that has two IP addresses per line (separated by ' > '), with or without a port number on one or both addresses.

    Can you give a brief but specific example of some actual input, along with the desired output it should produce? I'm afraid I can't guess this from what you've said so far.

      Thanks for the answer, Indeed it has no sense what I asked, Actually what I want to visualize the flows from a dump file and get a clarified idea of what is happening on the net. My first step was counting the number of packets from each source implied in the dump (IP A) to each source connected (IP B), in all port (port a, b c). True my question was wrong asked.