Commit 167ab3a9 authored by Guy Harris's avatar Guy Harris

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
parent 98d800ba
......@@ -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)
......@@ -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);
......
......@@ -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"
......
......@@ -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);
}
......
......@@ -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__ */
......@@ -32,10 +32,6 @@
#include <glib.h>
#include <gmodule.h>
#ifdef HAVE_LIBPCAP
#include <pcap.h>
#endif
#include "capture-pcap-util.h"
#include "capture-pcap-util-int.h"
......
......@@ -33,44 +33,7 @@
#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;
......
......@@ -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;
......
/* 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 */
/* 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.
*/