0

I am writing a PERL script, which captures packets, and then generate statistics in every second about all the TCP streams, which were online in that second. I am using NET::Pcap, and I want somehow to implement this, and if it's possible without using threads. I've tried with select(), and with pcap_breakloop(), but it doesn't semmed to work.

I was thinking of:

...
$pcap = pcap_open_live($dev, 1024, 1, 0, \$err);

select($pcap, undef, undef, 1)
if 1 sec elapsed print a line with data maintained by the pcap_callback function, 
and go back to pcap_loop

Do you have any idea how to solve this problem? I am not sure that I should use select, but I don't have any better idea, I am new to PERL. The reason I have chosen select, that I need to generate statistics even if there is no traffic.

For example I want to print the transmitted bytes in every second, then I need to generate total zero lines as well.

Any help would be appreciated :)

molnarg
  • 445
  • 4
  • 8

1 Answers1

0

I think I have found the answer, maybe it will be useful for other.

my $dev = Net::Pcap::pcap_lookupdev(\$err);
print "Capturing on: $dev\n";

my $pcap = pcap_open_live($dev, 1024, 1, 0, \$err);

if ($pcap eq NULL) {
  print "Could not capture on $dev. Terminating...\n";
  return 0;
}

my $main_loop = Glib::MainLoop->new;

Glib::IO->add_watch (pcap_get_selectable_fd($pcap), [qw/in/], \&watch_callback, $pcap); 
Glib::Timeout->add (1000, \&stats_callback, undef, 1 );

$main_loop->run;

print "Closing pcap...\n";

pcap_close($pcap);

sub watch_callback {
  Net::Pcap::pcap_dispatch($pcap, -1, \&process_packet, "");
  return 1;
}

sub stats_callback{
  #generate statistic...
  return 1;
}

sub process_packet {
  my ($user_data, $header, $packet) = @_;
  my $ether_data = NetPacket::Ethernet::strip($packet);
  ...
}

Be sure that your callback function default return value is true, so it can be called again.

molnarg
  • 445
  • 4
  • 8