异步 lib​​pcap:丢失数据包?

2023-11-21

我有一个程序将一组 TCP SYN 数据包发送到主机(使用原始套接字)并使用libpcap(使用过滤器)以获得响应。我正在尝试在异步 I/O 框架中实现这一点,但似乎libpcap缺少一些响应(即,当花费的时间少于100 microsecondsTCP SYN 和响应之间)。 pcap 句柄设置如下:

pcap_t* pcap = pcap_open_live(NULL, -1, false, -1, errorBuffer);
pcap_setnonblock(pcap, true, errorBuffer);

然后我添加一个过滤器(包含在 filterExpression 字符串中):

struct bpf_program filter;
pcap_compile(pcap, &filter, filterExpression.c_str(), false, 0);
pcap_setfilter(pcap, &filter);
pcap_freecode(&filter);

在循环中,发送每个数据包后,我使用 select 来知道是否可以从 libpcap 读取:

int pcapFd = pcap_get_selectable_fd(pcap);
fd_set fdRead;
FD_ZERO(&fdRead);
FD_SET(pcapFd, &fdRead);
select(pcapFd + 1, &fdRead, NULL, NULL, &selectTimeout);

并阅读它:

if (FD_ISSET(pcapFd, &fdRead)) {
     struct pcap_pkthdr* pktHeader;
     const u_char* pktData;
     if (pcap_next_ex(pcap, &pktHeader, &pktData) > 0) {
         // Process received response.
     }
     else {
         // Nothing to receive (or error).
     }
}

正如我之前所说,有些数据包丢失了(落入“无物可接收”的状态)。我知道这些数据包在那里,因为我可以以同步方式捕获它们(使用tcpdump或正在运行的线程pcap_loop)。我在这里遗漏了一些细节吗?或者这是一个问题libpcap?


如果 FD 为pcap_t被报告为可读select() (or poll()或您使用的任何调用/机制),不能保证这意味着只能读取一个数据包而不会阻塞。

如果你使用pcap_next_ex(),您将只读取一个数据包;如果有多个数据包可供读取,那么,如果您执行另一个数据包select(),它应该立即返回,报告 FD 再次可读,在这种情况下您可能会调用pcap_next_ex()再次,依此类推。这意味着每个数据包至少有一个系统调用(select()),可能还有更多调用,具体取决于您正在使用的操作系统版本以及您拥有的 libpcap 版本。

相反,如果您要致电pcap_dispatch(),当 packet-count 参数为 -1 时,该调用将返回通过一次读取操作可以获得的所有数据包并处理所有这些数据包,因此,在大多数平台上,您可能会通过一两个系统调用获得多个数据包如果有多个可用数据包(在网络流量较高的情况下,如果您使用 SYN 洪水测试程序,可能会出现这种情况)。

此外,在支持内存映射数据包捕获的 Linux 系统上(我认为所有 2.6 及更高版本的内核都支持,大多数 2.4 内核都支持),并且使用较新版本的 libpcap,pcap_next_ex()必须制作数据包的副本,以避免内核从处理数据包的代码下更改数据包,并避免无限期地“锁定”环形缓冲区中的一个槽,因此涉及额外的副本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

异步 lib​​pcap:丢失数据包? 的相关文章

随机推荐