Add support for getting nanosecond time stamp resolution when capturing.

If we have pcap_set_tstamp_precision(), use it to request nanosecond
time stamp resolution *if* we're writing a pcap-ng file; any code that
reads those files and can't handle nanosecond time stamp resolution is
broken and needs to be fixed.

If we're writing a pcap file, don't ask for nanosecond resolution time
stamps, as that requires a different magic number for pcap files, and
not all code that reads pcap files can handle that.  (Unlike pcap-ng,
where the ability to have non-microsecond time stamp resolution was
present from Day One, it's a relatively recent addition to pcap.)  We
could add a command-line option/GUI option for that, like the option
recent versions of tcpdump have, if it matters.

Change-Id: I8fa464eb929feecb9a70be70712502c9f0cc5270
Reviewed-on: https://code.wireshark.org/review/4355
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2014-09-28 16:28:36 -07:00
parent f6b9e7a79e
commit 392c41ce30
4 changed files with 37 additions and 2 deletions

View File

@ -627,7 +627,7 @@ install a newer version of the header file.])
AC_CHECK_FUNCS(pcap_datalink_val_to_description)
AC_CHECK_FUNCS(pcap_list_datalinks pcap_set_datalink pcap_lib_version)
AC_CHECK_FUNCS(pcap_get_selectable_fd pcap_free_datalinks)
AC_CHECK_FUNCS(pcap_create bpf_image)
AC_CHECK_FUNCS(pcap_create bpf_image pcap_set_tstamp_precision)
fi
LIBS="$ac_save_LIBS"
])

View File

@ -77,6 +77,7 @@ check_function_exists( "pcap_list_datalinks" HAVE_PCAP_LIST_DATALINKS )
check_function_exists( "pcap_set_datalink" HAVE_PCAP_SET_DATALINK )
check_function_exists( "bpf_image" HAVE_BPF_IMAGE )
check_function_exists( "pcap_setsampling" HAVE_PCAP_SETSAMPLING )
check_function_exists( "pcap_set_tstamp_precision" HAVE_PCAP_SET_TSTAMP_PRECISION )
# Remote pcap checks
check_function_exists( "pcap_open" HAVE_PCAP_OPEN )
check_function_exists( "pcap_findalldevs_ex" H_FINDALLDEVS_EX )

View File

@ -230,9 +230,12 @@
/* Define to 1 if you have the `pcap_set_datalink' function. */
#cmakedefine HAVE_PCAP_SET_DATALINK 1
/* Define to 1 if you have the `pcap_setsampling" function. */
/* Define to 1 if you have the `pcap_setsampling' function. */
#cmakedefine HAVE_PCAP_SETSAMPLING 1
/* Define to 1 if you have the `pcap_set_tstamp_precision' function. */
#cmakedefine HAVE_PCAP_SET_TSTAMP_PRECISION 1
/* Define to 1 if you have the <portaudio.h> header file. */
#cmakedefine HAVE_PORTAUDIO_H 1

View File

@ -714,6 +714,31 @@ open_capture_device(interface_options *interface_opts,
pcap_set_promisc(pcap_h, interface_opts->promisc_mode);
pcap_set_timeout(pcap_h, CAP_READ_TIMEOUT);
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
/*
* If we're writing pcap-ng files, try to enable
* nanosecond-resolution capture; any code that
* can read pcap-ng files must be able to handle
* nanosecond-resolution time stamps.
*
* If we're writing pcap files, don't try to enable
* nanosecond-resolution capture, as not all code
* that reads pcap files recognizes the nanosecond-
* resolution pcap file magic number.
*/
if (capture_opts->use_pcapng) {
/*
* The only errors this is documenting as returning
* are PCAP_ERROR_TSTAMP_PRECISION_NOTSUP, which just
* means we can't do nanosecond precision on this adapter,
* in which case we just live with whatever resolution
* we get by default, and PCAP_ERROR_ACTIVATED, which
* can't happen as we haven't activated the pcap_t yet.
*/
pcap_set_tstamp_precision(pcap_h, PCAP_TSTAMP_PRECISION_NANO);
}
#endif
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
"buffersize %d.", interface_opts->buffer_size);
if (interface_opts->buffer_size != 0) {
@ -2638,6 +2663,12 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
if (pcap_opts->pcap_h != NULL) {
/* we've opened "iface" as a network device */
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
/* Find out if we're getting nanosecond-precision time stamps */
pcap_opts->ts_nsec = pcap_get_tstamp_precision(pcap_opts->pcap_h) == PCAP_TSTAMP_PRECISION_NANO;
#endif
#ifdef _WIN32
/* try to set the capture buffer size */
if (interface_opts.buffer_size > 1 &&