On UN*X, if an interface has a description, use it as the "friendly
authorGuy Harris <guy@alum.mit.edu>
Thu, 22 Nov 2012 06:02:49 +0000 (06:02 -0000)
committerGuy Harris <guy@alum.mit.edu>
Thu, 22 Nov 2012 06:02:49 +0000 (06:02 -0000)
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

20 files changed:
Makefile.am
Makefile.common
capture-pcap-util-int.h
capture-pcap-util-unix.c
capture-pcap-util.c
capture_ifinfo.c
capture_ifinfo.h
capture_opts.c
capture_ui_utils.c
capture_unix_ifnames.c [new file with mode: 0644]
capture_unix_ifnames.h [new file with mode: 0644]
cfutils.c [new file with mode: 0644]
cfutils.h [new file with mode: 0644]
configure.ac
dumpcap.c
ui/gtk/capture_dlg.c
ui/gtk/capture_if_dlg.c
ui/gtk/prefs_capture.c
ui/iface_lists.c
version_info.c

index dc6b2fd4b052ae7b6a5245e498095880454ca1e2..9e4c452df8fb097d29121271479b77b69de30b74 100644 (file)
@@ -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)
index f7dbcce970bc06903b1f00463f9fb843c9c0c729..7a5b90b3bd47106f0edf2cd30ffe1966dae84da7 100644 (file)
@@ -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       \
index c42219f60ad8c2ed27d06b8ea37fc62f4edda8a6..9689bb10e1bcf1857e2f97794fac3b49842e046b 100644 (file)
@@ -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
index df78f03176c9ff996fa3d029c94ead84897a3915..6149acc675fc2817a5d98fb8dd3f44abb5b46f83 100644 (file)
@@ -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);
        }
index 3658513b0e04c1307bc0ce28fbe31da5b0f5fc5a..ffc8352eb0cfd0a7279d2f5ace4a7d2dba8c83dd 100644 (file)
 
 #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);
index 314a01ad1e55e50547e115f36618287bed8db9e1..df8940d85d6fe168d8412b3330a307c23c4a52ae 100644 (file)
@@ -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);
index 3ec2e511601277bf7107bf058eb54a14f2ea03fb..7802598bef466f66a5399bba891802acce0de818 100644 (file)
@@ -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;
index 3f9dd3b099660183b56f2ec6705a3053792166c6..52e5e6429a1a580716b1a88bf7c2b3f32e35d3bc 100644 (file)
@@ -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");
     }
index 7af80a9a720783e7c3065bc6de52905e5b420654..922f4aecd5f3aa8e743f1188f33dac5d28e8ac0d 100644 (file)
@@ -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 (file)
index 0000000..e258422
--- /dev/null
@@ -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 (file)
index 0000000..9966252
--- /dev/null
@@ -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 (file)
index 0000000..78db0ac
--- /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 (file)
index 0000000..98a726b
--- /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);
+
index a422c3d97899548c8124a41f704640e6493de2e1..fff0778ad05ede5dd5148159fa52358cf149c16d 100644 (file)
@@ -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)
 
 #
index 4602da345e19cc479612d0e2fc6f93b3602c016b..399f6043fdc0c0e203816b32e0932338ede2f23f 100644 (file)
--- 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
index 0a2f9fd1f2cbb88d3611f8e47f0675b59ce66cab..c5d404ba416453f9fae0bfc9121dc5b1f967a123 100644 (file)
@@ -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)
index c8f299f3edb95d1617dbfcfb09de27a0b9190a4e..e22b54ae6459f21fd76e1f0903b8348c62c7c089 100644 (file)
@@ -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");
     }
 
index 1baa8ad611d641d5e068c45e6c0009a6796656b2..47560acc8c0490ee1c31a14065ccee26c4f1dc3e 100644 (file)
@@ -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("");
 
index 41f360a358cddff5b953a6682dfbd25946e4c7d8..bbdc9073986114b7adf83a4adf6ee5a9df9ce19b 100644 (file)
@@ -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;
 
index 0ecc6ebd6f83ed51fc18f08363544fd8f2da91bf..adcdce3a7f3e39c12124e26810a91fbd5cccb342 100644 (file)
@@ -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);
 }
 
 /*