aboutsummaryrefslogtreecommitdiffstats
path: root/caputils/capture-pcap-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'caputils/capture-pcap-util.c')
-rw-r--r--caputils/capture-pcap-util.c68
1 files changed, 61 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)