summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2012-11-22 06:02:49 +0000
committerGuy Harris <guy@alum.mit.edu>2012-11-22 06:02:49 +0000
commitbd976ae6c06b2111bd82df16b77739731dc17402 (patch)
tree406d65d00129abb45868150687f267a139bbf670
parentb9e8e95ffe9f352cde5847d458081826523cf46f (diff)
downloadwireshark-bd976ae6c06b2111bd82df16b77739731dc17402.tar.gz
On UN*X, if an interface has a description, use it as the "friendly
name". If it doesn't have a description, on OS X, use the System Configuration framework to attempt to get a "friendly name" for interfaces. If a loopback device doesn't have a friendly name, give it "Loopback" as the friendly name. Move the "turn a CFString into a mallocated C string" routine into common code, as it's used in more than one place. svn path=/trunk/; revision=46131
-rw-r--r--Makefile.am8
-rw-r--r--Makefile.common4
-rw-r--r--capture-pcap-util-int.h3
-rw-r--r--capture-pcap-util-unix.c16
-rw-r--r--capture-pcap-util.c109
-rw-r--r--capture_ifinfo.c2
-rw-r--r--capture_ifinfo.h8
-rw-r--r--capture_opts.c10
-rw-r--r--capture_ui_utils.c27
-rw-r--r--capture_unix_ifnames.c116
-rw-r--r--capture_unix_ifnames.h33
-rw-r--r--cfutils.c56
-rw-r--r--cfutils.h28
-rw-r--r--configure.ac8
-rw-r--r--dumpcap.c5
-rw-r--r--ui/gtk/capture_dlg.c3
-rw-r--r--ui/gtk/capture_if_dlg.c8
-rw-r--r--ui/gtk/prefs_capture.c6
-rw-r--r--ui/iface_lists.c39
-rw-r--r--version_info.c13
20 files changed, 415 insertions, 87 deletions
diff --git a/Makefile.am b/Makefile.am
index dc6b2fd4b0..9e4c452df8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -271,7 +271,9 @@ wimaxasncp_DATA = \
wimaxasncp/dictionary.xml \
wimaxasncp/dictionary.dtd
-PLATFORM_SRC = capture-pcap-util-unix.c
+PLATFORM_SRC = \
+ capture-pcap-util-unix.c \
+ capture_unix_ifnames.c
if HAVE_PLUGINS
-include plugins/Custom.make
@@ -347,6 +349,7 @@ wireshark_LDADD = \
@ADNS_LIBS@ \
@KRB5_LIBS@ \
@APPLICATIONSERVICES_FRAMEWORKS@ \
+ @SYSTEMCONFIGURATION_FRAMEWORKS@ \
@COREFOUNDATION_FRAMEWORKS@ \
@PY_LIBS@ \
@LIBGCRYPT_LIBS@ \
@@ -381,6 +384,7 @@ tshark_LDADD = \
@C_ARES_LIBS@ \
@ADNS_LIBS@ \
@KRB5_LIBS@ \
+ @SYSTEMCONFIGURATION_FRAMEWORKS@ \
@COREFOUNDATION_FRAMEWORKS@ \
@PY_LIBS@ \
@LIBGCRYPT_LIBS@ \
@@ -409,6 +413,7 @@ rawshark_LDADD = \
@C_ARES_LIBS@ \
@ADNS_LIBS@ \
@KRB5_LIBS@ \
+ @SYSTEMCONFIGURATION_FRAMEWORKS@ \
@COREFOUNDATION_FRAMEWORKS@ \
@PY_LIBS@ \
@LIBGCRYPT_LIBS@ \
@@ -496,6 +501,7 @@ dumpcap_LDADD = \
@PCAP_LIBS@ \
@SOCKET_LIBS@ \
@NSL_LIBS@ \
+ @SYSTEMCONFIGURATION_FRAMEWORKS@ \
@COREFOUNDATION_FRAMEWORKS@ \
@LIBCAP_LIBS@
dumpcap_CFLAGS = $(AM_CLEAN_CFLAGS)
diff --git a/Makefile.common b/Makefile.common
index f7dbcce970..7a5b90b3bd 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -48,6 +48,7 @@ WIRESHARK_COMMON_SRC = \
$(PLATFORM_SRC) \
capture-pcap-util.c \
cfile.c \
+ cfutils.c \
clopts_common.c \
disabled_protos.c \
frame_data_sequence.c \
@@ -65,7 +66,9 @@ WIRESHARK_COMMON_INCLUDES = \
svnversion.h \
capture-pcap-util.h \
capture-pcap-util-int.h \
+ capture_unix_ifnames.h \
cfile.h \
+ cfutils.h \
clopts_common.h \
cmdarg_err.h \
console_io.h \
@@ -196,6 +199,7 @@ dumpcap_SOURCES = \
capture_opts.c \
capture-pcap-util.c \
capture_stop_conditions.c \
+ cfutils.c \
clopts_common.c \
conditions.c \
dumpcap.c \
diff --git a/capture-pcap-util-int.h b/capture-pcap-util-int.h
index c42219f60a..9689bb10e1 100644
--- a/capture-pcap-util-int.h
+++ b/capture-pcap-util-int.h
@@ -25,7 +25,8 @@
#ifndef __PCAP_UTIL_INT_H__
#define __PCAP_UTIL_INT_H__
-extern if_info_t *if_info_new(char *name, char *description);
+extern if_info_t *if_info_new(const char *name, const char *friendly_name,
+ const char *vendor_description, gboolean loopback);
extern void if_info_add_address(if_info_t *if_info, struct sockaddr *addr);
#ifdef HAVE_PCAP_FINDALLDEVS
#ifdef HAVE_PCAP_REMOTE
diff --git a/capture-pcap-util-unix.c b/capture-pcap-util-unix.c
index df78f03176..6149acc675 100644
--- a/capture-pcap-util-unix.c
+++ b/capture-pcap-util-unix.c
@@ -119,6 +119,7 @@ get_interface_list(int *err, char **err_str)
char *buf;
if_info_t *if_info;
char errbuf[PCAP_ERRBUF_SIZE];
+ gboolean loopback;
if (sock < 0) {
*err = CANT_GET_INTERFACE_LIST;
@@ -234,14 +235,14 @@ get_interface_list(int *err, char **err_str)
* don't want a loopback interface to be the default capture
* device unless there are no non-loopback devices.
*/
- if_info = if_info_new(ifr->ifr_name, NULL);
+ loopback = ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
+ strncmp(ifr->ifr_name, "lo", 2) == 0);
+ if_info = if_info_new(ifr->ifr_name, loopback ? "Loopback" : NULL,
+ NULL, loopback);
if_info_add_address(if_info, &ifr->ifr_addr);
- if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
- strncmp(ifr->ifr_name, "lo", 2) == 0) {
- if_info->loopback = TRUE;
+ if (loopback)
il = g_list_append(il, if_info);
- } else {
- if_info->loopback = FALSE;
+ else {
il = g_list_insert(il, if_info, nonloopback_pos);
/*
* Insert the next non-loopback interface after this
@@ -274,7 +275,8 @@ get_interface_list(int *err, char **err_str)
* It worked; we can use the "any" device.
*/
if_info = if_info_new("any",
- "Pseudo-device that captures on all interfaces");
+ "Pseudo-device that captures on all interfaces",
+ NULL, FALSE);
il = g_list_insert(il, if_info, -1);
pcap_close(pch);
}
diff --git a/capture-pcap-util.c b/capture-pcap-util.c
index 3658513b0e..ffc8352eb0 100644
--- a/capture-pcap-util.c
+++ b/capture-pcap-util.c
@@ -54,28 +54,28 @@
#ifdef _WIN32
#include "capture_win_ifnames.h" /* windows friendly interface names */
+#else
+#include "capture_unix_ifnames.h"
#endif
if_info_t *
-if_info_new(char *name, char *description)
+if_info_new(const char *name, const char *friendly_name,
+ const char *vendor_description, gboolean loopback)
{
if_info_t *if_info;
if_info = (if_info_t *)g_malloc(sizeof (if_info_t));
if_info->name = g_strdup(name);
- if (description == NULL)
- if_info->description = NULL;
+ if (friendly_name == NULL)
+ if_info->friendly_name = NULL;
else
- if_info->description = g_strdup(description);
-
-#ifdef _WIN32
- get_windows_interface_friendlyname(name, &if_info->friendly_name);
-#else
- if_info->friendly_name = NULL;
-#endif
-
+ if_info->friendly_name = g_strdup(friendly_name);
+ if (vendor_description == NULL)
+ if_info->vendor_description = NULL;
+ else
+ if_info->vendor_description = g_strdup(vendor_description);
+ if_info->loopback = loopback;
if_info->addrs = NULL;
- if_info->loopback = FALSE;
return if_info;
}
@@ -115,17 +115,13 @@ if_info_add_address(if_info_t *if_info, struct sockaddr *addr)
#ifdef HAVE_PCAP_FINDALLDEVS
/*
- * Get all IP address information, and the loopback flag, for the given
- * interface.
+ * Get all IP address information for the given interface.
*/
static void
if_info_ip(if_info_t *if_info, pcap_if_t *d)
{
pcap_addr_t *a;
- /* Loopback flag */
- if_info->loopback = (d->flags & PCAP_IF_LOOPBACK) ? TRUE : FALSE;
-
/* All addresses */
for (a = d->addresses; a != NULL; a = a->next) {
if (a->addr != NULL)
@@ -143,6 +139,8 @@ get_interface_list_findalldevs_ex(const char *source,
pcap_if_t *alldevs, *dev;
if_info_t *if_info;
char errbuf[PCAP_ERRBUF_SIZE];
+ gboolean loopback;
+ char *friendly_name;
if (pcap_findalldevs_ex((char *)source, auth, &alldevs, errbuf) == -1) {
*err = CANT_GET_INTERFACE_LIST;
@@ -162,7 +160,41 @@ get_interface_list_findalldevs_ex(const char *source,
}
for (dev = alldevs; dev != NULL; dev = dev->next) {
- if_info = if_info_new(dev->name, dev->description);
+ /* Loopback flag */
+ loopback = (dev->flags & PCAP_IF_LOOPBACK) ? TRUE : FALSE;
+
+#ifdef _WIN32
+ /*
+ * On Windows, the "description" is a vendor description,
+ * and the friendly name isn't returned by WinPcap.
+ * Fetch it ourselves.
+ */
+ get_windows_interface_friendly_name(dev->name, &friendly_name);
+ if_info = if_info_new(dev->name, friendly_name,
+ dev->description, loopback);
+#else
+ /*
+ * On UN*X, if there is a description, it's a friendly
+ * name, and there is no vendor description.
+ * If there's no description, fetch a friendly name
+ * if we can; if that fails, then, for a loopback
+ * interface, give it the friendly name "Loopback".
+ */
+ friendly_name = dev->description;
+ if (friendly_name == NULL) {
+ friendly_name = get_unix_interface_friendly_name(dev->name);
+ if (friendly_name == NULL) {
+ /*
+ * If this is a loopback interface, give it a
+ * "friendly name" of "Loopback".
+ */
+ if (loopback)
+ friendly_name = g_strdup("Loopback");
+ }
+ }
+ if_info = if_info_new(dev->name, friendly_name, NULL, loopback);
+#endif
+ g_free(friendly_name);
il = g_list_append(il, if_info);
if_info_ip(if_info, dev);
}
@@ -179,6 +211,8 @@ get_interface_list_findalldevs(int *err, char **err_str)
pcap_if_t *alldevs, *dev;
if_info_t *if_info;
char errbuf[PCAP_ERRBUF_SIZE];
+ gboolean loopback;
+ char *friendly_name;
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
*err = CANT_GET_INTERFACE_LIST;
@@ -198,7 +232,41 @@ get_interface_list_findalldevs(int *err, char **err_str)
}
for (dev = alldevs; dev != NULL; dev = dev->next) {
- if_info = if_info_new(dev->name, dev->description);
+ /* Loopback flag */
+ loopback = (dev->flags & PCAP_IF_LOOPBACK) ? TRUE : FALSE;
+
+#ifdef _WIN32
+ /*
+ * On Windows, the "description" is a vendor description,
+ * and the friendly name isn't returned by WinPcap.
+ * Fetch it ourselves.
+ */
+ get_windows_interface_friendly_name(dev->name, &friendly_name);
+ if_info = if_info_new(dev->name, friendly_name,
+ dev->description, loopback);
+#else
+ /*
+ * On UN*X, if there is a description, it's a friendly
+ * name, and there is no vendor description.
+ * If there's no description, fetch a friendly name
+ * if we can; if that fails, then, for a loopback
+ * interface, give it the friendly name "Loopback".
+ */
+ friendly_name = dev->description;
+ if (friendly_name == NULL) {
+ friendly_name = get_unix_interface_friendly_name(dev->name);
+ if (friendly_name == NULL) {
+ /*
+ * If this is a loopback interface, give it a
+ * "friendly name" of "Loopback".
+ */
+ if (loopback)
+ friendly_name = g_strdup("Loopback");
+ }
+ }
+ if_info = if_info_new(dev->name, friendly_name, NULL, loopback);
+#endif
+ g_free(friendly_name);
il = g_list_append(il, if_info);
if_info_ip(if_info, dev);
}
@@ -220,7 +288,8 @@ 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->description);
+ g_free(if_info->friendly_name);
+ g_free(if_info->vendor_description);
g_slist_foreach(if_info->addrs, free_if_info_addr_cb, NULL);
g_slist_free(if_info->addrs);
diff --git a/capture_ifinfo.c b/capture_ifinfo.c
index 314a01ad1e..df8940d85d 100644
--- a/capture_ifinfo.c
+++ b/capture_ifinfo.c
@@ -159,7 +159,7 @@ capture_interface_list(int *err, char **err_str)
if_info = g_malloc0(sizeof(if_info_t));
if_info->name = g_strdup(name);
if (strlen(if_parts[1]) > 0)
- if_info->description = g_strdup(if_parts[1]);
+ if_info->vendor_description = g_strdup(if_parts[1]);
if (strlen(if_parts[2]) > 0)
if_info->friendly_name = g_strdup(if_parts[2]);
addr_parts = g_strsplit(if_parts[3], ",", 0);
diff --git a/capture_ifinfo.h b/capture_ifinfo.h
index 3ec2e51160..7802598bef 100644
--- a/capture_ifinfo.h
+++ b/capture_ifinfo.h
@@ -35,8 +35,12 @@ extern "C" {
*/
typedef struct {
char *name; /* e.g. "eth0" */
- char *description; /* vendor description from libpcap, e.g. "Realtek PCIe GBE Family Controller" or NULL */
- char *friendly_name; /* from OS, e.g. "Local Area Connection" */
+ char *friendly_name; /* from OS, e.g. "Local Area Connection", or
+ NULL if not available */
+ char *vendor_description;
+ /* vendor description from pcap_findalldevs(),
+ e.g. "Realtek PCIe GBE Family Controller",
+ or NULL if not available */
GSList *addrs; /* containing address values of if_addr_t */
gboolean loopback; /* TRUE if loopback, FALSE otherwise */
} if_info_t;
diff --git a/capture_opts.c b/capture_opts.c
index 3f9dd3b099..52e5e6429a 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -874,13 +874,13 @@ capture_opts_print_interfaces(GList *if_list)
if_info = (if_info_t *)if_entry->data;
fprintf_stderr("%d. %s", i++, if_info->name);
- /* print the interface friendly name if known, if not fall back to vendor description */
+ /* Print the interface friendly name, if it exists;
+ if not fall back to vendor description, if it exists. */
if (if_info->friendly_name != NULL){
fprintf_stderr(" (%s)", if_info->friendly_name);
- }else{
- /* Print the description if it exists */
- if (if_info->description != NULL)
- fprintf_stderr(" (%s)", if_info->description);
+ } else {
+ if (if_info->vendor_description != NULL)
+ fprintf_stderr(" (%s)", if_info->vendor_description);
}
fprintf_stderr("\n");
}
diff --git a/capture_ui_utils.c b/capture_ui_utils.c
index 7af80a9a72..922f4aecd5 100644
--- a/capture_ui_utils.c
+++ b/capture_ui_utils.c
@@ -180,14 +180,18 @@ get_interface_descriptive_name(const char *if_name)
do {
if_info = if_entry->data;
if (strcmp(if_info->name, if_name) == 0) {
- if (if_info->friendly_name!= NULL) {
- /* use the friendly name */
+ if (if_info->friendly_name != NULL) {
+ /* We have a "friendly name"; return a copy of that
+ as the description - when we free the interface
+ list, that'll also free up the strings to which
+ it refers. */
descr = g_strdup(if_info->friendly_name);
- }else if (if_info->description != NULL) {
- /* Return a copy of that - when we free the interface
- list, that'll also free up the strings to which
- it refers. */
- descr = g_strdup(if_info->description);
+ } else if (if_info->vendor_description != NULL) {
+ /* We have no "friendly name", but we have a vendor
+ description; return a copy of that - when we free
+ the interface list, that'll also free up the strings
+ to which it refers. */
+ descr = g_strdup(if_info->vendor_description);
}
break;
}
@@ -243,9 +247,9 @@ build_capture_combo_name(GList *if_list, gchar *if_name)
/* No, we don't have a user-supplied description; did we get
one from the OS or libpcap? */
if_info = search_info(if_list, if_name);
- if (if_info != NULL && if_info->description != NULL) {
+ if (if_info != NULL && if_info->vendor_description != NULL) {
/* Yes - use it. */
- if_string = g_strdup_printf("%s: %s", if_info->description,
+ if_string = g_strdup_printf("%s: %s", if_info->vendor_description,
if_info->name);
} else {
/* No. */
@@ -287,9 +291,10 @@ build_capture_combo_list(GList *if_list, gboolean do_hide)
} else {
/* No, we don't have a user-supplied description; did we get
one from the OS or libpcap? */
- if (if_info->description != NULL) {
+ if (if_info->vendor_description != NULL) {
/* Yes - use it. */
- if_string = g_strdup_printf("%s: %s", if_info->description,
+ if_string = g_strdup_printf("%s: %s",
+ if_info->vendor_description,
if_info->name);
} else {
/* No. */
diff --git a/capture_unix_ifnames.c b/capture_unix_ifnames.c
new file mode 100644
index 0000000000..e2584226da
--- /dev/null
+++ b/capture_unix_ifnames.c
@@ -0,0 +1,116 @@
+/* capture_unix_ifnames.c
+ * Routines supporting the use of UN*X friendly interface names, if any,
+ * within Wireshark
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 2001 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "capture_unix_ifnames.h"
+
+/*
+ * Given an interface name, find the "friendly name" for the interface.
+ */
+
+#ifdef __APPLE__
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+#include "cfutils.h"
+
+/*
+ * On OS X, we do that by getting all the interfaces that the System
+ * Configuration framework knows about, look for the one with a "BSD
+ * name" matching the interface name, and, if we find it, return its
+ * "localized display name", if it has one.
+ */
+char *
+get_unix_interface_friendly_name(const char *ifname)
+{
+ CFStringRef ifname_CFString;
+ CFArrayRef interfaces;
+ CFIndex num_interfaces;
+ CFIndex i;
+ SCNetworkInterfaceRef interface;
+ CFStringRef bsdname_CFString;
+ CFStringRef friendly_name_CFString;
+ char *friendly_name = NULL;
+
+ interfaces = SCNetworkInterfaceCopyAll();
+ if (interfaces == NULL) {
+ /*
+ * Couldn't get a list of interfaces.
+ */
+ return NULL;
+ }
+
+ ifname_CFString = CFStringCreateWithCString(kCFAllocatorDefault,
+ ifname, kCFStringEncodingUTF8);
+ if (ifname_CFString == NULL) {
+ /*
+ * Couldn't convert the interface name to a CFString.
+ */
+ CFRelease(interfaces);
+ return NULL;
+ }
+
+ num_interfaces = CFArrayGetCount(interfaces);
+ for (i = 0; i < num_interfaces; i++) {
+ interface = CFArrayGetValueAtIndex(interfaces, i);
+ bsdname_CFString = SCNetworkInterfaceGetBSDName(interface);
+ if (bsdname_CFString == NULL) {
+ /*
+ * This interface has no BSD name, so it's not
+ * a regular network interface.
+ */
+ continue;
+ }
+ if (CFStringCompare(ifname_CFString, bsdname_CFString, 0) == 0) {
+ /*
+ * This is the interface.
+ */
+ friendly_name_CFString = SCNetworkInterfaceGetLocalizedDisplayName(interface);
+ if (friendly_name_CFString != NULL)
+ friendly_name = CFString_to_C_string(friendly_name_CFString);
+ break;
+ }
+ }
+
+ CFRelease(interfaces);
+ return friendly_name;
+}
+
+#else /* __APPLE__ */
+
+/*
+ * Nothing supported on other platforms.
+ */
+char *
+get_unix_interface_friendly_name(const char *ifname _U_)
+{
+ return NULL;
+}
+
+#endif /* __APPLE__ */
diff --git a/capture_unix_ifnames.h b/capture_unix_ifnames.h
new file mode 100644
index 0000000000..99662522b6
--- /dev/null
+++ b/capture_unix_ifnames.h
@@ -0,0 +1,33 @@
+/* capture_unix_ifnames.h
+ * Routines supporting the use of UN*X friendly interface names, if any,
+ * within Wireshark
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CAPTURE_UNIX_IFNAMES_H
+#define CAPTURE_UNIX_IFNAMES_H
+
+/* returns the interface friendly name for a device name; if it is unable to
+ * resolve the name, NULL is returned */
+char *get_unix_interface_friendly_name(const char *ifname);
+
+#endif
diff --git a/cfutils.c b/cfutils.c
new file mode 100644
index 0000000000..78db0ac26c
--- /dev/null
+++ b/cfutils.c
@@ -0,0 +1,56 @@
+/* cfutils.c
+ * Routines to work around deficiencies in Core Foundation, such as the
+ * lack of a routine to convert a CFString to a C string of arbitrary
+ * size.
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 2001 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_OS_X_FRAMEWORKS
+#include <glib.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include "cfutils.h"
+
+/*
+ * Convert a CFString to a UTF-8-encoded C string; the resulting string
+ * is allocated with g_malloc(). Returns NULL if the conversion fails.
+ */
+char *
+CFString_to_C_string(CFStringRef cfstring)
+{
+ CFIndex string_len;
+ char *string;
+
+ string_len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstring),
+ kCFStringEncodingUTF8);
+ string = g_malloc(string_len + 1);
+ if (!CFStringGetCString(cfstring, string, string_len + 1,
+ kCFStringEncodingUTF8)) {
+ g_free(string);
+ return NULL;
+ }
+ return string;
+}
+#endif
+
+
diff --git a/cfutils.h b/cfutils.h
new file mode 100644
index 0000000000..98a726bf89
--- /dev/null
+++ b/cfutils.h
@@ -0,0 +1,28 @@
+/* cfutils.h
+ * Declarations of routines to work around deficiencies in Core Foundation,
+ * such as the lack of a routine to convert a CFString to a C string of
+ * arbitrary size.
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 2001 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+extern char *CFString_to_C_string(CFStringRef cfstring);
+
diff --git a/configure.ac b/configure.ac
index a422c3d978..fff0778ad0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -595,8 +595,10 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])])
# "just Darwin" (as we don't currently support iOS, and as I don't
# think you can build and run "just Darwin" as an OS for PCs), we
# arrange to build some programs with Application Services so they
-# can launch Web browsers and Finder windows, and build any programs
-# that use either of those frameworks or that report version information
+# can launch Web browsers and Finder windows, arrange to build some
+# programs with System Configuration so they can get "friendly names"
+# and other information about interfaces, and build any programs that
+# use either of those frameworks or that report version information
# with Core Foundation as the frameworks in question use it and as we
# get version information from plists and thus need Core Foundation
# to process those plists.
@@ -606,6 +608,7 @@ case "$host_os" in
darwin*)
AC_DEFINE(HAVE_OS_X_FRAMEWORKS, 1, [Define to 1 if you have OS X frameworks])
APPLICATIONSERVICES_FRAMEWORKS="-framework ApplicationServices"
+ SYSTEMCONFIGURATION_FRAMEWORKS="-framework SystemConfiguration"
COREFOUNDATION_FRAMEWORKS="-framework CoreFoundation"
#
@@ -624,6 +627,7 @@ darwin*)
;;
esac
AC_SUBST(APPLICATIONSERVICES_FRAMEWORKS)
+AC_SUBST(SYSTEMCONFIGURATION_FRAMEWORKS)
AC_SUBST(COREFOUNDATION_FRAMEWORKS)
#
diff --git a/dumpcap.c b/dumpcap.c
index 4602da345e..399f6043fd 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -1307,11 +1307,12 @@ print_machine_readable_interfaces(GList *if_list)
* separated.
*/
/* XXX - Make sure our description doesn't contain a tab */
- if (if_info->description != NULL)
- printf("\t%s\t", if_info->description);
+ if (if_info->vendor_description != NULL)
+ printf("\t%s\t", if_info->vendor_description);
else
printf("\t\t");
+ /* XXX - Make sure our friendly name doesn't contain a tab */
if (if_info->friendly_name != NULL)
printf("%s\t", if_info->friendly_name);
else
diff --git a/ui/gtk/capture_dlg.c b/ui/gtk/capture_dlg.c
index 0a2f9fd1f2..c5d404ba41 100644
--- a/ui/gtk/capture_dlg.c
+++ b/ui/gtk/capture_dlg.c
@@ -3352,7 +3352,8 @@ add_pipe_cb(gpointer w _U_)
device.active_dlt = -1;
device.locked = FALSE;
device.if_info.name = g_strdup(g_save_file);
- device.if_info.description = NULL;
+ device.if_info.friendly_name = NULL;
+ device.if_info.vendor_description = NULL;
device.if_info.addrs = NULL;
device.if_info.loopback = FALSE;
#if defined(HAVE_PCAP_CREATE)
diff --git a/ui/gtk/capture_if_dlg.c b/ui/gtk/capture_if_dlg.c
index c8f299f3ed..e22b54ae64 100644
--- a/ui/gtk/capture_if_dlg.c
+++ b/ui/gtk/capture_if_dlg.c
@@ -745,16 +745,16 @@ capture_if_refresh_if_list(void)
data.descr_lb = gtk_label_new(user_descr);
g_free (user_descr);
} else {
- if (device.if_info.description)
- data.descr_lb = gtk_label_new(device.if_info.description);
+ if (device.if_info.vendor_description)
+ data.descr_lb = gtk_label_new(device.if_info.vendor_description);
else
data.descr_lb = gtk_label_new("");
}
gtk_misc_set_alignment(GTK_MISC(data.descr_lb), 0.0f, 0.5f);
gtk_table_attach_defaults(GTK_TABLE(if_tb), data.descr_lb, 4, 5, row, row+1);
- if (device.if_info.description) {
+ if (device.if_info.vendor_description) {
g_string_append(if_tool_str, "Description: ");
- g_string_append(if_tool_str, device.if_info.description);
+ g_string_append(if_tool_str, device.if_info.vendor_description);
g_string_append(if_tool_str, "\n");
}
diff --git a/ui/gtk/prefs_capture.c b/ui/gtk/prefs_capture.c
index 1baa8ad611..47560acc8c 100644
--- a/ui/gtk/prefs_capture.c
+++ b/ui/gtk/prefs_capture.c
@@ -1353,9 +1353,9 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info)
/* set device name text */
text[0] = g_strdup(if_info->name);
- /* set OS description */
- if (if_info->description != NULL)
- text[1] = g_strdup(if_info->description);
+ /* set vendor description */
+ if (if_info->vendor_description != NULL)
+ text[1] = g_strdup(if_info->vendor_description);
else
text[1] = g_strdup("");
diff --git a/ui/iface_lists.c b/ui/iface_lists.c
index 41f360a358..bbdc907398 100644
--- a/ui/iface_lists.c
+++ b/ui/iface_lists.c
@@ -43,16 +43,16 @@ capture_options global_capture_opts;
/*
* Used when sorting an interface list into alphabetical order by
- * their descriptions.
+ * their friendly names.
*/
gint
if_list_comparator_alph(const void *first_arg, const void *second_arg)
{
const if_info_t *first = first_arg, *second = second_arg;
- if (first != NULL && first->description != NULL &&
- second != NULL && second->description != NULL) {
- return g_ascii_strcasecmp(first->description, second->description);
+ if (first != NULL && first->friendly_name != NULL &&
+ second != NULL && second->friendly_name != NULL) {
+ return g_ascii_strcasecmp(first->friendly_name, second->friendly_name);
} else {
return 0;
}
@@ -114,7 +114,8 @@ scan_local_interfaces(void)
device.locked = FALSE;
temp = g_malloc0(sizeof(if_info_t));
temp->name = g_strdup(if_info->name);
- temp->description = g_strdup(if_info->description);
+ temp->friendly_name = g_strdup(if_info->friendly_name);
+ temp->vendor_description = g_strdup(if_info->vendor_description);
temp->loopback = if_info->loopback;
/* Is this interface hidden and, if so, should we include it anyway? */
@@ -130,30 +131,35 @@ scan_local_interfaces(void)
if (if_info->friendly_name != NULL) {
/* We have a friendly name from the OS, use it */
#ifdef _WIN32
- /* on windows, if known only show the interface friendly name - don't show the device guid */
+ /*
+ * On Windows, if we have a friendly name, just show it,
+ * don't show the name, as that's a string made out of
+ * the device GUID, and not at all friendly.
+ */
if_string = g_strdup_printf("%s", if_info->friendly_name);
#else
+ /*
+ * On UN*X, if we have a friendly name, show it along
+ * with the interface name; the interface name is short
+ * and somewhat friendly, and many UN*X users are used
+ * to interface names, so we should show it.
+ */
if_string = g_strdup_printf("%s: %s", if_info->friendly_name, if_info->name);
#endif
- } else if (if_info->description != NULL) {
+ } else if (if_info->vendor_description != NULL) {
/* We have a device description from libpcap - use it. */
- if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
+ if_string = g_strdup_printf("%s: %s", if_info->vendor_description, if_info->name);
} else {
/* No. */
if_string = g_strdup(if_info->name);
}
}
- if (if_info->loopback) {
- device.display_name = g_strdup_printf("%s (loopback)", if_string);
- } else {
- device.display_name = g_strdup(if_string);
- }
- g_free(if_string);
+ device.display_name = if_string;
device.selected = FALSE;
if (prefs_is_capture_device_hidden(if_info->name)) {
device.hidden = TRUE;
}
- device.type = get_interface_type(if_info->name, if_info->description);
+ device.type = get_interface_type(if_info->name, if_info->vendor_description);
monitor_mode = prefs_capture_device_monitor_mode(if_info->name);
caps = capture_get_if_capabilities(if_info->name, monitor_mode, NULL);
for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
@@ -313,7 +319,8 @@ scan_local_interfaces(void)
device.local = TRUE;
device.locked = FALSE;
device.if_info.name = g_strdup(interface_opts.name);
- device.if_info.description = g_strdup(interface_opts.descr);
+ device.if_info.friendly_name = NULL;
+ device.if_info.vendor_description = g_strdup(interface_opts.descr);
device.if_info.addrs = NULL;
device.if_info.loopback = FALSE;
diff --git a/version_info.c b/version_info.c
index 0ecc6ebd6f..adcdce3a7f 100644
--- a/version_info.c
+++ b/version_info.c
@@ -51,6 +51,7 @@
#ifdef HAVE_OS_X_FRAMEWORKS
#include <CoreFoundation/CoreFoundation.h>
+#include "cfutils.h"
#endif
#ifdef HAVE_LIBCAP
@@ -190,8 +191,6 @@ static char *
get_string_from_dictionary(CFPropertyListRef dict, CFStringRef key)
{
CFStringRef cfstring;
- CFIndex string_len;
- char *string;
cfstring = CFDictionaryGetValue(dict, key);
if (cfstring == NULL)
@@ -200,15 +199,7 @@ get_string_from_dictionary(CFPropertyListRef dict, CFStringRef key)
/* It isn't a string. Punt. */
return NULL;
}
- string_len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstring),
- kCFStringEncodingUTF8);
- string = g_malloc(string_len + 1);
- if (!CFStringGetCString(cfstring, string, string_len + 1,
- kCFStringEncodingUTF8)) {
- g_free(string);
- return NULL;
- }
- return string;
+ return CFString_to_C_string(cfstring);
}
/*