From bd976ae6c06b2111bd82df16b77739731dc17402 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 22 Nov 2012 06:02:49 +0000 Subject: [PATCH] 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 --- Makefile.am | 8 ++- Makefile.common | 4 ++ capture-pcap-util-int.h | 3 +- capture-pcap-util-unix.c | 16 +++--- capture-pcap-util.c | 109 +++++++++++++++++++++++++++++------- capture_ifinfo.c | 2 +- capture_ifinfo.h | 8 ++- capture_opts.c | 10 ++-- capture_ui_utils.c | 27 +++++---- capture_unix_ifnames.c | 116 +++++++++++++++++++++++++++++++++++++++ capture_unix_ifnames.h | 33 +++++++++++ cfutils.c | 56 +++++++++++++++++++ cfutils.h | 28 ++++++++++ configure.ac | 8 ++- dumpcap.c | 5 +- ui/gtk/capture_dlg.c | 3 +- ui/gtk/capture_if_dlg.c | 8 +-- ui/gtk/prefs_capture.c | 6 +- ui/iface_lists.c | 39 +++++++------ version_info.c | 13 +---- 20 files changed, 415 insertions(+), 87 deletions(-) create mode 100644 capture_unix_ifnames.c create mode 100644 capture_unix_ifnames.h create mode 100644 cfutils.c create mode 100644 cfutils.h 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 + * 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 + +#include "capture_unix_ifnames.h" + +/* + * Given an interface name, find the "friendly name" for the interface. + */ + +#ifdef __APPLE__ + +#include +#include + +#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 + * 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 + * 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 +#include +#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 + * 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 +#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); } /*