aboutsummaryrefslogtreecommitdiffstats
path: root/caputils
diff options
context:
space:
mode:
authorAhmad Fatoum <ahmad.fatoum@siemens.com>2017-08-07 16:38:52 +0200
committerAnders Broman <a.broman58@gmail.com>2017-08-22 07:55:26 +0000
commitaca55a29f7b982e7a0bd9911d1d176561c8d7a84 (patch)
tree35b4f2b92ba79f49d26ebb06ae805e9eb6f4e4ac /caputils
parent2845f6be8db0b1720e23db0877ec837f00967bdc (diff)
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.c68
-rw-r--r--caputils/capture_ifinfo.h9
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.
*/