tcpdump mailing list archives

libpcap support for nanosecond resolution timestamps?


From: Andy Fingerhut <andy.fingerhut () gmail com>
Date: Mon, 28 Nov 2011 14:02:09 -0800

libpcap has had support for pcap ng files since early 2010.  Such
files can contain timestamps with resolutions more precise than
microseconds.  From my reading of the code, it appears that when
libpcap reads from such a file, it converts the fractional time values
to units of microseconds, since that is what a struct timeval is
documented to contain in its tv_usec field.

libpcap also has a #define NSEC_TCPDUMP_MAGIC for pre-ng pcap format
files that have nanosecond resolution timestamps rather than
microseconds.  It appears that libpcap 1.2.0 does not support such
files right now.  I suppose if it did, to be consistent it would do
what reading a pcap ng file with nanosecond resolution timestamps does
-- convert to microsec in the libpcap API.

I haven't looked in detail, but would guess there are platforms
supporting live packet capture that similarly lose timestamp precision
due to the libpcap API definition.

Has any thought been given to extending the libpcap API so that the
caller can choose to get nanosecond resolution timestamps?  Or perhaps
"the best the underlying savefile / hardware supports?"  The former
would be a simpler extension to the libpcap API to define, implement,
and support than the latter.  Either would be nice for supporting more
precise time values on high speed links.  A 10 gigabit Ethernet link
can send 1250 bytes in a microsecond, which could be many small
packets.

Below are some quick thoughts on how the libpcap API might be extended
for the simpler case, i.e. adding an option only for a
caller-specified timestamp resolution.  I'm open to suggestions if it
is too complex, either in implementation within libpcap itself, or for
the libpcap users.  I am at least part-way through implementing it
(for reading pcap files using libpcap), and the changes are not huge
yet.

First, the default behavior of the libpcap API is to behave exactly as
it does today: struct timeval's contain two integers, one specifying
whole seconds, the other specifying microseconds.

A pcap_t *p created by any of the pcap_open_* calls can be used as an
argument to the new function:

int pcap_set_tv_usec_resolution(
pcap_t *p, int tv_usec_resol);

I am most interested in using this for pcap_t's created with
pcap_open_offline(), where the pcap_t is already activated before the
call returns, so unless there are better ideas, it seems like a good
idea to permit pcap_set_tv_usec_resolution() to be called at any time
on a pcap_t, not only before it is activated.  The documentation could
strongly recommend calling it before doing any packet I/O calls.

The intent is that the two most likely values for tv_usec_resol would
be 10^6 or 10^9, but perhaps allowing other values in between would be
OK.  10^10 would be too large, since it doesn't fit in a 32-bit int,
the size of the tv_usec field on most platforms, I believe.

If pcap_set_tv_usec_resolution() is called and returns success, all
future calls involving p and a pcap_pkthdr structure will use an
integer value tv_usec that are multiples of (1/tv_usec_resol).  There
is no promise that a successful return implies that the underlying
network device or file supports that particular resolution in
capturing, reading, or writing.  During capturing or reading, the
'native' resolution will be converted to the specified resolution.
During packet injection or writing, the specified resolution will be
converted to the best resolution supported by the file format or
device.

Thus the only reasons I can think of for pcap_set_tv_usec_resolution()
to fail would be if p is an invalid pointer, doesn't point at a pcap_t
properly initialized by one of the pcap_open_* calls.

Comments?

Thanks,
Andy Fingerhut
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: