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>
This commit is contained in:
parent
d48262753e
commit
149e74b70d
262
capture_opts.c
262
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);
|
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 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, "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, "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, "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);
|
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
|
#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
|
static int
|
||||||
capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p)
|
capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p)
|
||||||
{
|
{
|
||||||
|
@ -549,6 +672,28 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
interface_opts.name = g_strdup(if_info->name);
|
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) {
|
if (if_info->friendly_name != NULL) {
|
||||||
/*
|
/*
|
||||||
* We have a friendly name for the interface, so display that
|
* We have a friendly name for the interface, so display that
|
||||||
|
@ -557,100 +702,22 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
|
||||||
* XXX - on UN*X, the interface name is not quite so ugly,
|
* XXX - on UN*X, the interface name is not quite so ugly,
|
||||||
* and might be more familiar to users; display them both?
|
* 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 {
|
} else {
|
||||||
|
interface_opts.descr = NULL;
|
||||||
/* fallback to the interface name */
|
/* 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.if_type = if_info->type;
|
||||||
interface_opts.extcap = g_strdup(if_info->extcap);
|
interface_opts.extcap = g_strdup(if_info->extcap);
|
||||||
free_interface_list(if_list);
|
if_info_free(if_info);
|
||||||
} 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);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Retrieve the interface list so that we can search for the
|
* Search for that name in the interface list and, if we found
|
||||||
* specified option amongst both the interface names and the
|
* it, fill in fields in the interface_opts structure.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
if_list = capture_interface_list(&err, NULL, NULL);
|
if (!capture_opts_search_for_interface(&interface_opts, optarg_str_p)) {
|
||||||
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
|
* We didn't find the interface in the list; just use
|
||||||
* the specified name, so that, for example, if an
|
* the specified name, so that, for example, if an
|
||||||
|
@ -659,24 +726,13 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
|
||||||
* for testing purposes.
|
* for testing purposes.
|
||||||
*/
|
*/
|
||||||
interface_opts.name = g_strdup(optarg_str_p);
|
interface_opts.name = g_strdup(optarg_str_p);
|
||||||
interface_opts.console_display_name = g_strdup(optarg_str_p);
|
interface_opts.descr = NULL;
|
||||||
interface_opts.if_type = capture_opts->default_options.if_type;
|
interface_opts.display_name = g_strdup(optarg_str_p);
|
||||||
interface_opts.extcap = g_strdup(capture_opts->default_options.extcap);
|
|
||||||
}
|
|
||||||
free_interface_list(if_list);
|
|
||||||
} else {
|
|
||||||
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.if_type = capture_opts->default_options.if_type;
|
||||||
interface_opts.extcap = g_strdup(capture_opts->default_options.extcap);
|
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.cfilter = g_strdup(capture_opts->default_options.cfilter);
|
||||||
interface_opts.snaplen = capture_opts->default_options.snaplen;
|
interface_opts.snaplen = capture_opts->default_options.snaplen;
|
||||||
interface_opts.has_snaplen = capture_opts->default_options.has_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->name);
|
||||||
g_free(interface_opts->descr);
|
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->cfilter);
|
||||||
g_free(interface_opts->timestamp_type);
|
g_free(interface_opts->timestamp_type);
|
||||||
g_free(interface_opts->extcap);
|
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);
|
device = &g_array_index(capture_opts->all_ifaces, interface_t, i);
|
||||||
if (!device->hidden && device->selected) {
|
if (!device->hidden && device->selected) {
|
||||||
interface_opts.name = g_strdup(device->name);
|
interface_opts.name = g_strdup(device->name);
|
||||||
interface_opts.descr = g_strdup(device->display_name);
|
interface_opts.descr = g_strdup(device->friendly_name);
|
||||||
interface_opts.console_display_name = g_strdup(device->name);
|
interface_opts.display_name = g_strdup(device->display_name);
|
||||||
interface_opts.linktype = device->active_dlt;
|
interface_opts.linktype = device->active_dlt;
|
||||||
interface_opts.cfilter = g_strdup(device->cfilter);
|
interface_opts.cfilter = g_strdup(device->cfilter);
|
||||||
interface_opts.timestamp_type = g_strdup(device->timestamp_type);
|
interface_opts.timestamp_type = g_strdup(device->timestamp_type);
|
||||||
|
|
|
@ -197,9 +197,9 @@ typedef struct link_row_tag {
|
||||||
} link_row;
|
} link_row;
|
||||||
|
|
||||||
typedef struct interface_options_tag {
|
typedef struct interface_options_tag {
|
||||||
gchar *name; /* the name of the interface provided to winpcap/libpcap to specify the interface */
|
gchar *name; /* the name of the interface supplied to libpcap/WinPcap/Npcap to specify the interface */
|
||||||
gchar *descr;
|
gchar *descr; /* a more user-friendly description of the interface; may be NULL if none */
|
||||||
gchar *console_display_name; /* the name displayed in the console, also the basis for autonamed pcap filenames */
|
gchar *display_name; /* the name displayed in the console and title bar */
|
||||||
gchar *cfilter;
|
gchar *cfilter;
|
||||||
gboolean has_snaplen;
|
gboolean has_snaplen;
|
||||||
int snaplen;
|
int snaplen;
|
||||||
|
|
|
@ -260,6 +260,150 @@ add_unix_interface_ifinfo(if_info_t *if_info, const char *name _U_,
|
||||||
}
|
}
|
||||||
#endif
|
#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_t *
|
||||||
if_info_new(const char *name, const char *description, gboolean loopback)
|
if_info_new(const char *name, const char *description, gboolean loopback)
|
||||||
{
|
{
|
||||||
|
@ -528,14 +672,7 @@ get_interface_list_findalldevs(int *err, char **err_str)
|
||||||
static void
|
static void
|
||||||
free_if_cb(gpointer data, gpointer user_data _U_)
|
free_if_cb(gpointer data, gpointer user_data _U_)
|
||||||
{
|
{
|
||||||
if_info_t *if_info = (if_info_t *)data;
|
if_info_free((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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -75,6 +75,17 @@ extern GList *capture_interface_list(int *err, char **err_str, void (*update_cb)
|
||||||
|
|
||||||
void free_interface_list(GList *if_list);
|
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
|
* "get_if_capabilities()" and "capture_if_capabilities()" return a pointer
|
||||||
* to an allocated instance of this structure. "free_if_capabilities()"
|
* to an allocated instance of this structure. "free_if_capabilities()"
|
||||||
|
|
52
dumpcap.c
52
dumpcap.c
|
@ -3310,16 +3310,48 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
|
||||||
prefix = g_strdup_printf("wireshark_%d_interfaces", global_capture_opts.ifaces->len);
|
prefix = g_strdup_printf("wireshark_%d_interfaces", global_capture_opts.ifaces->len);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* One interface; use its name to generate the temporary file
|
* One interface; use its description, if it has one, to generate
|
||||||
* name prefix.
|
* the temporary file name, otherwise use its name.
|
||||||
*/
|
*/
|
||||||
gchar *basename;
|
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
|
#ifdef _WIN32
|
||||||
/* use the generic portion of the interface guid to form the basis of the filename */
|
/*
|
||||||
if (strncmp("NPF_{", basename, 5)==0)
|
* This is Windows, where we might have an ugly GUID-based
|
||||||
{
|
* interface name.
|
||||||
/* we have a windows guid style device name, extract the guid digits as the basis of the filename */
|
*
|
||||||
|
* 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;
|
GString *iface;
|
||||||
iface = isolate_uuid(basename);
|
iface = isolate_uuid(basename);
|
||||||
g_free(basename);
|
g_free(basename);
|
||||||
|
@ -3327,6 +3359,8 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
|
||||||
g_string_free(iface, TRUE);
|
g_string_free(iface, TRUE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
/* generate the temp file name prefix */
|
||||||
prefix = g_strconcat("wireshark_", basename, NULL);
|
prefix = g_strconcat("wireshark_", basename, NULL);
|
||||||
g_free(basename);
|
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_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) */
|
/* 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, "and ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_string_append_printf(str, "'%s'", interface_opts->console_display_name);
|
g_string_append_printf(str, "'%s'", interface_opts->display_name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g_string_append_printf(str, "%u interfaces", global_capture_opts.ifaces->len);
|
g_string_append_printf(str, "%u interfaces", global_capture_opts.ifaces->len);
|
||||||
|
|
|
@ -468,23 +468,27 @@ get_if_name(const char *if_text)
|
||||||
return if_name;
|
return if_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return interface_opts->descr (after setting it if it is not set)
|
/* Return a display name for the interface.
|
||||||
* This is necessary because capture_opts.c can't set descr (at least
|
|
||||||
* not without adding significant dependencies there).
|
|
||||||
*/
|
*/
|
||||||
static const char *
|
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;
|
interface_options *interface_opts;
|
||||||
|
|
||||||
if (i < capture_opts->ifaces->len) {
|
if (i < capture_opts->ifaces->len) {
|
||||||
interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
|
interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
|
||||||
if (!interface_opts->descr && interface_opts->name) {
|
if (interface_opts->display_name) {
|
||||||
|
return interface_opts->display_name;
|
||||||
|
}
|
||||||
|
if (!interface_opts->display_name) {
|
||||||
|
if (interface_opts->descr && interface_opts->name) {
|
||||||
interface_opts->descr = get_interface_descriptive_name(interface_opts->name);
|
interface_opts->descr = get_interface_descriptive_name(interface_opts->name);
|
||||||
}
|
}
|
||||||
return (interface_opts->descr);
|
interface_opts->display_name = g_strdup(interface_opts->descr);
|
||||||
|
}
|
||||||
|
return interface_opts->display_name;
|
||||||
} else {
|
} 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)
|
if (style & IFLIST_QUOTE_IF_DESCRIPTION)
|
||||||
g_string_append_printf(iface_list_string, "'");
|
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)
|
if (style & IFLIST_QUOTE_IF_DESCRIPTION)
|
||||||
g_string_append_printf(iface_list_string, "'");
|
g_string_append_printf(iface_list_string, "'");
|
||||||
if (style & IFLIST_SHOW_FILTER) {
|
if (style & IFLIST_SHOW_FILTER) {
|
||||||
|
|
Loading…
Reference in New Issue