异步的libpcap:丢失数据包?(Asynchronous libpcap: losing pac

2019-06-26 12:20发布

我有发送一组TCP SYN数据包的到主机(使用原始套接字),并使用一个程序libpcap (具有过滤器),以获得响应。 我想在异步I / O框架来实现这一点,但似乎libpcap缺少一些响应的(即一系列的第一包时只需不到100 microseconds的TCP 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

Answer 1:

如果在该FD pcap_t被报道为可读的select()poll()或任何调用你使用/机构),也不能保证,这意味着只有一个数据包可以无阻塞地读。

如果你使用pcap_next_ex()你会读到一个分组; 如果有一个以上的数据包可以被读取,那么,如果你这样做的另一个select()它应该立即返回,报告FD作为再次被读取,在这种情况下,你可能调用pcap_next_ex()再次,等等。 这意味着,每包至少一个系统调用(的select()以及可能更多的电话,这取决于你在做什么什么操作系统和版本是什么版本的libpcap的你。

相反,如果你要调用pcap_dispatch()为-1的分组计数的说法,该呼叫将返回所有可以用一个读操作来获得和处理全部的数据包,因此,在大多数平台上,如果有可用的(其中,具有很高的网络流量,因为你可能,如果你用SYN洪水测试程序得到的,很可能是这种情况)的多个数据包,你可以与一个或两个系统调用获取多个数据包。

此外,在支持内存映射的数据包捕获Linux系统(我认为所有的2.6及以后的内核做的,如果不是所有的2.4内核做),并与libpcap的更新版本, pcap_next_ex()必须做出的一个副本包,以避免具有内核从出改变数据包的代码下处理该分组,并避免“锁定”在不确定的时间周期的环形缓冲器的槽,所以有涉及的额外拷贝。



Answer 2:

这似乎是使用libpcap的Linux下的内存映射的问题。 请参阅我的其他问题的详细信息。



文章来源: Asynchronous libpcap: losing packets?