forked from osmocom/wireshark
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
This commit is contained in:
parent
98d800bae8
commit
167ab3a98c
|
@ -44,12 +44,10 @@ GENERATED_C_FILES = \
|
||||||
# All the generated files.
|
# All the generated files.
|
||||||
GENERATED_FILES = $(GENERATED_C_FILES) $(GENERATED_HEADER_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 = \
|
WIRESHARK_COMMON_SRC = \
|
||||||
$(PLATFORM_SRC) \
|
$(PLATFORM_SRC) \
|
||||||
capture_errs.c \
|
|
||||||
capture-pcap-util.c \
|
capture-pcap-util.c \
|
||||||
capture_ui_utils.c \
|
|
||||||
cfile.c \
|
cfile.c \
|
||||||
clopts_common.c \
|
clopts_common.c \
|
||||||
disabled_protos.c \
|
disabled_protos.c \
|
||||||
|
@ -66,10 +64,8 @@ WIRESHARK_COMMON_SRC = \
|
||||||
# corresponding headers
|
# corresponding headers
|
||||||
WIRESHARK_COMMON_INCLUDES = \
|
WIRESHARK_COMMON_INCLUDES = \
|
||||||
svnversion.h \
|
svnversion.h \
|
||||||
capture_errs.h \
|
|
||||||
capture-pcap-util.h \
|
capture-pcap-util.h \
|
||||||
capture-pcap-util-int.h \
|
capture-pcap-util-int.h \
|
||||||
capture_ui_utils.h \
|
|
||||||
cfile.h \
|
cfile.h \
|
||||||
clopts_common.h \
|
clopts_common.h \
|
||||||
cmdarg_err.h \
|
cmdarg_err.h \
|
||||||
|
@ -89,6 +85,19 @@ WIRESHARK_COMMON_INCLUDES = \
|
||||||
tap-rtp-common.h \
|
tap-rtp-common.h \
|
||||||
version_info.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
|
# sources for TShark taps
|
||||||
TSHARK_TAP_SRC = \
|
TSHARK_TAP_SRC = \
|
||||||
tap-afpstat.c \
|
tap-afpstat.c \
|
||||||
|
@ -139,6 +148,7 @@ EXTRA_wireshark_INCLUDES = \
|
||||||
# wireshark specifics
|
# wireshark specifics
|
||||||
wireshark_SOURCES = \
|
wireshark_SOURCES = \
|
||||||
$(WIRESHARK_COMMON_SRC) \
|
$(WIRESHARK_COMMON_SRC) \
|
||||||
|
$(SHARK_COMMON_CAPTURE_SRC) \
|
||||||
airpcap_loader.c \
|
airpcap_loader.c \
|
||||||
alert_box.c \
|
alert_box.c \
|
||||||
capture.c \
|
capture.c \
|
||||||
|
@ -181,6 +191,7 @@ wireshark_INCLUDES = \
|
||||||
# tshark specifics
|
# tshark specifics
|
||||||
tshark_SOURCES = \
|
tshark_SOURCES = \
|
||||||
$(WIRESHARK_COMMON_SRC) \
|
$(WIRESHARK_COMMON_SRC) \
|
||||||
|
$(SHARK_COMMON_CAPTURE_SRC) \
|
||||||
$(TSHARK_TAP_SRC) \
|
$(TSHARK_TAP_SRC) \
|
||||||
capture_opts.c \
|
capture_opts.c \
|
||||||
capture_sync.c \
|
capture_sync.c \
|
||||||
|
@ -249,6 +260,7 @@ dumpcap_INCLUDES = \
|
||||||
# this target needed for distribution only
|
# this target needed for distribution only
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
$(WIRESHARK_COMMON_INCLUDES) \
|
$(WIRESHARK_COMMON_INCLUDES) \
|
||||||
|
$(SHARK_COMMON_CAPTURE_INCLUDES) \
|
||||||
$(wireshark_INCLUDES) \
|
$(wireshark_INCLUDES) \
|
||||||
$(EXTRA_wireshark_INCLUDES) \
|
$(EXTRA_wireshark_INCLUDES) \
|
||||||
$(dumpcap_INCLUDES)
|
$(dumpcap_INCLUDES)
|
||||||
|
|
|
@ -26,9 +26,6 @@
|
||||||
#define __PCAP_UTIL_INT_H__
|
#define __PCAP_UTIL_INT_H__
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCAP
|
#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 if_info_t *if_info_new(char *name, char *description);
|
||||||
extern void if_info_add_address(if_info_t *if_info, struct sockaddr *addr);
|
extern void if_info_add_address(if_info_t *if_info, struct sockaddr *addr);
|
||||||
|
|
|
@ -47,8 +47,6 @@
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <pcap.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep Digital UNIX happy when including <net/if.h>.
|
* Keep Digital UNIX happy when including <net/if.h>.
|
||||||
*/
|
*/
|
||||||
|
@ -60,6 +58,7 @@ struct rtentry;
|
||||||
# include <sys/sockio.h>
|
# include <sys/sockio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "capture_ifinfo.h"
|
||||||
#include "capture-pcap-util.h"
|
#include "capture-pcap-util.h"
|
||||||
#include "capture-pcap-util-int.h"
|
#include "capture-pcap-util-int.h"
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <pcap.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,6 +46,7 @@
|
||||||
#include <wtap.h>
|
#include <wtap.h>
|
||||||
#include <libpcap.h>
|
#include <libpcap.h>
|
||||||
|
|
||||||
|
#include "capture_ifinfo.h"
|
||||||
#include "capture-pcap-util.h"
|
#include "capture-pcap-util.h"
|
||||||
#include "capture-pcap-util-int.h"
|
#include "capture-pcap-util-int.h"
|
||||||
|
|
||||||
|
@ -190,7 +189,7 @@ if_info_new(char *name, char *description)
|
||||||
if_info->description = NULL;
|
if_info->description = NULL;
|
||||||
else
|
else
|
||||||
if_info->description = g_strdup(description);
|
if_info->description = g_strdup(description);
|
||||||
if_info->ip_addr = NULL;
|
if_info->addrs = NULL;
|
||||||
if_info->loopback = FALSE;
|
if_info->loopback = FALSE;
|
||||||
return if_info;
|
return if_info;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +197,7 @@ if_info_new(char *name, char *description)
|
||||||
void
|
void
|
||||||
if_info_add_address(if_info_t *if_info, struct sockaddr *addr)
|
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;
|
struct sockaddr_in *ai;
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
struct sockaddr_in6 *ai6;
|
struct sockaddr_in6 *ai6;
|
||||||
|
@ -208,22 +207,22 @@ if_info_add_address(if_info_t *if_info, struct sockaddr *addr)
|
||||||
|
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
ai = (struct sockaddr_in *)addr;
|
ai = (struct sockaddr_in *)addr;
|
||||||
ip_addr = g_malloc(sizeof(*ip_addr));
|
if_addr = g_malloc(sizeof(*if_addr));
|
||||||
ip_addr->type = AT_IPv4;
|
if_addr->ifat_type = IF_AT_IPv4;
|
||||||
ip_addr->ip_addr.ip4_addr =
|
if_addr->addr.ip4_addr =
|
||||||
*((guint32 *)&(ai->sin_addr.s_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;
|
break;
|
||||||
|
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
ai6 = (struct sockaddr_in6 *)addr;
|
ai6 = (struct sockaddr_in6 *)addr;
|
||||||
ip_addr = g_malloc(sizeof(*ip_addr));
|
if_addr = g_malloc(sizeof(*if_addr));
|
||||||
ip_addr->type = AT_IPv6;
|
if_addr->ifat_type = IF_AT_IPv6;
|
||||||
memcpy((void *)&ip_addr->ip_addr.ip6_addr,
|
memcpy((void *)&if_addr->addr.ip6_addr,
|
||||||
(void *)&ai6->sin6_addr.s6_addr,
|
(void *)&ai6->sin6_addr.s6_addr,
|
||||||
sizeof ip_addr->ip_addr.ip6_addr);
|
sizeof if_addr->addr.ip6_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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -338,8 +337,8 @@ free_if_cb(gpointer data, gpointer user_data _U_)
|
||||||
g_free(if_info->name);
|
g_free(if_info->name);
|
||||||
g_free(if_info->description);
|
g_free(if_info->description);
|
||||||
|
|
||||||
g_slist_foreach(if_info->ip_addr, free_if_info_addr_cb, NULL);
|
g_slist_foreach(if_info->addrs, free_if_info_addr_cb, NULL);
|
||||||
g_slist_free(if_info->ip_addr);
|
g_slist_free(if_info->addrs);
|
||||||
g_free(if_info);
|
g_free(if_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PCAP_UTIL_H__
|
#ifndef __CAPTURE_PCAP_UTIL_H__
|
||||||
#define __PCAP_UTIL_H__
|
#define __CAPTURE_PCAP_UTIL_H__
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCAP
|
#ifdef HAVE_LIBPCAP
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#include <epan/address.h>
|
|
||||||
|
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,28 +42,6 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define MIN_PACKET_SIZE 1 /* minimum amount of packet data we can read */
|
#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);
|
GList *get_interface_list(int *err, char **err_str);
|
||||||
#ifdef HAVE_PCAP_REMOTE
|
#ifdef HAVE_PCAP_REMOTE
|
||||||
GList *get_remote_interface_list(const char *hostname, const char *port,
|
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);
|
const char *passwd, int *err, char **err_str);
|
||||||
#endif
|
#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);
|
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 */
|
/* get/set the link type of an interface */
|
||||||
/* (only used in capture_loop.c / capture-pcap-util.c) */
|
/* (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);
|
extern void get_runtime_pcap_version(GString *str);
|
||||||
|
|
||||||
#endif /* __PCAP_UTIL_H__ */
|
#endif /* __CAPTURE_PCAP_UTIL_H__ */
|
||||||
|
|
|
@ -32,10 +32,6 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCAP
|
|
||||||
#include <pcap.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "capture-pcap-util.h"
|
#include "capture-pcap-util.h"
|
||||||
#include "capture-pcap-util-int.h"
|
#include "capture-pcap-util-int.h"
|
||||||
|
|
||||||
|
|
195
capture.c
195
capture.c
|
@ -33,44 +33,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.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>
|
#include <glib.h>
|
||||||
|
|
||||||
|
@ -78,6 +41,7 @@
|
||||||
#include <epan/dfilter/dfilter.h>
|
#include <epan/dfilter/dfilter.h>
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
|
#include "capture_ifinfo.h"
|
||||||
#include "capture_sync.h"
|
#include "capture_sync.h"
|
||||||
#include "capture_info.h"
|
#include "capture_info.h"
|
||||||
#include "capture_ui_utils.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 *
|
if_stat_cache_t *
|
||||||
capture_stat_start(GList *if_list) {
|
capture_stat_start(GList *if_list) {
|
||||||
int stat_fd, fork_child;
|
int stat_fd, fork_child;
|
||||||
|
|
10
capture.h
10
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);
|
extern void capture_input_closed(capture_options *capture_opts);
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCAP
|
#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;
|
struct if_stat_cache_s;
|
||||||
typedef struct if_stat_cache_s if_stat_cache_t;
|
typedef struct if_stat_cache_s if_stat_cache_t;
|
||||||
|
|
|
@ -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 */
|
|
@ -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__ */
|
|
@ -68,6 +68,7 @@
|
||||||
#include "clopts_common.h"
|
#include "clopts_common.h"
|
||||||
#include "cmdarg_err.h"
|
#include "cmdarg_err.h"
|
||||||
|
|
||||||
|
#include "capture_ifinfo.h"
|
||||||
#include "capture-pcap-util.h"
|
#include "capture-pcap-util.h"
|
||||||
#include <wsutil/file_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");
|
cmdarg_err("There is no interface with that adapter index");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if_list = get_interface_list(&err, &err_str);
|
if_list = capture_interface_list(&err, &err_str);
|
||||||
if (if_list == NULL) {
|
if (if_list == NULL) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
|
|
||||||
|
@ -624,11 +625,11 @@ capture_opts_list_interfaces(gboolean machine_readable)
|
||||||
int err;
|
int err;
|
||||||
gchar *err_str;
|
gchar *err_str;
|
||||||
int i;
|
int i;
|
||||||
GSList *ip_addr;
|
GSList *addr;
|
||||||
if_addr_t *if_addr;
|
if_addr_t *if_addr;
|
||||||
char addr_str[ADDRSTRLEN];
|
char addr_str[ADDRSTRLEN];
|
||||||
|
|
||||||
if_list = get_interface_list(&err, &err_str);
|
if_list = capture_interface_list(&err, &err_str);
|
||||||
if (if_list == NULL) {
|
if (if_list == NULL) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case CANT_GET_INTERFACE_LIST:
|
case CANT_GET_INTERFACE_LIST:
|
||||||
|
@ -665,23 +666,23 @@ capture_opts_list_interfaces(gboolean machine_readable)
|
||||||
else
|
else
|
||||||
printf("\t\t");
|
printf("\t\t");
|
||||||
|
|
||||||
for(ip_addr = g_slist_nth(if_info->ip_addr, 0); ip_addr != NULL;
|
for(addr = g_slist_nth(if_info->addrs, 0); addr != NULL;
|
||||||
ip_addr = g_slist_next(ip_addr)) {
|
addr = g_slist_next(addr)) {
|
||||||
if (ip_addr != g_slist_nth(if_info->ip_addr, 0))
|
if (addr != g_slist_nth(if_info->addrs, 0))
|
||||||
printf(",");
|
printf(",");
|
||||||
|
|
||||||
if_addr = ip_addr->data;
|
if_addr = addr->data;
|
||||||
switch(if_addr->type) {
|
switch(if_addr->ifat_type) {
|
||||||
case AT_IPv4:
|
case IF_AT_IPv4:
|
||||||
if (inet_ntop(AF_INET, &if_addr->ip_addr.ip4_addr, addr_str,
|
if (inet_ntop(AF_INET, &if_addr->addr.ip4_addr, addr_str,
|
||||||
ADDRSTRLEN)) {
|
ADDRSTRLEN)) {
|
||||||
printf("%s", addr_str);
|
printf("%s", addr_str);
|
||||||
} else {
|
} else {
|
||||||
printf("<unknown IPv4>");
|
printf("<unknown IPv4>");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AT_IPv6:
|
case IF_AT_IPv6:
|
||||||
if (inet_ntop(AF_INET6, &if_addr->ip_addr.ip6_addr,
|
if (inet_ntop(AF_INET6, &if_addr->addr.ip6_addr,
|
||||||
addr_str, ADDRSTRLEN)) {
|
addr_str, ADDRSTRLEN)) {
|
||||||
printf("%s", addr_str);
|
printf("%s", addr_str);
|
||||||
} else {
|
} else {
|
||||||
|
@ -689,7 +690,7 @@ capture_opts_list_interfaces(gboolean machine_readable)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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 {
|
} else {
|
||||||
/* No - pick the first one from the list of interfaces. */
|
/* 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) {
|
if (if_list == NULL) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
|
|
||||||
|
|
|
@ -570,12 +570,11 @@ sync_pipe_start(capture_options *capture_opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open dumpcap with the supplied arguments. On success, msg points to
|
* Open a pipe to dumpcap with the supplied arguments. On success, *msg
|
||||||
* a buffer containing the dumpcap output and returns 0. read_fd and
|
* is unchanged and 0 is returned; read_fd and fork_child point to the
|
||||||
* fork_child point to the pipe's file descriptor and child PID/handle,
|
* pipe's file descriptor and child PID/handle, respectively. On failure,
|
||||||
* respectively. On failure, msg points to the error message returned by
|
* *msg points to an error message for the failure, and -1 is returned.
|
||||||
* dumpcap, and returns dumpcap's exit value. In either case, msg must be
|
* In the latter case, *msg must be freed with g_free().
|
||||||
* freed with g_free().
|
|
||||||
*/
|
*/
|
||||||
/* XXX - This duplicates a lot of code in sync_pipe_start() */
|
/* XXX - This duplicates a lot of code in sync_pipe_start() */
|
||||||
#define PIPE_BUF_SIZE 5120
|
#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));
|
*msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
|
||||||
g_free( (gpointer) argv[0]);
|
g_free( (gpointer) argv[0]);
|
||||||
g_free( (gpointer) argv);
|
g_free( (gpointer) argv);
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init STARTUPINFO */
|
/* init STARTUPINFO */
|
||||||
|
@ -658,7 +657,7 @@ sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar *
|
||||||
CloseHandle(sync_pipe_write);
|
CloseHandle(sync_pipe_write);
|
||||||
g_free( (gpointer) argv[0]);
|
g_free( (gpointer) argv[0]);
|
||||||
g_free( (gpointer) argv);
|
g_free( (gpointer) argv);
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
*fork_child = (int) pi.hProcess;
|
*fork_child = (int) pi.hProcess;
|
||||||
g_string_free(args, TRUE);
|
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));
|
*msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
|
||||||
g_free( (gpointer) argv[0]);
|
g_free( (gpointer) argv[0]);
|
||||||
g_free(argv);
|
g_free(argv);
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*fork_child = fork()) == 0) {
|
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. */
|
/* We couldn't even create the child process. */
|
||||||
*msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
|
*msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
|
||||||
ws_close(*read_fd);
|
ws_close(*read_fd);
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we might wait for a moment till child is ready, so update screen now */
|
/* 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;
|
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
|
static int
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
|
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) {
|
if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
|
||||||
*msg = g_strdup_printf("Child capture process stopped unexpectedly "
|
*msg = g_strdup_printf("Child capture process stopped unexpectedly "
|
||||||
"(errno:%u)", errno);
|
"(errno:%u)", errno);
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (wait(&fork_child_status) != -1) {
|
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",
|
*msg = g_strdup_printf("Child capture process died: wait status %#o",
|
||||||
fork_child_status);
|
fork_child_status);
|
||||||
}
|
}
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*msg = g_strdup_printf("Child capture process stopped unexpectedly "
|
*msg = g_strdup_printf("Child capture process stopped unexpectedly "
|
||||||
"(errno:%u)", errno);
|
"(errno:%u)", errno);
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run dumpcap with the supplied arguments. On success, msg points to
|
* Run dumpcap with the supplied arguments. On success, *msg points to
|
||||||
* a buffer containing the dumpcap output and returns 0. On failure, msg
|
* a buffer containing the dumpcap output, and 0 is returned. On failure,
|
||||||
* points to the error message returned by dumpcap, and returns dumpcap's
|
* *msg points to an error message, and -1 is returned. In either case,
|
||||||
* exit value. In either case, msg must be freed with g_free().
|
* *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() */
|
/* XXX - This duplicates a lot of code in sync_pipe_start() */
|
||||||
#define PIPE_BUF_SIZE 5120
|
#define PIPE_BUF_SIZE 5120
|
||||||
|
@ -801,8 +809,7 @@ sync_pipe_run_command(const char** argv, gchar **msg) {
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* We were able to set up to read dumpcap's output. Do so and
|
/* We were able to set up to read dumpcap's output. Do so. */
|
||||||
return its exit value. */
|
|
||||||
msg_buf = g_string_new("");
|
msg_buf = g_string_new("");
|
||||||
while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
|
while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
|
||||||
buf[count] = '\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
|
* Get an interface list using dumpcap. On success, *msg points to
|
||||||
* a buffer containing the dumpcap output and returns 0. On failure, msg
|
* a buffer containing the dumpcap output, and 0 is returned. On failure,
|
||||||
* points to the error message returned by dumpcap, and returns dumpcap's
|
* *msg points to an error message, and -1 is returned. In either case,
|
||||||
* exit value. In either case, msg must be freed with g_free().
|
* msg must be freed with g_free().
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sync_interface_list_open(gchar **msg) {
|
sync_interface_list_open(gchar **msg) {
|
||||||
|
@ -847,7 +854,7 @@ sync_interface_list_open(gchar **msg) {
|
||||||
|
|
||||||
if (!argv) {
|
if (!argv) {
|
||||||
*msg = g_strdup_printf("We don't know where to find dumpcap.");
|
*msg = g_strdup_printf("We don't know where to find dumpcap.");
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ask for the interface list */
|
/* 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
|
* Get an linktype list using dumpcap. On success, *msg points to
|
||||||
* a buffer containing the dumpcap output and returns 0. On failure, msg
|
* a buffer containing the dumpcap output, and 0 is returned. On failure,
|
||||||
* points to the error message returned by dumpcap, and returns dumpcap's
|
* *msg points to an error message, and -1 is returned. In either case,
|
||||||
* exit value. In either case, msg must be freed with g_free().
|
* *msg must be freed with g_free().
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sync_linktype_list_open(const gchar *ifname, gchar **msg) {
|
sync_linktype_list_open(const gchar *ifname, gchar **msg) {
|
||||||
|
@ -897,7 +904,7 @@ sync_linktype_list_open(const gchar *ifname, gchar **msg) {
|
||||||
|
|
||||||
if (!argv) {
|
if (!argv) {
|
||||||
*msg = g_strdup_printf("We don't know where to find dumpcap.");
|
*msg = g_strdup_printf("We don't know where to find dumpcap.");
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ask for the linktype list */
|
/* 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
|
* Start getting interface statistics using dumpcap. On success, read_fd
|
||||||
* contains the file descriptor for the pipe's stdout, msg is unchanged,
|
* 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
|
* 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.
|
* that must be g_free()d, and -1 will be returned.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
|
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) {
|
if (!argv) {
|
||||||
*msg = g_strdup_printf("We don't know where to find dumpcap.");
|
*msg = g_strdup_printf("We don't know where to find dumpcap.");
|
||||||
return CANT_RUN_DUMPCAP;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ask for the interface statistics */
|
/* Ask for the interface statistics */
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <epan/prefs.h>
|
#include <epan/prefs.h>
|
||||||
#include "capture-pcap-util.h"
|
#include "capture_ifinfo.h"
|
||||||
#include "capture_ui_utils.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.
|
* Return as descriptive a name for an interface as we can get.
|
||||||
* If the user has specified a comment, use that. Otherwise,
|
* 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.
|
* otherwise use the interface name.
|
||||||
*
|
*
|
||||||
* The result must be g_free()'d when you're done with it.
|
* 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
|
* 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
|
* captured on, this is an expensive routine to call, so don't call it
|
||||||
* frequently.
|
* 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
|
/* No, we don't have a user-supplied description; did we get
|
||||||
one from the OS or libpcap? */
|
one from the OS or libpcap? */
|
||||||
descr = NULL;
|
descr = NULL;
|
||||||
if_list = get_interface_list(&err, NULL);
|
if_list = capture_interface_list(&err, NULL);
|
||||||
if (if_list != NULL && if_name != NULL) {
|
if (if_list != NULL && if_name != NULL) {
|
||||||
if_entry = if_list;
|
if_entry = if_list;
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -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.
|
/** Return as descriptive a name for an interface as we can get.
|
||||||
* If the user has specified a comment, use that. Otherwise,
|
* 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.
|
* otherwise use the interface name.
|
||||||
*
|
*
|
||||||
* @param if_name The name of the interface.
|
* @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.
|
/** 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.
|
* @param do_hide Hide the "hidden" interfaces.
|
||||||
*
|
*
|
||||||
* @return A list of if_info_t structs (use free_capture_combo_list() later).
|
* @return A list of if_info_t structs (use free_capture_combo_list() later).
|
||||||
|
|
20
dumpcap.c
20
dumpcap.c
|
@ -90,6 +90,7 @@
|
||||||
#include "sync_pipe.h"
|
#include "sync_pipe.h"
|
||||||
|
|
||||||
#include "capture_opts.h"
|
#include "capture_opts.h"
|
||||||
|
#include "capture_ifinfo.h"
|
||||||
#include "capture_sync.h"
|
#include "capture_sync.h"
|
||||||
|
|
||||||
#include "conditions.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 {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
pcap_t *pch;
|
pcap_t *pch;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "../capture.h"
|
#include "../capture.h"
|
||||||
#include "../globals.h"
|
#include "../globals.h"
|
||||||
#include "../capture_errs.h"
|
#include "../capture_errs.h"
|
||||||
|
#include "../capture_ifinfo.h"
|
||||||
#include "../simple_dialog.h"
|
#include "../simple_dialog.h"
|
||||||
#include "../capture-pcap-util.h"
|
#include "../capture-pcap-util.h"
|
||||||
#include "../capture_ui_utils.h"
|
#include "../capture_ui_utils.h"
|
||||||
|
@ -263,8 +264,8 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
|
||||||
GtkWidget *if_ip_lb;
|
GtkWidget *if_ip_lb;
|
||||||
GString *ip_str = g_string_new("IP address: ");
|
GString *ip_str = g_string_new("IP address: ");
|
||||||
int ips = 0;
|
int ips = 0;
|
||||||
GSList *curr_ip;
|
GSList *curr_addr;
|
||||||
if_addr_t *ip_addr;
|
if_addr_t *addr;
|
||||||
#ifdef HAVE_PCAP_REMOTE
|
#ifdef HAVE_PCAP_REMOTE
|
||||||
GtkWidget *iftype_cbx;
|
GtkWidget *iftype_cbx;
|
||||||
int iftype;
|
int iftype;
|
||||||
|
@ -344,25 +345,26 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
|
||||||
lt_list = capture_pcap_linktype_list(if_name, NULL);
|
lt_list = capture_pcap_linktype_list(if_name, NULL);
|
||||||
|
|
||||||
/* create string of list of IP addresses of this interface */
|
/* 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)
|
if (ips != 0)
|
||||||
g_string_append(ip_str, ", ");
|
g_string_append(ip_str, ", ");
|
||||||
|
|
||||||
ip_addr = (if_addr_t *)curr_ip->data;
|
addr = (if_addr_t *)curr_addr->data;
|
||||||
switch (ip_addr->type) {
|
switch (addr->ifat_type) {
|
||||||
|
|
||||||
case AT_IPv4:
|
case IF_AT_IPv4:
|
||||||
g_string_append(ip_str,
|
g_string_append(ip_str,
|
||||||
ip_to_str((guint8 *)&ip_addr->ip_addr.ip4_addr));
|
ip_to_str((guint8 *)&addr->addr.ip4_addr));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AT_IPv6:
|
case IF_AT_IPv6:
|
||||||
g_string_append(ip_str,
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
/* In case we add non-IP addresses */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,11 @@
|
||||||
#include <epan/prefs.h>
|
#include <epan/prefs.h>
|
||||||
|
|
||||||
#include "../globals.h"
|
#include "../globals.h"
|
||||||
#include "../capture-pcap-util.h"
|
#include "../capture_errs.h"
|
||||||
|
#include "../capture_ifinfo.h"
|
||||||
#include "../simple_dialog.h"
|
#include "../simple_dialog.h"
|
||||||
#include "../capture.h"
|
#include "../capture.h"
|
||||||
#include "../capture_errs.h"
|
#include "../capture-pcap-util.h"
|
||||||
#include "../capture_ui_utils.h"
|
#include "../capture_ui_utils.h"
|
||||||
#include "wsutil/file_util.h"
|
#include "wsutil/file_util.h"
|
||||||
#include <wiretap/wtap.h>
|
#include <wiretap/wtap.h>
|
||||||
|
@ -442,28 +443,55 @@ GtkWidget * capture_get_if_icon(const if_info_t* if_info _U_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const gchar *
|
static int
|
||||||
set_ip_addr_label(GSList *ip_addr_list, GtkWidget *ip_lb, guint selected_ip_addr)
|
get_ip_addr_count(GSList *addr_list)
|
||||||
{
|
{
|
||||||
GSList *curr_ip;
|
GSList *curr_addr;
|
||||||
if_addr_t *ip_addr;
|
if_addr_t *addr;
|
||||||
const gchar *addr_str = NULL;
|
int count;
|
||||||
|
|
||||||
curr_ip = g_slist_nth(ip_addr_list, selected_ip_addr);
|
count = 0;
|
||||||
if (curr_ip) {
|
for (curr_addr = addr_list; curr_addr != NULL;
|
||||||
ip_addr = (if_addr_t *)curr_ip->data;
|
curr_addr = g_slist_next(curr_addr)) {
|
||||||
switch (ip_addr->type) {
|
addr = (if_addr_t *)curr_addr->data;
|
||||||
|
switch (addr->ifat_type) {
|
||||||
|
|
||||||
case AT_IPv4:
|
case IF_AT_IPv4:
|
||||||
addr_str = ip_to_str((guint8 *)&ip_addr->ip_addr.ip4_addr);
|
case IF_AT_IPv6:
|
||||||
break;
|
count++;
|
||||||
|
|
||||||
case AT_IPv6:
|
|
||||||
addr_str = ip6_to_str((struct e_in6_addr *)&ip_addr->ip_addr.ip6_addr);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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)
|
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);
|
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));
|
guint selected_ip_addr = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(ip_lb), CAPTURE_IF_SELECTED_IP_ADDR));
|
||||||
|
|
||||||
/* Select next IP address */
|
/* Select next IP address */
|
||||||
|
start_addr = g_slist_nth(addr_list, selected_ip_addr);
|
||||||
|
for (;;) {
|
||||||
selected_ip_addr++;
|
selected_ip_addr++;
|
||||||
if (g_slist_length(ip_addr_list) <= selected_ip_addr) {
|
if (g_slist_length(addr_list) <= selected_ip_addr) {
|
||||||
/* Probably have the last one, start over again */
|
/* Wrap around */
|
||||||
selected_ip_addr = 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
set_ip_addr_label(ip_addr_list, ip_lb, selected_ip_addr);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found:
|
||||||
|
set_ip_addr_label(addr_list, ip_lb, selected_ip_addr);
|
||||||
|
|
||||||
return FALSE;
|
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 */
|
/* Only one IP address will be shown, start with the first */
|
||||||
g_string_append(if_tool_str, "IP: ");
|
g_string_append(if_tool_str, "IP: ");
|
||||||
if_dlg_data->ip_lb = gtk_label_new("");
|
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) {
|
if (addr_str) {
|
||||||
gtk_widget_set_sensitive(if_dlg_data->ip_lb, TRUE);
|
gtk_widget_set_sensitive(if_dlg_data->ip_lb, TRUE);
|
||||||
g_string_append(if_tool_str, addr_str);
|
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 ();
|
eb = gtk_event_box_new ();
|
||||||
gtk_container_add(GTK_CONTAINER(eb), if_dlg_data->ip_lb);
|
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);
|
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 */
|
/* 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_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, "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, "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");
|
g_string_append(if_tool_str, "\n");
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ set_capture_if_dialog_for_capture_in_progress(gboolean capture_in_progress);
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCAP
|
#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.
|
/** User requested the "Capture Interfaces" dialog box by menu or toolbar.
|
||||||
*
|
*
|
||||||
|
|
|
@ -35,9 +35,8 @@
|
||||||
|
|
||||||
#include "../globals.h"
|
#include "../globals.h"
|
||||||
#include "../simple_dialog.h"
|
#include "../simple_dialog.h"
|
||||||
#include "../capture-pcap-util.h"
|
#include "../capture_ifinfo.h"
|
||||||
#include "../capture_ui_utils.h"
|
#include "../capture_ui_utils.h"
|
||||||
#include "../capture.h"
|
|
||||||
|
|
||||||
#include "gtk/prefs_capture.h"
|
#include "gtk/prefs_capture.h"
|
||||||
#include "gtk/prefs_dlg.h"
|
#include "gtk/prefs_dlg.h"
|
||||||
|
|
Loading…
Reference in New Issue