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 | |
parent | 2845f6be8db0b1720e23db0877ec837f00967bdc (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>
-rw-r--r-- | acinclude.m4 | 2 | ||||
-rw-r--r-- | capchild/capture_ifinfo.c | 35 | ||||
-rw-r--r-- | capchild/capture_sync.c | 5 | ||||
-rw-r--r-- | capture_opts.c | 64 | ||||
-rw-r--r-- | capture_opts.h | 37 | ||||
-rw-r--r-- | caputils/capture-pcap-util.c | 68 | ||||
-rw-r--r-- | caputils/capture_ifinfo.h | 9 | ||||
-rw-r--r-- | cmake/modules/FindPCAP.cmake | 1 | ||||
-rw-r--r-- | cmakeconfig.h.in | 3 | ||||
-rw-r--r-- | doc/dumpcap.pod | 14 | ||||
-rw-r--r-- | doc/tshark.pod | 11 | ||||
-rw-r--r-- | doc/wireshark.pod.template | 11 | ||||
-rw-r--r-- | docbook/release-notes.asciidoc | 1 | ||||
-rw-r--r-- | docbook/wsug_src/WSUG_app_tools.asciidoc | 4 | ||||
-rw-r--r-- | docbook/wsug_src/WSUG_chapter_customize.asciidoc | 16 | ||||
-rw-r--r-- | dumpcap.c | 98 | ||||
-rw-r--r-- | extcap.c | 1 | ||||
-rw-r--r-- | tshark.c | 37 | ||||
-rw-r--r-- | ui/commandline.c | 23 | ||||
-rw-r--r-- | ui/commandline.h | 1 | ||||
-rw-r--r-- | ui/gtk/main.c | 20 | ||||
-rw-r--r-- | wireshark-qt.cpp | 20 |
22 files changed, 379 insertions, 102 deletions
diff --git a/acinclude.m4 b/acinclude.m4 index 44545f6c1e..c76d2bf7d7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -412,7 +412,7 @@ install a newer version of the header file.]) AC_DEFINE(CAN_SET_CAPTURE_BUFFER_SIZE, 1, [Define to 1 if the capture buffer size can be set.]) ]) - AC_CHECK_FUNCS(bpf_image pcap_set_tstamp_precision) + AC_CHECK_FUNCS(bpf_image pcap_set_tstamp_precision pcap_set_tstamp_type) fi AC_WIRESHARK_POP_FLAGS diff --git a/capchild/capture_ifinfo.c b/capchild/capture_ifinfo.c index e3773f512b..d158cabe81 100644 --- a/capchild/capture_ifinfo.c +++ b/capchild/capture_ifinfo.c @@ -228,11 +228,10 @@ capture_get_if_capabilities(const gchar *ifname, gboolean monitor_mode, char **err_str, void (*update_cb)(void)) { if_capabilities_t *caps; - GList *linktype_list = NULL; + GList *linktype_list = NULL, *timestamp_list = NULL; int err, i; gchar *data, *primary_msg, *secondary_msg; - gchar **raw_list, **lt_parts; - data_link_info_t *data_link_info; + gchar **raw_list; g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities ..."); @@ -309,11 +308,12 @@ capture_get_if_capabilities(const gchar *ifname, gboolean monitor_mode, } /* - * The rest are link-layer types. + * The following are link-layer types. */ - for (i = 1; raw_list[i] != NULL; i++) { + for (i = 1; raw_list[i] != NULL && *raw_list[i] != '\0'; i++) { + data_link_info_t *data_link_info; /* ...and what if the interface name has a tab in it, Mr. Clever Programmer? */ - lt_parts = g_strsplit(raw_list[i], "\t", 3); + char **lt_parts = g_strsplit(raw_list[i], "\t", 3); if (lt_parts[0] == NULL || lt_parts[1] == NULL || lt_parts[2] == NULL) { g_strfreev(lt_parts); continue; @@ -330,6 +330,25 @@ capture_get_if_capabilities(const gchar *ifname, gboolean monitor_mode, linktype_list = g_list_append(linktype_list, data_link_info); } + + if (raw_list[i]) { /* Oh, timestamp types! */ + for (i++; raw_list[i] != NULL && *raw_list[i] != '\0'; i++) { + timestamp_info_t *timestamp_info; + char **tt_parts = g_strsplit(raw_list[i], "\t", 2); + if (tt_parts[0] == NULL || tt_parts[1] == NULL) { + g_strfreev(tt_parts); + continue; + } + + timestamp_info = g_new(timestamp_info_t,1); + timestamp_info->name = g_strdup(tt_parts[0]); + timestamp_info->description = g_strdup(tt_parts[1]); + g_strfreev(tt_parts); + + timestamp_list = g_list_append(timestamp_list, timestamp_info); + } + } + g_strfreev(raw_list); /* Check to see if we built a list */ @@ -340,7 +359,11 @@ capture_get_if_capabilities(const gchar *ifname, gboolean monitor_mode, g_free(caps); return NULL; } + caps->data_link_types = linktype_list; + /* Might be NULL. Not all systems report timestamp types */ + caps->timestamp_types = timestamp_list; + return caps; } diff --git a/capchild/capture_sync.c b/capchild/capture_sync.c index 96911bddae..9f3d0ca0b9 100644 --- a/capchild/capture_sync.c +++ b/capchild/capture_sync.c @@ -412,6 +412,10 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, inf argv = sync_pipe_add_arg(argv, &argc, ssampling); } #endif + if (interface_opts.timestamp_type) { + argv = sync_pipe_add_arg(argv, &argc, "--time-stamp-type"); + argv = sync_pipe_add_arg(argv, &argc, interface_opts.timestamp_type); + } } /* dumpcap should be running in capture child mode (hidden feature) */ @@ -1302,6 +1306,7 @@ sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode, const gcha argv = sync_pipe_add_arg(argv, &argc, "-i"); argv = sync_pipe_add_arg(argv, &argc, ifname); argv = sync_pipe_add_arg(argv, &argc, "-L"); + argv = sync_pipe_add_arg(argv, &argc, "--list-time-stamp-types"); if (monitor_mode) argv = sync_pipe_add_arg(argv, &argc, "-I"); if (auth) { diff --git a/capture_opts.c b/capture_opts.c index 92175ff78b..a5470904c2 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -90,6 +90,7 @@ capture_opts_init(capture_options *capture_opts) capture_opts->default_options.sampling_method = CAPTURE_SAMP_NONE; capture_opts->default_options.sampling_param = 0; #endif + capture_opts->default_options.timestamp_type = NULL; capture_opts->saving_to_file = FALSE; capture_opts->save_file = NULL; capture_opts->group_read_access = FALSE; @@ -193,6 +194,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio g_log(log_domain, log_level, "Sampling meth.[%02d] : %d", i, interface_opts.sampling_method); g_log(log_domain, log_level, "Sampling param.[%02d] : %d", i, interface_opts.sampling_param); #endif + g_log(log_domain, log_level, "Timestamp type [%02d] : %s", i, interface_opts.timestamp_type); } g_log(log_domain, log_level, "Interface name[df] : %s", capture_opts->default_options.name ? capture_opts->default_options.name : "(unspecified)"); g_log(log_domain, log_level, "Interface Descr[df] : %s", capture_opts->default_options.descr ? capture_opts->default_options.descr : "(unspecified)"); @@ -233,6 +235,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio g_log(log_domain, log_level, "Sampling meth. [df] : %d", capture_opts->default_options.sampling_method); g_log(log_domain, log_level, "Sampling param.[df] : %d", capture_opts->default_options.sampling_param); #endif + g_log(log_domain, log_level, "Timestamp type [df] : %s", capture_opts->default_options.timestamp_type ? capture_opts->default_options.timestamp_type : "(unspecified)"); g_log(log_domain, log_level, "SavingToFile : %u", capture_opts->saving_to_file); g_log(log_domain, log_level, "SaveFile : %s", (capture_opts->save_file) ? capture_opts->save_file : ""); g_log(log_domain, log_level, "GroupReadAccess : %u", capture_opts->group_read_access); @@ -732,6 +735,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str interface_opts.sampling_method = capture_opts->default_options.sampling_method; interface_opts.sampling_param = capture_opts->default_options.sampling_param; #endif + interface_opts.timestamp_type = capture_opts->default_options.timestamp_type; g_array_append_val(capture_opts->ifaces, interface_opts); @@ -800,6 +804,18 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_ case 'H': /* Hide capture info dialog box */ capture_opts->show_info = FALSE; break; + case LONGOPT_SET_TSTAMP_TYPE: /* Set capture time stamp type */ + if (capture_opts->ifaces->len > 0) { + interface_options interface_opts; + + interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); + capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); + interface_opts.timestamp_type = g_strdup(optarg_str_p); + g_array_append_val(capture_opts->ifaces, interface_opts); + } else { + capture_opts->default_options.timestamp_type = g_strdup(optarg_str_p); + } + break; case 'i': /* Use interface x */ status = capture_opts_add_iface_opt(capture_opts, optarg_str_p); if (status != 0) { @@ -939,26 +955,40 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_ } void -capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name, - gboolean monitor_mode) +capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name, int queries) { - GList *lt_entry; - data_link_info_t *data_link_info; + GList *lt_entry, *ts_entry; - if (caps->can_set_rfmon) - printf("Data link types of interface %s when %sin monitor mode (use option -y to set):\n", - name, monitor_mode ? "" : "not "); - else - printf("Data link types of interface %s (use option -y to set):\n", name); - for (lt_entry = caps->data_link_types; lt_entry != NULL; - lt_entry = g_list_next(lt_entry)) { - data_link_info = (data_link_info_t *)lt_entry->data; - printf(" %s", data_link_info->name); - if (data_link_info->description != NULL) - printf(" (%s)", data_link_info->description); + if (queries & CAPS_QUERY_LINK_TYPES) { + if (caps->can_set_rfmon) + printf("Data link types of interface %s when %sin monitor mode (use option -y to set):\n", + name, queries & CAPS_MONITOR_MODE ? "" : "not "); else - printf(" (not supported)"); - printf("\n"); + printf("Data link types of interface %s (use option -y to set):\n", name); + for (lt_entry = caps->data_link_types; lt_entry != NULL; + lt_entry = g_list_next(lt_entry)) { + data_link_info_t *data_link_info = (data_link_info_t *)lt_entry->data; + printf(" %s", data_link_info->name); + if (data_link_info->description != NULL) + printf(" (%s)", data_link_info->description); + else + printf(" (not supported)"); + printf("\n"); + } + } + + if (queries & CAPS_QUERY_TIMESTAMP_TYPES) { + printf("Timestamp types of the interface (use option --time-stamp-type to set):\n"); + for (ts_entry = caps->timestamp_types; ts_entry != NULL; + ts_entry = g_list_next(ts_entry)) { + timestamp_info_t *timestamp = (timestamp_info_t *)ts_entry->data; + printf(" %s", timestamp->name); + if (timestamp->description != NULL) + printf(" (%s)", timestamp->description); + else + printf(" (none)"); + printf("\n"); + } } } diff --git a/capture_opts.h b/capture_opts.h index 2fc04a339c..c3b830e3b3 100644 --- a/capture_opts.h +++ b/capture_opts.h @@ -60,7 +60,9 @@ extern "C" { * In short: we must not use 1 here, which is another reason to use * values outside the range of ASCII graphic characters. */ -#define LONGOPT_NUM_CAP_COMMENT 128 +#define LONGOPT_NUM_CAP_COMMENT 128 +#define LONGOPT_LIST_TSTAMP_TYPES 129 +#define LONGOPT_SET_TSTAMP_TYPE 130 /* * Options for capturing common to all capturing programs. @@ -89,17 +91,20 @@ extern "C" { #endif #define LONGOPT_CAPTURE_COMMON \ - {"capture-comment", required_argument, NULL, LONGOPT_NUM_CAP_COMMENT}, \ - {"autostop", required_argument, NULL, 'a'}, \ - {"ring-buffer", required_argument, NULL, 'b'}, \ + {"capture-comment", required_argument, NULL, LONGOPT_NUM_CAP_COMMENT}, \ + {"autostop", required_argument, NULL, 'a'}, \ + {"ring-buffer", required_argument, NULL, 'b'}, \ LONGOPT_BUFFER_SIZE \ - {"list-interfaces", no_argument, NULL, 'D'}, \ - {"interface", required_argument, NULL, 'i'}, \ + {"list-interfaces", no_argument, NULL, 'D'}, \ + {"interface", required_argument, NULL, 'i'}, \ LONGOPT_MONITOR_MODE \ - {"list-data-link-types", no_argument, NULL, 'L'}, \ - {"no-promiscuous-mode", no_argument, NULL, 'p'}, \ - {"snapshot-length", required_argument, NULL, 's'}, \ - {"linktype", required_argument, NULL, 'y'}, \ + {"list-data-link-types", no_argument, NULL, 'L'}, \ + {"no-promiscuous-mode", no_argument, NULL, 'p'}, \ + {"snapshot-length", required_argument, NULL, 's'}, \ + {"linktype", required_argument, NULL, 'y'}, \ + {"list-time-stamp-types", no_argument, NULL, LONGOPT_LIST_TSTAMP_TYPES}, \ + {"time-stamp-type", required_argument, NULL, LONGOPT_SET_TSTAMP_TYPE}, + #define OPTSTRING_CAPTURE_COMMON \ "a:" OPTSTRING_A "b:" OPTSTRING_B "c:Df:i:" OPTSTRING_I "Lps:y:" @@ -248,6 +253,9 @@ typedef struct interface_options_tag { capture_sampling sampling_method; int sampling_param; #endif + gchar *timestamp_type; /* requested timestamp as string */ + int timestamp_type_id; /* Timestamp type to pass to pcap_set_tstamp_type. + only valid if timestamp_type != NULL */ } interface_options; /** Capture options coming from user interface */ @@ -342,10 +350,15 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg, extern void capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts); +enum caps_query { + CAPS_MONITOR_MODE = 0x1, + CAPS_QUERY_LINK_TYPES = 0x2, + CAPS_QUERY_TIMESTAMP_TYPES = 0x4 +}; + /* print interface capabilities, including link layer types */ extern void -capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name, - gboolean monitor_mode); +capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name, int queries); /* print list of interfaces */ extern void 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. */ diff --git a/cmake/modules/FindPCAP.cmake b/cmake/modules/FindPCAP.cmake index 508d46b3a7..d8812c94c6 100644 --- a/cmake/modules/FindPCAP.cmake +++ b/cmake/modules/FindPCAP.cmake @@ -85,6 +85,7 @@ if( PCAP_FOUND ) check_function_exists( "bpf_image" HAVE_BPF_IMAGE ) check_function_exists( "pcap_setsampling" HAVE_PCAP_SETSAMPLING ) check_function_exists( "pcap_set_tstamp_precision" HAVE_PCAP_SET_TSTAMP_PRECISION ) + check_function_exists( "pcap_set_tstamp_type" HAVE_PCAP_SET_TSTAMP_TYPE ) # Remote pcap checks check_function_exists( "pcap_open" HAVE_PCAP_OPEN ) if( HAVE_PCAP_OPEN ) diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index 5437207981..2b4048a08d 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -278,6 +278,9 @@ /* Define to 1 if you have the `pcap_set_tstamp_precision' function. */ #cmakedefine HAVE_PCAP_SET_TSTAMP_PRECISION 1 +/* Define to 1 if you have the `pcap_set_tstamp_type' function. */ +#cmakedefine HAVE_PCAP_SET_TSTAMP_TYPE 1 + /* Define to 1 if you have the popcount function. */ #cmakedefine HAVE_POPCOUNT 1 diff --git a/doc/dumpcap.pod b/doc/dumpcap.pod index 1c76aa8fc2..e1e816bc4f 100644 --- a/doc/dumpcap.pod +++ b/doc/dumpcap.pod @@ -32,6 +32,8 @@ S<[ B<-v> ]> S<[ B<-w> E<lt>outfileE<gt> ]> S<[ B<-y> E<lt>capture link typeE<gt> ]> S<[ B<--capture-comment> E<lt>commentE<gt> ]> +S<[ B<--list-time-stamp-types> ]> +S<[ B<--time-stamp-type> E<lt>typeE<gt> ]> =head1 DESCRIPTION @@ -254,7 +256,8 @@ link types can be used for the B<-y> option. =item -M -When used with B<-D>, B<-L> or B<-S>, print machine-readable output. +When used with B<-D>, B<-L>, B<-S> or B<--list-time-stamp-types> print +machine-readable output. The machine-readable output is intended to be read by B<Wireshark> and B<TShark>; its format is subject to change from release to release. @@ -352,6 +355,15 @@ This option is only available if we output the captured packets to a single file in pcap-ng format. Only one capture comment may be set per output file. +=item --list-time-stamp-types + +List time stamp types supported for the interface. If no time stamp type can be +set, no time stamp types are listed. + +=item --time-stamp-type E<lt>typeE<gt> + +Change the interface's timestamp method. + =back =head1 CAPTURE FILTER SYNTAX diff --git a/doc/tshark.pod b/doc/tshark.pod index 664851bafe..185409468d 100644 --- a/doc/tshark.pod +++ b/doc/tshark.pod @@ -54,6 +54,8 @@ S<[ B<-Y> E<lt>displaY filterE<gt> ]> S<[ B<-M> E<lt>auto session resetE<gt> ]> S<[ B<-z> E<lt>statisticsE<gt> ]> S<[ B<--capture-comment> E<lt>commentE<gt> ]> +S<[ B<--list-time-stamp-types> ]> +S<[ B<--time-stamp-type> E<lt>typeE<gt> ]> S<[ B<--color> ]> S<[ B<--no-duplicate-keys> ]> S<[ B<--export-objects> E<lt>protocolE<gt>,E<lt>destdirE<gt> ]> @@ -1622,6 +1624,15 @@ Add a capture comment to the output file. This option is only available if a new output file in pcapng format is created. Only one capture comment may be set per output file. +=item --list-time-stamp-types + +List time stamp types supported for the interface. If no time stamp type can be +set, no time stamp types are listed. + +=item --time-stamp-type E<lt>typeE<gt> + +Change the interface's timestamp method. + =item --color Enable coloring of packets according to standard Wireshark color filters. This diff --git a/doc/wireshark.pod.template b/doc/wireshark.pod.template index d89bf546fc..09fb6feaa2 100644 --- a/doc/wireshark.pod.template +++ b/doc/wireshark.pod.template @@ -53,6 +53,8 @@ S<[ B<--enable-protocol> E<lt>proto_nameE<gt> ]> S<[ B<--disable-protocol> E<lt>proto_nameE<gt> ]> S<[ B<--enable-heuristic> E<lt>short_nameE<gt> ]> S<[ B<--disable-heuristic> E<lt>short_nameE<gt> ]> +S<[ B<--list-time-stamp-types> ]> +S<[ B<--time-stamp-type> E<lt>typeE<gt> ]> S<[ E<lt>infileE<gt> ]> =head1 DESCRIPTION @@ -987,6 +989,15 @@ Enable dissection of heuristic protocol. Disable dissection of heuristic protocol. +=item --list-time-stamp-types + +List time stamp types supported for the interface. If no time stamp type can be +set, no time stamp types are listed. + +=item --time-stamp-type E<lt>typeE<gt> + +Change the interface's timestamp method. + =back =head1 INTERFACE diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc index 6bfff65a67..33511794e0 100644 --- a/docbook/release-notes.asciidoc +++ b/docbook/release-notes.asciidoc @@ -41,6 +41,7 @@ since version 2.4.0: * File load time in Status Bar is now disabled by default and can be enabled in Preferences -> Appearance -> Layout -> Show file load time. * Support for G.729 codec in the RTP Player (via the bcg729 library). +* Support for hardware-timestamping of packets //=== Removed Dissectors diff --git a/docbook/wsug_src/WSUG_app_tools.asciidoc b/docbook/wsug_src/WSUG_app_tools.asciidoc index 87c88559f0..e05b033ecf 100644 --- a/docbook/wsug_src/WSUG_app_tools.asciidoc +++ b/docbook/wsug_src/WSUG_app_tools.asciidoc @@ -42,8 +42,10 @@ Capture interface: -I capture in monitor mode, if available -B <buffer size> size of kernel buffer (def: 2MB) -y <link type> link layer type (def: first appropriate) + --time-stamp-type <type> timestamp method for interface -D print list of interfaces and exit -L print list of link-layer types of iface and exit + --list-time-stamp-types print list of timestamp types for iface and exit Capture stop conditions: -c <packet count> stop after n packets (def: infinite) @@ -185,8 +187,10 @@ Capture interface: -I capture in monitor mode, if available -B <buffer size> size of kernel buffer in MiB (def: 2MiB) -y <link type> link layer type (def: first appropriate) + --time-stamp-type <type> timestamp method for interface -D print list of interfaces and exit -L print list of link-layer types of iface and exit + --list-time-stamp-types print list of timestamp types for iface and exit -d print generated BPF code for capture filter -k set channel on wifi interface <freq>,[<type>] -S print statistics for each interface once per second diff --git a/docbook/wsug_src/WSUG_chapter_customize.asciidoc b/docbook/wsug_src/WSUG_chapter_customize.asciidoc index 1f797bd7db..618303529a 100644 --- a/docbook/wsug_src/WSUG_chapter_customize.asciidoc +++ b/docbook/wsug_src/WSUG_chapter_customize.asciidoc @@ -56,8 +56,10 @@ Capture interface: -I capture in monitor mode, if available -B <buffer size> size of kernel buffer (def: 2MB) -y <link type> link layer type (def: first appropriate) + --time-stamp-type <type> timestamp method for interface -D print list of interfaces and exit -L print list of link-layer types of iface and exit + --list-time-stamp-types print list of timestamp types for iface and exit Capture stop conditions: -c <packet count> stop after n packets (def: infinite) @@ -273,6 +275,10 @@ updated automatically as packets arrive during a capture ( as specified by the List the data link types supported by the interface and exit. +--list-time-stamp-types:: + +List timestamp types configurable for the iface and exit + -m <font>:: This option sets the name of the font used for most text displayed by Wireshark. @@ -420,10 +426,16 @@ This option sets the name of the file to be used to save captured packets. -y <capture link type>:: -If a capture is started from the command line with -k, set the data -link type to use while capturing packets. The values reported by -L +If a capture is started from the command line with `-k`, set the data +link type to use while capturing packets. The values reported by `-L` are the values that can be used. +--time-stamp-type <type>:: + +If a capture is started from the command line with `-k`, set the data +link type to use while capturing packets. The values reported by +`--list-time-stamp-types` are the values that can be used. + -X <eXtension option>:: Specify an option to be passed to a TShark module. The eXtension option is in @@ -493,8 +493,10 @@ print_usage(FILE *output) fprintf(output, " -B <buffer size> size of kernel buffer in MiB (def: %dMiB)\n", DEFAULT_CAPTURE_BUFFER_SIZE); #endif fprintf(output, " -y <link type> link layer type (def: first appropriate)\n"); + fprintf(output, " --time-stamp-type <type> timestamp method for interface\n"); fprintf(output, " -D print list of interfaces and exit\n"); fprintf(output, " -L print list of link-layer types of iface and exit\n"); + fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n"); #ifdef HAVE_BPF_IMAGE fprintf(output, " -d print generated BPF code for capture filter\n"); #endif @@ -906,10 +908,9 @@ print_machine_readable_interfaces(GList *if_list) * you MUST update capture_ifinfo.c:capture_get_if_capabilities() accordingly! */ static void -print_machine_readable_if_capabilities(if_capabilities_t *caps) +print_machine_readable_if_capabilities(if_capabilities_t *caps, int queries) { - GList *lt_entry; - data_link_info_t *data_link_info; + GList *lt_entry, *ts_entry; const gchar *desc_str; if (capture_child) { @@ -917,19 +918,33 @@ print_machine_readable_if_capabilities(if_capabilities_t *caps) pipe_write_block(2, SP_SUCCESS, NULL); } - if (caps->can_set_rfmon) - printf("1\n"); - else - printf("0\n"); - for (lt_entry = caps->data_link_types; lt_entry != NULL; - lt_entry = g_list_next(lt_entry)) { - data_link_info = (data_link_info_t *)lt_entry->data; - if (data_link_info->description != NULL) - desc_str = data_link_info->description; - else - desc_str = "(not supported)"; - printf("%d\t%s\t%s\n", data_link_info->dlt, data_link_info->name, - desc_str); + if (queries & CAPS_QUERY_LINK_TYPES) { + if (caps->can_set_rfmon) + printf("1\n"); + else + printf("0\n"); + for (lt_entry = caps->data_link_types; lt_entry != NULL; + lt_entry = g_list_next(lt_entry)) { + data_link_info_t *data_link_info = (data_link_info_t *)lt_entry->data; + if (data_link_info->description != NULL) + desc_str = data_link_info->description; + else + desc_str = "(not supported)"; + printf("%d\t%s\t%s\n", data_link_info->dlt, data_link_info->name, + desc_str); + } + } + printf("\n"); + if (queries & CAPS_QUERY_TIMESTAMP_TYPES) { + for (ts_entry = caps->timestamp_types; ts_entry != NULL; + ts_entry = g_list_next(ts_entry)) { + timestamp_info_t *timestamp = (timestamp_info_t *)ts_entry->data; + if (timestamp->description != NULL) + desc_str = timestamp->description; + else + desc_str = "(none)"; + printf("%s\t%s\n", timestamp->name, desc_str); + } } } @@ -3888,7 +3903,7 @@ main(int argc, char *argv[]) struct pcap_stat stats; GLogLevelFlags log_flags; gboolean list_interfaces = FALSE; - gboolean list_link_layer_types = FALSE; + int caps_queries = 0; #ifdef HAVE_BPF_IMAGE gboolean print_bpf_code = FALSE; #endif @@ -4241,6 +4256,7 @@ main(int argc, char *argv[]) case 'f': /* capture filter */ case 'g': /* enable group read access on file(s) */ case 'i': /* Use interface x */ + case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */ case 'n': /* Use pcapng format */ case 'p': /* Don't capture in promiscuous mode */ case 'P': /* Use pcap format */ @@ -4306,11 +4322,14 @@ main(int argc, char *argv[]) } break; case 'L': /* Print list of link-layer types and exit */ - if (!list_link_layer_types) { - list_link_layer_types = TRUE; + if (!(caps_queries & CAPS_QUERY_LINK_TYPES)) { + caps_queries |= CAPS_QUERY_LINK_TYPES; run_once_args++; } break; + case LONGOPT_LIST_TSTAMP_TYPES: + caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES; + break; #ifdef HAVE_BPF_IMAGE case 'd': /* Print BPF code for capture filter and exit */ if (!print_bpf_code) { @@ -4387,9 +4406,9 @@ main(int argc, char *argv[]) if (run_once_args > 1) { #ifdef HAVE_BPF_IMAGE - cmdarg_err("Only one of -D, -L, -d, -k, or -S may be supplied."); + cmdarg_err("Only one of -D, -L, -d, -k or -S may be supplied."); #else - cmdarg_err("Only one of -D, -L, -k, or -S may be supplied."); + cmdarg_err("Only one of -D, -L, -k or -S may be supplied."); #endif exit_main(1); } else if (run_once_args == 1) { @@ -4452,7 +4471,7 @@ main(int argc, char *argv[]) int err; gchar *err_str; - if_list = capture_interface_list(&err, &err_str,NULL); + if_list = capture_interface_list(&err, &err_str, NULL); if (if_list == NULL) { if (err == 0) { /* @@ -4512,13 +4531,14 @@ main(int argc, char *argv[]) exit_main(status); } - if (list_link_layer_types) { - /* Get the list of link-layer types for the capture device. */ + if (caps_queries) { + /* Get the list of link-layer and/or timestamp types for the capture device. */ if_capabilities_t *caps; gchar *err_str; guint ii; for (ii = 0; ii < global_capture_opts.ifaces->len; ii++) { + int if_caps_queries = caps_queries; interface_options interface_opts; interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, ii); @@ -4531,22 +4551,40 @@ main(int argc, char *argv[]) g_free(err_str); exit_main(2); } - if (caps->data_link_types == NULL) { + if ((if_caps_queries & CAPS_QUERY_LINK_TYPES) && caps->data_link_types == NULL) { cmdarg_err("The capture device \"%s\" has no data link types.", interface_opts.name); exit_main(2); - } + } /* No timestamp types is no big deal. So we will just ignore it */ + + if (interface_opts.monitor_mode) + if_caps_queries |= CAPS_MONITOR_MODE; + if (machine_readable) /* tab-separated values to stdout */ - /* XXX: We need to change the format and adopt consumers */ - print_machine_readable_if_capabilities(caps); + /* XXX: We need to change the format and adapt consumers */ + print_machine_readable_if_capabilities(caps, if_caps_queries); else /* XXX: We might want to print also the interface name */ - capture_opts_print_if_capabilities(caps, interface_opts.name, - interface_opts.monitor_mode); + capture_opts_print_if_capabilities(caps, interface_opts.name, if_caps_queries); free_if_capabilities(caps); } exit_main(0); } +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + for (j = 0; j < global_capture_opts.ifaces->len; j++) { + interface_options *interface_opts; + + interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, j); + if (interface_opts->timestamp_type) { + interface_opts->timestamp_type_id = pcap_tstamp_type_name_to_val(interface_opts->timestamp_type); + if (interface_opts->timestamp_type_id < 0) { + cmdarg_err("Invalid argument to option: --time-stamp-type=%s", interface_opts->timestamp_type); + exit_main(1); + } + } + } +#endif + /* We're supposed to do a capture, or print the BPF code for a filter. */ /* Let the user know what interfaces were chosen. */ @@ -383,6 +383,7 @@ static gboolean cb_dlt(extcap_callback_info_t cb_info) */ caps = (if_capabilities_t *) g_malloc(sizeof * caps); caps->can_set_rfmon = FALSE; + caps->timestamp_types = NULL; while (dlts) { @@ -148,6 +148,7 @@ #define INVALID_CAPABILITY 2 #define INVALID_TAP 2 #define INVALID_DATA_LINK 2 +#define INVALID_TIMESTAMP_TYPE 2 #define INVALID_CAPTURE 2 #define INIT_FAILED 2 @@ -353,8 +354,10 @@ print_usage(FILE *output) fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE); #endif fprintf(output, " -y <link type> link layer type (def: first appropriate)\n"); + fprintf(output, " --time-stamp-type <type> timestamp method for interface\n"); fprintf(output, " -D print list of interfaces and exit\n"); fprintf(output, " -L print list of link-layer types of iface and exit\n"); + fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n"); fprintf(output, "\n"); fprintf(output, "Capture stop conditions:\n"); fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n"); @@ -686,7 +689,7 @@ main(int argc, char *argv[]) volatile gboolean success; volatile int exit_status = EXIT_SUCCESS; #ifdef HAVE_LIBPCAP - gboolean list_link_layer_types = FALSE; + int caps_queries = 0; gboolean start_capture = FALSE; GList *if_list; gchar *err_str; @@ -1082,6 +1085,7 @@ main(int argc, char *argv[]) case 'f': /* capture filter */ case 'g': /* enable group read access on file(s) */ case 'i': /* Use interface x */ + case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */ case 'p': /* Don't capture in promiscuous mode */ #ifdef HAVE_PCAP_REMOTE case 'A': /* Authentication */ @@ -1226,7 +1230,15 @@ main(int argc, char *argv[]) break; case 'L': /* Print list of link-layer types and exit */ #ifdef HAVE_LIBPCAP - list_link_layer_types = TRUE; + caps_queries |= CAPS_QUERY_LINK_TYPES; +#else + capture_option_specified = TRUE; + arg_error = TRUE; +#endif + break; + case LONGOPT_LIST_TSTAMP_TYPES: /* List possible timestamp types */ +#ifdef HAVE_LIBPCAP + caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES; #else capture_option_specified = TRUE; arg_error = TRUE; @@ -1601,12 +1613,13 @@ main(int argc, char *argv[]) } #ifdef HAVE_LIBPCAP - if (list_link_layer_types) { - /* We're supposed to list the link-layer types for an interface; + if (caps_queries) { + /* We're supposed to list the link-layer/timestamp types for an interface; did the user also specify a capture file to be read? */ if (cf_name) { /* Yes - that's bogus. */ - cmdarg_err("You can't specify -L and a capture file to be read."); + cmdarg_err("You can't specify %s and a capture file to be read.", + caps_queries & CAPS_QUERY_LINK_TYPES ? "-L" : "--list-time-stamp-types"); exit_status = INVALID_OPTION; goto clean_exit; } @@ -2079,7 +2092,7 @@ main(int argc, char *argv[]) } /* if requested, list the link layer types and exit */ - if (list_link_layer_types) { + if (caps_queries) { guint i; /* Get the list of link-layer types for the capture devices. */ @@ -2087,6 +2100,7 @@ main(int argc, char *argv[]) interface_options interface_opts; if_capabilities_t *caps; char *auth_str = NULL; + int if_caps_queries = caps_queries; interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); #ifdef HAVE_PCAP_REMOTE @@ -2102,12 +2116,19 @@ main(int argc, char *argv[]) exit_status = INVALID_CAPABILITY; goto clean_exit; } - if (caps->data_link_types == NULL) { + if ((if_caps_queries & CAPS_QUERY_LINK_TYPES) && caps->data_link_types == NULL) { cmdarg_err("The capture device \"%s\" has no data link types.", interface_opts.name); exit_status = INVALID_DATA_LINK; goto clean_exit; } - capture_opts_print_if_capabilities(caps, interface_opts.name, interface_opts.monitor_mode); + if ((if_caps_queries & CAPS_QUERY_TIMESTAMP_TYPES) && caps->timestamp_types == NULL) { + cmdarg_err("The capture device \"%s\" has no timestamp types.", interface_opts.name); + exit_status = INVALID_TIMESTAMP_TYPE; + goto clean_exit; + } + if (interface_opts.monitor_mode) + if_caps_queries |= CAPS_MONITOR_MODE; + capture_opts_print_if_capabilities(caps, interface_opts.name, if_caps_queries); free_if_capabilities(caps); } exit_status = EXIT_SUCCESS; diff --git a/ui/commandline.c b/ui/commandline.c index dc20e1505b..e692a5e57d 100644 --- a/ui/commandline.c +++ b/ui/commandline.c @@ -109,8 +109,10 @@ commandline_print_usage(gboolean for_help_option) { fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE); #endif fprintf(output, " -y <link type> link layer type (def: first appropriate)\n"); + fprintf(output, " --time-stamp-type <type> timestamp method for interface\n"); fprintf(output, " -D print list of interfaces and exit\n"); fprintf(output, " -L print list of link-layer types of iface and exit\n"); + fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n"); fprintf(output, "\n"); fprintf(output, "Capture stop conditions:\n"); fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n"); @@ -352,6 +354,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset) { int opt; gboolean arg_error = FALSE; + const char *list_option_supplied = NULL; #ifdef HAVE_LIBPCAP int status; #else @@ -405,6 +408,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset) #ifdef HAVE_LIBPCAP global_commandline_info.start_capture = FALSE; global_commandline_info.list_link_layer_types = FALSE; + global_commandline_info.list_timestamp_types = FALSE; global_commandline_info.quit_after_cap = getenv("WIRESHARK_QUIT_AFTER_CAPTURE") ? TRUE : FALSE; #endif global_commandline_info.full_screen = FALSE; @@ -420,6 +424,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset) case 'H': /* Hide capture info dialog box */ case 'p': /* Don't capture in promiscuous mode */ case 'i': /* Use interface x */ + case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */ #ifdef HAVE_PCAP_CREATE case 'I': /* Capture in monitor mode, if available */ #endif @@ -469,6 +474,16 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset) case 'L': /* Print list of link-layer types and exit */ #ifdef HAVE_LIBPCAP global_commandline_info.list_link_layer_types = TRUE; + list_option_supplied = "-L"; +#else + capture_option_specified = TRUE; + arg_error = TRUE; +#endif + break; + case LONGOPT_LIST_TSTAMP_TYPES: +#ifdef HAVE_LIBPCAP + global_commandline_info.list_timestamp_types = TRUE; + list_option_supplied = "--list-time-stamp-types"; #else capture_option_specified = TRUE; arg_error = TRUE; @@ -631,18 +646,18 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset) } #ifdef HAVE_LIBPCAP - if (global_commandline_info.start_capture && global_commandline_info.list_link_layer_types) { + if (global_commandline_info.start_capture && list_option_supplied) { /* Specifying *both* is bogus. */ - cmdarg_err("You can't specify both -L and a live capture."); + cmdarg_err("You can't specify both %s and a live capture.", list_option_supplied); exit(1); } - if (global_commandline_info.list_link_layer_types) { + if (list_option_supplied) { /* We're supposed to list the link-layer types for an interface; did the user also specify a capture file to be read? */ if (global_commandline_info.cf_name) { /* Yes - that's bogus. */ - cmdarg_err("You can't specify -L and a capture file to be read."); + cmdarg_err("You can't specify %s and a capture file to be read.", list_option_supplied); exit(1); } /* No - did they specify a ring buffer option? */ diff --git a/ui/commandline.h b/ui/commandline.h index 85ba97c0c5..344805f1e1 100644 --- a/ui/commandline.h +++ b/ui/commandline.h @@ -37,6 +37,7 @@ typedef struct commandline_param_info { #ifdef HAVE_LIBPCAP gboolean list_link_layer_types; + gboolean list_timestamp_types; gboolean start_capture; gboolean quit_after_cap; #endif diff --git a/ui/gtk/main.c b/ui/gtk/main.c index b9b4292cc4..8214139455 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -1996,6 +1996,7 @@ main(int argc, char *argv[]) #endif #endif #endif + int caps_queries = 0; gint pl_size = 280, tv_size = 95, bv_size = 75; gchar *rc_file; dfilter_t *rfcode = NULL; @@ -2294,8 +2295,13 @@ main(int argc, char *argv[]) fill_in_local_interfaces(main_window_update); - if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) { - /* We're supposed to do a live capture or get a list of link-layer + if (global_commandline_info.list_link_layer_types) + caps_queries |= CAPS_QUERY_LINK_TYPES; + if (global_commandline_info.list_timestamp_types) + caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES; + + if (global_commandline_info.start_capture || caps_queries) { + /* We're supposed to do a live capture or get a list of link-layer/timestamp types for a live capture device; if the user didn't specify an interface to use, pick a default. */ ret = capture_opts_default_iface_if_necessary(&global_capture_opts, @@ -2305,13 +2311,13 @@ main(int argc, char *argv[]) } } - if (global_commandline_info.list_link_layer_types) { + if (caps_queries) { /* Get the list of link-layer types for the capture devices. */ if_capabilities_t *caps; guint i; interface_t device; for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { - + int if_caps_queries = caps_queries; device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); if (device.selected) { gchar* auth_str = NULL; @@ -2342,10 +2348,10 @@ main(int argc, char *argv[]) create_console(); #endif /* _WIN32 */ #if defined(HAVE_PCAP_CREATE) - capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported); -#else - capture_opts_print_if_capabilities(caps, device.name, FALSE); + if (device.monitor_mode_supported) + if_caps_queries |= CAPS_MONITOR_MODE; #endif + capture_opts_print_if_capabilities(caps, device.name, if_caps_queries); #ifdef _WIN32 destroy_console(); #endif /* _WIN32 */ diff --git a/wireshark-qt.cpp b/wireshark-qt.cpp index ab7b99c666..4a704e46cb 100644 --- a/wireshark-qt.cpp +++ b/wireshark-qt.cpp @@ -366,6 +366,7 @@ int main(int argc, char *qt_argv[]) GString *runtime_info_str = NULL; QString dfilter, read_filter; + int caps_queries = 0; /* Start time in microseconds*/ guint64 start_time = g_get_monotonic_time(); #ifdef DEBUG_STARTUP_TIME @@ -714,8 +715,13 @@ int main(int argc, char *qt_argv[]) fill_in_local_interfaces(main_window_update); - if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) { - /* We're supposed to do a live capture or get a list of link-layer + if (global_commandline_info.list_link_layer_types) + caps_queries |= CAPS_QUERY_LINK_TYPES; + if (global_commandline_info.list_timestamp_types) + caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES; + + if (global_commandline_info.start_capture || caps_queries) { + /* We're supposed to do a live capture or get a list of link-layer/timestamp types for a live capture device; if the user didn't specify an interface to use, pick a default. */ ret_val = capture_opts_default_iface_if_necessary(&global_capture_opts, @@ -725,13 +731,13 @@ int main(int argc, char *qt_argv[]) } } - if (global_commandline_info.list_link_layer_types) { + if (caps_queries) { /* Get the list of link-layer types for the capture devices. */ if_capabilities_t *caps; guint i; interface_t device; for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { - + int if_caps_queries = caps_queries; device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); if (device.selected) { #if defined(HAVE_PCAP_CREATE) @@ -754,10 +760,10 @@ int main(int argc, char *qt_argv[]) create_console(); #endif /* _WIN32 */ #if defined(HAVE_PCAP_CREATE) - capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported); -#else - capture_opts_print_if_capabilities(caps, device.name, FALSE); + if (device.monitor_mode_supported) + if_caps_queries |= CAPS_MONITOR_MODE; #endif + capture_opts_print_if_capabilities(caps, device.name, if_caps_queries); #ifdef _WIN32 destroy_console(); #endif /* _WIN32 */ |