0

我正在编写一个 PERL 脚本,该脚本捕获数据包,然后每秒生成有关所有 TCP 流的统计信息,这些流在该秒内在线。我正在使用 NET::Pcap,我想以某种方式实现这一点,如果可以不使用线程。我尝试过使用 select() 和 pcap_breakloop(),但它似乎不起作用。

我在想:

...
$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

你知道如何解决这个问题吗?我不确定我应该使用 select,但我没有更好的主意,我是 PERL 的新手。我选择 select 的原因是,即使没有流量,我也需要生成统计信息。

例如,我想每秒打印传输的字节,然后我还需要生成总零行。

任何帮助,将不胜感激 :)

4

1 回答 1

0

我想我已经找到了答案,也许它对其他人有用。

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);
  ...
}

确保你的回调函数默认返回值为真,这样才能再次调用。

于 2013-04-02T11:33:52.890 回答