Have "get_interface_list()" return a list of "if_info_t" structures

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.

svn path=/trunk/; revision=8440
This commit is contained in:
Guy Harris 2003-09-10 05:35:26 +00:00
parent df25d41673
commit 27ea7816ee
10 changed files with 376 additions and 266 deletions

View 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 \

View 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 \

161
gtk/capture_combo_utils.c Normal file
View File

@ -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 */

31
gtk/capture_combo_utils.h Normal file
View File

@ -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

View 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 */

View 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);

View 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);
}
}

View 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:
*
* 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".
* a sequence of null-terminated ASCII strings (i.e., each one is
* terminated by a single 0 byte), giving the names of the interfaces;
*
* 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.
* 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;
*
* an empty Unicode string (i.e., a double 0 byte);
*
* 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

View 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()". */

View 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);
}
}