2012-06-28 18:16:18 +00:00
|
|
|
/* iface_lists.c
|
|
|
|
* Code to manage the global list of interfaces and to update widgets/windows
|
|
|
|
* displaying items from those lists
|
|
|
|
*
|
|
|
|
* $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
|
2012-06-28 22:56:06 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2012-06-28 18:16:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include <epan/prefs.h>
|
|
|
|
#include <epan/to_str.h>
|
|
|
|
|
|
|
|
#include "../capture_ui_utils.h"
|
|
|
|
|
|
|
|
#include "ui/gtk/capture_dlg.h"
|
|
|
|
#include "ui/gtk/capture_if_dlg.h"
|
|
|
|
#include "ui/gtk/capture_globals.h"
|
|
|
|
#include "ui/gtk/main_welcome.h"
|
2012-07-05 02:01:43 +00:00
|
|
|
#include "ui/gtk/main_80211_toolbar.h"
|
2012-06-28 18:16:18 +00:00
|
|
|
|
|
|
|
#include "ui/gtk/iface_lists.h"
|
|
|
|
|
|
|
|
capture_options global_capture_opts;
|
|
|
|
|
2012-06-28 20:52:26 +00:00
|
|
|
/*
|
|
|
|
* Used when sorting an interface list into alphabetical order by
|
|
|
|
* their descriptions.
|
|
|
|
*/
|
|
|
|
gint
|
|
|
|
if_list_comparator_alph(const void *first_arg, const void *second_arg)
|
|
|
|
{
|
|
|
|
const if_info_t *first = first_arg, *second = second_arg;
|
|
|
|
|
|
|
|
if (first != NULL && first->description != NULL &&
|
|
|
|
second != NULL && second->description != NULL) {
|
|
|
|
return g_ascii_strcasecmp(first->description, second->description);
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-28 18:16:18 +00:00
|
|
|
/*
|
|
|
|
* Fetch the list of local interfaces with capture_interface_list()
|
|
|
|
* and set the list of "all interfaces" in *capture_opts to include
|
|
|
|
* those interfaces.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
scan_local_interfaces(capture_options* capture_opts)
|
|
|
|
{
|
|
|
|
GList *if_entry, *lt_entry, *if_list;
|
|
|
|
if_info_t *if_info, *temp;
|
|
|
|
char *if_string;
|
|
|
|
gchar *descr;
|
|
|
|
if_capabilities_t *caps=NULL;
|
|
|
|
gint linktype_count;
|
|
|
|
cap_settings_t cap_settings;
|
|
|
|
GSList *curr_addr;
|
|
|
|
int ips = 0, i, err;
|
|
|
|
guint count = 0, j;
|
|
|
|
if_addr_t *addr, *temp_addr;
|
|
|
|
link_row *link = NULL;
|
|
|
|
data_link_info_t *data_link_info;
|
|
|
|
interface_t device;
|
|
|
|
GString *ip_str;
|
|
|
|
interface_options interface_opts;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
if (capture_opts->all_ifaces->len > 0) {
|
|
|
|
for (i = (int)capture_opts->all_ifaces->len-1; i >= 0; i--) {
|
|
|
|
device = g_array_index(capture_opts->all_ifaces, interface_t, i);
|
|
|
|
if (device.local) {
|
|
|
|
capture_opts->all_ifaces = g_array_remove_index(capture_opts->all_ifaces, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Scan through the list and build a list of strings to display. */
|
|
|
|
if_list = capture_interface_list(&err, NULL);
|
|
|
|
count = 0;
|
|
|
|
for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
|
|
|
|
if_info = if_entry->data;
|
|
|
|
ip_str = g_string_new("");
|
|
|
|
ips = 0;
|
|
|
|
if (strstr(if_info->name, "rpcap:")) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
device.name = g_strdup(if_info->name);
|
|
|
|
device.hidden = FALSE;
|
|
|
|
device.locked = FALSE;
|
|
|
|
temp = g_malloc0(sizeof(if_info_t));
|
|
|
|
temp->name = g_strdup(if_info->name);
|
|
|
|
temp->description = g_strdup(if_info->description);
|
|
|
|
temp->loopback = if_info->loopback;
|
|
|
|
/* Is this interface hidden and, if so, should we include it anyway? */
|
|
|
|
|
|
|
|
/* Do we have a user-supplied description? */
|
|
|
|
descr = capture_dev_user_descr_find(if_info->name);
|
|
|
|
if (descr != NULL) {
|
|
|
|
/* Yes, we have a user-supplied description; use it. */
|
|
|
|
if_string = g_strdup_printf("%s: %s", descr, if_info->name);
|
|
|
|
g_free(descr);
|
|
|
|
} else {
|
|
|
|
/* No, we don't have a user-supplied description; did we get
|
|
|
|
one from the OS or libpcap? */
|
|
|
|
if (if_info->description != NULL) {
|
|
|
|
/* Yes - use it. */
|
|
|
|
if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
|
|
|
|
} else {
|
|
|
|
/* No. */
|
|
|
|
if_string = g_strdup(if_info->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (if_info->loopback) {
|
|
|
|
device.display_name = g_strdup_printf("%s (loopback)", if_string);
|
|
|
|
} else {
|
|
|
|
device.display_name = g_strdup(if_string);
|
|
|
|
}
|
|
|
|
g_free(if_string);
|
|
|
|
device.selected = FALSE;
|
|
|
|
if (prefs_is_capture_device_hidden(if_info->name)) {
|
|
|
|
device.hidden = TRUE;
|
|
|
|
}
|
|
|
|
device.type = get_interface_type(if_info->name, if_info->description);
|
|
|
|
cap_settings = capture_get_cap_settings(if_info->name);
|
|
|
|
caps = capture_get_if_capabilities(if_info->name, cap_settings.monitor_mode, NULL);
|
|
|
|
for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
|
|
|
|
temp_addr = g_malloc0(sizeof(if_addr_t));
|
|
|
|
if (ips != 0) {
|
|
|
|
g_string_append(ip_str, "\n");
|
|
|
|
}
|
|
|
|
addr = (if_addr_t *)curr_addr->data;
|
|
|
|
if (addr) {
|
|
|
|
temp_addr->ifat_type = addr->ifat_type;
|
|
|
|
switch (addr->ifat_type) {
|
|
|
|
case IF_AT_IPv4:
|
|
|
|
temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
|
|
|
|
g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
|
|
|
|
break;
|
|
|
|
case IF_AT_IPv6:
|
|
|
|
memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
|
|
|
|
g_string_append(ip_str, ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* In case we add non-IP addresses */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
g_free(temp_addr);
|
|
|
|
temp_addr = NULL;
|
|
|
|
}
|
|
|
|
if (temp_addr) {
|
|
|
|
temp->addrs = g_slist_append(temp->addrs, temp_addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef HAVE_PCAP_REMOTE
|
|
|
|
device.local = TRUE;
|
|
|
|
device.remote_opts.src_type = CAPTURE_IFLOCAL;
|
|
|
|
device.remote_opts.remote_host_opts.remote_host = g_strdup(capture_opts->default_options.remote_host);
|
|
|
|
device.remote_opts.remote_host_opts.remote_port = g_strdup(capture_opts->default_options.remote_port);
|
|
|
|
device.remote_opts.remote_host_opts.auth_type = capture_opts->default_options.auth_type;
|
|
|
|
device.remote_opts.remote_host_opts.auth_username = g_strdup(capture_opts->default_options.auth_username);
|
|
|
|
device.remote_opts.remote_host_opts.auth_password = g_strdup(capture_opts->default_options.auth_password);
|
|
|
|
device.remote_opts.remote_host_opts.datatx_udp = capture_opts->default_options.datatx_udp;
|
|
|
|
device.remote_opts.remote_host_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap;
|
|
|
|
device.remote_opts.remote_host_opts.nocap_local = capture_opts->default_options.nocap_local;
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_PCAP_SETSAMPLING
|
|
|
|
device.remote_opts.sampling_method = capture_opts->default_options.sampling_method;
|
2012-06-28 18:22:02 +00:00
|
|
|
device.remote_opts.sampling_param = capture_opts->default_options.sampling_param;
|
2012-06-28 18:16:18 +00:00
|
|
|
#endif
|
|
|
|
linktype_count = 0;
|
|
|
|
device.links = NULL;
|
|
|
|
if (caps != NULL) {
|
|
|
|
#if defined(HAVE_PCAP_CREATE)
|
|
|
|
device.monitor_mode_enabled = cap_settings.monitor_mode;
|
|
|
|
device.monitor_mode_supported = caps->can_set_rfmon;
|
|
|
|
#endif
|
|
|
|
for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
|
|
|
|
data_link_info = lt_entry->data;
|
|
|
|
if (linktype_count == 0) {
|
|
|
|
device.active_dlt = data_link_info->dlt;
|
|
|
|
}
|
|
|
|
link = (link_row *)g_malloc(sizeof(link_row));
|
|
|
|
if (data_link_info->description != NULL) {
|
|
|
|
link->dlt = data_link_info->dlt;
|
|
|
|
link->name = g_strdup_printf("%s", data_link_info->description);
|
|
|
|
} else {
|
|
|
|
link->dlt = -1;
|
|
|
|
link->name = g_strdup_printf("%s (not supported)", data_link_info->name);
|
|
|
|
}
|
|
|
|
device.links = g_list_append(device.links, link);
|
|
|
|
linktype_count++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cap_settings.monitor_mode = FALSE;
|
|
|
|
#if defined(HAVE_PCAP_CREATE)
|
|
|
|
device.monitor_mode_enabled = FALSE;
|
|
|
|
device.monitor_mode_supported = FALSE;
|
|
|
|
#endif
|
|
|
|
device.active_dlt = -1;
|
|
|
|
}
|
|
|
|
device.addresses = g_strdup(ip_str->str);
|
|
|
|
device.no_addresses = ips;
|
|
|
|
device.local = TRUE;
|
|
|
|
device.if_info = *temp;
|
|
|
|
device.last_packets = 0;
|
|
|
|
device.pmode = capture_opts->default_options.promisc_mode;
|
|
|
|
device.has_snaplen = capture_opts->default_options.has_snaplen;
|
|
|
|
device.snaplen = capture_opts->default_options.snaplen;
|
|
|
|
device.cfilter = g_strdup(capture_opts->default_options.cfilter);
|
|
|
|
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
|
|
|
|
device.buffer = 1;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (capture_opts->ifaces->len > 0) {
|
|
|
|
for (j = 0; j < capture_opts->ifaces->len; j++) {
|
|
|
|
interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
|
|
|
|
if (strcmp(interface_opts.name, device.name) == 0) {
|
|
|
|
#if defined(HAVE_PCAP_CREATE)
|
|
|
|
device.buffer = interface_opts.buffer_size;
|
|
|
|
device.monitor_mode_enabled = interface_opts.monitor_mode;
|
|
|
|
#endif
|
|
|
|
device.pmode = interface_opts.promisc_mode;
|
|
|
|
device.has_snaplen = interface_opts.has_snaplen;
|
|
|
|
device.snaplen = interface_opts.snaplen;
|
|
|
|
device.cfilter = g_strdup(interface_opts.cfilter);
|
|
|
|
device.active_dlt = interface_opts.linktype;
|
|
|
|
device.selected = TRUE;
|
|
|
|
capture_opts->num_selected++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (capture_opts->all_ifaces->len <= count) {
|
|
|
|
g_array_append_val(capture_opts->all_ifaces, device);
|
|
|
|
count = capture_opts->all_ifaces->len;
|
|
|
|
} else {
|
|
|
|
g_array_insert_val(capture_opts->all_ifaces, count, device);
|
|
|
|
}
|
|
|
|
if (caps != NULL) {
|
|
|
|
free_if_capabilities(caps);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_string_free(ip_str, TRUE);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
free_interface_list(if_list);
|
|
|
|
/* see whether there are additional interfaces in ifaces */
|
|
|
|
for (j = 0; j < capture_opts->ifaces->len; j++) {
|
|
|
|
interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
|
|
|
|
found = FALSE;
|
|
|
|
for (i = 0; i < (int)capture_opts->all_ifaces->len; i++) {
|
|
|
|
device = g_array_index(capture_opts->all_ifaces, interface_t, i);
|
|
|
|
if (strcmp(device.name, interface_opts.name) == 0) {
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) { /* new interface, maybe a pipe */
|
|
|
|
device.name = g_strdup(interface_opts.name);
|
|
|
|
device.display_name = g_strdup_printf("%s", device.name);
|
|
|
|
device.hidden = FALSE;
|
|
|
|
device.selected = TRUE;
|
|
|
|
device.type = IF_PIPE;
|
|
|
|
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
|
|
|
|
device.buffer = interface_opts.buffer_size;
|
|
|
|
#endif
|
|
|
|
#if defined(HAVE_PCAP_CREATE)
|
|
|
|
device.monitor_mode_enabled = interface_opts.monitor_mode;
|
|
|
|
device.monitor_mode_supported = FALSE;
|
|
|
|
#endif
|
|
|
|
device.pmode = interface_opts.promisc_mode;
|
|
|
|
device.has_snaplen = interface_opts.has_snaplen;
|
|
|
|
device.snaplen = interface_opts.snaplen;
|
|
|
|
device.cfilter = g_strdup(interface_opts.cfilter);
|
|
|
|
device.active_dlt = interface_opts.linktype;
|
|
|
|
device.addresses = NULL;
|
|
|
|
device.no_addresses = 0;
|
|
|
|
device.last_packets = 0;
|
|
|
|
device.links = NULL;
|
|
|
|
device.local = TRUE;
|
|
|
|
device.locked = FALSE;
|
|
|
|
|
|
|
|
g_array_append_val(capture_opts->all_ifaces, device);
|
|
|
|
capture_opts->num_selected++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the global interface list. Generate it if we haven't
|
|
|
|
* done so already.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
fill_in_local_interfaces(capture_options* capture_opts)
|
|
|
|
{
|
|
|
|
static gboolean initialized = FALSE;
|
|
|
|
|
|
|
|
if (!initialized) {
|
|
|
|
scan_local_interfaces(capture_opts);
|
|
|
|
initialized = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Refresh everything visible that shows an interface list that
|
|
|
|
* includes local interfaces.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
refresh_local_interface_lists(void)
|
|
|
|
{
|
|
|
|
/* Reload the local interface list. */
|
|
|
|
scan_local_interfaces(&global_capture_opts);
|
|
|
|
|
|
|
|
/* If there's an interfaces dialog up, refresh it. */
|
|
|
|
if (interfaces_dialog_window_present())
|
|
|
|
refresh_if_window();
|
|
|
|
|
|
|
|
/* If there's a capture options dialog up, refresh it. */
|
|
|
|
if (capture_dlg_window_present())
|
|
|
|
capture_dlg_refresh_if();
|
|
|
|
|
|
|
|
/* If the welcome screen is up, refresh its interface list. */
|
|
|
|
if (get_welcome_window() != NULL)
|
|
|
|
welcome_if_panel_reload();
|
2012-07-05 02:01:43 +00:00
|
|
|
|
|
|
|
/* Refresh the 802.11 toolbar. */
|
|
|
|
tb80211_refresh_interfaces();
|
2012-06-28 18:16:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Refresh everything visible that shows an interface list that
|
|
|
|
* includes non-local interfaces.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
refresh_non_local_interface_lists(void)
|
|
|
|
{
|
|
|
|
/* If there's a capture options dialog up, refresh it. */
|
|
|
|
if (capture_dlg_window_present())
|
|
|
|
capture_dlg_refresh_if();
|
|
|
|
|
|
|
|
/* If the welcome screen is up, refresh its interface list. */
|
|
|
|
if (get_welcome_window() != NULL)
|
|
|
|
welcome_if_panel_reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
hide_interface(gchar* new_hide)
|
|
|
|
{
|
|
|
|
gchar *tok;
|
|
|
|
guint i;
|
|
|
|
interface_t device;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
GList *hidden_devices = NULL, *entry;
|
|
|
|
if (new_hide != NULL) {
|
|
|
|
for (tok = strtok (new_hide, ","); tok; tok = strtok(NULL, ",")) {
|
|
|
|
hidden_devices = g_list_append(hidden_devices, tok);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
|
|
|
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
|
|
|
found = FALSE;
|
|
|
|
for (entry = hidden_devices; entry != NULL; entry = g_list_next(entry)) {
|
|
|
|
if (strcmp(entry->data, device.name)==0) {
|
|
|
|
device.hidden = TRUE;
|
|
|
|
if (device.selected) {
|
|
|
|
device.selected = FALSE;
|
|
|
|
global_capture_opts.num_selected--;
|
|
|
|
}
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
device.hidden = FALSE;
|
|
|
|
}
|
|
|
|
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
|
|
|
|
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* HAVE_LIBPCAP */
|