diff options
-rw-r--r-- | caputils/capture-pcap-util-unix.c | 64 | ||||
-rw-r--r-- | caputils/capture-pcap-util.h | 8 | ||||
-rw-r--r-- | dumpcap.c | 15 |
3 files changed, 68 insertions, 19 deletions
diff --git a/caputils/capture-pcap-util-unix.c b/caputils/capture-pcap-util-unix.c index 8aae100c33..33047317d5 100644 --- a/caputils/capture-pcap-util-unix.c +++ b/caputils/capture-pcap-util-unix.c @@ -26,11 +26,13 @@ #ifdef HAVE_LIBPCAP -#ifdef HAVE_PCAP_FINDALLDEVS - #include <pcap.h> -#else /* HAVE_PCAP_FINDALLDEVS */ +#ifdef __APPLE__ +#include <dlfcn.h> +#endif + +#ifndef HAVE_PCAP_FINDALLDEVS #include <stdlib.h> #include <string.h> @@ -60,8 +62,6 @@ struct rtentry; # include <sys/sockio.h> #endif -#include "caputils/capture-pcap-util.h" - #endif /* HAVE_PCAP_FINDALLDEVS */ #ifdef HAVE_LIBCAP @@ -334,6 +334,60 @@ cant_get_if_list_error_message(const char *err_str) return g_strdup_printf("Can't get list of interfaces: %s", err_str); } +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION +/* + * Request high-resolution time stamps. + * + * We don't check for errors - if this fails, we just live with boring old + * microsecond-resolution time stamps. The only errors pcap_set_tstamp_precision() + * 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 shouldn't happen as we shouldn't call this + * after we've activated the pcap_t. + */ +void +request_high_resolution_timestamp(pcap_t *pcap_h) +{ +#ifdef __APPLE__ + /* + * On OS X, if you build with a newer SDK, pcap_set_tstamp_precision() + * is available, so the code will be built with it. + * + * However, if you then try to run on an older release that + * doesn't have pcap_set_tstamp_precision(), the dynamic linker + * will fail, as it won't find pcap_set_tstamp_precision(). + * + * libpcap doesn't use OS X "weak linking" for new routines, + * so we can't just check whether a pointer to + * pcap_set_tstamp_precision() is null and, if it is, not + * call it. We have to, instead, use dlopen() to load + * libpcap, and dlsym() to find a pointer to pcap_set_tstamp_precision(), + * and if we find the pointer, call it. + */ + static gboolean initialized = FALSE; + static void *libpcap_handle; + static int (*p_pcap_set_tstamp_precision)(pcap_t *, int); + + if (!initialized) { + p_pcap_set_tstamp_precision = + (int (*)(pcap_t *, int)) + dlsym(RTLD_NEXT, "pcap_set_tstamp_precision"); + initialized = TRUE; + } + if (p_pcap_set_tstamp_precision != NULL) + (*p_pcap_set_tstamp_precision)(pcap_h, PCAP_TSTAMP_PRECISION_NANO); +#else /* __APPLE__ */ + /* + * On other UN*Xes we require that we be run on an OS version + * with a libpcap equal to or later than the version with which + * we were built. + */ + pcap_set_tstamp_precision(pcap_h, PCAP_TSTAMP_PRECISION_NANO); +#endif /* __APPLE__ */ +} +#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ + /* * Get the versions of libpcap, libpcap, and libnl with which we were * compiled, and append them to a GString. diff --git a/caputils/capture-pcap-util.h b/caputils/capture-pcap-util.h index 617bcc82e5..079e3fabd7 100644 --- a/caputils/capture-pcap-util.h +++ b/caputils/capture-pcap-util.h @@ -50,12 +50,16 @@ GList *get_remote_interface_list(const char *hostname, const char *port, const char *linktype_val_to_name(int dlt); int linktype_name_to_val(const char *linktype); -#endif /* HAVE_LIBPCAP */ - +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION /* * Get the versions of capture libraries with which we were compiled, * and append them to a GString. */ +void request_high_resolution_timestamp(pcap_t *pcap_h); +#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ + +#endif /* HAVE_LIBPCAP */ + extern void get_compiled_caplibs_version(GString *str); /* @@ -730,18 +730,9 @@ open_capture_device(capture_options *capture_opts * 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 + if (capture_opts->use_pcapng) + request_high_resolution_timestamp(pcap_h); +#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "buffersize %d.", interface_opts->buffer_size); |