aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-08-12 20:32:01 -0700
committerGuy Harris <guy@alum.mit.edu>2018-08-13 04:37:00 +0000
commit149e74b70d207228802a463214271c9e537476c9 (patch)
tree1deea5228d89492b4950735b99159bde6eba90b2
parentd48262753eecd46a5ba0fc13bbc8c336fa16c207 (diff)
Put the interface descrptions into the IDB when capturing to pcapng.
capture_opts_add_iface_opt(), when called in a program acting as a capture child, will fetch the description for the interface, and will also generate a "display name" for the interface. In the process, we clean up capture_opts_add_iface_opt() a bit, combining duplicate code. We rename console_display_name to just display_name, as it may also be used in the title bar of Wireshark when capturing. Change-Id: Ifd18955bb3cb41df4c0ed4362d4854068c825b96 Reviewed-on: https://code.wireshark.org/review/29117 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--capture_opts.c276
-rw-r--r--capture_opts.h6
-rw-r--r--caputils/capture-pcap-util.c153
-rw-r--r--caputils/capture_ifinfo.h11
-rw-r--r--dumpcap.c64
-rw-r--r--ui/capture_ui_utils.c22
6 files changed, 387 insertions, 145 deletions
diff --git a/capture_opts.c b/capture_opts.c
index 8b249d6175..47f6dab00e 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -155,7 +155,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
g_log(log_domain, log_level, "Interface name[%02d] : %s", i, interface_opts->name ? interface_opts->name : "(unspecified)");
g_log(log_domain, log_level, "Interface description[%02d] : %s", i, interface_opts->descr ? interface_opts->descr : "(unspecified)");
- g_log(log_domain, log_level, "Console display name[%02d]: %s", i, interface_opts->console_display_name ? interface_opts->console_display_name : "(unspecified)");
+ g_log(log_domain, log_level, "Display name[%02d]: %s", i, interface_opts->display_name ? interface_opts->display_name : "(unspecified)");
g_log(log_domain, log_level, "Capture filter[%02d] : %s", i, interface_opts->cfilter ? interface_opts->cfilter : "(unspecified)");
g_log(log_domain, log_level, "Snap length[%02d] (%u) : %d", i, interface_opts->has_snaplen, interface_opts->snaplen);
g_log(log_domain, log_level, "Link Type[%02d] : %d", i, interface_opts->linktype);
@@ -499,6 +499,129 @@ get_auth_arguments(capture_options *capture_opts, const char *arg)
}
#endif
+#ifdef _WIN32
+static char *
+capture_opts_generate_display_name(const char *friendly_name,
+ const char *name _U_)
+{
+ /*
+ * Display the friendly name rather than the not-so-friendly
+ * GUID-based interface name.
+ */
+ return g_strdup(friendly_name);
+}
+#else
+static char *
+capture_opts_generate_display_name(const char *friendly_name,
+ const char *name)
+{
+ /*
+ * On UN*X, however, users are more used to interface names,
+ * and may find it helpful to see them.
+ */
+ return g_strdup_printf("%s: %s", friendly_name, name);
+}
+#endif
+
+static gboolean
+capture_opts_search_for_interface(interface_options *interface_opts,
+ const char *name)
+{
+ gboolean matched;
+ GList *if_list;
+ int err;
+ GList *if_entry;
+ if_info_t *if_info;
+ size_t prefix_length;
+
+ matched = FALSE;
+ if_list = capture_interface_list(&err, NULL, NULL);
+ if (if_list != NULL) {
+ /* try and do an exact match (case insensitive) */
+ for (if_entry = g_list_first(if_list); if_entry != NULL;
+ if_entry = g_list_next(if_entry))
+ {
+ if_info = (if_info_t *)if_entry->data;
+
+ /*
+ * Does the specified name match the interface name
+ * with a case-insensitive match?
+ */
+ if (g_ascii_strcasecmp(if_info->name, name) == 0) {
+ /*
+ * Yes.
+ */
+ matched = TRUE;
+ break;
+ }
+
+ /*
+ * Does this interface have a friendly name and, if so,
+ * does the specified name match the friendly name with
+ * a case-insensitive match?
+ */
+ if (if_info->friendly_name != NULL &&
+ g_ascii_strcasecmp(if_info->friendly_name, name) == 0) {
+ /*
+ * Yes.
+ */
+ matched = TRUE;
+ break;
+ }
+ }
+
+ if (!matched) {
+ /*
+ * We didn't find it; attempt a case-insensitive prefix match
+ * of the friendly name.
+ */
+ prefix_length = strlen(name);
+ for (if_entry = g_list_first(if_list); if_entry != NULL;
+ if_entry = g_list_next(if_entry))
+ {
+ if_info = (if_info_t *)if_entry->data;
+
+ if (if_info->friendly_name != NULL &&
+ g_ascii_strncasecmp(if_info->friendly_name, name, prefix_length) == 0) {
+ /*
+ * We found an interface whose friendly name matches
+ * with a case-insensitive prefix match.
+ */
+ matched = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if (matched) {
+ /*
+ * We found an interface that matches.
+ */
+ interface_opts->name = g_strdup(if_info->name);
+
+ if (if_info->friendly_name != NULL) {
+ /*
+ * We have a friendly name; remember it as the
+ * description...
+ */
+ interface_opts->descr = g_strdup(if_info->friendly_name);
+ /*
+ * ...and use it in the console display name.
+ */
+ interface_opts->display_name = capture_opts_generate_display_name(if_info->friendly_name, if_info->name);
+ } else {
+ /* fallback to the interface name */
+ interface_opts->descr = NULL;
+ interface_opts->display_name = g_strdup(if_info->name);
+ }
+ interface_opts->if_type = if_info->type;
+ interface_opts->extcap = g_strdup(if_info->extcap);
+ }
+ free_interface_list(if_list);
+ return matched;
+}
+
static int
capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p)
{
@@ -551,132 +674,65 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
interface_opts.name = g_strdup(if_info->name);
if (if_info->friendly_name != NULL) {
/*
+ * We have a friendly name for the interface, so remember that
+ * as the description.
+ */
+ interface_opts.descr = g_strdup(if_info->friendly_name);
+ interface_opts.display_name = capture_opts_generate_display_name(if_info->friendly_name, if_info->name);
+ } else {
+ /* fallback to the interface name */
+ interface_opts.descr = NULL;
+ interface_opts.display_name = g_strdup(if_info->name);
+ }
+ interface_opts.if_type = if_info->type;
+ interface_opts.extcap = g_strdup(if_info->extcap);
+ free_interface_list(if_list);
+ } else if (capture_opts->capture_child) {
+ /*
+ * In Wireshark capture child mode, so the exact interface name
+ * is supplied, and we don't need to look it up.
+ */
+ if_info = if_info_get(optarg_str_p);
+ interface_opts.name = g_strdup(if_info->name);
+ if (if_info->friendly_name != NULL) {
+ /*
* We have a friendly name for the interface, so display that
* instead of the interface name/guid.
*
* XXX - on UN*X, the interface name is not quite so ugly,
* and might be more familiar to users; display them both?
*/
- interface_opts.console_display_name = g_strdup(if_info->friendly_name);
+ interface_opts.descr = g_strdup(if_info->friendly_name);
+ interface_opts.display_name = g_strdup(if_info->friendly_name);
} else {
+ interface_opts.descr = NULL;
/* fallback to the interface name */
- interface_opts.console_display_name = g_strdup(if_info->name);
+ interface_opts.display_name = g_strdup(if_info->name);
}
interface_opts.if_type = if_info->type;
interface_opts.extcap = g_strdup(if_info->extcap);
- free_interface_list(if_list);
- } else if (capture_opts->capture_child) {
- /* In Wireshark capture child mode, thus proper device name is supplied. */
- /* No need for trying to match it for friendly names. */
- interface_opts.name = g_strdup(optarg_str_p);
- interface_opts.console_display_name = g_strdup(optarg_str_p);
- interface_opts.if_type = capture_opts->default_options.if_type;
- interface_opts.extcap = g_strdup(capture_opts->default_options.extcap);
+ if_info_free(if_info);
} else {
/*
- * Retrieve the interface list so that we can search for the
- * specified option amongst both the interface names and the
- * friendly names and so that we find the friendly name even
- * if an interface name was specified.
- *
- * If we can't get the list, just use the specified option as
- * the interface name, so that the user can try specifying an
- * interface explicitly for testing purposes.
+ * Search for that name in the interface list and, if we found
+ * it, fill in fields in the interface_opts structure.
*/
- if_list = capture_interface_list(&err, NULL, NULL);
- if (if_list != NULL) {
- /* try and do an exact match (case insensitive) */
- GList *if_entry;
- gboolean matched;
-
- matched = FALSE;
- for (if_entry = g_list_first(if_list); if_entry != NULL;
- if_entry = g_list_next(if_entry))
- {
- if_info = (if_info_t *)if_entry->data;
- /* exact name check */
- if (g_ascii_strcasecmp(if_info->name, optarg_str_p) == 0) {
- /* exact match on the interface name, use that for displaying etc */
- interface_opts.name = g_strdup(if_info->name);
-
- if (if_info->friendly_name != NULL) {
- /*
- * If we have a friendly name, use that for the
- * console display name, as it is the basis for
- * the auto generated temp filename.
- */
- interface_opts.console_display_name = g_strdup(if_info->friendly_name);
- } else {
- interface_opts.console_display_name = g_strdup(if_info->name);
- }
- interface_opts.if_type = if_info->type;
- interface_opts.extcap = g_strdup(if_info->extcap);
- matched = TRUE;
- break;
- }
-
- /* exact friendly name check */
- if (if_info->friendly_name != NULL &&
- g_ascii_strcasecmp(if_info->friendly_name, optarg_str_p) == 0) {
- /* exact match - use the friendly name for display */
- interface_opts.name = g_strdup(if_info->name);
- interface_opts.console_display_name = g_strdup(if_info->friendly_name);
- interface_opts.if_type = if_info->type;
- interface_opts.extcap = g_strdup(if_info->extcap);
- matched = TRUE;
- break;
- }
- }
-
- /* didn't find, attempt a case insensitive prefix match of the friendly name*/
- if (!matched) {
- size_t prefix_length;
-
- prefix_length = strlen(optarg_str_p);
- for (if_entry = g_list_first(if_list); if_entry != NULL;
- if_entry = g_list_next(if_entry))
- {
- if_info = (if_info_t *)if_entry->data;
-
- if (if_info->friendly_name != NULL &&
- g_ascii_strncasecmp(if_info->friendly_name, optarg_str_p, prefix_length) == 0) {
- /* prefix match - use the friendly name for display */
- interface_opts.name = g_strdup(if_info->name);
- interface_opts.console_display_name = g_strdup(if_info->friendly_name);
- interface_opts.if_type = if_info->type;
- interface_opts.extcap = g_strdup(if_info->extcap);
- matched = TRUE;
- break;
- }
- }
- }
- if (!matched) {
- /*
- * We didn't find the interface in the list; just use
- * the specified name, so that, for example, if an
- * interface doesn't show up in the list for some
- * reason, the user can try specifying it explicitly
- * for testing purposes.
- */
- interface_opts.name = g_strdup(optarg_str_p);
- interface_opts.console_display_name = g_strdup(optarg_str_p);
- interface_opts.if_type = capture_opts->default_options.if_type;
- interface_opts.extcap = g_strdup(capture_opts->default_options.extcap);
- }
- free_interface_list(if_list);
- } else {
+ if (!capture_opts_search_for_interface(&interface_opts, optarg_str_p)) {
+ /*
+ * We didn't find the interface in the list; just use
+ * the specified name, so that, for example, if an
+ * interface doesn't show up in the list for some
+ * reason, the user can try specifying it explicitly
+ * for testing purposes.
+ */
interface_opts.name = g_strdup(optarg_str_p);
- interface_opts.console_display_name = g_strdup(optarg_str_p);
+ interface_opts.descr = NULL;
+ interface_opts.display_name = g_strdup(optarg_str_p);
interface_opts.if_type = capture_opts->default_options.if_type;
interface_opts.extcap = g_strdup(capture_opts->default_options.extcap);
}
}
- /* We don't set iface_descr here because doing so requires
- * capture_ui_utils.c which requires epan/prefs.c which is
- * probably a bit too much dependency for here...
- */
- interface_opts.descr = g_strdup(capture_opts->default_options.descr);
interface_opts.cfilter = g_strdup(capture_opts->default_options.cfilter);
interface_opts.snaplen = capture_opts->default_options.snaplen;
interface_opts.has_snaplen = capture_opts->default_options.has_snaplen;
@@ -1119,7 +1175,7 @@ capture_opts_del_iface(capture_options *capture_opts, guint if_index)
g_free(interface_opts->name);
g_free(interface_opts->descr);
- g_free(interface_opts->console_display_name);
+ g_free(interface_opts->display_name);
g_free(interface_opts->cfilter);
g_free(interface_opts->timestamp_type);
g_free(interface_opts->extcap);
@@ -1164,8 +1220,8 @@ collect_ifaces(capture_options *capture_opts)
device = &g_array_index(capture_opts->all_ifaces, interface_t, i);
if (!device->hidden && device->selected) {
interface_opts.name = g_strdup(device->name);
- interface_opts.descr = g_strdup(device->display_name);
- interface_opts.console_display_name = g_strdup(device->name);
+ interface_opts.descr = g_strdup(device->friendly_name);
+ interface_opts.display_name = g_strdup(device->display_name);
interface_opts.linktype = device->active_dlt;
interface_opts.cfilter = g_strdup(device->cfilter);
interface_opts.timestamp_type = g_strdup(device->timestamp_type);
diff --git a/capture_opts.h b/capture_opts.h
index 9bbd3e8599..d0b433706f 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -197,9 +197,9 @@ typedef struct link_row_tag {
} link_row;
typedef struct interface_options_tag {
- gchar *name; /* the name of the interface provided to winpcap/libpcap to specify the interface */
- gchar *descr;
- gchar *console_display_name; /* the name displayed in the console, also the basis for autonamed pcap filenames */
+ gchar *name; /* the name of the interface supplied to libpcap/WinPcap/Npcap to specify the interface */
+ gchar *descr; /* a more user-friendly description of the interface; may be NULL if none */
+ gchar *display_name; /* the name displayed in the console and title bar */
gchar *cfilter;
gboolean has_snaplen;
int snaplen;
diff --git a/caputils/capture-pcap-util.c b/caputils/capture-pcap-util.c
index 1647511aa0..366d92e6c3 100644
--- a/caputils/capture-pcap-util.c
+++ b/caputils/capture-pcap-util.c
@@ -261,6 +261,150 @@ add_unix_interface_ifinfo(if_info_t *if_info, const char *name _U_,
#endif
if_info_t *
+if_info_get(const char *name)
+{
+ char *description = NULL;
+ if_info_t *if_info;
+#ifdef SIOCGIFDESCR
+ /*
+ * Try to fetch the description of this interface.
+ * XXX - this is only here because libpcap has no API to
+ * get the description of a *single* interface; it really
+ * needs both an API to get pcapng-IDB-style attributes
+ * for a single interface and to get a list of interfaces
+ * with pcapng-IDB-style attributes for each interface.
+ */
+ int s;
+ struct ifreq ifrdesc;
+#ifndef IFDESCRSIZE
+ size_t descrlen = 64;
+#else
+ size_t descrlen = IFDESCRSIZE;
+#endif /* IFDESCRSIZE */
+
+ /*
+ * Get the description for the interface.
+ */
+ memset(&ifrdesc, 0, sizeof ifrdesc);
+ g_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s >= 0) {
+#ifdef __FreeBSD__
+ /*
+ * On FreeBSD, if the buffer isn't big enough for the
+ * description, the ioctl succeeds, but the description
+ * isn't copied, ifr_buffer.length is set to the description
+ * length, and ifr_buffer.buffer is set to NULL.
+ */
+ for (;;) {
+ g_free(description);
+ if ((description = g_malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_buffer.buffer = description;
+ ifrdesc.ifr_buffer.length = descrlen;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
+ if (ifrdesc.ifr_buffer.buffer ==
+ description)
+ break;
+ else
+ descrlen = ifrdesc.ifr_buffer.length;
+ } else {
+ /*
+ * Failed to get interface description.
+ */
+ g_free(description);
+ description = NULL;
+ break;
+ }
+ } else
+ break;
+ }
+#else /* __FreeBSD__ */
+ /*
+ * The only other OS that currently supports
+ * SIOCGIFDESCR is OpenBSD, and it has no way
+ * to get the description length - it's clamped
+ * to a maximum of IFDESCRSIZE.
+ */
+ if ((description = g_malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_data = (caddr_t)description;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
+ /*
+ * Failed to get interface description.
+ */
+ g_free(description);
+ description = NULL;
+ }
+ }
+#endif /* __FreeBSD__ */
+ close(s);
+ if (description != NULL && strlen(description) == 0) {
+ /*
+ * Description is empty, so discard it.
+ */
+ g_free(description);
+ description = NULL;
+ }
+ }
+
+#ifdef __FreeBSD__
+ /*
+ * For FreeBSD, if we didn't get a description, and this is
+ * a device with a name of the form usbusN, label it as a USB
+ * bus.
+ */
+ if (description == NULL) {
+ if (strncmp(name, "usbus", 5) == 0) {
+ /*
+ * OK, it begins with "usbus".
+ */
+ long busnum;
+ char *p;
+
+ errno = 0;
+ busnum = strtol(name + 5, &p, 10);
+ if (errno == 0 && p != name + 5 && *p == '\0' &&
+ busnum >= 0 && busnum <= INT_MAX) {
+ /*
+ * OK, it's a valid number that's not
+ * bigger than INT_MAX. Construct
+ * a description from it.
+ */
+ static const char descr_prefix[] = "USB bus number ";
+ size_t descr_size;
+
+ /*
+ * Allow enough room for a 32-bit bus number.
+ * sizeof (descr_prefix) includes the
+ * terminating NUL.
+ */
+ descr_size = sizeof (descr_prefix) + 10;
+ description = g_malloc(descr_size);
+ if (description != NULL) {
+ pcap_snprintf(description, descr_size,
+ "%s%ld", descr_prefix, busnum);
+ }
+ }
+ }
+ }
+#endif /* __FreeBSD__ */
+#endif /* SIOCGIFDESCR */
+ if_info = if_info_new(name, description, FALSE);
+ g_free(description);
+ return if_info;
+}
+
+void
+if_info_free(if_info_t *if_info)
+{
+ g_free(if_info->name);
+ g_free(if_info->friendly_name);
+ g_free(if_info->vendor_description);
+ g_free(if_info->extcap);
+ g_slist_free_full(if_info->addrs, g_free);
+ g_free(if_info);
+}
+
+if_info_t *
if_info_new(const char *name, const char *description, gboolean loopback)
{
if_info_t *if_info;
@@ -528,14 +672,7 @@ get_interface_list_findalldevs(int *err, char **err_str)
static void
free_if_cb(gpointer data, gpointer user_data _U_)
{
- if_info_t *if_info = (if_info_t *)data;
-
- g_free(if_info->name);
- g_free(if_info->friendly_name);
- g_free(if_info->vendor_description);
- g_free(if_info->extcap);
- g_slist_free_full(if_info->addrs, g_free);
- g_free(if_info);
+ if_info_free((if_info_t *)data);
}
void
diff --git a/caputils/capture_ifinfo.h b/caputils/capture_ifinfo.h
index 7ee447aa5c..171561d16c 100644
--- a/caputils/capture_ifinfo.h
+++ b/caputils/capture_ifinfo.h
@@ -75,6 +75,17 @@ extern GList *capture_interface_list(int *err, char **err_str, void (*update_cb)
void free_interface_list(GList *if_list);
+/**
+ * Get an if_info_t for a particular interface.
+ * (May require privilege, so should only be used by dumpcap.)
+ */
+extern if_info_t *if_info_get(const char *name);
+
+/**
+ * Free an if_info_t.
+ */
+void if_info_free(if_info_t *if_info);
+
/*
* "get_if_capabilities()" and "capture_if_capabilities()" return a pointer
* to an allocated instance of this structure. "free_if_capabilities()"
diff --git a/dumpcap.c b/dumpcap.c
index f17424b738..1fad72bcd8 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -3310,23 +3310,57 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
prefix = g_strdup_printf("wireshark_%d_interfaces", global_capture_opts.ifaces->len);
} else {
/*
- * One interface; use its name to generate the temporary file
- * name prefix.
+ * One interface; use its description, if it has one, to generate
+ * the temporary file name, otherwise use its name.
*/
gchar *basename;
- basename = g_path_get_basename((&g_array_index(global_capture_opts.ifaces, interface_options, 0))->console_display_name);
+ const interface_options *interface_opts;
+
+ interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, 0);
+
+ /*
+ * Do we have a description?
+ */
+ if (interface_opts->descr) {
+ /*
+ * Yes - use it.
+ *
+ * Strip off any stuff we shouldn't use in the file name,
+ * by getting the last component of what would be a file
+ * name.
+ */
+ basename = g_path_get_basename(interface_opts->descr);
+ } else {
+ /*
+ * No - use the name.
+ *
+ * Strip off any stuff we shouldn't use in the file name,
+ * by getting the last component of what would be a file
+ * name.
+ */
+ basename = g_path_get_basename(interface_opts->name);
#ifdef _WIN32
- /* use the generic portion of the interface guid to form the basis of the filename */
- if (strncmp("NPF_{", basename, 5)==0)
- {
- /* we have a windows guid style device name, extract the guid digits as the basis of the filename */
- GString *iface;
- iface = isolate_uuid(basename);
- g_free(basename);
- basename = g_strdup(iface->str);
- g_string_free(iface, TRUE);
- }
+ /*
+ * This is Windows, where we might have an ugly GUID-based
+ * interface name.
+ *
+ * If it's an ugly GUID-based name, use the generic portion
+ * of the interface GUID to form the basis of the filename.
+ */
+ if (strncmp("NPF_{", basename, 5) == 0) {
+ /*
+ * We have a GUID-based name; extract the GUID digits
+ * as the basis of the filename.
+ */
+ GString *iface;
+ iface = isolate_uuid(basename);
+ g_free(basename);
+ basename = g_strdup(iface->str);
+ g_string_free(iface, TRUE);
+ }
#endif
+ }
+ /* generate the temp file name prefix */
prefix = g_strconcat("wireshark_", basename, NULL);
g_free(basename);
}
@@ -3990,7 +4024,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
report_capture_error(errmsg, please_report);
}
}
- report_packet_drops(received, pcap_dropped, pcap_src->dropped, pcap_src->flushed, stats->ps_ifdrop, interface_opts->console_display_name);
+ report_packet_drops(received, pcap_dropped, pcap_src->dropped, pcap_src->flushed, stats->ps_ifdrop, interface_opts->display_name);
}
/* close the input file (pcap or capture pipe) */
@@ -5141,7 +5175,7 @@ main(int argc, char *argv[])
g_string_append_printf(str, "and ");
}
}
- g_string_append_printf(str, "'%s'", interface_opts->console_display_name);
+ g_string_append_printf(str, "'%s'", interface_opts->display_name);
}
} else {
g_string_append_printf(str, "%u interfaces", global_capture_opts.ifaces->len);
diff --git a/ui/capture_ui_utils.c b/ui/capture_ui_utils.c
index 92ff44d77f..0f7fe1c39f 100644
--- a/ui/capture_ui_utils.c
+++ b/ui/capture_ui_utils.c
@@ -468,23 +468,27 @@ get_if_name(const char *if_text)
return if_name;
}
-/* Return interface_opts->descr (after setting it if it is not set)
- * This is necessary because capture_opts.c can't set descr (at least
- * not without adding significant dependencies there).
+/* Return a display name for the interface.
*/
static const char *
-get_iface_description_for_interface(capture_options *capture_opts, guint i)
+get_display_name_for_interface(capture_options *capture_opts, guint i)
{
interface_options *interface_opts;
if (i < capture_opts->ifaces->len) {
interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
- if (!interface_opts->descr && interface_opts->name) {
- interface_opts->descr = get_interface_descriptive_name(interface_opts->name);
+ if (interface_opts->display_name) {
+ return interface_opts->display_name;
}
- return (interface_opts->descr);
+ if (!interface_opts->display_name) {
+ if (interface_opts->descr && interface_opts->name) {
+ interface_opts->descr = get_interface_descriptive_name(interface_opts->name);
+ }
+ interface_opts->display_name = g_strdup(interface_opts->descr);
+ }
+ return interface_opts->display_name;
} else {
- return (NULL);
+ return NULL;
}
}
@@ -569,7 +573,7 @@ get_iface_list_string(capture_options *capture_opts, guint32 style)
}
if (style & IFLIST_QUOTE_IF_DESCRIPTION)
g_string_append_printf(iface_list_string, "'");
- g_string_append_printf(iface_list_string, "%s", get_iface_description_for_interface(capture_opts, i));
+ g_string_append_printf(iface_list_string, "%s", get_display_name_for_interface(capture_opts, i));
if (style & IFLIST_QUOTE_IF_DESCRIPTION)
g_string_append_printf(iface_list_string, "'");
if (style & IFLIST_SHOW_FILTER) {