pcap_dispatch 卡在网络过滤器集上

pcap_dispatch stuck with network filter set

当我 运行 我的程序带有环回设备“lo”并应用了一些过滤器时,它在轮询调用中挂起(请参阅下面的 gdb)。如果跳过 pcap_compile() 和 pcap_setfilter() 调用,则不会发生这种情况,其他网络设备也不会发生这种情况。 pcap_dispatch 在循环中被调用。程序按顺序调用这些 libpcap 函数:

1. pcap_create("lo", errbuf)
2. pcap_set_promisc(handle, 0)
3. pcap_set_snaplen(handle, 65000)
4. pcap_set_timeout(handle, 1000)
5. pcap_activate(handle)
6. pcap_lookupnet("lo", &localnet, &mask, errbuf)
7. pcap_compile(handle, &fp, "port 12345", 0, mask)
8. pcap_setfilter(handle &fp)
9. pcap_dump_open(handle, file)
10. pcap_dispatch(handle, 5, packet_handler, dumpObject)

它卡在 pcap_dispatch 而不是 return。我试图调用 pcap_breakloop() 但这不起作用。调用随机数据包的 pcap_inject() 仅在没有编译和设置过滤器(用于环回设备)的情况下才有效。这是回溯(一些细节omitted/changed):

#0  __GI___poll (timeout=-1, nfds=1, fds=[some address]) at .xxxx/poll.c:29
#1  __GI___poll (fds=[some address], nfds=1, timeout=-1) at .xxxx/poll.c:26
#2  in pcap_wait_for_frames_mmap () from /libpcap.so.1
#3  in pcap_read_linux_mmap_v3 () from /libpcap.so.1
#4  in execute() ()

我猜它正在等待通过过滤器的数据包可供轮询结束。但是有什么办法可以解决这个问题吗?

这似乎是 1.10.0 之前的版本中的问题。从 1.10.0 开始,发出 pcap_breakloop() 将强制 poll() 调用结束并导致 pcap_dispatch 到 return 和 PCAP_ERROR_BREAK.

如果使用旧版本,一个快速的解决方案是在 pcap_activate() 之后调用 pcap_setnonblock(),然后在 pcap_dispatch() 调用之间休眠以获得一定数量的 milliseconds/seconds。这有助于避免 pcap_dispatch() 的循环过载。您可以使用“0”或在这种情况下所需的任何数据包来调用 pcap_dispatch(),并且在下次发送时它们应该可用。然后,您可以使用 pcap_breakloop() 或您自己的机制取消循环。