On Linux Mint (either 17 or 17.1) I'm using tcpdump to capture some packets with this command:
tcpdump -UnvXSs 4096 -B 1024 -i eth0
Despite the -U option, it doesn't actually output packets immediately. Instead, they're saved up and output almost exactly once per second, the only exception being that if I cause a lot of network activity, they'll be output more often. I also tried the -l option, it makes no difference. Using a smaller buffer (the -B argument) makes it so that less traffic can cause more frequent output, but the smallest possible is 128 which is still large enough that the traffic I want to see is only output once per second.
I ran strace on tcpdump. It repeatedly pauses at the following line:
poll([{fd=3, events=POLLIN}], 1, 1000) = 1 ([{fd=3, revents=POLLIN}])
It stays there for 1 second, then resumes, outputs more packets, then returns to that poll() call.
The last system call to return a 3 before these poll() calls occur is this one:
socket(PF_PACKET, SOCK_RAW, 768) = 3
Between those calls to poll(), there are nothing but write() calls, so it isn't being delayed by DNS lookups or anything.
So I'm left to conclude that the reason tcpdump is only displaying packets once per second is because that's as often that the kernel is delivering them.
How I can get it to output the packets as soon as they are received by the kernel?
Linux version 3.13.0-24-generic (buildd@batsu) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014