Have "get_interface_list()" return a list of "if_info_t" structures
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 10 Sep 2003 05:35:26 +0000 (05:35 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 10 Sep 2003 05:35:26 +0000 (05:35 +0000)
containing a pointer to an interface name and possibly a pointer to an
interface description (although that pointer might be null if no
description is available), rather than having the Windows version glue
together the name and description into a single string.

Supply for the Linux "any" device the same description that libpcap's
"pcap_findalldevs()" returns.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@8440 f5534014-38df-0310-8fa8-9805f1628bb7

gtk/Makefile.am
gtk/Makefile.nmake
gtk/capture_combo_utils.c [new file with mode: 0644]
gtk/capture_combo_utils.h [new file with mode: 0644]
gtk/capture_dlg.c
gtk/capture_prefs.c
gtk/main.c
pcap-util.c
pcap-util.h
tethereal.c

index bffaccc82f537a35ea3dac2ec70c0003ae54afc7..2d85306bfdcfe1f162ce4175bf12789cc66a8c36 100644 (file)
@@ -1,7 +1,7 @@
 # Makefile.am
 # Automake file for the GTK interface routines for Ethereal
 #
-# $Id: Makefile.am,v 1.66 2003/09/02 22:47:58 guy Exp $
+# $Id: Makefile.am,v 1.67 2003/09/10 05:35:25 guy Exp $
 #
 # Ethereal - Network traffic analyzer
 # By Gerald Combs <gerald@ethereal.com>
@@ -54,6 +54,8 @@ ethereal-tap-register.c: $(ETHEREAL_TAP_SRC) $(top_srcdir)/make-tapreg-dotc
 
 if USE_GTK2
 libui_a_SOURCES = \
+       capture_combo_utils.c \
+       capture_combo_utils.h \
        capture_dlg.c   \
        capture_dlg.h   \
        capture_prefs.c \
@@ -134,6 +136,8 @@ libui_a_SOURCES = \
        $(ETHEREAL_TAP_SRC)
 else
 libui_a_SOURCES = \
+       capture_combo_utils.c \
+       capture_combo_utils.h \
        capture_dlg.c   \
        capture_dlg.h   \
        capture_prefs.c \
index 766b0e502b23bb2eae5a5c999dde83e0c4f0dc48..28787f808176ef36380c638fd8e00cba4ce80c14 100644 (file)
@@ -1,7 +1,7 @@
 ## Makefile for building ethereal.exe with Microsoft C and nmake
 ## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
 #
-# $Id: Makefile.nmake,v 1.51 2003/09/02 22:47:58 guy Exp $
+# $Id: Makefile.nmake,v 1.52 2003/09/10 05:35:25 guy Exp $
 
 include ..\config.nmake
 
@@ -44,9 +44,15 @@ ETHEREAL_TAP_OBJECTS = $(ETHEREAL_TAP_SRC:.c=.obj)
 
 # gtkclist.obj is not in here because it is gtk+-1.2 code,
 # while the DLL for GTK+ on windows is gtk+-1.3, and there's
-# some functions that have disappeared in gtk+-1.3. I might
-# get around to #ifdef'ing them out in our gtkclist.c.
-OBJECTS=capture_dlg.obj \
+# some functions that have disappeared in gtk+-1.3 - and
+# the only purpose our gtkclist.c serves is to be faster
+# than versions of the CList code in some older GTK+ 1.2[.x]
+# releases, but as of 1.2.8 the standard GTK+ should have
+# the performance fix that's in our gtkclist.c, so there's no
+# reason to use our gtkclist.c.
+OBJECTS = \
+       capture_combo_utils.obj \
+       capture_dlg.obj \
        capture_prefs.obj \
        color_dlg.obj    \
        color_filters.obj \
diff --git a/gtk/capture_combo_utils.c b/gtk/capture_combo_utils.c
new file mode 100644 (file)
index 0000000..e0806aa
--- /dev/null
@@ -0,0 +1,161 @@
+/* capture_combo_utils.c
+ * Utilities for combo box of interface names
+ *
+ * $Id: capture_combo_utils.c,v 1.1 2003/09/10 05:35:25 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_LIBPCAP
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <pcap.h>
+
+#include "prefs.h"
+#include "pcap-util.h"
+#include "capture_combo_utils.h"
+
+/*
+ * Find capture device description that matches interface name.
+ */
+static char *
+capture_dev_descr_find(const gchar *if_name)
+{
+       char    *p;
+       char    *p2 = NULL;
+       char    *descr = NULL;
+       int             lp = 0;
+       int             ct = 0;
+       
+       if (prefs.capture_devices_descr == NULL) {
+               /* There are no descriptions. */
+               return NULL;
+       }
+
+       if ((p = strstr(prefs.capture_devices_descr, if_name)) == NULL) {
+               /* There are, but there isn't one for this interface. */
+               return NULL;
+       }
+       
+       while (*p != '\0') {
+               /* error: ran into next interface description */
+               if (*p == ',')
+                       return NULL;
+               /* found left parenthesis, start of description */
+               else if (*p == '(') {
+                       lp++;
+                       /* skip over left parenthesis */
+                       p++;
+                       /* save pointer to beginning of description */
+                       p2 = p;
+                       continue;
+               }
+               else if (*p == ')') {
+                       /* end of description */
+                       break;
+               }
+               else {
+                       p++;
+                       ct++;
+               }
+       }
+       
+       if ((lp == 1) && (ct > 0) && (p2 != NULL)) {
+               /* Allocate enough space to return the string,
+                  which runs from p2 to p, plus a terminating
+                  '\0'. */
+               descr = g_malloc(p - p2 + 1);
+               memcpy(descr, p2, p - p2);
+               descr[p - p2] = '\0';
+               return descr;
+       }
+       else
+               return NULL;
+}
+
+GList *
+build_capture_combo_list(GList *if_list, gboolean do_hide)
+{
+  GList *combo_list;
+  GList *if_entry;
+  if_info_t *if_info;
+  char *if_string;
+  gchar *descr;
+
+  combo_list = NULL;
+  if (if_list != NULL) {
+    /* Scan through the list and build a list of strings to display. */
+    for (if_entry = g_list_first(if_list); if_entry != NULL;
+       if_entry = g_list_next(if_entry)) {
+      if_info = if_entry->data;
+
+      /* Is this interface hidden and, if so, should we include it
+         anyway? */
+      if (prefs.capture_devices_hide == NULL ||
+         strstr(prefs.capture_devices_hide, if_info->name) == NULL ||
+         !do_hide) {
+       /* It's not hidden, or it is but we should include it in the list. */
+
+       /* Do we have a user-supplied description? */
+       descr = capture_dev_descr_find(if_info->name);
+       if (descr != NULL) {
+         /* Yes, we have a user-supplied description; use it. */
+         if_string = g_strdup_printf("%s: %s", descr, if_info->name);
+         g_free(descr);
+       } else {
+         /* No, we don't have a user-supplied description; did we get
+            one from the OS or libpcap? */
+         if (if_info->description != NULL) {
+           /* Yes - use it. */
+           if_string = g_strdup_printf("%s: %s", if_info->description,
+                                       if_info->name);
+         } else {
+           /* No. */
+           if_string = g_strdup(if_info->name);
+         }
+       }
+       combo_list = g_list_append(combo_list, if_string);
+      }
+    }
+  }
+  return combo_list;
+}
+
+static void
+free_if_string(gpointer data, gpointer user_data _U_)
+{
+  g_free(data);
+}
+
+void
+free_capture_combo_list(GList *combo_list)
+{
+  if (combo_list != NULL) {
+    g_list_foreach(combo_list, free_if_string, NULL);
+    g_list_free(combo_list);
+  }
+}
+
+#endif /* HAVE_LIBPCAP */
diff --git a/gtk/capture_combo_utils.h b/gtk/capture_combo_utils.h
new file mode 100644 (file)
index 0000000..87c4ba4
--- /dev/null
@@ -0,0 +1,31 @@
+/* capture_combo_utils.c
+ * Declarations of tilities for combo box of interface names
+ *
+ * $Id: capture_combo_utils.h,v 1.1 2003/09/10 05:35:25 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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_COMBO_UTILS_H__
+#define __CAPTURE_COMBO_UTILS_H__
+
+GList *build_capture_combo_list(GList *if_list, gboolean do_hide);
+void free_capture_combo_list(GList *combo_list);
+
+#endif
index 1331b69b14de7c4da36eb71115e0655cb64b5f6c..98d835c54c0f1e755be14d85d334e2c21a07ca47 100644 (file)
@@ -1,7 +1,7 @@
 /* capture_dlg.c
  * Routines for packet capture windows
  *
- * $Id: capture_dlg.c,v 1.80 2003/09/08 21:44:42 guy Exp $
+ * $Id: capture_dlg.c,v 1.81 2003/09/10 05:35:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -43,6 +43,7 @@
 #include "simple_dialog.h"
 #include "dlg_utils.h"
 #include "pcap-util.h"
+#include "capture_combo_utils.h"
 #include "prefs.h"
 #include "ringbuffer.h"
 #include <epan/filesystem.h>
@@ -104,15 +105,6 @@ capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w);
 static void
 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
 
-static GList *
-capture_dev_descr_add(GList *if_list);
-
-static char *
-capture_dev_descr_find(gchar *devs_descr, gchar *if_name);
-
-static GList *
-capture_dev_hide(GList *if_list);
-
 void
 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
 {
@@ -155,7 +147,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
 #endif
   GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
                *count_adj, *filesize_adj, *duration_adj, *ring_duration_adj;
-  GList         *if_list;
+  GList         *if_list, *combo_list;
   int           err;
   char          err_str[PCAP_ERRBUF_SIZE];
 
@@ -230,15 +222,9 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   gtk_widget_show(if_lb);
 
   if_cb = gtk_combo_new();
-  if (if_list != NULL) {
-    /* remove interface(s) from list if "hidden" */
-    if (prefs.capture_devices_hide != NULL)
-      if_list = capture_dev_hide(if_list);
-    /* prepend interface descriptions to device name */
-    if (prefs.capture_devices_descr != NULL)
-      if_list = capture_dev_descr_add(if_list);
-    gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), if_list);
-  }
+  combo_list = build_capture_combo_list(if_list, TRUE);
+  gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
+  free_capture_combo_list(combo_list);
   if (cfile.iface == NULL && prefs.capture_device != NULL) {
     /* No interface was specified on the command line or in a previous
        capture, but there is one specified in the preferences file;
@@ -247,13 +233,14 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   }
   if (cfile.iface != NULL)
     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
-  else if (if_list != NULL)
-    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), if_list->data);
+  else if (if_list != NULL) {
+    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
+                      ((if_info_t *)(if_list->data))->name);
+  }
+  free_interface_list(if_list);
   gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
   gtk_widget_show(if_cb);
 
-  free_interface_list(if_list);
-
   /* Capture length row */
   snap_hb = gtk_hbox_new(FALSE, 3);
   gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
@@ -807,7 +794,7 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
     g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
   /* Remove interface description. Also, Windows combo entries have a 
      description followed by the interface name. These two cases are
-     OK as long as they're in front (see capture_dev_descr_add()). */
+     OK as long as they're in front. */
   if_name = strrchr(if_text, ' ');
   if (if_name == NULL) {
     if_name = if_text;
@@ -1075,145 +1062,4 @@ capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
 
 }
 
-/*
- * Prepend capture devices description to interface list. Remove OS (pcap)
- * supplied description if present.
- */
-static GList *
-capture_dev_descr_add(GList *if_list)
-{
-
-       GList   *if_new_list = NULL;
-       char    *osd;
-       char    *tmp_descr;
-       gchar   *tmp_devs_descr;
-       gchar   *tmp_dev_name;
-       guint   i;
-       guint   nitems;
-       
-       /* Seems we need to be at list head for g_list_length()? */
-       if_list = g_list_first(if_list);
-       nitems = g_list_length(if_list);
-       
-       /* Create new interface list with "(descr) if_name". */
-       for (i=0; i < nitems; i++) {
-               tmp_dev_name = g_list_nth_data(if_list, i);
-               /* should never happen, but just in case */
-               if (tmp_dev_name == NULL) {
-                       if (if_new_list != NULL)
-                               free_interface_list(if_new_list);
-                       return if_list;
-               }
-               /* create copy since capture_dev_descr_find() inserts terminator */
-               tmp_devs_descr = g_strdup(prefs.capture_devices_descr);
-               /* find matching description */
-               tmp_descr = capture_dev_descr_find(tmp_devs_descr, tmp_dev_name);
-               /* prepend description */
-               if (tmp_descr != NULL) {
-                       /* remove OS (pcap) description */
-                       if ((osd = strrchr(tmp_dev_name, ' ')) != NULL) {
-                               osd++;
-                               if (osd != NULL)
-                                       tmp_dev_name = osd;
-                       }
-                       if_new_list = g_list_append(if_new_list, 
-                               g_strdup_printf("%s %s", tmp_descr, tmp_dev_name));
-               }
-               /* no description for this interface, just copy name */
-               else {
-                       if_new_list = g_list_append(if_new_list, g_strdup(tmp_dev_name));
-               }
-               g_free(tmp_devs_descr);
-       }
-       
-       free_interface_list(if_list);
-       /* return pointer to new interface list with descriptions */
-       return if_new_list;
-}
-
-/*
- * Find capture device description that matches interface name.
- */
-static char *
-capture_dev_descr_find(gchar *devs_descr, gchar *if_name)
-{
-       char    *p;
-       char    *p2 = NULL;
-       char    *descr = NULL;
-       int             lp = 0;
-       int             ct = 0;
-       
-       if (if_name == NULL)
-               return NULL;
-       
-       if ((p = strstr(devs_descr, if_name)) == NULL)
-               return NULL;
-       
-       while (p != NULL) {
-               /* error: ran into next interface description */
-               if (*p == ',')
-                       return NULL;
-               /* found left parenthesis, start of description */
-               else if (*p == '(') {
-                       lp++;
-                       /* save pointer to beginning of description */
-                       p2 = p;
-                       p++;
-                       continue;
-               }
-               else if (*p == ')') {
-                       /* end of description */
-                       break;
-               }
-               else {
-                       p++;
-                       ct++;
-               }
-       }
-       
-       if ((lp == 1) && (ct > 0) && (p2 != NULL)) {
-               /* set returned pointer to beginning of description */
-               descr = p2;
-               /* insert terminator */
-               *(p+1) = '\0';
-               return descr;
-       }
-       else
-               return NULL;
-}
-
-/*
- * Remove "hidden" interface(s) from list.
- */
-static GList *
-capture_dev_hide(GList *if_list)
-{
-       GList   *if_new_list = NULL;
-       gchar   *tmp_dev_name;
-       guint   i;
-       guint   nitems;
-       
-       /* Seems we need to be at list head for g_list_length()? */
-       if_list = g_list_first(if_list);
-       nitems = g_list_length(if_list);
-       
-       /* Create new list without "hidden" interfaces. */
-       for (i=0; i < nitems; i++) {
-               tmp_dev_name = g_list_nth_data(if_list, i);
-               /* should never happen, but just in case */
-               if (tmp_dev_name == NULL) {
-                       if (if_new_list != NULL)
-                               free_interface_list(if_new_list);
-                       return if_list;
-               }
-               /* check if interface name is in "hidden" preferences string */
-               if (strstr(prefs.capture_devices_hide, tmp_dev_name) == NULL)
-                       if_new_list = g_list_append(if_new_list, g_strdup(tmp_dev_name));
-       }
-       
-       free_interface_list(if_list);
-       /* return pointer to new interface list */
-       return if_new_list;
-}
-
 #endif /* HAVE_LIBPCAP */
index 5c3c15f9f246847f521559861581081b21a88621..ac1730bf9c96a8f7a9f65b62d30b101179674ea8 100644 (file)
@@ -1,7 +1,7 @@
 /* capture_prefs.c
  * Dialog box for capture preferences
  *
- * $Id: capture_prefs.c,v 1.20 2003/09/09 18:27:49 guy Exp $
+ * $Id: capture_prefs.c,v 1.21 2003/09/10 05:35:26 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -42,6 +42,7 @@
 #include "dlg_utils.h"
 #include "simple_dialog.h"
 #include "pcap-util.h"
+#include "capture_combo_utils.h"
 #include "main.h"
 #include "compat_macros.h"
 
@@ -72,7 +73,7 @@ static void ifopts_edit_ifunsel_cb(GtkWidget *clist, gint row, gint column,
     GdkEventButton *event, gpointer data);
 static void ifopts_old_options_add(GtkCList *clist);
 static gboolean ifopts_old_options_chk(GtkCList *clist, gchar *ifname);
-static void ifopts_new_options_add(GtkCList *clist, gchar *ifname);
+static void ifopts_new_options_add(GtkCList *clist, if_info_t *if_info);
 static void ifopts_options_free(gchar *text[]);
 static void ifopts_if_clist_add(GtkCList *clist);
 static void ifopts_write_new_descr(void);
@@ -84,7 +85,7 @@ capture_prefs_show(void)
        GtkWidget       *main_tb, *main_vb;
        GtkWidget       *if_cb, *if_lb, *promisc_cb, *sync_cb, *auto_scroll_cb;
        GtkWidget       *ifopts_lb, *ifopts_bt;
-       GList           *if_list;
+       GList           *if_list, *combo_list;
        int             err;
        char            err_str[PCAP_ERRBUF_SIZE];
 
@@ -110,8 +111,10 @@ capture_prefs_show(void)
         * XXX - what if we can't get the list?
         */
        if_list = get_interface_list(&err, err_str);
-       if (if_list != NULL)
-               gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), if_list);
+       combo_list = build_capture_combo_list(if_list, FALSE);
+       free_interface_list(if_list);
+       gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
+       free_capture_combo_list(combo_list);
        if (prefs.capture_device)
                gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
                    prefs.capture_device);
@@ -119,8 +122,6 @@ capture_prefs_show(void)
        gtk_widget_show(if_cb);
        OBJECT_SET_DATA(main_vb, DEVICE_KEY, if_cb);
 
-       free_interface_list(if_list);
-
        /* Interface options */
        ifopts_lb = gtk_label_new("Interface options:");
        gtk_table_attach_defaults(GTK_TABLE(main_tb), ifopts_lb, 0, 1, 1, 2);
@@ -678,13 +679,13 @@ ifopts_old_options_chk(GtkCList *clist, gchar *ifname)
  * machine or disabled and no longer apply.
  */
 static void
-ifopts_new_options_add(GtkCList *clist, gchar *ifname)
+ifopts_new_options_add(GtkCList *clist, if_info_t *if_info)
 {
        gchar   *p;
        gchar   *ifnm;
        gchar   *desc;
        gchar   *pr_descr;
-       gchar   *text[3] = { '\0' };
+       gchar   *text[3] = { NULL, NULL, NULL };
        
        /* add interface descriptions and "hidden" flag */
        if (prefs.capture_devices_descr != NULL) {
@@ -692,16 +693,16 @@ ifopts_new_options_add(GtkCList *clist, gchar *ifname)
                pr_descr = g_strdup(prefs.capture_devices_descr);
                
                /* if we find a description for this interface */
-               if ((ifnm = strstr(pr_descr, ifname)) != NULL) {
+               if ((ifnm = strstr(pr_descr, if_info->name)) != NULL) {
                        p = ifnm;
                        while (*p != '\0') {
                                /* found left parenthesis, start of description */
                                if (*p == '(') {
                                        /* set interface name text */
-                                       text[0] = g_strdup(ifname);
+                                       text[0] = g_strdup(if_info->name);
                                        /* check if interface is "hidden" */
                                        if (prefs.capture_devices_hide != NULL) {
-                                               if (strstr(prefs.capture_devices_hide, ifname) != NULL)
+                                               if (strstr(prefs.capture_devices_hide, if_info->name) != NULL)
                                                        text[2] = g_strdup("1");
                                                else
                                                        text[2] = g_strdup("0");
@@ -746,12 +747,12 @@ ifopts_new_options_add(GtkCList *clist, gchar *ifname)
                /* if there's no description for this interface */
                else {
                        /* set interface name */
-                       text[0] = g_strdup(ifname);
+                       text[0] = g_strdup(if_info->name);
                        /* set empty description */
                        text[1] = g_strdup("");
                        /* check if interface is "hidden" */
                        if (prefs.capture_devices_hide != NULL) {
-                               if (strstr(prefs.capture_devices_hide, ifname) != NULL)
+                               if (strstr(prefs.capture_devices_hide, if_info->name) != NULL)
                                        text[2] = g_strdup("1");
                                else
                                        text[2] = g_strdup("0");
@@ -771,11 +772,11 @@ ifopts_new_options_add(GtkCList *clist, gchar *ifname)
         */
        else if (prefs.capture_devices_hide != NULL) {
                /* set interface name */
-               text[0] = g_strdup(ifname);
+               text[0] = g_strdup(if_info->name);
                /* set empty description */
                text[1] = g_strdup("");
                /* check if interface is "hidden" */
-               if (strstr(prefs.capture_devices_hide, ifname) != NULL)
+               if (strstr(prefs.capture_devices_hide, if_info->name) != NULL)
                        text[2] = g_strdup("1");
                else
                        text[2] = g_strdup("0");
@@ -789,7 +790,7 @@ ifopts_new_options_add(GtkCList *clist, gchar *ifname)
         */
        else {
                /* set interface name */
-               text[0] = g_strdup(ifname);
+               text[0] = g_strdup(if_info->name);
                /* set empty description */
                text[1] = g_strdup("");
                /* interface is not "hidden" */
@@ -820,12 +821,13 @@ ifopts_options_free(gchar *text[])
 static void
 ifopts_if_clist_add(GtkCList *clist)
 {
-       GList   *if_list;
+       GList           *if_list;
        int             err;
-       char    err_str[PCAP_ERRBUF_SIZE];
-       gchar   *text[1];
-       guint   i;
-       guint   nitems;
+       char            err_str[PCAP_ERRBUF_SIZE];
+       if_info_t       *if_info;
+       gchar           *text[1];
+       guint           i;
+       guint           nitems;
        
        if_list = get_interface_list(&err, err_str);
        if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
@@ -840,13 +842,14 @@ ifopts_if_clist_add(GtkCList *clist)
        
        /* add interface name text to CList */
        for (i=0; i < nitems; i++) {
-               text[0] = g_list_nth_data(if_list, i);
+               if_info = g_list_nth_data(if_list, i);
                /* should never happen, but just in case */
-               if (text[0] == NULL)
+               if (if_info == NULL)
                        continue;
+               text[0] = if_info->name;
                gtk_clist_append(GTK_CLIST(clist), text);
                /* fill "new" options CList with previously saved values */
-               ifopts_new_options_add(GTK_CLIST(new_clist), text[0]);
+               ifopts_new_options_add(GTK_CLIST(new_clist), if_info);
        }
        
        free_interface_list(if_list);
index 9bfa5f107984220b776319ee930117890f7bb0db..c7344c8ec4c66c92415782e0c3c8ee9f6139b0f9 100644 (file)
@@ -1,6 +1,6 @@
 /* main.c
  *
- * $Id: main.c,v 1.309 2003/09/03 23:32:40 guy Exp $
+ * $Id: main.c,v 1.310 2003/09/10 05:35:26 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -1511,6 +1511,7 @@ main(int argc, char *argv[])
   gboolean             start_capture = FALSE;
   gchar               *save_file = NULL;
   GList               *if_list;
+  if_info_t           *if_info;
   gchar                err_str[PCAP_ERRBUF_SIZE];
   gboolean             stats_known;
   struct pcap_stat     stats;
@@ -2074,7 +2075,8 @@ main(int argc, char *argv[])
           }
           exit(2);
         }
-        cfile.iface = g_strdup(if_list->data); /* first interface */
+        if_info = if_list->data;       /* first interface */
+        cfile.iface = g_strdup(if_info->name);
         free_interface_list(if_list);
       }
     }
index 318dfb3976b6c3aefa3611b849031020e4019edc..f059086efcb40f36abd08addea024b2887c60652 100644 (file)
@@ -1,7 +1,7 @@
 /* pcap-util.c
  * Utility routines for packet capture
  *
- * $Id: pcap-util.c,v 1.15 2003/09/08 21:44:41 guy Exp $
+ * $Id: pcap-util.c,v 1.16 2003/09/10 05:35:23 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -213,6 +213,20 @@ search_for_if_cb(gpointer data, gpointer user_data);
 static void
 free_if_cb(gpointer data, gpointer user_data);
 
+static if_info_t *
+if_info_new(char *name, char *description)
+{
+       if_info_t *if_info;
+
+       if_info = g_malloc(sizeof (if_info_t));
+       if_info->name = g_strdup(name);
+       if (description == NULL)
+               if_info->description = NULL;
+       else
+               if_info->description = g_strdup(description);
+       return if_info;
+}
+
 #ifndef WIN32
 GList *
 get_interface_list(int *err, char *err_str)
@@ -227,6 +241,7 @@ get_interface_list(int *err, char *err_str)
        pcap_t *pch;
        int len, lastlen;
        char *buf;
+       if_info_t *if_info;
 
        if (sock < 0) {
                sprintf(err_str, "Error opening socket: %s",
@@ -328,12 +343,12 @@ 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);
                if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
                    strncmp(ifr->ifr_name, "lo", 2) == 0)
-                       il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
+                       il = g_list_insert(il, if_info, -1);
                else {
-                       il = g_list_insert(il, g_strdup(ifr->ifr_name),
-                           nonloopback_pos);
+                       il = g_list_insert(il, if_info, nonloopback_pos);
                        /*
                         * Insert the next non-loopback interface after this
                         * one.
@@ -364,7 +379,9 @@ get_interface_list(int *err, char *err_str)
                /*
                 * It worked; we can use the "any" device.
                 */
-               il = g_list_insert(il, g_strdup("any"), -1);
+               if_info = if_info_new("any",
+                   "Pseudo-device that captures on all interfaces");
+               il = g_list_insert(il, if_info, -1);
                pcap_close(pch);
        }
 #endif
@@ -393,8 +410,9 @@ static void
 search_for_if_cb(gpointer data, gpointer user_data)
 {
        struct search_user_data *search_user_data = user_data;
+       if_info_t *if_info = data;
 
-       if (strcmp((char *)data, search_user_data->name) == 0)
+       if (strcmp(if_info->name, search_user_data->name) == 0)
                search_user_data->found = TRUE;
 }
 #else /* Windows */
@@ -403,7 +421,8 @@ get_interface_list(int *err, char *err_str) {
   GList  *il = NULL;
   wchar_t *names;
   char *win95names;
-  char newname[MAX_WIN_IF_NAME_LEN + 1];
+  char ascii_name[MAX_WIN_IF_NAME_LEN + 1];
+  char ascii_desc[MAX_WIN_IF_NAME_LEN + 1];
   int i, j;
 
   /* On Windows pcap_lookupdev is implemented by calling
@@ -411,22 +430,36 @@ get_interface_list(int *err, char *err_str) {
    * (http://winpcap.polito.it/docs/dll.htm#PacketGetAdapterNames)
    * this means that:
    *
-   * On Windows 95x, pcap_lookupdev returns an ASCII string with the
-   * names of the adapters separated by a single ASCII "\0", a double
-   * "\0", followed by the descriptions of the adapters separated by a
-   * single ASCII "\0" . The string is terminated by a double "\0".
+   * On Windows OT (95, 98, Me), pcap_lookupdev returns a sequence of bytes
+   * consisting of:
+   *
+   *   a sequence of null-terminated ASCII strings (i.e., each one is
+   *   terminated by a single 0 byte), giving the names of the interfaces;
+   *
+   *   an empty ASCII string (i.e., a single 0 byte);
+   *
+   *   a sequence of null-terminated ASCII strings, giving the
+   *   descriptions of the interfaces;
+   *
+   *   an empty ASCII string.
+   *
+   * On Windows NT (NT 4.0, W2K, WXP, W2K3, etc.), pcap_lookupdev returns
+   * a sequence of bytes consisting of:
+   *
+   *   a sequence of null-terminated double-byte Unicode strings (i.e.,
+   *   each one consits of a sequence of double-byte characters,
+   *   terminated by a double-byte 0), giving the names of the interfaces;
    *
-   * On Windows NTx, pcap_lookupdev returns the names of the adapters,
-   * in UNICODE format, separated by a single UNICODE "\0" (i.e. 2
-   * ASCII "\0"), a double UNICODE "\0", followed by the descriptions
-   * of the adapters, in ASCII format, separated by a single ASCII
-   * "\0" . The string is terminated by a double ASCII "\0".
+   *   an empty Unicode string (i.e., a double 0 byte);
    *
-   * We prepend the device name with a description to make it easier
-   * for users to choose the interface they want.  This requires that
-   * we split out the device name later on in tethereal.c and gtk/main.c.
-   * It might be useful to have separate structures for raw names and
-   * descriptions at some point.
+   *   a sequence of null-terminated ASCII strings, giving the
+   *   descriptions of the interfaces;
+   *
+   *   an empty ASCII string.
+   *
+   * The Nth string in the first sequence is the name of the Nth adapter;
+   * the Nth string in the second sequence is the descriptio of the Nth
+   * adapter.
    */
 
   names = (wchar_t *)pcap_lookupdev(err_str);
@@ -446,53 +479,65 @@ get_interface_list(int *err, char *err_str) {
 
                  while (names[i] != 0)
                  {
+                       /*
+                        * Copy the Unicode description to an ASCII
+                        * string.
+                        */
                        j = 0;
-                       while (*desc) {
+                       while (*desc != 0) {
                            if (j < MAX_WIN_IF_NAME_LEN)
-                               newname[j++] = *desc++;
-                       }
-                       *desc++;
-                       if (j < MAX_WIN_IF_NAME_LEN - 1) {
-                           newname[j++] = ':';
-                           newname[j++] = ' ';
+                               ascii_desc[j++] = *desc;
+                               desc++;
                        }
+                       ascii_desc[j] = '\0';
+                       desc++;
+
+                       /*
+                        * Copy the Unicode name to an ASCII string.
+                        */
+                       j = 0;
                        while (names[i] != 0) {
                            if (j < MAX_WIN_IF_NAME_LEN)
-                               newname[j++] = names[i++];
+                               ascii_name[j++] = names[i++];
                        }
+                       ascii_name[j] = '\0';
                        i++;
-                       newname[j] = 0;
-                       il = g_list_append(il, g_strdup(newname));
+                       il = g_list_append(il,
+                           if_info_new(ascii_name, ascii_description));
                  }
          }
          else {
-                 /* Otherwise we are in Windows 95/98 and using ascii(8 bit)
-                    characters */
+                 /* Otherwise we are in Windows 95/98 and using ASCII
+                    (8 bit) characters */
                  win95names=(char *)names;
                  while(*(win95names+desc_pos) || *(win95names+desc_pos-1))
                        desc_pos++;
                  desc_pos++;   /* Step over the extra '\0' */
                  desc = win95names + desc_pos;
 
-                 while (win95names[i] != 0)
+                 while (win95names[i] != '\0')
                  {
-                       j = 0;
-                       while (*desc) {
-                           if (j < MAX_WIN_IF_NAME_LEN)
-                               newname[j++] = *desc++;
-                       }
-                       *desc++;
-                       if (j < MAX_WIN_IF_NAME_LEN - 1) {
-                           newname[j++] = ':';
-                           newname[j++] = ' ';
-                       }
-                       while (win95names[i] != 0) {
-                           if (j < MAX_WIN_IF_NAME_LEN)
-                               newname[j++] = win95names[i++];
-                       }
+                       /*
+                        * "&win95names[i]" points to the current interface
+                        * name, and "desc" points to that interface's
+                        * description.
+                        */
+                       il = g_list_append(il,
+                           if_info_new(&win95names[i], desc));
+
+                       /*
+                        * Skip to the next description.
+                        */
+                       while (*desc != 0)
+                               desc++;
+                       desc++;
+
+                       /*
+                        * Skip to the next name.
+                        */
+                       while (win95names[i] != 0)
+                           i++;
                        i++;
-                       newname[j] = 0;
-                       il = g_list_append(il, g_strdup(newname));
                  }
          }
   }
@@ -510,7 +555,11 @@ get_interface_list(int *err, char *err_str) {
 static void
 free_if_cb(gpointer data, gpointer user_data _U_)
 {
-       g_free(data);
+       if_info_t *if_info = data;
+
+       g_free(if_info->name);
+       if (if_info->description != NULL)
+               g_free(if_info->description);
 }
 
 void
index 38a6495646fddfca98f87ea8852b7986ba736f43..fe9c71bbd3c00b172b649c38fc513497b60ae3ec 100644 (file)
@@ -1,7 +1,7 @@
 /* pcap-util.h
  * Utility definitions for packet capture
  *
- * $Id: pcap-util.h,v 1.3 2003/09/08 21:44:41 guy Exp $
+ * $Id: pcap-util.h,v 1.4 2003/09/10 05:35:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -34,6 +34,16 @@ extern "C" {
 int get_pcap_linktype(pcap_t *pch, char *devname);
 
 #define MAX_WIN_IF_NAME_LEN 511
+
+/*
+ * The list of interfaces returned by "get_interface_list()" is
+ * a list of these structures.
+ */
+typedef struct {
+       char    *name;
+       char    *description;
+} if_info_t;
+
 GList *get_interface_list(int *err, char *err_str);
 
 /* Error values from "get_interface_list()". */
index 2a601c15f79a2dcb3d7f5506d6a4c83b5a83034c..3e14a584bc754b97f7b60b15c3414f8416ca82ef 100644 (file)
@@ -1,6 +1,6 @@
 /* tethereal.c
  *
- * $Id: tethereal.c,v 1.194 2003/09/07 00:47:55 guy Exp $
+ * $Id: tethereal.c,v 1.195 2003/09/10 05:35:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -782,6 +782,7 @@ main(int argc, char *argv[])
 #ifdef HAVE_LIBPCAP
   gboolean             capture_filter_specified = FALSE;
   GList               *if_list, *if_entry;
+  if_info_t           *if_info;
   long                 adapter_index;
   char                *p;
   gchar                err_str[PCAP_ERRBUF_SIZE];
@@ -956,8 +957,13 @@ main(int argc, char *argv[])
         }
         i = 1;  /* Interface id number */
         for (if_entry = g_list_first(if_list); if_entry != NULL;
-               if_entry = g_list_next(if_entry))
-          printf("%d. %s\n", i++, (char *)if_entry->data);
+               if_entry = g_list_next(if_entry)) {
+         if_info = if_entry->data;
+          printf("%d. %s", i++, if_info->name);
+          if (if_info->description != NULL)
+            printf(" (%s)", if_info->description);
+          printf("\n");
+        }
         free_interface_list(if_list);
         exit(0);
 #else
@@ -1030,16 +1036,12 @@ main(int argc, char *argv[])
             }
             exit(2);
           }
-          if_text = (char *)g_list_nth_data(if_list, adapter_index - 1);
-          if (if_text == NULL) {
+          if_info = g_list_nth_data(if_list, adapter_index - 1);
+          if (if_info == NULL) {
             fprintf(stderr, "tethereal: there is no interface with that adapter index\n");
             exit(1);
           }
-#ifdef _WIN32
-          /* XXX - why is this done? */
-          if_text = strchr(if_text, '\\');
-#endif
-          cfile.iface = g_strdup(if_text);
+          cfile.iface = g_strdup(if_info->name);
           free_interface_list(if_list);
         } else
           cfile.iface = g_strdup(optarg);
@@ -1393,12 +1395,8 @@ main(int argc, char *argv[])
                 }
                 exit(2);
             }
-           if_text = strrchr(if_list->data, ' ');      /* first interface */
-           if (if_text == NULL) {
-               cfile.iface = g_strdup(if_list->data);
-           } else {
-               cfile.iface = g_strdup(if_text + 1); /* Skip over space */
-           }
+           if_info = if_list->data;    /* first interface */
+           cfile.iface = g_strdup(if_info->name);
             free_interface_list(if_list);
         }
     }