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

hi, am new to perl. am working on counting number of syn+ack packets from a machine. though the source and destination is being displayed correctly, the problem lies in counting them. i would be grateful to get some amount of help on this... my code is given below:
use Net::Pcap; use NetPacket::Ethernet; use NetPacket::IP; use NetPacket::TCP; use strict; my $err; # Use network device passed in program arguments or if no # argument is passed, determine an appropriate network # device for packet sniffing using the # Net::Pcap::lookupdev method my $dev = $ARGV[0]; unless (defined $dev) { $dev = Net::Pcap::lookupdev(\$err); if (defined $err) { die 'Unable to determine network device for monitoring - ', $e +rr; } } # Look up network address information about network # device using Net::Pcap::lookupnet - This also acts as a # check on bogus network device arguments that may be # passed to the program as an argument my ($address, $netmask); if (Net::Pcap::lookupnet($dev, \$address, \$netmask, \$err)) { die 'Unable to look up device information for ', $dev, ' - ', $err +; } # Create packet capture object on device my $object; $object = Net::Pcap::open_live($dev, 1500, 0, 0, \$err); unless (defined $object) { die 'Unable to create packet capture on device ', $dev, ' - ', $er +r; } # Compile and set packet filter for packet capture # object - For the capture of TCP packets with the SYN # header flag set directed at the external interface of # the local host, the packet filter of '(dst IP) && (tcp # [13] & 2 != 0)' is used where IP is the IP address of # the external interface of the machine. For # illustrative purposes, the IP address of 127.0.0.1 is # used in this example. my $filter; Net::Pcap::compile( $object, \$filter, '(src 192.168.11.248) && (tcp[13] & 2 != 0) && (tcp[14] & 2 != 0)' +, 0, $netmask ) && die 'Unable to compile packet capture filter'; Net::Pcap::setfilter($object, $filter) && die 'Unable to set packet capture filter'; # Set callback function and initiate packet capture loop my $count = 0; Net::Pcap::loop($object, -1, \&syn_packets, '$count++') || die 'Unable to perform packet capture'; print "$count"; Net::Pcap::close($object); sub syn_packets { my ($user_data, $header, $packet) = @_; # Strip ethernet encapsulation of captured packet my $ether_data = NetPacket::Ethernet::strip($packet); # Decode contents of TCP/IP packet contained within # captured ethernet packet my $ip = NetPacket::IP->decode($ether_data); my $tcp = NetPacket::TCP->decode($ip->{'data'}); # Print all out where its coming from and where its # going to! print $ip->{'src_ip'}, ":", $tcp->{'src_port'}, " -> ", $ip->{'dest_ip'}, ":", $tcp->{'dest_port'}, "\n"; }

Replies are listed 'Best First'.
Re: counting syn+ack. Help!!!
by roboticus (Chancellor) on Jan 03, 2011 at 10:52 UTC

    Arijit:

    I commend you for including the code, but what's the problem you're having with counting the packets? Don't just tell us you have a problem with it, tell us what the problem is. I don't mind reading the code looking for an issue, but without knowing exactly what the problem is, I don't know what sorts of errors to look for.

    Having said that, I read the code anyway. When I looked for counters, the only thing I found is:

    my $count = 0; Net::Pcap::loop($object, -1, \&syn_packets, '$count++') || die 'Unable to perform packet capture'; print "$count";

    I don't have Net::Pcap installed on my machine, so I'm not trying out your program, but seeing '$count++' looks like an obvious problem. First, since it's in single quotes, the $count variable won't be interpolated. Second, since it's a function call argument, and the function call isn't in a loop, it will be evaluated only once. Third, the documentation mentions that the argument is simply a chunk data to pass to the callback, not a code reference to execute. I suggest adding $count++ to your callback function and eliminating the '$count++' argument.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: counting syn+ack. Help!!!
by jethro (Monsignor) on Jan 03, 2011 at 10:37 UTC

    It seems syn_packets is only called for syn packets (as the name implies), so you probably won't be counting ack packets without changing the filter expression. That should be the same number normally but bugs, network problems or malice might make them differ)

    Now what is your problem with counting? It seems this is already done with '$count++'. The only thing missing seems to be the reporting (the print after the loop call won't be executed if the capture loop is endless). Either write to a log file or print a report every 100 or 1000 packets or after some time has elapsed (this can be done in the syn_packets subroutine). The time in seconds you get with time(). Put the starting time in some variable and subtract the actual time from that to know how much time elapsed. Or check how to end the Net::Pcap::loop (check the documentation) so that the print afterwards really gets executed

Re: counting syn+ack. Help!!!
by Anonyrnous Monk (Hermit) on Jan 03, 2011 at 10:45 UTC
    Net::Pcap::loop($object, -1, \&syn_packets, '$count++') ||

    The 4th parameter to Net::Pcap::loop()'$count++' — is what's being passed as argument to the callback function, i.e. what you get as $user_data in syn_packets() (which you don't even use there). So I'm not really sure what this is meant to achieve.

    If you want to count how many times the callback function is being called, it's probably better to place $count++ (without quotes) in the body of that function.