In Wireshark and TShark, run dumpcap to get interface lists and lists of
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 4 Mar 2010 01:12:04 +0000 (01:12 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 4 Mar 2010 01:12:04 +0000 (01:12 +0000)
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.

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

19 files changed:
Makefile.common
capture-pcap-util-int.h
capture-pcap-util-unix.c
capture-pcap-util.c
capture-pcap-util.h
capture-wpcap.c
capture.c
capture.h
capture_ifinfo.c [new file with mode: 0644]
capture_ifinfo.h [new file with mode: 0644]
capture_opts.c
capture_sync.c
capture_ui_utils.c
capture_ui_utils.h
dumpcap.c
gtk/capture_dlg.c
gtk/capture_if_dlg.c
gtk/capture_if_dlg.h
gtk/prefs_capture.c

index b2995d6820af1dd9f94add395f6f67de3d1d9d6f..0676bce0a95f449aabfbb4c67a9579b62ee0ba30 100644 (file)
@@ -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)
index c749d5e042c761fb2463f9f298f1b34dd6633cd9..426595d3414aa0916b1582bf9f28941ccb363d4f 100644 (file)
@@ -26,9 +26,6 @@
 #define __PCAP_UTIL_INT_H__
 
 #ifdef HAVE_LIBPCAP
-#ifdef HAVE_PCAP_REMOTE
-#include <pcap.h>
-#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);
index 589ac7d74403f112576af48b439a84180cc136e0..3ffda24fac59d7047e9ba47d38a7cf1ef1b534dd 100644 (file)
@@ -47,8 +47,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <pcap.h>
-
 /*
  * Keep Digital UNIX happy when including <net/if.h>.
  */
@@ -60,6 +58,7 @@ struct rtentry;
 # include <sys/sockio.h>
 #endif
 
+#include "capture_ifinfo.h"
 #include "capture-pcap-util.h"
 #include "capture-pcap-util-int.h"
 
index fd4d0525a3ee758bacf7604fb88bc1eccb0f9ae3..4dd666497b979bef41b819553d2987764662f72c 100644 (file)
@@ -35,8 +35,6 @@
 #include <limits.h>
 #include <string.h>
 
-#include <pcap.h>
-
 #ifdef HAVE_SYS_TYPES_H
 # include <sys/types.h>
 #endif
@@ -48,6 +46,7 @@
 #include <wtap.h>
 #include <libpcap.h>
 
+#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);
 }
 
index 3b9bf831bdbc264773604b023207e0fae41191e9..c1fe38f147d2f47dc886b48acc5044b27120a51f 100644 (file)
@@ -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 <epan/address.h>
-
 #include <pcap.h>
 
 /*
@@ -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__ */
index 4d5deb7f0e4b15244bbe0e19fb3679dd6a52f4af..09f9ea45ef42811a258cbdd60261aa4d8bbcce7e 100644 (file)
 #include <glib.h>
 #include <gmodule.h>
 
-#ifdef HAVE_LIBPCAP
-#include <pcap.h>
-#endif
-
 #include "capture-pcap-util.h"
 #include "capture-pcap-util-int.h"
 
index 493f626eac1bc24875ea370ba198458474682210..68f2fbb9d68d9e260ea4c3dd0cbe8b9935440c13 100644 (file)
--- a/capture.c
+++ b/capture.c
 #endif
 
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>         /* needed to define AF_ values on UNIX */
-#endif
-
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>           /* needed to define AF_ values on Windows */
-#endif
-
-#ifdef NEED_INET_V6DEFS_H
-# include "inet_v6defs.h"
-#endif
-
-#include <signal.h>
-#include <errno.h>
 
 #include <glib.h>
 
@@ -78,6 +41,7 @@
 #include <epan/dfilter/dfilter.h>
 #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;
index 168660fdc5354ecb072d3c5549f2ee58248245b6..3465d40c4c57d4e003c6d9d256e656cd916bb353 100644 (file)
--- 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 (file)
index 0000000..e7f35c1
--- /dev/null
@@ -0,0 +1,217 @@
+/* capture.c
+ * Routines for getting interface information from dumpcap
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_LIBPCAP
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>         /* needed to define AF_ values on UNIX */
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>           /* needed to define AF_ values on Windows */
+#endif
+
+#ifdef NEED_INET_V6DEFS_H
+# include "inet_v6defs.h"
+#endif
+
+#include <glib.h>
+
+#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 (file)
index 0000000..28ebb5c
--- /dev/null
@@ -0,0 +1,88 @@
+/* capture_ifinfo.h
+ * Definitions for routines to get information about capture interfaces
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __CAPTURE_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__ */
index 243b6919ce370c38c6a7de9fef0bbd7b80ccf488..c61b5061df265b0909096f4efc3b435bb145e9ae 100644 (file)
@@ -68,6 +68,7 @@
 #include "clopts_common.h"
 #include "cmdarg_err.h"
 
+#include "capture_ifinfo.h"
 #include "capture-pcap-util.h"
 #include <wsutil/file_util.h>
 
@@ -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("<unknown IPv4>");
                     }
                     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("<type unknown %u>", if_addr->type);
+                    printf("<type unknown %u>", 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) {
 
index 3b0493333702cc9c771c97812554a2efd790209c..b26293d32d8e7a38b528e573e23995af53ba381a 100644 (file)
@@ -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 */
index c975aa6df581f4bddf92c2d06b2ece6f344cb5a1..ffff697eda955c5c64f583d012a5aba0dee819b2 100644 (file)
@@ -34,7 +34,7 @@
 #include <glib.h>
 
 #include <epan/prefs.h>
-#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 {
index 57c2572cdeecb81983bf58bb1365a68e7cf33f1e..e93142c79d295bd564a9a12beca1f002ac5aceaa 100644 (file)
@@ -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).
index 7a4eeb446694a96200612ab8856f5cab59d68269..0822535c824f30dc072442df1b06ff3c98de903a 100644 (file)
--- 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;
index 5905ba0f8442fd80f71e162e33e684fa5763c403..e029fb8efd8c35b2b4dba961cd3b1e2f0304d352 100644 (file)
@@ -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;
            }
          }
 
index ef3b676afa3a4d7e0cf79e1c1548bcb61e41c709..2604485a1f3cf98df2f6d0fe3bc486c0d22b7b27 100644 (file)
 #include <epan/prefs.h>
 
 #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 <wiretap/wtap.h>
@@ -442,28 +443,55 @@ GtkWidget * capture_get_if_icon(const if_info_t* if_info _U_)
 }
 
 
+static int
+get_ip_addr_count(GSList *addr_list)
+{
+  GSList *curr_addr;
+  if_addr_t *addr;
+  int count;
+
+  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 IF_AT_IPv4:
+    case IF_AT_IPv6:
+      count++;
+      break;
+
+    default:
+      /* In case we add non-IP addresses */
+      break;
+    }
+  }
+  return count;
+}
+
 static const gchar *
-set_ip_addr_label(GSList *ip_addr_list, GtkWidget *ip_lb, guint selected_ip_addr)
+set_ip_addr_label(GSList *addr_list, GtkWidget *ip_lb, guint selected_ip_addr)
 {
-  GSList *curr_ip;
-  if_addr_t *ip_addr;
+  GSList *curr_addr;
+  if_addr_t *addr;
   const gchar *addr_str = NULL;
 
-  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) {
+  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 AT_IPv4:
-      addr_str = ip_to_str((guint8 *)&ip_addr->ip_addr.ip4_addr);
+    case IF_AT_IPv4:
+      addr_str = ip_to_str((guint8 *)&addr->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_IPv6:
+      addr_str = ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr);
       break;
 
     default:
-      g_assert_not_reached();
+      /* 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");
 
index aa15b5a6e46bafc8ab6bfb1c532e7e29daaec14e..dcf59aee06c4f4c7b967145193e08a2efcfefea8 100644 (file)
@@ -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.
  *
index fd13eeee25a4eedd4b299a2866189a44c42f8618..17cd411a32f373256c8dcde5c146b8c7e749c74d 100644 (file)
@@ -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"