diff options
author | Ahmad Fatoum <ahmad.fatoum@siemens.com> | 2017-08-07 16:38:52 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2017-08-22 07:55:26 +0000 |
commit | aca55a29f7b982e7a0bd9911d1d176561c8d7a84 (patch) | |
tree | 35b4f2b92ba79f49d26ebb06ae805e9eb6f4e4ac /caputils | |
parent | 2845f6be8db0b1720e23db0877ec837f00967bdc (diff) | |
download | wireshark-aca55a29f7b982e7a0bd9911d1d176561c8d7a84.tar.gz wireshark-aca55a29f7b982e7a0bd9911d1d176561c8d7a84.tar.bz2 wireshark-aca55a29f7b982e7a0bd9911d1d176561c8d7a84.zip |
Add hardware timestamping support
pcap provides a pcap_set_tstamp_type function, which can be used to request
hardware timestamps from a supporting kernel.
This patch adds support for aforementioned function as well as two new
command line options to dumpcap, wireshark and tshark:
--list-time-stamp-types
List time stamp types supported for the interface
--time-stamp-type <type>
Change the interface's timestamp method
Name choice mimics those used by tcpdump(1), which already supports this
feature. However, unlike tcpdump, we provide both options unconditionally.
If Wireshark was configured without pcap_set_tstamp_type being available,
--list-time-stamp-types reports an empty list.
Change-Id: I418a4b2b84cb01949cd262aad0ad8427f5ac0652
Signed-off-by: Ahmad Fatoum <ahmad.fatoum@siemens.com>
Reviewed-on: https://code.wireshark.org/review/23113
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'caputils')
-rw-r--r-- | caputils/capture-pcap-util.c | 68 | ||||
-rw-r--r-- | caputils/capture_ifinfo.h | 9 |
2 files changed, 70 insertions, 7 deletions
diff --git a/caputils/capture-pcap-util.c b/caputils/capture-pcap-util.c index 4da5579e3d..07d7db06f7 100644 --- a/caputils/capture-pcap-util.c +++ b/caputils/capture-pcap-util.c @@ -668,11 +668,24 @@ free_linktype_cb(gpointer data, gpointer user_data _U_) g_free(linktype_info); } +static void +free_timestamp_cb(gpointer data, gpointer user_data _U_) +{ + /* timestamp_info_t's contents are immutable and in static memory, + * so we only need to free the struct itself + */ + g_free(data); +} + void free_if_capabilities(if_capabilities_t *caps) { g_list_foreach(caps->data_link_types, free_linktype_cb, NULL); g_list_free(caps->data_link_types); + + g_list_foreach(caps->timestamp_types, free_timestamp_cb, NULL); + g_list_free(caps->timestamp_types); + g_free(caps); } @@ -861,10 +874,7 @@ create_data_link_info(int dlt) else data_link_info->name = g_strdup_printf("DLT %d", dlt); text = pcap_datalink_val_to_description(dlt); - if (text != NULL) - data_link_info->description = g_strdup(text); - else - data_link_info->description = NULL; + data_link_info->description = g_strdup(text); return data_link_info; } @@ -960,6 +970,34 @@ get_data_link_types(pcap_t *pch, interface_options *interface_opts, return data_link_types; } +/* Get supported timestamp types for a libpcap device. */ +static GList* +get_pcap_timestamp_types(pcap_t *pch _U_, char **err_str _U_) +{ + GList *list = NULL; +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + int *types; + int ntypes = pcap_list_tstamp_types(pch, &types); + + if (err_str) + *err_str = ntypes < 0 ? pcap_geterr(pch) : NULL; + + if (ntypes <= 0) + return NULL; + + while (ntypes--) { + timestamp_info_t *info = (timestamp_info_t *)g_malloc(sizeof *info); + info->name = pcap_tstamp_type_val_to_name(types[ntypes]); + info->description = pcap_tstamp_type_val_to_description(types[ntypes]); + list = g_list_prepend(list, info); + } + + pcap_free_tstamp_types(types); +#endif + return list; +} + + #ifdef HAVE_PCAP_CREATE #ifdef HAVE_BONDING static gboolean @@ -1079,6 +1117,8 @@ get_if_capabilities_pcap_create(interface_options *interface_opts, return NULL; } + caps->timestamp_types = get_pcap_timestamp_types(pch, NULL); + pcap_close(pch); if (err_str != NULL) @@ -1088,7 +1128,7 @@ get_if_capabilities_pcap_create(interface_options *interface_opts, pcap_t * open_capture_device_pcap_create(capture_options *capture_opts -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION +#if defined(HAVE_PCAP_SET_TSTAMP_PRECISION) || defined (HAVE_PCAP_SET_TSTAMP_TYPE) , #else _U_, @@ -1141,6 +1181,18 @@ open_capture_device_pcap_create(capture_options *capture_opts request_high_resolution_timestamp(pcap_h); #endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (interface_opts->timestamp_type) { + err = pcap_set_tstamp_type(pcap_h, interface_opts->timestamp_type_id); + if (err == PCAP_ERROR) { + g_strlcpy(*open_err_str, pcap_geterr(pcap_h), + sizeof *open_err_str); + pcap_close(pcap_h); + return NULL; + } + } +#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "buffersize %d.", interface_opts->buffer_size); if (interface_opts->buffer_size != 0) @@ -1195,6 +1247,8 @@ get_if_capabilities_pcap_open_live(interface_options *interface_opts, return NULL; } + caps->timestamp_types = get_pcap_timestamp_types(pch, NULL); + pcap_close(pch); if (err_str != NULL) @@ -1295,8 +1349,8 @@ get_if_capabilities(interface_options *interface_opts, char **err_str) caps->data_link_types = NULL; deflt = get_pcap_datalink(pch, interface_opts->name); data_link_info = create_data_link_info(deflt); - caps->data_link_types = g_list_append(caps->data_link_types, - data_link_info); + caps->data_link_types = g_list_append(caps->data_link_types, data_link_info); + caps->timestamp_types = get_pcap_timestamp_types(pch, NULL); pcap_close(pch); if (err_str != NULL) diff --git a/caputils/capture_ifinfo.h b/caputils/capture_ifinfo.h index 16ae28fd51..48c54feec8 100644 --- a/caputils/capture_ifinfo.h +++ b/caputils/capture_ifinfo.h @@ -99,6 +99,7 @@ void free_interface_list(GList *if_list); typedef struct { gboolean can_set_rfmon; /* TRUE if can be put into monitor mode */ GList *data_link_types; /* GList of data_link_info_t's */ + GList *timestamp_types; /* GList of timestamp_info_t's */ } if_capabilities_t; /* @@ -110,6 +111,14 @@ typedef struct { char *description; /* descriptive name from wiretap e.g. "Ethernet", NULL if unknown */ } data_link_info_t; +/* + * Information about timestamp types. + */ +typedef struct { + const char *name; /* e.g. "adapter_unsynced" */ + const char *description; /* description from libpcap e.g. "Adapter, not synced with system time" */ +} timestamp_info_t; + /** * Fetch the linktype list for the specified interface from a child process. */ |