aboutsummaryrefslogtreecommitdiffstats
path: root/caputils
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 /caputils
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>
Diffstat (limited to 'caputils')
-rw-r--r--caputils/capture-pcap-util.c153
-rw-r--r--caputils/capture_ifinfo.h11
2 files changed, 156 insertions, 8 deletions
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()"