CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Searching two-value hash array

 



CPS
Novice

Sep 14, 2012, 5:31 AM

Post #1 of 15 (3140 views)
Searching two-value hash array Can't Post

Hi,

I would like to compare two values in the one hash key.
To be more clear let's assume this situation:


Code
HASH KEY              |-VALUE-|  
(a) (b)
250 50 4 <- PAIR 1
50 250 5 <- PAIR 1
47 250 1 <- PAIR 2
101 250 7 <- PAIR 3
250 47 8 <- PAIR 2
250 101 9 <- PAIR 3



And i Would like to get following output:

KEYS | a value | b value | total
250 50 | 4 | 5 | 9
47 250 | 1 | 8 | 9
101 250 | 7 | 9 | 16


How i could do that?


(This post was edited by CPS on Sep 14, 2012, 5:33 AM)


FishMonger
Veteran / Moderator

Sep 14, 2012, 6:46 AM

Post #2 of 15 (3137 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

This looks like a homework assignment.

How are you building the hash and why are you using a concatenated hash key which needs to be split apart to do the comparison?

What have you tried thus far?

What errors/warnings does your code produce?

What part of the process is giving you trouble?


CPS
Novice

Sep 14, 2012, 10:59 AM

Post #3 of 15 (3125 views)
Re: [FishMonger] Searching two-value hash array [In reply to] Can't Post

Hello.
Thanks for the reply.

Well, the biggest problems i have with creating an algoritm and perl language as well.

Maybe i'll write about what i need to parse.
Basically i would like to parse tcpdump output (pcap file) with perl using following modules:
Net::TcpDumpLog; NetPacket::Ethernet; NetPacket::IP; NetPacket::TCP;

More information (+sample script) about that:

http://hype-free.blogspot.fr/2010/03/parsing-pcap-files-with-perl.html

The problem is this script generates output in the following format:
Session Bytes Total
===================================================================
10.197.191.250:445 <-> 10.197.191.50:47766 778663 < - SESSION 1
10.197.191.50:47766 <-> 10.197.191.250:445 739008 <- SESSION 1
10.197.191.250:9090 <-> 10.197.191.101:4968 240466 <- SESSION 2
10.197.191.250:9090 <-> 10.197.191.45:27547 181070 < -SESSION 3
(...)

As you can see above, both first lines store information about one connection.
Let's say that 10.197.191.250 is the server and other addresses are clients.
So 10.197.191.250 received 778663 bytes from 10.197.191.50, and 10.197.191.50 received 739008 bytes from 10.197.191.250.

HAving this in mind I would like this output in the format:
SESSION REC SENT TOTAL
10.197.191.250:445 <-> 10.197.191.250 778663 739008 1517671
(...)

So, i need to count and place information about one particular connection in one line.

I've modified code from the above link to the following:
============== EDIT================

Code
 
my $othcnt;
my @arrayz;
my $res;
foreach $key (keys(%sum))
{
my @excludeList = split("<->", $key);
my $firstvalue = trim($excludeList[0]); # ip address
my $secondvalue = trim($excludeList[1]); # ip address
foreach $keyx (keys(%sum))
{
$res = 0;
@excludeList = split("<->", $keyx);
my $thirdvalue = trim($excludeList[0]); # ip address
my $forth = trim($excludeList[1]); # ip address
if (($firstvalue eq $forth) && ($thirdvalue eq $secondvalue))
{
$res = &checkArray($thirdvalue, $forth);
if ($res != 1)
{
$arrayz[$othcnt] = $key;
$othcnt = $othcnt + 1;
my $suma;
$suma = $sum{$key} + $sum{$keyx};
print "$key \t $sum{$key} \t $sum{$keyx} \t $suma \n";
}

}
}
#print "\t$key \t$sum{$key}\n";
}

sub trim($)
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}

sub checkArray($val, $val2)
{
my $arrayvalue;
my $result = 0;
foreach $arrayvalue(@arrayz)
{
my @excludeList = split("<->", $arrayvalue);
my $firstvalue = trim($excludeList[0]); # ip address of first
my $secondvalue = trim($excludeList[1]); # ip address of first
if (($val1 eq $secondvalue) && ($val2 eq $firstvalue))
{
$result = 1;
}

}
return $result;
}


Do you have any ideas?
Please help


(This post was edited by CPS on Sep 14, 2012, 11:26 AM)


FishMonger
Veteran / Moderator

Sep 14, 2012, 12:00 PM

Post #4 of 15 (3114 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

That code has a lot of problems and if you were using the strict pragma, as you always should be doing, your script won't even compile.

You should not be using prototypes in your subs and the proto definition for the checkArray() sub is not a valid definition and is one of the things which would prevent the script from compiling.

Don't use the & when calling subs unless you know about and need its side effect, which is almost never.

You're doing nested looping over the %sum hash, which is very wasteful.

With one exception, the first argument to the split function is a regex pattern, not a string. The function has been designed to accommodate using a string, primarily for its one exception, but it's poor practice to use a string outside of that exception.

I can list about a dozen more issues, but your starting point should be to add the warnings and strict pragmas and fix the problems that they point out.

Code
use strict; 
use warnings;



FishMonger
Veteran / Moderator

Sep 14, 2012, 12:17 PM

Post #5 of 15 (3112 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

I suggest that work on this issue at a higher level. Meaning you should look at reworking how the %sum hash is built. Maybe a HoH (Hash of Hashes) would be a better data structure.


CPS
Novice

Sep 14, 2012, 12:41 PM

Post #6 of 15 (3109 views)
Re: [FishMonger] Searching two-value hash array [In reply to] Can't Post

Thanks for the reply.

Ok, let's back to the begining.
I've modified earlier post because i though my script worked (i guess it worked for a while because i had proper results. However i've changed something and it's not working anymore ;))

Ok, so here it goes, code which i placed here before:



Code
#!/usr/bin/perl 
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use Net::TcpDumpLog;
use strict;
use warnings;

if ($#ARGV gt 0 ) {
print "Usage: pcap.pl <pcap.file>\n";
exit;
}

my $key;
my $value;
my %sum;
my $keyx;
my $log = Net::TcpDumpLog->new();
$log->read($ARGV[0]);

my @arrays = ();
my @keys = ();
foreach my $index ($log->indexes) {
my ($length_orig, $length_incl, $drops, $secs, $msecs) = $log->header($index);
my $data = $log->data($index);

my $eth_obj = NetPacket::Ethernet->decode($data);
next unless $eth_obj->{type} == NetPacket::Ethernet::ETH_TYPE_IP;

my $ip_obj = NetPacket::IP->decode($eth_obj->{data});
next unless $ip_obj->{proto} == NetPacket::IP::IP_PROTO_TCP;

my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data});
my $keyName = $ip_obj->{src_ip}.":".$tcp_obj->{src_port}." <-> ".$ip_obj->{dest_ip}.":".$tcp_obj->{dest_port};

if ($sum{$keyName}) {
$sum{$keyName} = $ip_obj->{len} + $sum{$keyName};
}
else
{
$sum{$keyName} = $ip_obj->{len};
}

}

my $cnt = 0;
print "\tSession \t\t\t\tREC\tSENT\tBytes Total\n";
print "===================================================================\n";


foreach $key (keys(%sum))
{
my @excludeList = split("<->", $key);
my $firstvalue = trim($excludeList[0]); # ip address of first
my $secondvalue = trim($excludeList[1]); # ip address of first
foreach $keyx (keys(%sum))
{
@excludeList = split("<->", $keyx);
my $thirdvalue = trim($excludeList[0]); # ip address of first
my $forth = trim($excludeList[1]); # ip address of first
if (($firstvalue eq $forth) && ($thirdvalue eq $secondvalue))
{
{
my $suma;
$suma = $sum{$key} + $sum{$keyx};
print "$key \t $sum{$key} \t $sum{$keyx} \t $suma \n";
}

}
}
#print "\t$key \t$sum{$key}\n";
}

sub trim($)
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}



Script compiles successfully, and i got proper results. However the results are doubled. The reason is clear for me. How to ignore doubled values there?
Some checkArray sub which checks other array with values stored before, ID in the hash list? Hash of the hash list? How to do that and place in script?


FishMonger
Veteran / Moderator

Sep 14, 2012, 12:52 PM

Post #7 of 15 (3104 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

Can you attach your test pcap file so that I can run sum tests?


FishMonger
Veteran / Moderator

Sep 14, 2012, 2:23 PM

Post #8 of 15 (3100 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

This should help you to work out a cleaner and more efficient solution.


Code
#!/usr/bin/perl 

use strict;
use warnings;
use Data::Dumper;

my %sum;

while ( my $line = <DATA> ) {
chomp $line;
my ($src, $dest, $bytes) = split(/\s/, $line);
my $key = join(' <-> ', sort($src, $dest));

$sum{$key} += $bytes;
}

print Dumper \%sum;


__DATA__
10.197.191.250:445 10.197.191.50:47766 778663
10.197.191.50:47766 10.197.191.250:445 739008
10.197.191.250:9090 10.197.191.101:4968 240466
10.197.191.101:4968 10.197.191.250:9090 264865
10.197.191.250:9090 10.197.191.45:27547 181070
10.197.191.45:27547 10.197.191.250:9090 532157



(This post was edited by FishMonger on Sep 14, 2012, 2:24 PM)


CPS
Novice

Sep 14, 2012, 3:19 PM

Post #9 of 15 (3098 views)
Re: [FishMonger] Searching two-value hash array [In reply to] Can't Post

Hi,

I'm attaching pcap file which i used.
Unfortunately i'm not available tomorrow, so i will analyse your response on sunday.

Thanks :)

PCAP FILE:
http://www20.zippyshare.com/v/5914541/file.html


(This post was edited by CPS on Sep 14, 2012, 3:22 PM)


FishMonger
Veteran / Moderator

Sep 16, 2012, 8:00 AM

Post #10 of 15 (3060 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

As would be expected, the pcap shows that each connection has more than just a single value from each direction; some of them have a lot more. It would not make sense to me to list all of those values in the ouput. Maybe just the total.

Here's new script, which still needs some tweaking, but does most of what you need.


Code
#!/usr/bin/perl 

use 5.10.0;
use strict;
use warnings;
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use Net::TcpDumpLog;
use List::Util qw(sum);

@ARGV or die "Usage: $0 <pcap.file>\n";

my $log = Net::TcpDumpLog->new();
$log->read($ARGV[0]);

my %summary;
foreach my $index ($log->indexes) {
my $data = $log->data($index);

my $eth_obj = NetPacket::Ethernet->decode($data);
next unless $eth_obj->{type} == NetPacket::Ethernet::ETH_TYPE_IP;

my $ip_obj = NetPacket::IP->decode($eth_obj->{data});
next unless $ip_obj->{proto} == NetPacket::IP::IP_PROTO_TCP;

my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data});
my $src = "$ip_obj->{src_ip}:$tcp_obj->{src_port}";
my $dest = "$ip_obj->{dest_ip}:$tcp_obj->{dest_port}";

my $key = join(' <-> ', sort $src, $dest);
push @{ $summary{$key} }, $ip_obj->{len};
}

for my $key ( sort %summary ) {
no warnings 'uninitialized';

#say join(' | ', $key, @{ $summary{$key}, sum @{ $summary{$key} } );
say join(' | ', $key, sum @{ $summary{$key} } );
}



CPS
Novice

Sep 17, 2012, 3:29 AM

Post #11 of 15 (3049 views)
Re: [FishMonger] Searching two-value hash array [In reply to] Can't Post

Hello,

So you're assuming that there are more than 2 connections between two hosts ?
Are you sure?

and what about thsese "ARRAY(0x190d3c4)" messages in the output?

Code
10.197.191.101:4968 <-> 10.197.191.250:9090 | 244386 
10.197.191.112:3696 <-> 10.197.191.250:9090 | 1513
10.197.191.250:445 <-> 10.197.191.50:47766 | 1517671
10.197.191.250:9090 <-> 10.197.191.43:10461 | 782
10.197.191.250:9090 <-> 10.197.191.43:11200 | 160
10.197.191.250:9090 <-> 10.197.191.45:27547 | 184070
10.197.191.250:9090 <-> 10.197.191.45:29466 | 3567
10.197.191.250:9090 <-> 10.197.191.47:4308 | 4750
10.197.191.250:9090 <-> 10.197.191.47:4687 | 160
10.197.191.250:9090 <-> 10.197.191.47:4688 | 160
10.197.191.250:9090 <-> 10.197.191.47:4705 | 120
10.197.191.250:9090 <-> 10.197.191.47:4707 | 5284
10.197.191.250:9090 <-> 10.197.191.50:51663 | 6472
10.197.191.250:9090 <-> 10.197.191.52:2533 | 3203
10.197.191.250:9090 <-> 10.197.191.52:3019 | 160
10.197.191.250:9090 <-> 10.197.191.70:10263 | 136
ARRAY(0x190d3c4) |
ARRAY(0x191a09c) |
ARRAY(0x191a0cc) |
ARRAY(0x191a12c) |
ARRAY(0x191a16c) |
ARRAY(0x191a30c) |
ARRAY(0x191a48c) |
ARRAY(0x191a62c) |
ARRAY(0x191a77c) |
ARRAY(0x191a8cc) |
ARRAY(0x192506c) |
ARRAY(0x19255ec) |
ARRAY(0x192593c) |
ARRAY(0x1925a5c) |
ARRAY(0x1925bec) |
ARRAY(0x192646c) |



CPS
Novice

Sep 17, 2012, 4:11 AM

Post #12 of 15 (3043 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

Hm, basically if there are more than one connection between hosts i think there is still sense to summ up all connections with received/sent bytes, like this:


Code
        Session                                 REC     SENT    Bytes Total 
===================================================================
10.197.191.43:10461 <-> 10.197.191.250:9090 578 204 782
10.197.191.250:9090 <-> 10.197.191.70:10263 96 40 136
10.197.191.250:9090 <-> 10.197.191.52:3019 80 80 160
10.197.191.250:9090 <-> 10.197.191.101:4968 240466 3920 244386
10.197.191.250:9090 <-> 10.197.191.112:3696 854 659 1513
10.197.191.250:9090 <-> 10.197.191.45:29466 1691 1876 3567
10.197.191.50:47766 <-> 10.197.191.250:445 739008 778663 1517671
10.197.191.47:4688 <-> 10.197.191.250:9090 80 80 160
10.197.191.250:9090 <-> 10.197.191.47:4688 80 80 160
10.197.191.250:9090 <-> 10.197.191.50:51663 6312 160 6472
10.197.191.250:9090 <-> 10.197.191.43:10461 204 578 782
10.197.191.45:29466 <-> 10.197.191.250:9090 1876 1691 3567
10.197.191.45:27547 <-> 10.197.191.250:9090 3000 181070 184070
10.197.191.47:4687 <-> 10.197.191.250:9090 80 80 160
10.197.191.250:9090 <-> 10.197.191.47:4707 935 4349 5284
10.197.191.52:2533 <-> 10.197.191.250:9090 2207 996 3203
10.197.191.250:9090 <-> 10.197.191.47:4687 80 80 160
10.197.191.47:4707 <-> 10.197.191.250:9090 4349 935 5284
10.197.191.250:445 <-> 10.197.191.50:47766 778663 739008 1517671
10.197.191.43:11200 <-> 10.197.191.250:9090 80 80 160
10.197.191.250:9090 <-> 10.197.191.43:11200 80 80 160
10.197.191.250:9090 <-> 10.197.191.45:27547 181070 3000 184070
10.197.191.50:51663 <-> 10.197.191.250:9090 160 6312 6472
10.197.191.101:4968 <-> 10.197.191.250:9090 3920 240466 244386
10.197.191.250:9090 <-> 10.197.191.52:2533 996 2207 3203
10.197.191.47:4705 <-> 10.197.191.250:9090 40 80 120
10.197.191.250:9090 <-> 10.197.191.47:4705 80 40 120
10.197.191.70:10263 <-> 10.197.191.250:9090 40 96 136
10.197.191.112:3696 <-> 10.197.191.250:9090 659 854 1513
10.197.191.47:4308 <-> 10.197.191.250:9090 3997 753 4750
10.197.191.250:9090 <-> 10.197.191.47:4308 753 3997 4750
10.197.191.52:3019 <-> 10.197.191.250:9090 80 80 160



FishMonger
Veteran / Moderator

Sep 17, 2012, 8:22 AM

Post #13 of 15 (3024 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

The "ARRAY(0x190d3c4)" lines were due to the hash containing empty array refs that I did not filter out.

This updated version should let you see what I was referring to on the multiple connections.


Code
#!/usr/bin/perl 

use 5.10.0;
use strict;
use warnings;
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use Net::TcpDumpLog;
use List::Util qw(sum);

@ARGV or die "Usage: $0 <pcap.file>\n";

my $log = Net::TcpDumpLog->new();
$log->read($ARGV[0]);

my %summary;
foreach my $index ($log->indexes) {
my $data = $log->data($index);

my $eth_obj = NetPacket::Ethernet->decode($data);
next unless $eth_obj->{type} == NetPacket::Ethernet::ETH_TYPE_IP;

my $ip_obj = NetPacket::IP->decode($eth_obj->{data});
next unless $ip_obj->{proto} == NetPacket::IP::IP_PROTO_TCP;

my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data});
my $src = "$ip_obj->{src_ip}:$tcp_obj->{src_port}";
my $dest = "$ip_obj->{dest_ip}:$tcp_obj->{dest_port}";

my $key = join(' -> ', $src, $dest);
push @{$summary{$key}}, $ip_obj->{len};
}

for my $key ( sort %summary ) {
next if ! $summary{$key};
my $transmission_count = scalar(@{$summary{$key}});
my $total = sum(@{ $summary{$key} });

say join(' | ', $key,
"$transmission_count transmissions",
"$total total bytes"
);
}


Which outputs:

Quote
D:\perl>pcap.pl out.pcap
10.197.191.101:4968 -> 10.197.191.250:9090 | 98 transmissions | 3920 total bytes
10.197.191.112:3696 -> 10.197.191.250:9090 | 2 transmissions | 659 total bytes
10.197.191.250:445 -> 10.197.191.50:47766 | 691 transmissions | 778663 total bytes
10.197.191.250:9090 -> 10.197.191.101:4968 | 167 transmissions | 240466 total bytes
10.197.191.250:9090 -> 10.197.191.112:3696 | 2 transmissions | 854 total bytes
10.197.191.250:9090 -> 10.197.191.43:10461 | 2 transmissions | 204 total bytes
10.197.191.250:9090 -> 10.197.191.43:11200 | 2 transmissions | 80 total bytes
10.197.191.250:9090 -> 10.197.191.45:27547 | 146 transmissions | 181070 total bytes
10.197.191.250:9090 -> 10.197.191.45:29466 | 9 transmissions | 1691 total bytes
10.197.191.250:9090 -> 10.197.191.47:4308 | 6 transmissions | 753 total bytes
10.197.191.250:9090 -> 10.197.191.47:4687 | 2 transmissions | 80 total bytes
10.197.191.250:9090 -> 10.197.191.47:4688 | 2 transmissions | 80 total bytes
10.197.191.250:9090 -> 10.197.191.47:4705 | 2 transmissions | 80 total bytes
10.197.191.250:9090 -> 10.197.191.47:4707 | 8 transmissions | 935 total bytes
10.197.191.250:9090 -> 10.197.191.50:51663 | 8 transmissions | 6312 total bytes
10.197.191.250:9090 -> 10.197.191.52:2533 | 3 transmissions | 996 total bytes
10.197.191.250:9090 -> 10.197.191.52:3019 | 2 transmissions | 80 total bytes
10.197.191.250:9090 -> 10.197.191.70:10263 | 1 transmissions | 96 total bytes
10.197.191.43:10461 -> 10.197.191.250:9090 | 2 transmissions | 578 total bytes
10.197.191.43:11200 -> 10.197.191.250:9090 | 2 transmissions | 80 total bytes
10.197.191.45:27547 -> 10.197.191.250:9090 | 75 transmissions | 3000 total bytes
10.197.191.45:29466 -> 10.197.191.250:9090 | 8 transmissions | 1876 total bytes
10.197.191.47:4308 -> 10.197.191.250:9090 | 5 transmissions | 3997 total bytes
10.197.191.47:4687 -> 10.197.191.250:9090 | 2 transmissions | 80 total bytes
10.197.191.47:4688 -> 10.197.191.250:9090 | 2 transmissions | 80 total bytes
10.197.191.47:4705 -> 10.197.191.250:9090 | 1 transmissions | 40 total bytes
10.197.191.47:4707 -> 10.197.191.250:9090 | 5 transmissions | 4349 total bytes
10.197.191.50:47766 -> 10.197.191.250:445 | 958 transmissions | 739008 total bytes
10.197.191.50:51663 -> 10.197.191.250:9090 | 4 transmissions | 160 total bytes
10.197.191.52:2533 -> 10.197.191.250:9090 | 3 transmissions | 2207 total bytes
10.197.191.52:3019 -> 10.197.191.250:9090 | 2 transmissions | 80 total bytes
10.197.191.70:10263 -> 10.197.191.250:9090 | 1 transmissions | 40 total bytes



(This post was edited by FishMonger on Sep 17, 2012, 8:24 AM)


CPS
Novice

Sep 17, 2012, 9:22 AM

Post #14 of 15 (3019 views)
Re: [FishMonger] Searching two-value hash array [In reply to] Can't Post

Thanks for reply. There are so many things in perl which i need to learn. And what about printing information about bytes sent/received and total without doubling the lines?


Code
        Session                                 REC     SENT    Bytes Total 
===================================================================
10.197.191.43:10461 <-> 10.197.191.250:9090 578 204 782
10.197.191.250:9090 <-> 10.197.191.70:10263 96 40 136
10.197.191.250:9090 <-> 10.197.191.52:3019 80 80 160
10.197.191.250:9090 <-> 10.197.191.101:4968 240466 3920 244386
10.197.191.250:9090 <-> 10.197.191.112:3696 854 659 1513
10.197.191.250:9090 <-> 10.197.191.45:29466 1691 1876 3567
10.197.191.50:47766 <-> 10.197.191.250:445 739008 778663 1517671
10.197.191.47:4688 <-> 10.197.191.250:9090 80 80 160
10.197.191.250:9090 <-> 10.197.191.50:51663 6312 160 6472
10.197.191.45:27547 <-> 10.197.191.250:9090 3000 181070 184070
10.197.191.47:4687 <-> 10.197.191.250:9090 80 80 160
10.197.191.250:9090 <-> 10.197.191.47:4707 935 4349 5284
10.197.191.52:2533 <-> 10.197.191.250:9090 2207 996 3203
10.197.191.43:11200 <-> 10.197.191.250:9090 80 80 160
10.197.191.47:4705 <-> 10.197.191.250:9090 40 80 120
10.197.191.47:4308 <-> 10.197.191.250:9090 3997 753 4750



I did it by this non-professional newbie code, which I wrote before (now it's a little bit modified):


Code
#!/usr/bin/perl 
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use Net::TcpDumpLog;
use strict;
use warnings;

if ($#ARGV gt 0 ) {
print "Usage: pcap.pl <pcap.file>\n";
exit;
}


my %sum;
my $key;
my $keyx;
my $log = Net::TcpDumpLog->new();
$log->read($ARGV[0]);

my @keys = ();

foreach my $index ($log->indexes) {
my ($length_orig, $length_incl, $drops, $secs, $msecs) = $log->header($index);
my $data = $log->data($index);

my $eth_obj = NetPacket::Ethernet->decode($data);
next unless $eth_obj->{type} == NetPacket::Ethernet::ETH_TYPE_IP;

my $ip_obj = NetPacket::IP->decode($eth_obj->{data});
next unless $ip_obj->{proto} == NetPacket::IP::IP_PROTO_TCP;

my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data});
my $keyName = $ip_obj->{src_ip}.":".$tcp_obj->{src_port}." <-> ".$ip_obj->{dest_ip}.":".$tcp_obj->{dest_port};

if ($sum{$keyName}) {
$sum{$keyName} = $ip_obj->{len} + $sum{$keyName};
}
else
{
$sum{$keyName} = $ip_obj->{len};
}

}

sub hashSort {
$sum{$b} <=> $sum{$a};
}
my $cnt = 0;
print "\tSession \t\t\t\tREC\tSENT\tBytes Total\n";
print "===================================================================\n";

my $ip = "";
my $othcnt = 0;
my @arrayz;
my $firstvalue;
my $secondvalue;
my $thirdvalue;
my $forth;
foreach $key (keys(%sum))
{
my @excludeList = split("<->", $key);
$firstvalue = trim($excludeList[0]); # ip address
$secondvalue = trim($excludeList[1]); # ip address
foreach $keyx (keys(%sum))
{
@excludeList = split("<->", $keyx);
$thirdvalue = trim($excludeList[0]); # ip address
$forth = trim($excludeList[1]); # ip address
if (($firstvalue eq $forth) && ($thirdvalue eq $secondvalue))
{
$ip = &checkArray($thirdvalue,$forth);
if ($ip ne 666)
{
$arrayz[$othcnt] = $keyx;
$othcnt = $othcnt + 1;
my $suma;
$suma = $sum{$key} + $sum{$keyx};
print "$key \t $sum{$key} \t $sum{$keyx} \t $suma \n";
}
}
}
}

sub trim($)
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}

sub checkArray
{
my($a,$b) = @_;
my $arrayvalue="";
foreach $arrayvalue(@arrayz)
{
my @excludeList = split("<->", $arrayvalue);
my $one = trim($excludeList[0]); # ip address of first
my $sec = trim($excludeList[1]); # ip address of first
if ((($a eq $sec) && ($b eq $one)) || (($a eq $one) && ($b eq $sec)))
{
return 666;
}
}
}


And generally that is all which i want to get, so
REC BYES, SENT BYTES, TOTAL BYTES (REC+SENT).

However, it doesn't work quite well, because if i have completely different connections (client only sent some data didn't receive nothing for example) they won't be printed in output:

Code
        Session                                         Bytes Total 
===================================================================
10.197.191.250:51182 <-> 10.39.0.123:21 76
10.197.191.250:50779 <-> 10.39.0.123:23 60



CPS
Novice

Sep 20, 2012, 6:43 AM

Post #15 of 15 (2912 views)
Re: [CPS] Searching two-value hash array [In reply to] Can't Post

Ok,

I have modified code to the following. It looks better and works good.
Again thanks for the reply!

Code of the main loop:

Code
foreach $key (keys(%sum)) 
{
my @excludeList = split(",", $key);
$firstvalue = trim($excludeList[0]); # ip address
$secondvalue = trim($excludeList[1]); # ip address
$tempkey = "$secondvalue,$firstvalue";
$ip = &checkArray($secondvalue,$firstvalue);
if ($ip ne 666)
{
if (exists($sum{$tempkey}))
{
$arrayz[$othcnt] = $key;
$othcnt = $othcnt + 1;
my $tempvalue = $sum{$tempkey}; #keyx
print "$key,0,$sum{$key},0,$tempvalue\n";
}
else
{
print "$key,0,$sum{$key},0,0\n";

}
}
}



(This post was edited by CPS on Sep 20, 2012, 6:44 AM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives