diff options
author | guy <guy@f5534014-38df-0310-8fa8-9805f1628bb7> | 2010-03-04 01:12:04 +0000 |
---|---|---|
committer | guy <guy@f5534014-38df-0310-8fa8-9805f1628bb7> | 2010-03-04 01:12:04 +0000 |
commit | 58a3f1328d7bac383111dbdef7d335d5e09e19cb (patch) | |
tree | c2af1e714cc510427cdd87a9b63979038cfc40ac /capture_ifinfo.c | |
parent | b7e1b595c94c47d44a3fceffb19440ceda8731ce (diff) |
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.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@32104 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'capture_ifinfo.c')
-rw-r--r-- | capture_ifinfo.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/capture_ifinfo.c b/capture_ifinfo.c new file mode 100644 index 0000000000..e7f35c1ed0 --- /dev/null +++ b/capture_ifinfo.c @@ -0,0 +1,217 @@ +/* capture.c + * Routines for getting interface information from dumpcap + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <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 */ |