From 167ab3a98c4583344f8b95d81b079b7a5df7e5ff Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 4 Mar 2010 01:12:04 +0000 Subject: [PATCH] In Wireshark and TShark, run dumpcap to get interface lists and lists of link-layer header types for interfaces; if special privileges are necessary to open capture devices, Wireshark and TShark shouldn't have those privileges, but dumpcap should. svn path=/trunk/; revision=32104 --- Makefile.common | 22 +++- capture-pcap-util-int.h | 3 - capture-pcap-util-unix.c | 3 +- capture-pcap-util.c | 29 +++--- capture-pcap-util.h | 48 +-------- capture-wpcap.c | 4 - capture.c | 195 +---------------------------------- capture.h | 10 -- capture_ifinfo.c | 217 +++++++++++++++++++++++++++++++++++++++ capture_ifinfo.h | 88 ++++++++++++++++ capture_opts.c | 31 +++--- capture_sync.c | 73 +++++++------ capture_ui_utils.c | 8 +- capture_ui_utils.h | 4 +- dumpcap.c | 20 ++++ gtk/capture_dlg.c | 22 ++-- gtk/capture_if_dlg.c | 105 ++++++++++++++----- gtk/capture_if_dlg.h | 2 +- gtk/prefs_capture.c | 3 +- 19 files changed, 515 insertions(+), 372 deletions(-) create mode 100644 capture_ifinfo.c create mode 100644 capture_ifinfo.h diff --git a/Makefile.common b/Makefile.common index b2995d6820..0676bce0a9 100644 --- a/Makefile.common +++ b/Makefile.common @@ -44,12 +44,10 @@ GENERATED_C_FILES = \ # All the generated files. GENERATED_FILES = $(GENERATED_C_FILES) $(GENERATED_HEADER_FILES) -# sources common for wireshark and tshark +# sources common for wireshark, tshark, and rawshark WIRESHARK_COMMON_SRC = \ $(PLATFORM_SRC) \ - capture_errs.c \ capture-pcap-util.c \ - capture_ui_utils.c \ cfile.c \ clopts_common.c \ disabled_protos.c \ @@ -66,10 +64,8 @@ WIRESHARK_COMMON_SRC = \ # corresponding headers WIRESHARK_COMMON_INCLUDES = \ svnversion.h \ - capture_errs.h \ capture-pcap-util.h \ capture-pcap-util-int.h \ - capture_ui_utils.h \ cfile.h \ clopts_common.h \ cmdarg_err.h \ @@ -89,6 +85,19 @@ WIRESHARK_COMMON_INCLUDES = \ tap-rtp-common.h \ version_info.h +# sources common for wireshark and tshark, but not rawshark; +# these are for programs that capture traffic by running dumpcap +SHARK_COMMON_CAPTURE_SRC = \ + capture_errs.c \ + capture_ifinfo.c \ + capture_ui_utils.c + +# corresponding headers +SHARK_COMMON_CAPTURE_INCLUDES = \ + capture_errs.h \ + capture_ifinfo.h \ + capture_ui_utils.h + # sources for TShark taps TSHARK_TAP_SRC = \ tap-afpstat.c \ @@ -139,6 +148,7 @@ EXTRA_wireshark_INCLUDES = \ # wireshark specifics wireshark_SOURCES = \ $(WIRESHARK_COMMON_SRC) \ + $(SHARK_COMMON_CAPTURE_SRC) \ airpcap_loader.c \ alert_box.c \ capture.c \ @@ -181,6 +191,7 @@ wireshark_INCLUDES = \ # tshark specifics tshark_SOURCES = \ $(WIRESHARK_COMMON_SRC) \ + $(SHARK_COMMON_CAPTURE_SRC) \ $(TSHARK_TAP_SRC) \ capture_opts.c \ capture_sync.c \ @@ -249,6 +260,7 @@ dumpcap_INCLUDES = \ # this target needed for distribution only noinst_HEADERS = \ $(WIRESHARK_COMMON_INCLUDES) \ + $(SHARK_COMMON_CAPTURE_INCLUDES) \ $(wireshark_INCLUDES) \ $(EXTRA_wireshark_INCLUDES) \ $(dumpcap_INCLUDES) diff --git a/capture-pcap-util-int.h b/capture-pcap-util-int.h index c749d5e042..426595d341 100644 --- a/capture-pcap-util-int.h +++ b/capture-pcap-util-int.h @@ -26,9 +26,6 @@ #define __PCAP_UTIL_INT_H__ #ifdef HAVE_LIBPCAP -#ifdef HAVE_PCAP_REMOTE -#include -#endif /* HAVE_PCAP_REMOTE */ extern if_info_t *if_info_new(char *name, char *description); extern void if_info_add_address(if_info_t *if_info, struct sockaddr *addr); diff --git a/capture-pcap-util-unix.c b/capture-pcap-util-unix.c index 589ac7d744..3ffda24fac 100644 --- a/capture-pcap-util-unix.c +++ b/capture-pcap-util-unix.c @@ -47,8 +47,6 @@ #include #endif -#include - /* * Keep Digital UNIX happy when including . */ @@ -60,6 +58,7 @@ struct rtentry; # include #endif +#include "capture_ifinfo.h" #include "capture-pcap-util.h" #include "capture-pcap-util-int.h" diff --git a/capture-pcap-util.c b/capture-pcap-util.c index fd4d0525a3..4dd666497b 100644 --- a/capture-pcap-util.c +++ b/capture-pcap-util.c @@ -35,8 +35,6 @@ #include #include -#include - #ifdef HAVE_SYS_TYPES_H # include #endif @@ -48,6 +46,7 @@ #include #include +#include "capture_ifinfo.h" #include "capture-pcap-util.h" #include "capture-pcap-util-int.h" @@ -190,7 +189,7 @@ if_info_new(char *name, char *description) if_info->description = NULL; else if_info->description = g_strdup(description); - if_info->ip_addr = NULL; + if_info->addrs = NULL; if_info->loopback = FALSE; return if_info; } @@ -198,7 +197,7 @@ if_info_new(char *name, char *description) void if_info_add_address(if_info_t *if_info, struct sockaddr *addr) { - if_addr_t *ip_addr; + if_addr_t *if_addr; struct sockaddr_in *ai; #ifdef INET6 struct sockaddr_in6 *ai6; @@ -208,22 +207,22 @@ if_info_add_address(if_info_t *if_info, struct sockaddr *addr) case AF_INET: ai = (struct sockaddr_in *)addr; - ip_addr = g_malloc(sizeof(*ip_addr)); - ip_addr->type = AT_IPv4; - ip_addr->ip_addr.ip4_addr = + if_addr = g_malloc(sizeof(*if_addr)); + if_addr->ifat_type = IF_AT_IPv4; + if_addr->addr.ip4_addr = *((guint32 *)&(ai->sin_addr.s_addr)); - if_info->ip_addr = g_slist_append(if_info->ip_addr, ip_addr); + if_info->addrs = g_slist_append(if_info->addrs, if_addr); break; #ifdef INET6 case AF_INET6: ai6 = (struct sockaddr_in6 *)addr; - ip_addr = g_malloc(sizeof(*ip_addr)); - ip_addr->type = AT_IPv6; - memcpy((void *)&ip_addr->ip_addr.ip6_addr, + if_addr = g_malloc(sizeof(*if_addr)); + if_addr->ifat_type = IF_AT_IPv6; + memcpy((void *)&if_addr->addr.ip6_addr, (void *)&ai6->sin6_addr.s6_addr, - sizeof ip_addr->ip_addr.ip6_addr); - if_info->ip_addr = g_slist_append(if_info->ip_addr, ip_addr); + sizeof if_addr->addr.ip6_addr); + if_info->addrs = g_slist_append(if_info->addrs, if_addr); break; #endif } @@ -338,8 +337,8 @@ free_if_cb(gpointer data, gpointer user_data _U_) g_free(if_info->name); g_free(if_info->description); - g_slist_foreach(if_info->ip_addr, free_if_info_addr_cb, NULL); - g_slist_free(if_info->ip_addr); + g_slist_foreach(if_info->addrs, free_if_info_addr_cb, NULL); + g_slist_free(if_info->addrs); g_free(if_info); } diff --git a/capture-pcap-util.h b/capture-pcap-util.h index 3b9bf831bd..c1fe38f147 100644 --- a/capture-pcap-util.h +++ b/capture-pcap-util.h @@ -22,8 +22,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __PCAP_UTIL_H__ -#define __PCAP_UTIL_H__ +#ifndef __CAPTURE_PCAP_UTIL_H__ +#define __CAPTURE_PCAP_UTIL_H__ #ifdef HAVE_LIBPCAP @@ -31,8 +31,6 @@ extern "C" { #endif /* __cplusplus */ -#include - #include /* @@ -44,28 +42,6 @@ extern "C" { */ #define MIN_PACKET_SIZE 1 /* minimum amount of packet data we can read */ -/* - * The list of interfaces returned by "get_interface_list()" is - * a list of these structures. - */ -typedef struct { - char *name; /* e.g. "eth0" */ - char *description; /* from OS, e.g. "Local Area Connection" or NULL */ - GSList *ip_addr; /* containing address values of if_addr_t */ - gboolean loopback; /* TRUE if loopback, FALSE otherwise */ -} if_info_t; - -/* - * An address in the "ip_addr" list. - */ -typedef struct { - address_type type; /* AT_IPv4 or AT_IPv6 */ - union { - guint32 ip4_addr; /* 4 byte IP V4 address, or */ - guint8 ip6_addr[16];/* 16 byte IP V6 address */ - } ip_addr; -} if_addr_t; - GList *get_interface_list(int *err, char **err_str); #ifdef HAVE_PCAP_REMOTE GList *get_remote_interface_list(const char *hostname, const char *port, @@ -73,25 +49,7 @@ GList *get_remote_interface_list(const char *hostname, const char *port, const char *passwd, int *err, char **err_str); #endif -/* Error values from "get_interface_list()/capture_interface_list()". */ -#define CANT_GET_INTERFACE_LIST 1 /* error getting list */ -#define NO_INTERFACES_FOUND 2 /* list is empty */ -#define CANT_RUN_DUMPCAP 3 /* problem running dumpcap */ - -void free_interface_list(GList *if_list); - -/* - * The list of data link types returned by "get_pcap_linktype_list()" is - * a list of these structures. - */ -typedef struct { - int dlt; /* e.g. DLT_EN10MB (which is 1) */ - char *name; /* e.g. "EN10MB" or "DLT 1" */ - char *description; /* descriptive name from wiretap e.g. "Ethernet", NULL if unknown */ -} data_link_info_t; - GList *get_pcap_linktype_list(const char *devname, char **err_str); -void free_pcap_linktype_list(GList *linktype_list); /* get/set the link type of an interface */ /* (only used in capture_loop.c / capture-pcap-util.c) */ @@ -122,4 +80,4 @@ extern void get_compiled_pcap_version(GString *str); */ extern void get_runtime_pcap_version(GString *str); -#endif /* __PCAP_UTIL_H__ */ +#endif /* __CAPTURE_PCAP_UTIL_H__ */ diff --git a/capture-wpcap.c b/capture-wpcap.c index 4d5deb7f0e..09f9ea45ef 100644 --- a/capture-wpcap.c +++ b/capture-wpcap.c @@ -32,10 +32,6 @@ #include #include -#ifdef HAVE_LIBPCAP -#include -#endif - #include "capture-pcap-util.h" #include "capture-pcap-util-int.h" diff --git a/capture.c b/capture.c index 493f626eac..68f2fbb9d6 100644 --- a/capture.c +++ b/capture.c @@ -33,44 +33,7 @@ #endif #include -#include #include -#include - -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#ifdef HAVE_NETDB_H -#include -#endif - -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include /* needed to define AF_ values on UNIX */ -#endif - -#ifdef HAVE_WINSOCK2_H -#include /* needed to define AF_ values on Windows */ -#endif - -#ifdef NEED_INET_V6DEFS_H -# include "inet_v6defs.h" -#endif - -#include -#include #include @@ -78,6 +41,7 @@ #include #include "file.h" #include "capture.h" +#include "capture_ifinfo.h" #include "capture_sync.h" #include "capture_info.h" #include "capture_ui_utils.h" @@ -652,163 +616,6 @@ capture_input_closed(capture_options *capture_opts) } } -/** - * Fetch the interface list from a child process (dumpcap). - * - * @return A GList containing if_info_t structs if successful, NULL (with err and possibly err_str set) otherwise. - * - */ - -/* XXX - We parse simple text output to get our interface list. Should - * we use "real" data serialization instead, e.g. via XML? */ -GList * -capture_interface_list(int *err, char **err_str) -{ - GList *if_list = NULL; - int i, j; - gchar *msg; - gchar **raw_list, **if_parts, **addr_parts; - gchar *name; - if_info_t *if_info; - if_addr_t *if_addr; - - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ..."); - - /* Try to get our interface list */ - *err = sync_interface_list_open(&msg); - if (*err != 0) { - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!"); - if (err_str) { - *err_str = msg; - } else { - g_free(msg); - } - return NULL; - } - - /* Split our lines */ -#ifdef _WIN32 - raw_list = g_strsplit(msg, "\r\n", 0); -#else - raw_list = g_strsplit(msg, "\n", 0); -#endif - g_free(msg); - - for (i = 0; raw_list[i] != NULL; i++) { - if_parts = g_strsplit(raw_list[i], "\t", 4); - if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL || - if_parts[3] == NULL) { - g_strfreev(if_parts); - continue; - } - - /* Number followed by the name, e.g "1. eth0" */ - name = strchr(if_parts[0], ' '); - if (name) { - name++; - } else { - g_strfreev(if_parts); - continue; - } - - 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]); - addr_parts = g_strsplit(if_parts[2], ",", 0); - for (j = 0; addr_parts[j] != NULL; j++) { - if_addr = g_malloc0(sizeof(if_addr_t)); - if (inet_pton(AF_INET, addr_parts[j], &if_addr->ip_addr.ip4_addr)) { - if_addr->type = AT_IPv4; - } else if (inet_pton(AF_INET6, addr_parts[j], - &if_addr->ip_addr.ip6_addr)) { - if_addr->type = AT_IPv6; - } else { - g_free(if_addr); - if_addr = NULL; - } - if (if_addr) { - if_info->ip_addr = g_slist_append(if_info->ip_addr, if_addr); - } - } - if (strcmp(if_parts[3], "loopback") == 0) - if_info->loopback = TRUE; - g_strfreev(if_parts); - g_strfreev(addr_parts); - if_list = g_list_append(if_list, if_info); - } - g_strfreev(raw_list); - - /* Check to see if we built a list */ - if (if_list == NULL) { - *err = NO_INTERFACES_FOUND; - if (err_str) - *err_str = g_strdup("No interfaces found"); - } - return if_list; -} - -/* XXX - We parse simple text output to get our interface list. Should - * we use "real" data serialization instead, e.g. via XML? */ -GList * -capture_pcap_linktype_list(const gchar *ifname, char **err_str) -{ - GList *linktype_list = NULL; - int err, i; - gchar *msg; - gchar **raw_list, **lt_parts; - data_link_info_t *data_link_info; - - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List ..."); - - /* Try to get our interface list */ - err = sync_linktype_list_open(ifname, &msg); - if (err != 0) { - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List failed!"); - if (err_str) { - *err_str = msg; - } else { - g_free(msg); - } - return NULL; - } - - /* Split our lines */ -#ifdef _WIN32 - raw_list = g_strsplit(msg, "\r\n", 0); -#else - raw_list = g_strsplit(msg, "\n", 0); -#endif - g_free(msg); - - for (i = 0; raw_list[i] != NULL; i++) { - /* ...and what if the interface name has a tab in it, Mr. Clever Programmer? */ - lt_parts = g_strsplit(raw_list[i], "\t", 3); - if (lt_parts[0] == NULL || lt_parts[1] == NULL || lt_parts[2] == NULL) { - g_strfreev(lt_parts); - continue; - } - - data_link_info = g_malloc(sizeof (data_link_info_t)); - data_link_info->dlt = (int) strtol(lt_parts[0], NULL, 10); - data_link_info->name = g_strdup(lt_parts[1]); - if (strcmp(lt_parts[2], "(not supported)") != 0) - data_link_info->description = g_strdup(lt_parts[2]); - else - data_link_info->description = NULL; - - linktype_list = g_list_append(linktype_list, data_link_info); - } - g_strfreev(raw_list); - - /* Check to see if we built a list */ - if (linktype_list == NULL) { - if (err_str) - *err_str = NULL; - } - return linktype_list; -} - if_stat_cache_t * capture_stat_start(GList *if_list) { int stat_fd, fork_child; diff --git a/capture.h b/capture.h index 168660fdc5..3465d40c4c 100644 --- a/capture.h +++ b/capture.h @@ -102,16 +102,6 @@ extern void capture_input_cfilter_error_message(capture_options *capture_opts, c extern void capture_input_closed(capture_options *capture_opts); #ifdef HAVE_LIBPCAP -/** - * Fetch the interface list from a child process. - */ -extern GList *capture_interface_list(int *err, char **err_str); - -/** - * Fetch the linktype list for the specified interface from a child process. - */ -extern GList *capture_pcap_linktype_list(const char *devname, char **err_str); - struct if_stat_cache_s; typedef struct if_stat_cache_s if_stat_cache_t; diff --git a/capture_ifinfo.c b/capture_ifinfo.c new file mode 100644 index 0000000000..e7f35c1ed0 --- /dev/null +++ b/capture_ifinfo.c @@ -0,0 +1,217 @@ +/* capture.c + * Routines for getting interface information from dumpcap + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_LIBPCAP + +#include +#include + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include /* needed to define AF_ values on UNIX */ +#endif + +#ifdef HAVE_WINSOCK2_H +#include /* needed to define AF_ values on Windows */ +#endif + +#ifdef NEED_INET_V6DEFS_H +# include "inet_v6defs.h" +#endif + +#include + +#include "capture_opts.h" +#include "capture_sync.h" +#include "log.h" + +#include "capture_ifinfo.h" + +/** + * Fetch the interface list from a child process (dumpcap). + * + * @return A GList containing if_info_t structs if successful, NULL (with err and possibly err_str set) otherwise. + * + */ + +/* XXX - We parse simple text output to get our interface list. Should + * we use "real" data serialization instead, e.g. via XML? */ +GList * +capture_interface_list(int *err, char **err_str) +{ + int ret; + GList *if_list = NULL; + int i, j; + gchar *msg; + gchar **raw_list, **if_parts, **addr_parts; + gchar *name; + if_info_t *if_info; + if_addr_t *if_addr; + + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ..."); + + /* Try to get our interface list */ + ret = sync_interface_list_open(&msg); + if (ret != 0) { + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!"); + if (err_str) { + *err_str = msg; + } else { + g_free(msg); + } + *err = CANT_RUN_DUMPCAP; + return NULL; + } + + /* Split our lines */ +#ifdef _WIN32 + raw_list = g_strsplit(msg, "\r\n", 0); +#else + raw_list = g_strsplit(msg, "\n", 0); +#endif + g_free(msg); + + for (i = 0; raw_list[i] != NULL; i++) { + if_parts = g_strsplit(raw_list[i], "\t", 4); + if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL || + if_parts[3] == NULL) { + g_strfreev(if_parts); + continue; + } + + /* Number followed by the name, e.g "1. eth0" */ + name = strchr(if_parts[0], ' '); + if (name) { + name++; + } else { + g_strfreev(if_parts); + continue; + } + + 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]); + addr_parts = g_strsplit(if_parts[2], ",", 0); + for (j = 0; addr_parts[j] != NULL; j++) { + if_addr = g_malloc0(sizeof(if_addr_t)); + if (inet_pton(AF_INET, addr_parts[j], &if_addr->addr.ip4_addr)) { + if_addr->ifat_type = IF_AT_IPv4; + } else if (inet_pton(AF_INET6, addr_parts[j], + &if_addr->addr.ip6_addr)) { + if_addr->ifat_type = IF_AT_IPv6; + } else { + g_free(if_addr); + if_addr = NULL; + } + if (if_addr) { + if_info->addrs = g_slist_append(if_info->addrs, if_addr); + } + } + if (strcmp(if_parts[3], "loopback") == 0) + if_info->loopback = TRUE; + g_strfreev(if_parts); + g_strfreev(addr_parts); + if_list = g_list_append(if_list, if_info); + } + g_strfreev(raw_list); + + /* Check to see if we built a list */ + if (if_list == NULL) { + *err = NO_INTERFACES_FOUND; + if (err_str) + *err_str = g_strdup("No interfaces found"); + } + return if_list; +} + +/* XXX - We parse simple text output to get our interface list. Should + * we use "real" data serialization instead, e.g. via XML? */ +GList * +capture_pcap_linktype_list(const gchar *ifname, char **err_str) +{ + GList *linktype_list = NULL; + int err, i; + gchar *msg; + gchar **raw_list, **lt_parts; + data_link_info_t *data_link_info; + + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List ..."); + + /* Try to get our interface list */ + err = sync_linktype_list_open(ifname, &msg); + if (err != 0) { + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List failed!"); + if (err_str) { + *err_str = msg; + } else { + g_free(msg); + } + return NULL; + } + + /* Split our lines */ +#ifdef _WIN32 + raw_list = g_strsplit(msg, "\r\n", 0); +#else + raw_list = g_strsplit(msg, "\n", 0); +#endif + g_free(msg); + + for (i = 0; raw_list[i] != NULL; i++) { + /* ...and what if the interface name has a tab in it, Mr. Clever Programmer? */ + lt_parts = g_strsplit(raw_list[i], "\t", 3); + if (lt_parts[0] == NULL || lt_parts[1] == NULL || lt_parts[2] == NULL) { + g_strfreev(lt_parts); + continue; + } + + data_link_info = g_malloc(sizeof (data_link_info_t)); + data_link_info->dlt = (int) strtol(lt_parts[0], NULL, 10); + data_link_info->name = g_strdup(lt_parts[1]); + if (strcmp(lt_parts[2], "(not supported)") != 0) + data_link_info->description = g_strdup(lt_parts[2]); + else + data_link_info->description = NULL; + + linktype_list = g_list_append(linktype_list, data_link_info); + } + g_strfreev(raw_list); + + /* Check to see if we built a list */ + if (linktype_list == NULL) { + if (err_str) + *err_str = NULL; + } + return linktype_list; +} + +#endif /* HAVE_LIBPCAP */ diff --git a/capture_ifinfo.h b/capture_ifinfo.h new file mode 100644 index 0000000000..28ebb5c701 --- /dev/null +++ b/capture_ifinfo.h @@ -0,0 +1,88 @@ +/* capture_ifinfo.h + * Definitions for routines to get information about capture interfaces + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __CAPTURE_IFINFO_H__ +#define __CAPTURE_IFINFO_H__ + +#ifdef HAVE_LIBPCAP + +/* + * The list of interfaces returned by "get_interface_list()" is + * a list of these structures. + */ +typedef struct { + char *name; /* e.g. "eth0" */ + char *description; /* from OS, e.g. "Local Area Connection" or NULL */ + GSList *addrs; /* containing address values of if_addr_t */ + gboolean loopback; /* TRUE if loopback, FALSE otherwise */ +} if_info_t; + +/* + * An address in the "addrs" list. + */ +typedef enum { + IF_AT_IPv4, + IF_AT_IPv6 +} if_address_type; + +typedef struct { + if_address_type ifat_type; + union { + guint32 ip4_addr; /* 4 byte IP V4 address, or */ + guint8 ip6_addr[16];/* 16 byte IP V6 address */ + } addr; +} if_addr_t; + +/** + * Fetch the interface list from a child process. + */ +extern GList *capture_interface_list(int *err, char **err_str); + +/* Error values from "get_interface_list()/capture_interface_list()". */ +#define CANT_GET_INTERFACE_LIST 1 /* error getting list */ +#define NO_INTERFACES_FOUND 2 /* list is empty */ +#define CANT_RUN_DUMPCAP 3 /* problem running dumpcap */ + +void free_interface_list(GList *if_list); + +/* + * The list of data link types returned by "get_pcap_linktype_list()" and + * "capture_pcap_linktype_list()" is a list of these structures. + */ +typedef struct { + int dlt; /* e.g. DLT_EN10MB (which is 1) */ + char *name; /* e.g. "EN10MB" or "DLT 1" */ + char *description; /* descriptive name from wiretap e.g. "Ethernet", NULL if unknown */ +} data_link_info_t; + +/** + * Fetch the linktype list for the specified interface from a child process. + */ +extern GList *capture_pcap_linktype_list(const char *devname, char **err_str); + +void free_pcap_linktype_list(GList *linktype_list); + +#endif /* HAVE_LIBPCAP */ + +#endif /* __CAPTURE_IFINFO_H__ */ diff --git a/capture_opts.c b/capture_opts.c index 243b6919ce..c61b5061df 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -68,6 +68,7 @@ #include "clopts_common.h" #include "cmdarg_err.h" +#include "capture_ifinfo.h" #include "capture-pcap-util.h" #include @@ -403,7 +404,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str cmdarg_err("There is no interface with that adapter index"); return 1; } - if_list = get_interface_list(&err, &err_str); + if_list = capture_interface_list(&err, &err_str); if (if_list == NULL) { switch (err) { @@ -624,11 +625,11 @@ capture_opts_list_interfaces(gboolean machine_readable) int err; gchar *err_str; int i; - GSList *ip_addr; + GSList *addr; if_addr_t *if_addr; char addr_str[ADDRSTRLEN]; - if_list = get_interface_list(&err, &err_str); + if_list = capture_interface_list(&err, &err_str); if (if_list == NULL) { switch (err) { case CANT_GET_INTERFACE_LIST: @@ -645,7 +646,7 @@ capture_opts_list_interfaces(gboolean machine_readable) i = 1; /* Interface id number */ for (if_entry = g_list_first(if_list); if_entry != NULL; - if_entry = g_list_next(if_entry)) { + if_entry = g_list_next(if_entry)) { if_info = if_entry->data; printf("%d. %s", i++, if_info->name); @@ -665,23 +666,23 @@ capture_opts_list_interfaces(gboolean machine_readable) else printf("\t\t"); - for(ip_addr = g_slist_nth(if_info->ip_addr, 0); ip_addr != NULL; - ip_addr = g_slist_next(ip_addr)) { - if (ip_addr != g_slist_nth(if_info->ip_addr, 0)) + for(addr = g_slist_nth(if_info->addrs, 0); addr != NULL; + addr = g_slist_next(addr)) { + if (addr != g_slist_nth(if_info->addrs, 0)) printf(","); - if_addr = ip_addr->data; - switch(if_addr->type) { - case AT_IPv4: - if (inet_ntop(AF_INET, &if_addr->ip_addr.ip4_addr, addr_str, + if_addr = addr->data; + switch(if_addr->ifat_type) { + case IF_AT_IPv4: + if (inet_ntop(AF_INET, &if_addr->addr.ip4_addr, addr_str, ADDRSTRLEN)) { printf("%s", addr_str); } else { printf(""); } break; - case AT_IPv6: - if (inet_ntop(AF_INET6, &if_addr->ip_addr.ip6_addr, + case IF_AT_IPv6: + if (inet_ntop(AF_INET6, &if_addr->addr.ip6_addr, addr_str, ADDRSTRLEN)) { printf("%s", addr_str); } else { @@ -689,7 +690,7 @@ capture_opts_list_interfaces(gboolean machine_readable) } break; default: - printf("", if_addr->type); + printf("", if_addr->ifat_type); } } @@ -748,7 +749,7 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt */ } else { /* No - pick the first one from the list of interfaces. */ - if_list = get_interface_list(&err, &err_str); + if_list = capture_interface_list(&err, &err_str); if (if_list == NULL) { switch (err) { diff --git a/capture_sync.c b/capture_sync.c index 3b04933337..b26293d32d 100644 --- a/capture_sync.c +++ b/capture_sync.c @@ -570,12 +570,11 @@ sync_pipe_start(capture_options *capture_opts) { } /* - * Open dumpcap with the supplied arguments. On success, msg points to - * a buffer containing the dumpcap output and returns 0. read_fd and - * fork_child point to the pipe's file descriptor and child PID/handle, - * respectively. On failure, msg points to the error message returned by - * dumpcap, and returns dumpcap's exit value. In either case, msg must be - * freed with g_free(). + * Open a pipe to dumpcap with the supplied arguments. On success, *msg + * is unchanged and 0 is returned; read_fd and fork_child point to the + * pipe's file descriptor and child PID/handle, respectively. On failure, + * *msg points to an error message for the failure, and -1 is returned. + * In the latter case, *msg must be freed with g_free(). */ /* XXX - This duplicates a lot of code in sync_pipe_start() */ #define PIPE_BUF_SIZE 5120 @@ -621,7 +620,7 @@ sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar * *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno)); g_free( (gpointer) argv[0]); g_free( (gpointer) argv); - return CANT_RUN_DUMPCAP; + return -1; } /* init STARTUPINFO */ @@ -658,7 +657,7 @@ sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar * CloseHandle(sync_pipe_write); g_free( (gpointer) argv[0]); g_free( (gpointer) argv); - return CANT_RUN_DUMPCAP; + return -1; } *fork_child = (int) pi.hProcess; g_string_free(args, TRUE); @@ -673,7 +672,7 @@ sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar * *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno)); g_free( (gpointer) argv[0]); g_free(argv); - return CANT_RUN_DUMPCAP; + return -1; } if ((*fork_child = fork()) == 0) { @@ -721,7 +720,7 @@ sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar * /* We couldn't even create the child process. */ *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno)); ws_close(*read_fd); - return CANT_RUN_DUMPCAP; + return -1; } /* we might wait for a moment till child is ready, so update screen now */ @@ -729,6 +728,12 @@ sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar * return 0; } +/* + * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is + * returned. On failure, *msg points to an error message for the + * failure, and -1 is returned. In the latter case, *msg must be + * freed with g_free(). + */ static int #ifdef _WIN32 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) { @@ -747,7 +752,7 @@ sync_pipe_close_command(int *read_fd, gchar **msg) { if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) { *msg = g_strdup_printf("Child capture process stopped unexpectedly " "(errno:%u)", errno); - return CANT_RUN_DUMPCAP; + return -1; } #else if (wait(&fork_child_status) != -1) { @@ -770,22 +775,25 @@ sync_pipe_close_command(int *read_fd, gchar **msg) { *msg = g_strdup_printf("Child capture process died: wait status %#o", fork_child_status); } - return CANT_RUN_DUMPCAP; + return -1; } } else { *msg = g_strdup_printf("Child capture process stopped unexpectedly " "(errno:%u)", errno); - return CANT_RUN_DUMPCAP; + return -1; } #endif return 0; } /* - * Run dumpcap with the supplied arguments. On success, msg points to - * a buffer containing the dumpcap output and returns 0. On failure, msg - * points to the error message returned by dumpcap, and returns dumpcap's - * exit value. In either case, msg must be freed with g_free(). + * Run dumpcap with the supplied arguments. On success, *msg points to + * a buffer containing the dumpcap output, and 0 is returned. On failure, + * *msg points to an error message, and -1 is returned. In either case, + * *msg must be freed with g_free(). + * + * XXX - this doesn't check the exit status of dumpcap if it can be + * started and its return status could be fetched. */ /* XXX - This duplicates a lot of code in sync_pipe_start() */ #define PIPE_BUF_SIZE 5120 @@ -801,8 +809,7 @@ sync_pipe_run_command(const char** argv, gchar **msg) { if (ret) return ret; - /* We were able to set up to read dumpcap's output. Do so and - return its exit value. */ + /* We were able to set up to read dumpcap's output. Do so. */ msg_buf = g_string_new(""); while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) { buf[count] = '\0'; @@ -826,10 +833,10 @@ sync_pipe_run_command(const char** argv, gchar **msg) { } /* - * Get an interface list using dumpcap. On success, msg points to - * a buffer containing the dumpcap output and returns 0. On failure, msg - * points to the error message returned by dumpcap, and returns dumpcap's - * exit value. In either case, msg must be freed with g_free(). + * Get an interface list using dumpcap. On success, *msg points to + * a buffer containing the dumpcap output, and 0 is returned. On failure, + * *msg points to an error message, and -1 is returned. In either case, + * msg must be freed with g_free(). */ int sync_interface_list_open(gchar **msg) { @@ -847,7 +854,7 @@ sync_interface_list_open(gchar **msg) { if (!argv) { *msg = g_strdup_printf("We don't know where to find dumpcap."); - return CANT_RUN_DUMPCAP; + return -1; } /* Ask for the interface list */ @@ -876,10 +883,10 @@ sync_interface_list_open(gchar **msg) { } /* - * Get an linktype list using dumpcap. On success, msg points to - * a buffer containing the dumpcap output and returns 0. On failure, msg - * points to the error message returned by dumpcap, and returns dumpcap's - * exit value. In either case, msg must be freed with g_free(). + * Get an linktype list using dumpcap. On success, *msg points to + * a buffer containing the dumpcap output, and 0 is returned. On failure, + * *msg points to an error message, and -1 is returned. In either case, + * *msg must be freed with g_free(). */ int sync_linktype_list_open(const gchar *ifname, gchar **msg) { @@ -897,7 +904,7 @@ sync_linktype_list_open(const gchar *ifname, gchar **msg) { if (!argv) { *msg = g_strdup_printf("We don't know where to find dumpcap."); - return CANT_RUN_DUMPCAP; + return -1; } /* Ask for the linktype list */ @@ -928,9 +935,9 @@ sync_linktype_list_open(const gchar *ifname, gchar **msg) { /* * Start getting interface statistics using dumpcap. On success, read_fd - * contains the file descriptor for the pipe's stdout, msg is unchanged, - * and zero is returned. On failure, msg will point to an error message - * that must be g_free()d and a nonzero error value will be returned. + * contains the file descriptor for the pipe's stdout, *msg is unchanged, + * and zero is returned. On failure, *msg will point to an error message + * that must be g_free()d, and -1 will be returned. */ int sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) { @@ -948,7 +955,7 @@ sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) { if (!argv) { *msg = g_strdup_printf("We don't know where to find dumpcap."); - return CANT_RUN_DUMPCAP; + return -1; } /* Ask for the interface statistics */ diff --git a/capture_ui_utils.c b/capture_ui_utils.c index c975aa6df5..ffff697eda 100644 --- a/capture_ui_utils.c +++ b/capture_ui_utils.c @@ -34,7 +34,7 @@ #include #include -#include "capture-pcap-util.h" +#include "capture_ifinfo.h" #include "capture_ui_utils.h" /* @@ -130,12 +130,12 @@ capture_dev_user_linktype_find(const gchar *if_name) /* * Return as descriptive a name for an interface as we can get. * If the user has specified a comment, use that. Otherwise, - * if get_interface_list() supplies a description, use that, + * if capture_interface_list() supplies a description, use that, * otherwise use the interface name. * * The result must be g_free()'d when you're done with it. * - * Note: given that this calls get_interface_list(), which attempts to + * Note: given that this calls capture_interface_list(), which attempts to * open all adapters it finds in order to check whether they can be * captured on, this is an expensive routine to call, so don't call it * frequently. @@ -158,7 +158,7 @@ get_interface_descriptive_name(const char *if_name) /* No, we don't have a user-supplied description; did we get one from the OS or libpcap? */ descr = NULL; - if_list = get_interface_list(&err, NULL); + if_list = capture_interface_list(&err, NULL); if (if_list != NULL && if_name != NULL) { if_entry = if_list; do { diff --git a/capture_ui_utils.h b/capture_ui_utils.h index 57c2572cde..e93142c79d 100644 --- a/capture_ui_utils.h +++ b/capture_ui_utils.h @@ -45,7 +45,7 @@ gint capture_dev_user_linktype_find(const gchar *if_name); /** Return as descriptive a name for an interface as we can get. * If the user has specified a comment, use that. Otherwise, - * if get_interface_list() supplies a description, use that, + * if capture_interface_list() supplies a description, use that, * otherwise use the interface name. * * @param if_name The name of the interface. @@ -56,7 +56,7 @@ char *get_interface_descriptive_name(const char *if_name); /** Build the GList of available capture interfaces. * - * @param if_list An interface list from get_interface_list(). + * @param if_list An interface list from capture_interface_list(). * @param do_hide Hide the "hidden" interfaces. * * @return A list of if_info_t structs (use free_capture_combo_list() later). diff --git a/dumpcap.c b/dumpcap.c index 7a4eeb4466..0822535c82 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -90,6 +90,7 @@ #include "sync_pipe.h" #include "capture_opts.h" +#include "capture_ifinfo.h" #include "capture_sync.h" #include "conditions.h" @@ -423,6 +424,25 @@ cmdarg_err_cont(const char *fmt, ...) } } +/* + * capture_interface_list() is expected to do the right thing to get + * a list of interfaces. + * + * In most of the programs in the Wireshark suite, "the right thing" + * is to run dumpcap and ask it for the list, because dumpcap may + * be the only program in the suite with enough privileges to get + * the list. + * + * In dumpcap itself, however, we obviously can't run dumpcap to + * ask for the list. Therefore, our capture_interface_list() should + * just call get_interface_list(). + */ +GList * +capture_interface_list(int *err, char **err_str) +{ + return get_interface_list(err, err_str); +} + typedef struct { char *name; pcap_t *pch; diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c index 5905ba0f84..e029fb8efd 100644 --- a/gtk/capture_dlg.c +++ b/gtk/capture_dlg.c @@ -46,6 +46,7 @@ #include "../capture.h" #include "../globals.h" #include "../capture_errs.h" +#include "../capture_ifinfo.h" #include "../simple_dialog.h" #include "../capture-pcap-util.h" #include "../capture_ui_utils.h" @@ -263,8 +264,8 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry) GtkWidget *if_ip_lb; GString *ip_str = g_string_new("IP address: "); int ips = 0; - GSList *curr_ip; - if_addr_t *ip_addr; + GSList *curr_addr; + if_addr_t *addr; #ifdef HAVE_PCAP_REMOTE GtkWidget *iftype_cbx; int iftype; @@ -344,25 +345,26 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry) lt_list = capture_pcap_linktype_list(if_name, NULL); /* create string of list of IP addresses of this interface */ - for (; (curr_ip = g_slist_nth(if_info->ip_addr, ips)) != NULL; ips++) { + for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) { if (ips != 0) g_string_append(ip_str, ", "); - ip_addr = (if_addr_t *)curr_ip->data; - switch (ip_addr->type) { + addr = (if_addr_t *)curr_addr->data; + switch (addr->ifat_type) { - case AT_IPv4: + case IF_AT_IPv4: g_string_append(ip_str, - ip_to_str((guint8 *)&ip_addr->ip_addr.ip4_addr)); + ip_to_str((guint8 *)&addr->addr.ip4_addr)); break; - case AT_IPv6: + case IF_AT_IPv6: g_string_append(ip_str, - ip6_to_str((struct e_in6_addr *)&ip_addr->ip_addr.ip6_addr)); + ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr)); break; default: - g_assert_not_reached(); + /* In case we add non-IP addresses */ + break; } } diff --git a/gtk/capture_if_dlg.c b/gtk/capture_if_dlg.c index ef3b676afa..2604485a1f 100644 --- a/gtk/capture_if_dlg.c +++ b/gtk/capture_if_dlg.c @@ -40,10 +40,11 @@ #include #include "../globals.h" -#include "../capture-pcap-util.h" +#include "../capture_errs.h" +#include "../capture_ifinfo.h" #include "../simple_dialog.h" #include "../capture.h" -#include "../capture_errs.h" +#include "../capture-pcap-util.h" #include "../capture_ui_utils.h" #include "wsutil/file_util.h" #include @@ -442,28 +443,55 @@ GtkWidget * capture_get_if_icon(const if_info_t* if_info _U_) } -static const gchar * -set_ip_addr_label(GSList *ip_addr_list, GtkWidget *ip_lb, guint selected_ip_addr) +static int +get_ip_addr_count(GSList *addr_list) { - GSList *curr_ip; - if_addr_t *ip_addr; - const gchar *addr_str = NULL; + GSList *curr_addr; + if_addr_t *addr; + int count; - curr_ip = g_slist_nth(ip_addr_list, selected_ip_addr); - if (curr_ip) { - ip_addr = (if_addr_t *)curr_ip->data; - switch (ip_addr->type) { + count = 0; + for (curr_addr = addr_list; curr_addr != NULL; + curr_addr = g_slist_next(curr_addr)) { + addr = (if_addr_t *)curr_addr->data; + switch (addr->ifat_type) { - case AT_IPv4: - addr_str = ip_to_str((guint8 *)&ip_addr->ip_addr.ip4_addr); - break; - - case AT_IPv6: - addr_str = ip6_to_str((struct e_in6_addr *)&ip_addr->ip_addr.ip6_addr); + case IF_AT_IPv4: + case IF_AT_IPv6: + count++; break; default: - g_assert_not_reached(); + /* In case we add non-IP addresses */ + break; + } + } + return count; +} + +static const gchar * +set_ip_addr_label(GSList *addr_list, GtkWidget *ip_lb, guint selected_ip_addr) +{ + GSList *curr_addr; + if_addr_t *addr; + const gchar *addr_str = NULL; + + curr_addr = g_slist_nth(addr_list, selected_ip_addr); + if (curr_addr) { + addr = (if_addr_t *)curr_addr->data; + switch (addr->ifat_type) { + + case IF_AT_IPv4: + addr_str = ip_to_str((guint8 *)&addr->addr.ip4_addr); + break; + + case IF_AT_IPv6: + addr_str = ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr); + break; + + default: + /* Ignore non-IP addresses, in case we ever support them */ + break; } } @@ -500,17 +528,40 @@ static gboolean ip_label_press_cb(GtkWidget *widget, GdkEvent *event _U_, gpointer data) { GtkWidget *ip_lb = g_object_get_data(G_OBJECT(widget), CAPTURE_IF_IP_ADDR_LABEL); - GSList *ip_addr_list = data; + GSList *addr_list = data; + GSList *curr_addr, *start_addr; + if_addr_t *addr; guint selected_ip_addr = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(ip_lb), CAPTURE_IF_SELECTED_IP_ADDR)); /* Select next IP address */ - selected_ip_addr++; - if (g_slist_length(ip_addr_list) <= selected_ip_addr) { - /* Probably have the last one, start over again */ - selected_ip_addr = 0; + start_addr = g_slist_nth(addr_list, selected_ip_addr); + for (;;) { + selected_ip_addr++; + if (g_slist_length(addr_list) <= selected_ip_addr) { + /* Wrap around */ + selected_ip_addr = 0; + } + curr_addr = g_slist_nth(addr_list, selected_ip_addr); + if (curr_addr == start_addr) { + /* We wrapped all the way around */ + break; + } + + addr = (if_addr_t *)curr_addr->data; + switch (addr->ifat_type) { + + case IF_AT_IPv4: + case IF_AT_IPv6: + goto found; + + default: + /* In case we add non-IP addresses */ + break; + } } - set_ip_addr_label(ip_addr_list, ip_lb, selected_ip_addr); +found: + set_ip_addr_label(addr_list, ip_lb, selected_ip_addr); return FALSE; } @@ -734,7 +785,7 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_) /* Only one IP address will be shown, start with the first */ g_string_append(if_tool_str, "IP: "); if_dlg_data->ip_lb = gtk_label_new(""); - addr_str = set_ip_addr_label (if_info->ip_addr, if_dlg_data->ip_lb, 0); + addr_str = set_ip_addr_label (if_info->addrs, if_dlg_data->ip_lb, 0); if (addr_str) { gtk_widget_set_sensitive(if_dlg_data->ip_lb, TRUE); g_string_append(if_tool_str, addr_str); @@ -745,12 +796,12 @@ capture_if_cb(GtkWidget *w _U_, gpointer d _U_) eb = gtk_event_box_new (); gtk_container_add(GTK_CONTAINER(eb), if_dlg_data->ip_lb); gtk_table_attach_defaults(GTK_TABLE(if_tb), eb, 3, 4, row, row+1); - if (g_slist_length(if_info->ip_addr) > 1) { + if (get_ip_addr_count(if_info->addrs) > 1) { /* More than one IP address, make it possible to toggle */ g_object_set_data(G_OBJECT(eb), CAPTURE_IF_IP_ADDR_LABEL, if_dlg_data->ip_lb); g_signal_connect(eb, "enter-notify-event", G_CALLBACK(ip_label_enter_cb), NULL); g_signal_connect(eb, "leave-notify-event", G_CALLBACK(ip_label_leave_cb), NULL); - g_signal_connect(eb, "button-press-event", G_CALLBACK(ip_label_press_cb), if_info->ip_addr); + g_signal_connect(eb, "button-press-event", G_CALLBACK(ip_label_press_cb), if_info->addrs); } g_string_append(if_tool_str, "\n"); diff --git a/gtk/capture_if_dlg.h b/gtk/capture_if_dlg.h index aa15b5a6e4..dcf59aee06 100644 --- a/gtk/capture_if_dlg.h +++ b/gtk/capture_if_dlg.h @@ -34,7 +34,7 @@ set_capture_if_dialog_for_capture_in_progress(gboolean capture_in_progress); #ifdef HAVE_LIBPCAP -#include "capture-pcap-util.h" /* for if_info_t */ +#include "capture_ifinfo.h" /* for if_info_t */ /** User requested the "Capture Interfaces" dialog box by menu or toolbar. * diff --git a/gtk/prefs_capture.c b/gtk/prefs_capture.c index fd13eeee25..17cd411a32 100644 --- a/gtk/prefs_capture.c +++ b/gtk/prefs_capture.c @@ -35,9 +35,8 @@ #include "../globals.h" #include "../simple_dialog.h" -#include "../capture-pcap-util.h" +#include "../capture_ifinfo.h" #include "../capture_ui_utils.h" -#include "../capture.h" #include "gtk/prefs_capture.h" #include "gtk/prefs_dlg.h"