3
votes

I have a packet capture application which does the packet capture using pcap_loop() but am seeing packet loss.

I am trying to send 20 DNS queries to the host machine. Running tcpdump on the machine shows me 1 have recieved 20 DNS query packets and 20 DNS resposne packets which is correct. But my packet capture application receives 20 queries but gets only 11 resposne packets. Any idea why pcap_loop is missing some response packets?

I came across this link below which says: link: Asynchronous libpcap: losing packets? **"It may be the case that you're sending too many requests too quickly, and the server is sending responses faster then you can handle them thus overloading the OS's network buffer and dropping packets.

Even if you see the packets in tcpdump, they could still be dropped by OS if your application can't handle the rate they are received at."**

Could this be the reason for my packet loss? if so how how can i handle such case because i cannot add delay in serve to send response late because other applications running in my host will be affected.

i am using the following pcap routine configuration for my packet captue application in the following order:

  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);

Note: filterexp exp is udp port 53

if i send around 10 DNS queries then i get all queries and resposne packets.I see this problem only when we have more packets. Any pointers would be helpful.

Thanks.******

$ 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
What version of what OS are you doing this on (unless this is Windows, run uname -sr to get the version information), and what version of libpcap/WinPcap are you using?user862787
Hi , my os version and libcap version is : -bash-4.0# uname -sr Linux 2.6.32.8 bash-4.0# ldconfig -p | grep pcap libpcap.so.1 (libc6,x86-64) => /usr/lib64/libpcap.so.1 -bash-4.0#Pam
That just says "the libpcap shared library is version 1"; a number of different versions of libpcap have the same version (because there's upwards binary compatibility). What does tcpdump -h print?user862787
i had give tcpdump on the interface i am receving packets and i am getting all DNS query and DNS resposne packets ther. ii.e if i send 20 DNS queries i got all 20 queries and 20 resposne packets on tcpdump udp -i eth1 -n.Pam
tcpdump receives all packets.. Not sure why is my application which runs pcap_loop dropping some response packets ..Pam

1 Answers

3
votes

OK, they're both using libpcap 1.1.1.

Sadly, that means that "the OS buffer" is always going to be a collection of single-packet buffer slots that will be as large as the snapshot length used when opening the capture device. It defaults to 2MB, so, with a snapshot length of 65535, that's 32 buffer slots, so, if your program isn't processing the packets fast enough, 40 packets could overflow the buffer. 20+11=31, so it looks as if that might be what's happening.

Tcpdump is also using a snapshot length of 65535; if it's doing less work in its pcap_loop() callback than your program is doing in its callback, and if it doesn't get blocked printing to the standard output any more than your program does by doing any per-packet I/O, it might be able to keep up.

Try using, for example, 2048 as the snapshot length, rather than 65535. You won't be getting TCP packets, so you don't have to worry about TCP segmentation offloading causing your program to get very large packets, and you're probably capturing on a network whose packet lengths are limited to the maximum Ethernet packet size (1514 bytes, unless "jumbo frames" are being used), so that should be sufficient. That will reduce the size of the single-packet buffer slots and thus increase the number of those slots.

That won't, of course, keep your program from getting behind, so, if it's going to be running for a significant period of time, you have to make sure it can process packets at the average rate at which they arrive - the buffering in the OS handles bursts where, for a short period of time, packets arrive faster than they can be consumed, but where the program can catch up during a "slower" period.

Later versions of libpcap (1.2 and later) attempt, if they can, to reduce the size of the single-packet buffer slots to the maximum packet size ("if they can" means that it can't always determine the maximum packet size; it only works on Ethernet, and then only when various forms of TCP segmentation/desegmentation offloading are turned off).

Until Linux 3.2, which introduced TPACKET_V3 (which doesn't have those annoying fixed-length single-packet buffer slots), Linux PF_PACKET sockets (which is the built-in mechanism Linux offers for packet capture) didn't support packet capture very well, and even TPACKET_V3 has some annoying botches not fixed until 3.19.