diff options
Diffstat (limited to 'caputils/capture-pcap-util.c')
-rw-r--r-- | caputils/capture-pcap-util.c | 68 |
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) |