2
votes

I am developing a program that sniffs network packets using a raw socket (AF_PACKET, SOCK_RAW) and processes them in some way.

I am not sure whether my program runs fast enough and succeeds to capture all packets on the socket. I am worried that the recieve buffer for this socket occainally gets full (due to traffic bursts) and some packets are dropped.

How do I know if packets were dropped due to lack of space in the socket's receive buffer?

I have tried running ss -f link -nlp.

This outputs the number of bytes that are currently stored in the revice buffer for that socket, but I can not tell if any packets were dropped.

I am using Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-52-generic x86_64).

Thanks.

2
You can't count things that don't exist.user207421

2 Answers

2
votes

I was having a similar problem as you. I knew that tcpdump was able to to generate statistics about packet drops, so I tried to figure out how it did that. By looking at the code of tcpdump, I noticed that it is not generating those statistic by itself, but that it is using the libpcap library to get those statistics. The libpcap is on the other hand getting those statistics by accessing the if_packet.h header and calling the PACKET_STATISTICS socket option (at least I think so, but I'm no C expert).

Therefore, I saw only two solutions to the problem:

  1. I had to interact somehow with the linux header files from my Pyhton script to get the packet statistics, which seemed a bit complicated.
  2. Use the Python version of libpcap which is pypcap to get those information.

Since I had no clue how to do the first thing, I implemented the second option. Here is an example how to get packet statistics using pypcap and how to get the packet data using dpkg:

import pcap
import dpkt
import socket

pc=pcap.pcap(name="eth0", timeout_ms=10000, immediate=True)

def packet_handler(ts,pkt):

    #printing packet statistic (packets received, packets dropped, packets dropped by interface
    print pc.stats()

    #example packet parsing using dpkt
    eth=dpkt.ethernet.Ethernet(pkt)
    if eth.type != dpkt.ethernet.ETH_TYPE_IP:
        return
    ip =eth.data
    layer4=ip.data
    ipsrc=socket.inet_ntoa(ip.src)
    ipdst=socket.inet_ntoa(ip.dst)

pc.loop(0,packet_handler)

tpacket_stats structure is defined in linux/packet.h header file

Create variable using the tpacket_stats structre and pass it to getSockOpt with PACKET_STATISTICS SOL_SOCKET options will give packets received and dropped count.

-- some times drop can be due to buffer size -- so if you want to decrease the drop count check increasing the buffersize using setsockopt function

-4
votes

First off, switch your operating system.

You need a reliable, network oriented operating system. Not some pink fluffy "ease of use" with "security" functionality enabled. NetBSD or Gentoo/ArchLinux (the bare installations, not the GUI kitted ones).


Start a simultaneous tcpdump on a network tap and capture the traffic you're supposed to receive along side of your program and compare the results.

There's no efficient way to check if you've received all the packets you intended to on the receiving end since the packets might be dropped on a lower level than you anticipate.

Also this is a question for Unix @ StackOverflow, there's no programming here what I can see, at least there's no code.


The only certain way to verify packet drops is to have a much more beefy sender (perhaps a farm of machines that send packets) to a single client, record every packet sent to your reciever. Have the statistical data analyzed and compared against your senders and see how much you dropped.

The cheaper way is to buy a network tap or even more ad-hoc enable port mirroring in your switch if possible. This enables you to dump as much traffic as possible into a second machine.

This will give you a more accurate result because your application machine will be busy as it is taking care of incoming traffic and processing it. Further more, this is why network taps are effective because they split the communication up into two channels, the receiving and sending directions of your traffic if you will. This enables you to capture traffic on two separate machines (also using tcpdump, but instead of a mirrored port, you get a more accurate traffic mirroring).

So either use port mirroring

enter image description here


Or you buy one of these:

enter image description here