Wireshark-dev: Re: [Wireshark-dev] Capture->Interface shows incorrect statistics

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Thu, 30 Aug 2007 10:43:04 -0700
Stig Bj�rlykke wrote:
2007/8/30, Fulko Hew <fulko.hew@xxxxxxxxx>:
I was looking at the results from the Capture->Interface statistics display
 and the information I get from _my_ embedded system, and I thought
 I had an error, but I don't think I do...

Strange.  I was just looking at this code earlier today to figure out
the same problem, and when I look closer to this it seems like you are
right.  At least if the comments are correct.

But when testing on a older linux machine with svn 21019 it seems to
work correctly.  Hmmm, maybe we both have the unix version of libpcap
with the same error as winpcap?

"The unix version of libpcap" is really several different UN*X versions of libpcap; both libpcap and WinPcap share a bunch of code, but even libpcap on one UN*X doesn't necessarily share the low-level capture code, including the capture-statistics code, with libpcap on another version of UN*X, and WinPcap doesn't share it with any UN*X version of libpcap. (That's one thing libpcap is about - providing as platform-independent as possible an interface to doing captures on OSes with very different underlying packet capture mechanisms.)

On systems with BPF (various free-software BSDs, a certain free-software-at-the-UN*X-layer Mach+BSD, and AIX), statistics come from the kernel, and are not reset when fetched from the kernel.

On Linux:

in pre-2.4 kernels, statistics are calculated in userland (which means you don't know how many packets were discarded because they didn't match the filter, if the filtering is being done in the kernel (as is the case in 2.2 and later kernels, at least if socket filters are enabled in the kernel), and just keep accumulating;

in 2.4 and later kernels, statistics come from the kernel, and are reset when fetched from the kernel. Really old versions of libpcap (pre-0.7) didn't know that, and treated them like pre-2.4 kernels; "middle-aged" versions of libpcap (0.7[.x] and 0.8[.x]) fetched statistics from the kernel, but didn't compensate for this by keeping its own copy of the statistics, adding the fetched values to that copy, and returning the accumulated values as the statistics; libpcap 0.9.0 and later do that (0.9.0 through 0.9.4 had some bugs in that, fixed in 0.9.5).

On Windows, at least with WinPcap 4.x, statistics come from the kernel, and are not reset when fetched from the kernel.

On other OSes, statistics are calculated in userland and just keep accumulating.

So the unusual case is Linux systems with

a 2.4 or later kernel and libpcap was built on a system with a newer kernel (and glibc?) so that it tries to fetch statistics from the kernel

and

	libpcap 0.7[.x] and 0.8[.x]

where code that assumes that statistics fetched from libpcap are cumulative (which they are supposed to be!) will break.

The "XXX" in the comment before update_if() is mine; I have no idea why the claim was made that, in winpcap, pcap_stats() "returns the number of packets since the last pcap_stats call".