使用pcap_loop时丢包

时间:2015-03-26 14:32:14

标签: pcap

我有一个数据包捕获应用程序,使用pcap_loop()进行数据包捕获,但看到数据包丢失。

我正在尝试向主机发送20个DNS查询。在机器上运行tcpdump显示我已收到20个DNS查询数据包和20个DNS resposne数据包,这是正确的。 但我的数据包捕获应用程序接收20个查询,但只获得11个resposne数据包。 知道为什么pcap_loop缺少一些响应数据包吗?

我在下面看到这个链接说: 链接: Asynchronous libpcap: losing packets? **“可能是您发送的请求过快,服务器发送响应速度快,然后您可以处理它们,从而使操作系统的网络缓冲区过载并丢弃数据包。

即使您在tcpdump中看到数据包,如果您的应用程序无法处理它们收到的速率,它们仍然可以被操作系统删除。“**

这可能是我丢包的原因吗?如果是这样,我怎么能处理这种情况,因为我不能延迟发送响应迟到,因为在我的主机上运行的其他应用程序将受到影响。

我按以下顺序对我的数据包捕获应用程序使用以下pcap例程配置:

  1. pcap_lookupnet((char *)dev,& net,& mask,errbuf)
  2. pcap_open_live((char *)dev,65535,0,1000,errbuf)
  3. pcap_compile(pc,& prog,(char *)filterexpr,0,net)
  4. pcap_setfilter(pc,& prog)
  5. pcap_compile(pc,& prog,(char *)filterexpr,0,net)
  6. pcap_loop(pc,-1,handle_packet,NULL);
  7. 注意:filterexp exp是udp port 53

    如果我发送大约10个DNS查询,那么我将获得所有查询和resposne数据包。我只有在有更多数据包时才会看到此问题。 任何指针都会有所帮助。

    感谢。******

    $ tcpdump udp -i eth1 -n
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
    10:05:27.066801 IP 10.36.0.96.45267 > 10.35.103.6.domain: 1+ A? Baaaaaaaaaaaaaaaaaa.t2oovm3zgkx9xp05gvn0y2.com. (64)
    10:05:27.066828 IP 10.36.0.96.45267 > 10.35.103.6.domain: 2+ A? aaaaaaaaaaaaaaaaab.ad2rn4fqq7uc0tlsqz4ygm.net. (63)
    10:05:27.066831 IP 10.36.0.96.45267 > 10.35.103.6.domain: 3+ A? aaaaaaaaaaaaaaaaac.aawabh0usmsle87qtdg8br.edu. (63)
    10:05:27.066837 IP 10.36.0.96.45267 > 10.35.103.6.domain: 4+ A? aaaaaaaaaaaaaaaaad.vrgztlp1fatm1hipf315r9.jp. (62)
    10:05:27.066842 IP 10.36.0.96.45267 > 10.35.103.6.domain: 5+ A? aaaaaaaaaaaaaaaaae.xr3au4o2plet984siue2wr.xxx. (63)
    10:05:27.066845 IP 10.36.0.96.45267 > 10.35.103.6.domain: 6+ A? aaaaaaaaaaaaaaaaaf.gvcx9lia6hlah8ay4wheps.com. (63)
    10:05:27.066848 IP 10.36.0.96.45267 > 10.35.103.6.domain: 7+ A? aaaaaaaaaaaaaaaaag.jhiu5ebw9bmbnq0reufe9z.net. (63)
    10:05:27.066851 IP 10.36.0.96.45267 > 10.35.103.6.domain: 8+ A? aaaaaaaaaaaaaaaaah.a325vjl3v1gkw9sf8mjgna.edu. (63)
    10:05:27.066853 IP 10.36.0.96.45267 > 10.35.103.6.domain: 9+ A? aaaaaaaaaaaaaaaaab.ad2rn4fqq7uc0tlsqz4ygm.net. (63)
    10:05:27.066857 IP 10.36.0.96.45267 > 10.35.103.6.domain: 10+ A? aaaaaaaaaaaaaaaaac.aawabh0usmsle87qtdg8br.edu. (63)
    10:05:27.066860 IP 10.36.0.96.45267 > 10.35.103.6.domain: 11+ A? aaaaaaaaaaaaaaaaad.vrgztlp1fatm1hipf315r9.jp. (62)
    10:05:27.066882 IP 10.36.0.96.45267 > 10.35.103.6.domain: 12+ A? aaaaaaaaaaaaaaaaae.xr3au4o2plet984siue2wr.xxx. (63)
    10:05:27.066886 IP 10.36.0.96.45267 > 10.35.103.6.domain: 13+ A? aaaaaaaaaaaaaaaaaf.gvcx9lia6hlah8ay4wheps.com. (63)
    10:05:27.066888 IP 10.36.0.96.45267 > 10.35.103.6.domain: 14+ A? aaaaaaaaaaaaaaaaag.jhiu5ebw9bmbnq0reufe9z.net. (63)
    10:05:27.066892 IP 10.36.0.96.45267 > 10.35.103.6.domain: 15+ A? aaaaaaaaaaaaaaaaah.a325vjl3v1gkw9sf8mjgna.edu. (63)
    10:05:27.066935 IP 10.36.0.96.45267 > 10.35.103.6.domain: 16+ A? aaaaaaaaaaaaaaaaai.f5t6kc1ijgnd655fauwk6e.jp. (62)
    10:05:27.066940 IP 10.36.0.96.45267 > 10.35.103.6.domain: 17+ A? aaaaaaaaaaaaaaaaai.f5t6kc1ijgnd655fauwk6e.jp. (62)
    10:05:27.066944 IP 10.36.0.96.45267 > 10.35.103.6.domain: 18+ A? aaaaaaaaaaaaaaaaai.f5t6kc1ijgnd655fauwk6e.jp. (62)
    10:05:27.066946 IP 10.36.0.96.45267 > 10.35.103.6.domain: 19+ A? aaaaaaaaaaaaaaaaai.f5t6kc1ijgnd655fauwk6e.jp. (62)
    10:05:27.066983 IP 10.36.0.96.45267 > 10.35.103.6.domain: 20+ A? aaaaaaaaaaaaaaaaaj.iaoq8srst9fud1uvgv72iw.xxx. (63)
    10:05:27.067239 IP 10.35.103.6.domain > 10.36.0.96.45267: 1 1/0/0 A 158.143.55.1 (80)
    10:05:27.067252 IP 10.35.103.6.domain > 10.36.0.96.45267: 3 1/0/0 A 169.143.55.1 (79)
    10:05:27.067288 IP 10.35.103.6.domain > 10.36.0.96.45267: 2 1/0/0 A 164.143.55.1 (79)
    10:05:27.067300 IP 10.35.103.6.domain > 10.36.0.96.45267: 4 1/0/0 A 159.143.55.1 (78)
    10:05:27.067335 IP 10.35.103.6.domain > 10.36.0.96.45267: 7 1/0/0 A 167.143.55.1 (79)
    10:05:27.067343 IP 10.35.103.6.domain > 10.36.0.96.45267: 5 1/0/0 A 165.143.55.1 (79)
    10:05:27.067345 IP 10.35.103.6.domain > 10.36.0.96.45267: 6 1/0/0 A 177.143.55.1 (79)
    10:05:27.067375 IP 10.35.103.6.domain > 10.36.0.96.45267: 10 1/0/0 A 169.143.55.1 (79)
    10:05:27.067383 IP 10.35.103.6.domain > 10.36.0.96.45267: 8 1/0/0 A 168.143.55.1 (79)
    10:05:27.067412 IP 10.35.103.6.domain > 10.36.0.96.45267: 12 1/0/0 A 165.143.55.1 (79)
    10:05:27.067421 IP 10.35.103.6.domain > 10.36.0.96.45267: 13 1/0/0 A 177.143.55.1 (79)
    10:05:27.067448 IP 10.35.103.6.domain > 10.36.0.96.45267: 14 1/0/0 A 167.143.55.1 (79)
    10:05:27.067455 IP 10.35.103.6.domain > 10.36.0.96.45267: 9 1/0/0 A 164.143.55.1 (79)
    10:05:27.067470 IP 10.35.103.6.domain > 10.36.0.96.45267: 11 1/0/0 A 159.143.55.1 (78)
    10:05:27.067485 IP 10.35.103.6.domain > 10.36.0.96.45267: 17 1/0/0 A 176.143.55.1 (78)
    10:05:27.067495 IP 10.35.103.6.domain > 10.36.0.96.45267: 18 1/0/0 A 176.143.55.1 (78)
    10:05:27.067502 IP 10.35.103.6.domain > 10.36.0.96.45267: 16 1/0/0 A 176.143.55.1 (78)
    10:05:27.067532 IP 10.35.103.6.domain > 10.36.0.96.45267: 15 1/0/0 A 168.143.55.1 (79)
    10:05:27.067539 IP 10.35.103.6.domain > 10.36.0.96.45267: 19 1/0/0 A 176.143.55.1 (78)
    10:05:27.067618 IP 10.35.103.6.domain > 10.36.0.96.45267: 20 1/0/0 A 171.143.55.1 (79)
    10:05:34.642563 IP 42.0.1.41.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:30:48:9e:a3:bb, length 300
    

1 个答案:

答案 0 :(得分:3)

好的,他们都使用libpcap 1.1.1。

可悲的是,这意味着“OS缓冲区”始终是单个数据包缓冲区插槽的集合,它将与打开捕获设备时使用的快照长度一样大。它默认为2MB,因此,快照长度为65535,即32个缓冲区插槽,因此,如果您的程序没有足够快地处理数据包,则40个数据包可能会溢出缓冲区。 20 + 11 = 31,所以看起来好像正在发生的事情。

Tcpdump也使用了65535的快照长度; if 它在pcap_loop()回调中的工作量比你的程序在回调中做的少,而如果它没有被阻止打印到标准输出任何通过执行任何每个数据包的I / O,你的程序可以做得更多,它可能能够跟上。

尝试使用例如2048作为快照长度而不是65535.您将不会获得TCP数据包,因此您不必担心TCP分段卸载会导致程序获取非常大的数据包,并且您可能正在网络上捕获其数据包长度限制为最大以太网数据包大小(1514字节,除非正在使用“巨型帧”),因此这应该足够了。这将减少单数据包缓冲器插槽的大小,从而增加这些插槽的数量。

当然,这不会让您的程序落后,所以,如果它将在很长一段时间内运行,您必须确保它能够以它们到达的平均速率处理数据包 - OS中的缓冲处理突发,其中,对于时间段,数据包到达的速度比可以消耗的速度快,但程序可以在“较慢”的时间段内赶上。

更高版本的libpcap(1.2及更高版本)尝试 if ,以便将单数据包缓冲区的大小减小到最大数据包大小(“ if 他们可以“意味着它不能始终确定最大数据包大小;它只适用于以太网,然后只有在关闭各种形式的TCP分段/解除分段卸载时才能使用。”

直到Linux 3.2引入了TPACKET_V3(没有那些烦人的固定长度单包缓冲区插槽),Linux PF_PACKET套接字(Linux为数据包捕获提供的内置机制)不支持数据包捕获得非常好,甚至TPACKET_V3也有一些烦人的漏洞,直到3.19都没有修复。