如何使libpcap / pcap_loop无阻塞?

时间:2015-07-08 23:40:52

标签: c++ linux multithreading libpcap packet-sniffers

我目前正在使用libpcap以混杂模式嗅探流量

int main() 
{
    // some stuff
    printf("Opening device: %s\n", devname.c_str());

    handle = pcap_open_live(devname.c_str(), 65536 , 1 , 0 , errbuf);

    if (handle == NULL)
    {
        fprintf(stderr, "Couldn't open device %s : %s..." , devname.c_str(), errbuf);
        return 1;
    }
    printf(" Done\n");

    pcap_loop(handle , -1 , process_packet , NULL);
    // here run a thread to do some stuff. however, pcap_loop is blocking
    return 0;
}

我想添加一个外部线程来做其他事情。如何更改上面的代码以使其无阻塞?

3 个答案:

答案 0 :(得分:3)

当你在libpcap上使用非阻塞模式时你必须使用pcap_dispatch,但请注意,pcap_dispatch可以在阻塞或非阻塞模式下工作,这取决于你如何设置libpcap,设置libpcap来工作非阻塞你使用函数pcap_setnonblock

int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf);

阻塞和非阻塞之间的区别不是永远运行的循环,而是阻塞函数pcap_dispatch等待数据包并且仅在收到此数据包时返回,但是,在非阻塞模式下函数立即返回,回调必须处理数据包。

  

在“非阻塞”模式下,尝试从捕获中读取   如果当前没有数据包,则使用pcap_dispatch()的描述符   可以读取,立即返回0而不是阻塞   等待数据包到达。 pcap_loop()和pcap_next()不会   以“非阻塞”模式工作。

http://www.tcpdump.org/manpages/pcap_setnonblock.3pcap.html

答案 1 :(得分:0)

pcap_loop意味着继续直到所有输入结束。如果您不想要这种行为,请改为在循环中调用pcap_dispatch。根据定义,pcap_loop将永远不会返回,它意味着始终搜索更多数据。

答案 2 :(得分:0)

我使用pcap_next_ex它返回一个结果,指示是否已读取数据包。这样我就可以管理我自己的线程。查看示例hereread_timeout中的pcap_open也会影响此功能。