Discussion:
libpcap 1.5.3 pcap_open_offline_with_tstamp_precision() broken
Steffen Bauch
2014-06-05 17:21:26 UTC
Permalink
Hi,

libpcap 1.5.3 (as deployed in Ubuntu 14.04 LTS) (and current GIT master
head) will not output timestamps in a right way if pcapng savefiles are
used and timestamp conversion is requested with
pcap_open_offline_with_tstamp_precision(). For traditional pcap files
necessary timestamp conversion will work in a right way.

To reproduce this problem:

1. Capture a network trace with dumpcap as pcapng file

dumpcap -i eth0 -w timestamp_problem.pcapng

per default this capture will have microsecond timestamp resolution

2. Open the file with pcap_open_offline_with_tstamp_precision(filename,
PCAP_TSTAMP_PRECISION_NANO, errbuf);

3. Retrieve frames with pcap_dispatch and a callback function and print
the content of the timevals (sec and usec).

All frames retrieved will have subsecond timestamps between 0 and 999,
which is wrong.

4. Convert the file from pcapng to pcap

editcap timestamp_problem.pcapng timestamp_working.pcap -F pcap

5. Perform steps 2 and 3 for the pcap file and see correct subsecond
timestamps in nanosecond range 0 - 999999999

The reason for the problem is a wrong computation of the scaling factor
in pcap_ng_next_packet in sf-pcap-ng.c

Assume you have a file with microsecond resolution and request
nanosecond output. In this case you will be required to scale the value
up for representation purposes. But the code will perform the following:

frac *= ps->ifaces[interface_id].tsresol; /* resolution
of the interface: multiply with a small value: 1000000 */
frac /= ps->user_tsresol; /* requested output
resolution, divide with a large value: 1000000000 */

This will lead to an overall downscaling of the fractional part, an
overall division by factor 1000 which doesn't seem to be right. In my
opinion the code should multiply with the output resolution and divide
by the interface resolution.

frac *= ps->user_tsresol; /* requested output resolution, multiply
with a large value: 1000000000 */
frac /= ps->ifaces[interface_id].tsresol; /* resolution
of the interface: divide with a small value: 1000000 */

Best regards,

Steffen
--
Web: http://datenkobold.de Twitter: @steffenbauch
Michal Sekletar
2014-06-06 10:24:19 UTC
Permalink
Post by Steffen Bauch
Hi,
libpcap 1.5.3 (as deployed in Ubuntu 14.04 LTS) (and current GIT
master head) will not output timestamps in a right way if pcapng
savefiles are used and timestamp conversion is requested with
pcap_open_offline_with_tstamp_precision(). For traditional pcap
files necessary timestamp conversion will work in a right way.
1. Capture a network trace with dumpcap as pcapng file
dumpcap -i eth0 -w timestamp_problem.pcapng
per default this capture will have microsecond timestamp resolution
2. Open the file with
pcap_open_offline_with_tstamp_precision(filename,
PCAP_TSTAMP_PRECISION_NANO, errbuf);
3. Retrieve frames with pcap_dispatch and a callback function and
print the content of the timevals (sec and usec).
All frames retrieved will have subsecond timestamps between 0 and
999, which is wrong.
4. Convert the file from pcapng to pcap
editcap timestamp_problem.pcapng timestamp_working.pcap -F pcap
5. Perform steps 2 and 3 for the pcap file and see correct subsecond
timestamps in nanosecond range 0 - 999999999
The reason for the problem is a wrong computation of the scaling
factor in pcap_ng_next_packet in sf-pcap-ng.c
Assume you have a file with microsecond resolution and request
nanosecond output. In this case you will be required to scale the
value up for representation purposes. But the code will perform the
frac *= ps->ifaces[interface_id].tsresol; /*
resolution of the interface: multiply with a small value: 1000000 */
frac /= ps->user_tsresol; /* requested output
resolution, divide with a large value: 1000000000 */
This will lead to an overall downscaling of the fractional part, an
overall division by factor 1000 which doesn't seem to be right. In
my opinion the code should multiply with the output resolution and
divide by the interface resolution.
frac *= ps->user_tsresol; /* requested output resolution, multiply
with a large value: 1000000000 */
frac /= ps->ifaces[interface_id].tsresol; /*
resolution of the interface: divide with a small value: 1000000 */
Thanks for reporting this. I tested your patch and I can confirm it fixes the
issue. Can you please open pull request and submit your patch via github?
Post by Steffen Bauch
Best regards,
Steffen
Cheers,

Michal
Post by Steffen Bauch
--
_______________________________________________
tcpdump-workers mailing list
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
Loading...