From Guy Harris himself:
the "packets captured" number is a number that's incremented every time tcpdump sees a packet, so it counts packets that tcpdump reads from libpcap and thus that libpcap reads from BPF and supplies to tcpdump.
The "packets received by filter" number is the "ps_recv" number from a call to pcap_stats(); with BPF, that's the bs_recv number from the BIOCGSTATS ioctl. That count includes all packets that were handed to BPF; those packets might still be in a buffer that hasn't yet been read by libpcap (and thus not handed to tcpdump), or might be in a buffer that's been read by libpcap but not yet handed to tcpdump, so it can count packets that aren't reported as "captured".
And from the tcpdump
man page:
packets ``dropped by kernel'' (this is the number of packets that were dropped, due to a lack of buffer space, by the packet capture mechanism in the OS on which tcpdump is running, if the OS reports that information to applications; if not, it will be reported as 0).
To attempt to improve capture performance, here are a few things to try:
- Don't capture in promiscuous mode if you don't need to. That will cut down on the amount of traffic that the kernel has to process. Do this by using the
-p
option.
- Since you're only interested in TCP traffic, apply a capture expression that limits the traffic to TCP only. Do this by appending
"tcp"
to your command.
- Try writing the packets to a file (or files to limit size) rather than displaying packets to the screen. Do this with the
-w file
option or look into the -C file_size
and -G rotate_seconds
options if you want to limit file sizes.
- You could try to improve
tcpdump
's scheduling priority via nice
.
From Wireshark's Performance wiki page:
- stop other programs running on that machine, to remove system load
- buy a bigger, faster machine :)
- increase the buffer size (which you're already doing)
- set a snap length (which you're already doing)
- write capture files to a RAM disk
Try using PF_RING.
You could also try using dumpcap
instead of tcpdump
, although I would be surprised if the performance was drastically different.
You could try capturing with an external, dedicated device using a TAP or Switch+SPAN port. See Wireshark's Ethernet Capture Setup wiki page for ideas.
Another promising possibility: Capturing Packets in Linux at a Speed of Millions of Packets per Second without Using Third Party Libraries.
See also Andrew Brown's Sharkfest '14 Maximizing Packet Capture Performance document for still more ideas.
Good luck!