如何在libpcap数据包接收函数中定期超时

时间:2011-07-24 23:29:29

标签: packet-capture libpcap tcpdump

我在stackoverflow.com上发现了这篇文章 listening using Pcap with timeout

我面临着一个类似(但不同)的问题:当使用libpcap数据包接收功能接收捕获的数据包时,GENERIC(平台无关)定期超时的方法是什么? 实际上,我想知道是否有可能定期从pcap_dispatch(pcap_t ...)/ pcap_next_ex(pcap_t ...)超时?如果可以的话,我可以像使用经典的select(... timeout)函数(http://linux.die.net/man/2/select)一样使用它们。

此外,从官方网页(http://www.tcpdump.org/pcap3_man.html),我发现原来的超时机制被认为是错误的和特定于平台的(这很糟糕,因为我的程序可能在不同的Linux和Unix机器上运行):<登记/> “...... to_ms指定读取超时(以毫秒为单位)。读取超时用于安排读取不一定在看到数据包时立即返回,但它等待一段时间以允许更多数据包到达并且在一次操作中从OS内核读取多个数据包。并非所有平台都支持读取超时;在没有读取超时的平台上,忽略读取超时...... ... 注意:在读取实时捕获时,pcap_dispatch()在读取超时时不一定会返回;在某些平台上,不支持读取超时,并且在其他平台上,定时器在至少一个数据包到达之前不会启动。这意味着不应在例如交互式应用程序中使用读取超时,以允许数据包捕获循环定期“轮询”用户输入,因为无法保证pcap_dispatch()将在超时到期后返回。 ......“

因此,我想我需要自己实现GENERIC(平台无关)超时机制,如下所示?

  1. 使用pcap_open_live()创建一个pcap_t结构。
  2. 使用pcap_setnonblock(pcap_t ...)将其设置为非阻塞模式。
  3. 使用已注册的OS计时器轮询此非阻塞pcap_t,如:
  4. 注册OS timer_x,并重置timer_x;

    while(1){

    if(timer_x超时)   {做一些需要定期做的事情; reset timer_x;}

    通过调用pcap_dispatch(pcap_t ...)/ pcap_next_ex(pcap_t ...)来轮询pcap_t以接收一些数据包;
      用这些数据包做一些事情;

    } //结束时间(1)

    的问候,
    DC

1 个答案:

答案 0 :(得分:1)

您可以使用pcap_fileno()获取句柄并选择()它。 OfferReceiver :: Listen()中有一个示例here