Support monitor mode in the capture preferences.

Use prefs_is_capture_device_hidden() to find out whether a device should
be hidden - don't scan the list of hidden devices ourselves.

svn path=/trunk/; revision=32820
This commit is contained in:
Guy Harris 2010-05-15 19:38:13 +00:00
parent 2de348060c
commit e1e576c11b
6 changed files with 430 additions and 101 deletions

View File

@ -1194,24 +1194,25 @@ init_prefs(void) {
G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR;
/* set the default values for the capture dialog box */
prefs.capture_device = NULL;
prefs.capture_devices_linktypes= NULL;
prefs.capture_devices_descr = NULL;
prefs.capture_devices_hide = NULL;
prefs.capture_prom_mode = TRUE;
prefs.capture_pcap_ng = FALSE;
prefs.capture_real_time = TRUE;
prefs.capture_auto_scroll = TRUE;
prefs.capture_show_info = FALSE;
prefs.capture_device = NULL;
prefs.capture_devices_linktypes = NULL;
prefs.capture_devices_descr = NULL;
prefs.capture_devices_hide = NULL;
prefs.capture_devices_monitor_mode = NULL;
prefs.capture_prom_mode = TRUE;
prefs.capture_pcap_ng = FALSE;
prefs.capture_real_time = TRUE;
prefs.capture_auto_scroll = TRUE;
prefs.capture_show_info = FALSE;
/* set the default values for the name resolution dialog box */
prefs.name_resolve = RESOLV_ALL ^ RESOLV_NETWORK;
prefs.name_resolve_concurrency = 500;
prefs.load_smi_modules = FALSE;
prefs.suppress_smi_errors = FALSE;
prefs.suppress_smi_errors = FALSE;
/* set the default values for the tap/statistics dialog box */
prefs.tap_update_interval = TAP_UPDATE_DEFAULT_INTERVAL;
prefs.tap_update_interval = TAP_UPDATE_DEFAULT_INTERVAL;
prefs.rtp_player_max_visible = RTP_PLAYER_DEFAULT_VISIBLE;
prefs.display_hidden_proto_items = FALSE;
@ -1239,6 +1240,7 @@ prefs_reset(void)
g_free(prefs.capture_devices_linktypes);
g_free(prefs.capture_devices_descr);
g_free(prefs.capture_devices_hide);
g_free(prefs.capture_devices_monitor_mode);
uat_unload_all();
oids_cleanup();
@ -1622,6 +1624,30 @@ prefs_is_capture_device_hidden(const char *name)
return FALSE;
}
/*
* Returns TRUE if the given device should capture in monitor mode by default
*/
gboolean
prefs_capture_device_monitor_mode(const char *name)
{
gchar *tok, *devices;
size_t len;
if (prefs.capture_devices_monitor_mode && name) {
devices = g_strdup (prefs.capture_devices_monitor_mode);
len = strlen (name);
for (tok = strtok (devices, ","); tok; tok = strtok(NULL, ",")) {
if (strlen (tok) == len && strcmp (name, tok) == 0) {
g_free (devices);
return TRUE;
}
}
g_free (devices);
}
return FALSE;
}
#define PRS_PRINT_FMT "print.format"
#define PRS_PRINT_DEST "print.destination"
#define PRS_PRINT_FILE "print.file"
@ -1692,15 +1718,16 @@ prefs_is_capture_device_hidden(const char *name)
#define PRS_CAP_NAME_RESOLVE "capture.name_resolve"
/* values for the capture dialog box */
#define PRS_CAP_DEVICE "capture.device"
#define PRS_CAP_DEVICES_LINKTYPES "capture.devices_linktypes"
#define PRS_CAP_DEVICES_DESCR "capture.devices_descr"
#define PRS_CAP_DEVICES_HIDE "capture.devices_hide"
#define PRS_CAP_PROM_MODE "capture.prom_mode"
#define PRS_CAP_PCAP_NG "capture.pcap_ng"
#define PRS_CAP_REAL_TIME "capture.real_time_update"
#define PRS_CAP_AUTO_SCROLL "capture.auto_scroll"
#define PRS_CAP_SHOW_INFO "capture.show_info"
#define PRS_CAP_DEVICE "capture.device"
#define PRS_CAP_DEVICES_LINKTYPES "capture.devices_linktypes"
#define PRS_CAP_DEVICES_DESCR "capture.devices_descr"
#define PRS_CAP_DEVICES_HIDE "capture.devices_hide"
#define PRS_CAP_DEVICES_MONITOR_MODE "capture.devices_monitor_mode"
#define PRS_CAP_PROM_MODE "capture.prom_mode"
#define PRS_CAP_PCAP_NG "capture.pcap_ng"
#define PRS_CAP_REAL_TIME "capture.real_time_update"
#define PRS_CAP_AUTO_SCROLL "capture.auto_scroll"
#define PRS_CAP_SHOW_INFO "capture.show_info"
#define RED_COMPONENT(x) (guint16) (((((x) >> 16) & 0xff) * 65535 / 255))
#define GREEN_COMPONENT(x) (guint16) (((((x) >> 8) & 0xff) * 65535 / 255))
@ -2162,11 +2189,14 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_)
} else if (strcmp(pref_name, PRS_CAP_DEVICES_HIDE) == 0) {
g_free(prefs.capture_devices_hide);
prefs.capture_devices_hide = g_strdup(value);
} else if (strcmp(pref_name, PRS_CAP_DEVICES_MONITOR_MODE) == 0) {
g_free(prefs.capture_devices_monitor_mode);
prefs.capture_devices_monitor_mode = g_strdup(value);
} else if (strcmp(pref_name, PRS_CAP_PROM_MODE) == 0) {
prefs.capture_prom_mode = ((g_ascii_strcasecmp(value, "true") == 0)?TRUE:FALSE);
} else if (strcmp(pref_name, PRS_CAP_PCAP_NG) == 0) {
} else if (strcmp(pref_name, PRS_CAP_PCAP_NG) == 0) {
prefs.capture_pcap_ng = ((g_ascii_strcasecmp(value, "true") == 0)?TRUE:FALSE);
} else if (strcmp(pref_name, PRS_CAP_REAL_TIME) == 0) {
} else if (strcmp(pref_name, PRS_CAP_REAL_TIME) == 0) {
prefs.capture_real_time = ((g_ascii_strcasecmp(value, "true") == 0)?TRUE:FALSE);
} else if (strcmp(pref_name, PRS_CAP_AUTO_SCROLL) == 0) {
prefs.capture_auto_scroll = ((g_ascii_strcasecmp(value, "true") == 0)?TRUE:FALSE);
@ -3023,6 +3053,12 @@ write_prefs(char **pf_path_return)
fprintf(pf, PRS_CAP_DEVICES_HIDE ": %s\n", prefs.capture_devices_hide);
}
if (prefs.capture_devices_monitor_mode != NULL) {
fprintf(pf, "\n# By default, capture in monitor mode on interface?\n");
fprintf(pf, "# Ex: eth0,eth3,...\n");
fprintf(pf, PRS_CAP_DEVICES_MONITOR_MODE ": %s\n", prefs.capture_devices_monitor_mode);
}
fprintf(pf, "\n# Capture in promiscuous mode?\n");
fprintf(pf, "# TRUE or FALSE (case-insensitive).\n");
fprintf(pf, PRS_CAP_PROM_MODE ": %s\n",
@ -3183,6 +3219,7 @@ copy_prefs(e_prefs *dest, e_prefs *src)
dest->capture_devices_linktypes = g_strdup(src->capture_devices_linktypes);
dest->capture_devices_descr = g_strdup(src->capture_devices_descr);
dest->capture_devices_hide = g_strdup(src->capture_devices_hide);
dest->capture_devices_monitor_mode = g_strdup(src->capture_devices_monitor_mode);
dest->capture_prom_mode = src->capture_prom_mode;
dest->capture_pcap_ng = src->capture_pcap_ng;
dest->capture_real_time = src->capture_real_time;
@ -3241,6 +3278,10 @@ free_prefs(e_prefs *pr)
g_free(pr->capture_devices_hide);
pr->capture_devices_hide = NULL;
}
if (pr->capture_devices_monitor_mode != NULL) {
g_free(pr->capture_devices_monitor_mode);
pr->capture_devices_monitor_mode = NULL;
}
}
static void
@ -3260,5 +3301,3 @@ free_col_info(e_prefs *pr)
g_list_free(pr->col_list);
pr->col_list = NULL;
}

View File

@ -153,6 +153,7 @@ typedef struct _e_prefs {
gchar *capture_devices_linktypes;
gchar *capture_devices_descr;
gchar *capture_devices_hide;
gchar *capture_devices_monitor_mode;
gboolean capture_prom_mode;
gboolean capture_pcap_ng;
gboolean capture_real_time;
@ -447,4 +448,9 @@ extern prefs_set_pref_e prefs_set_pref(char *prefarg);
*/
extern gboolean prefs_is_capture_device_hidden(const char *name);
/*
* Returns TRUE if the given device should capture in monitor mode by default
*/
extern gboolean prefs_capture_device_monitor_mode(const char *name);
#endif /* prefs.h */

View File

@ -164,7 +164,7 @@
*/
static GtkWidget *cap_open_w;
static GtkWidget * dl_hdr_menu=NULL;
static GHashTable *linktype_history=NULL;
static GHashTable *cap_settings_history=NULL;
#ifdef HAVE_PCAP_REMOTE
static GHashTable *remote_host_list=NULL;
@ -227,24 +227,25 @@ capture_restart_cb(GtkWidget *w _U_, gpointer d _U_)
capture_restart(&global_capture_opts);
}
gint
capture_get_linktype (gchar *if_name)
cap_settings_t
capture_get_cap_settings (gchar *if_name)
{
gint linktype, *linktype_p;
cap_settings_t cap_settings, *cap_settings_p;
if (linktype_history) {
linktype_p = g_hash_table_lookup(linktype_history, if_name);
if (cap_settings_history) {
cap_settings_p = g_hash_table_lookup(cap_settings_history, if_name);
} else {
linktype_p = NULL;
cap_settings_p = NULL;
}
if (linktype_p) {
linktype = *linktype_p;
if (cap_settings_p) {
cap_settings = *cap_settings_p;
} else {
linktype = capture_dev_user_linktype_find(if_name);
cap_settings.monitor_mode = prefs_capture_device_monitor_mode(if_name);
cap_settings.linktype = capture_dev_user_linktype_find(if_name);;
}
return linktype;
return cap_settings;
}
/*
@ -255,7 +256,7 @@ capture_get_linktype (gchar *if_name)
* it will be disabled.
*/
static void
set_if_capabilities(void)
set_if_capabilities(gboolean monitor_mode_changed)
{
gchar *entry_text;
gchar *if_text;
@ -267,7 +268,8 @@ set_if_capabilities(void)
int err;
GtkWidget *lt_menu, *lt_menu_item;
GList *lt_entry;
gint linktype, linktype_select, linktype_count;
cap_settings_t cap_settings;
gint linktype_select, linktype_count;
data_link_info_t *data_link_info;
gchar *linktype_menu_label;
guint num_supported_link_types;
@ -287,7 +289,6 @@ set_if_capabilities(void)
#ifdef HAVE_PCAP_CREATE
GtkWidget *monitor_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_MONITOR_KEY);
#endif
gboolean monitor_mode;
#ifdef HAVE_AIRPCAP
GtkWidget *advanced_bt;
#endif
@ -301,7 +302,16 @@ set_if_capabilities(void)
entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
if_text = g_strstrip(entry_text);
if_name = g_strdup(get_if_name(if_text));
linktype = capture_get_linktype(if_name);
cap_settings = capture_get_cap_settings(if_name);
if (monitor_mode_changed) {
#ifdef HAVE_PCAP_CREATE
/* Get the new setting of the monitor mode button. */
cap_settings.monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb));
#else
/* No monitor-mode support. */
cap_settings.monitor_mode = FALSE;
#endif
}
#ifdef HAVE_AIRPCAP
/* is it an airpcap interface??? */
@ -354,18 +364,16 @@ set_if_capabilities(void)
if (strcmp(if_info->name, if_name) == 0) {
/*
* It's in the list.
* Get the list of link-layer types for it.
* Get the interface capabilities for it.
*/
#ifdef HAVE_PCAP_REMOTE
if (iftype == CAPTURE_IFLOCAL)
/* Not able to get link-layer for remote interfaces */
if (iftype == CAPTURE_IFREMOTE) {
/* Not able to get interface capabilities for remote interfaces */
caps = NULL;
} else
#endif
#ifdef HAVE_PCAP_CREATE
monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb));
#else
monitor_mode = FALSE;
#endif
caps = capture_get_if_capabilities(if_name, monitor_mode, NULL);
caps = capture_get_if_capabilities(if_name, cap_settings.monitor_mode,
NULL);
/* create string of list of IP addresses of this interface */
for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
@ -428,8 +436,8 @@ set_if_capabilities(void)
lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
g_free(linktype_menu_label);
}
if (data_link_info->dlt == linktype) {
/* Found a matching dlt, selecth this */
if (data_link_info->dlt == cap_settings.linktype) {
/* Found a matching dlt, select this */
linktype_select = linktype_count;
}
gtk_menu_shell_append(GTK_MENU_SHELL(lt_menu), lt_menu_item);
@ -451,9 +459,15 @@ set_if_capabilities(void)
gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
gtk_widget_set_sensitive(linktype_om, num_supported_link_types >= 2);
g_object_set_data(G_OBJECT(linktype_om), E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(linktype));
g_object_set_data(G_OBJECT(linktype_om), E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(cap_settings.linktype));
global_capture_opts.linktype = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(linktype_om), E_CAP_OM_LT_VALUE_KEY));
#ifdef HAVE_PCAP_CREATE
/* Set the monitor-mode checkbox to the appropriate value */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor_cb),
cap_settings.monitor_mode);
#endif
/* Restore the menu to the last index used */
gtk_option_menu_set_history(GTK_OPTION_MENU(linktype_om),linktype_select);
if_ip_lb = g_object_get_data(G_OBJECT(linktype_om), E_CAP_IFACE_KEY);
@ -486,31 +500,31 @@ static GtkWidget *time_unit_combo_box_new(guint32 value) {
GtkWidget *unit_combo_box;
int i;
unit_combo_box = gtk_combo_box_new_text ();
for(i=0;i<MAX_TIME_UNITS;i++){
gtk_combo_box_append_text (GTK_COMBO_BOX (unit_combo_box), time_unit_name[i]);
}
unit_combo_box = gtk_combo_box_new_text ();
for(i = 0; i < MAX_TIME_UNITS; i++) {
gtk_combo_box_append_text (GTK_COMBO_BOX (unit_combo_box), time_unit_name[i]);
}
/* the selected combo_box item can't be changed, once the combo_box
is created, so set the matching combo_box item now */
/* days */
if(value >= 60 * 60 * 24) {
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_DAY);
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_DAY);
} else {
/* hours */
if(value >= 60 * 60) {
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_HOUR);
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_HOUR);
} else {
/* minutes */
if(value >= 60) {
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_MINUTE);
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_MINUTE);
} else {
/* seconds */
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_SECOND);
gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_SECOND);
}
}
}
return unit_combo_box;
return unit_combo_box;
}
/* convert time value from raw to displayed (e.g. 60s -> 1min) */
@ -1716,8 +1730,8 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
/* g_object_set_data(G_OBJECT(linktype_om), E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(-1)); */
g_object_set_data(G_OBJECT(linktype_om), E_CAP_IFACE_KEY, if_ip_lb);
dl_hdr_menu=NULL;
if (linktype_history == NULL) {
linktype_history = g_hash_table_new(g_str_hash, g_str_equal);
if (cap_settings_history == NULL) {
cap_settings_history = g_hash_table_new(g_str_hash, g_str_equal);
}
/*
* XXX - in some cases, this is "multiple link-layer header types", e.g.
@ -1780,7 +1794,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
* you have it, the monitor mode checkbox. That's why we do this
* now.
*/
set_if_capabilities();
set_if_capabilities(FALSE);
/* Pcap-NG row */
pcap_ng_cb = gtk_check_button_new_with_mnemonic("Capture packets in pcap-ng format (experimental)");
@ -2392,7 +2406,7 @@ capture_start_cb(GtkWidget *w _U_, gpointer d _U_)
{
gpointer dialog;
gchar *if_name;
gint *linktype_p = NULL;
cap_settings_t *cap_settings_p = NULL;
#ifdef HAVE_AIRPCAP
airpcap_if_active = airpcap_if_selected;
@ -2433,16 +2447,18 @@ capture_start_cb(GtkWidget *w _U_, gpointer d _U_)
if_name = g_strdup(global_capture_opts.iface);
}
if (linktype_history != NULL) {
linktype_p = g_hash_table_lookup(linktype_history, if_name);
if (linktype_p == NULL) {
linktype_p = g_malloc(sizeof (int));
g_hash_table_insert(linktype_history, if_name, linktype_p);
if (cap_settings_history != NULL) {
cap_settings_p = g_hash_table_lookup(cap_settings_history, if_name);
if (cap_settings_p == NULL) {
cap_settings_p = g_malloc(sizeof (cap_settings_t));
g_hash_table_insert(cap_settings_history, if_name, cap_settings_p);
} else {
g_free(if_name);
}
*linktype_p = global_capture_opts.linktype;
cap_settings_p->monitor_mode = global_capture_opts.monitor_mode;
cap_settings_p->linktype = global_capture_opts.linktype;
} else {
global_capture_opts.monitor_mode = prefs_capture_device_monitor_mode(if_name);
global_capture_opts.linktype = capture_dev_user_linktype_find(if_name);
g_free(if_name);
}
@ -2919,7 +2935,7 @@ capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
static void
capture_prep_interface_changed_cb(GtkWidget *entry _U_, gpointer argp _U_)
{
set_if_capabilities();
set_if_capabilities(FALSE);
}
#ifdef HAVE_PCAP_CREATE
@ -2927,7 +2943,7 @@ capture_prep_interface_changed_cb(GtkWidget *entry _U_, gpointer argp _U_)
static void
capture_prep_monitor_changed_cb(GtkWidget *monitor _U_, gpointer argp _U_)
{
set_if_capabilities();
set_if_capabilities(TRUE);
}
#endif

View File

@ -71,12 +71,26 @@ void capture_start_confirmed(void);
void
capture_air_cb(GtkWidget *widget, gpointer data);
/** Get linktype for interface
/*
* We remember the capture settings for each interface when a capture
* is started on it; the next time we select that interface we start
* out with those settings.
*
* XXX - we currently only do that for monitor mode and the link-layer
* type; arguably we should do it for the snapshot length, and perhaps
* promiscuous mode.
*/
typedef struct {
gboolean monitor_mode;
int linktype;
} cap_settings_t;
/** Get capture settings for interface
*
* @param if_name interface name
*/
gint
capture_get_linktype (gchar *if_name);
cap_settings_t
capture_get_cap_settings (gchar *if_name);
#ifdef HAVE_PCAP_REMOTE

View File

@ -540,6 +540,8 @@ main_welcome_add_recent_capture_files(const char *widget_cf_name)
static gboolean
welcome_if_press_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data)
{
cap_settings_t cap_settings;
g_free(global_capture_opts.iface);
g_free(global_capture_opts.iface_descr);
@ -547,7 +549,9 @@ welcome_if_press_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data)
global_capture_opts.iface_descr = NULL;
/* XXX - fix this */
/*global_capture_opts.iface_descr = get_interface_descriptive_name(global_capture_opts.iface);*/
global_capture_opts.linktype = capture_get_linktype (global_capture_opts.iface);
cap_settings = capture_get_cap_settings (global_capture_opts.iface);;
global_capture_opts.monitor_mode = cap_settings.monitor_mode;
global_capture_opts.linktype = cap_settings.linktype;
/* XXX - remove this? */
if (global_capture_opts.save_file) {

View File

@ -67,6 +67,9 @@
/* interface options dialog */
static GtkWidget *cur_list, *if_dev_lb, *if_name_lb, *if_linktype_cb, *if_descr_te, *if_hide_cb;
#ifdef HAVE_PCAP_CREATE
static GtkWidget *if_monitor_cb;
#endif
static GtkTreeSelection *if_selection; /* current interface row selected */
static int num_linktypes;
static gboolean interfaces_info_nochange; /* TRUE to ignore Interface Options Properties */
@ -76,12 +79,18 @@ static void ifopts_edit_cb(GtkWidget *w, gpointer data);
static void ifopts_edit_ok_cb(GtkWidget *w, gpointer parent_w);
static void ifopts_edit_destroy_cb(GtkWidget *win, gpointer data);
static void ifopts_edit_ifsel_cb(GtkTreeSelection *selection, gpointer data);
#ifdef HAVE_PCAP_CREATE
static void ifopts_edit_monitor_changed_cb(GtkToggleButton *tbt, gpointer udata);
#endif
static void ifopts_edit_linktype_changed_cb(GtkComboBox *ed, gpointer udata);
static void ifopts_edit_descr_changed_cb(GtkEditable *ed, gpointer udata);
static void ifopts_edit_hide_changed_cb(GtkToggleButton *tbt, gpointer udata);
static void ifopts_options_add(GtkListStore *list_store, if_info_t *if_info);
static void ifopts_options_free(gchar *text[]);
static void ifopts_if_liststore_add(void);
#ifdef HAVE_PCAP_CREATE
static void ifopts_write_new_monitor_mode(void);
#endif
static void ifopts_write_new_linklayer(void);
static void ifopts_write_new_descr(void);
static void ifopts_write_new_hide(void);
@ -273,6 +282,9 @@ enum
{
DEVICE_COLUMN,
DESC_COLUMN,
#ifdef HAVE_PCAP_CREATE
DEF_MONITOR_MODE_COLUMN,
#endif
DEF_LINK_LAYER_COLUMN,
COMMENT_COLUMN,
HIDE_COLUMN,
@ -285,7 +297,11 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
{
GtkWidget *ifopts_edit_dlg, *cur_scr_win, *main_hb, *main_tb,
*cur_opts_fr, *ed_opts_fr, *main_vb,
*if_linktype_lb, *if_descr_lb, *if_hide_lb,
*if_linktype_lb, *if_descr_lb,
#ifdef HAVE_PCAP_CREATE
*if_monitor_lb,
#endif
*if_hide_lb,
*bbox, *ok_bt, *cancel_bt, *help_bt;
GtkListStore *list_store;
@ -311,7 +327,7 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
/* create a new dialog */
ifopts_edit_dlg = dlg_conf_window_new("Wireshark: Preferences: Interface Options");
gtk_window_set_default_size(GTK_WINDOW(ifopts_edit_dlg), DEF_WIDTH, 440);
gtk_window_set_default_size(GTK_WINDOW(ifopts_edit_dlg), 1000, 440);
main_vb = gtk_vbox_new(FALSE, 1);
gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
@ -335,6 +351,9 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
list_store = gtk_list_store_new(N_COLUMN, /* Total number of columns XXX */
G_TYPE_STRING, /* Device */
G_TYPE_STRING, /* Description */
#ifdef HAVE_PCAP_CREATE
G_TYPE_BOOLEAN, /* Monitor mode */
#endif
G_TYPE_STRING, /* Default link-layer */
G_TYPE_STRING, /* Comment */
G_TYPE_BOOLEAN, /* Hide? */
@ -366,6 +385,7 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
/* Add the column to the view. */
gtk_tree_view_append_column (list_view, column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Description", renderer,
"text", DESC_COLUMN,
NULL);
@ -376,6 +396,22 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
/* Add the column to the view. */
gtk_tree_view_append_column (list_view, column);
#ifdef HAVE_PCAP_CREATE
/*
* XXX - for some reason, this doesn't show up.
*/
renderer = gtk_cell_renderer_toggle_new ();
column = gtk_tree_view_column_new_with_attributes ("Default to monitor mode", renderer,
"active", DEF_MONITOR_MODE_COLUMN,
NULL);
gtk_tree_view_column_set_resizable(column, FALSE);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
/* Add the column to the view. */
gtk_tree_view_append_column (list_view, column);
#endif
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Default link-layer", renderer,
"text", DEF_LINK_LAYER_COLUMN,
NULL);
@ -386,6 +422,7 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
/* Add the column to the view. */
gtk_tree_view_append_column (list_view, column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Comment", renderer,
"text", COMMENT_COLUMN,
NULL);
@ -408,6 +445,7 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
#if 0
/* Don't show the DLT column */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("DLT", renderer,
"text", DLT_COLUMN,
NULL);
@ -475,6 +513,21 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_)
gtk_widget_show(if_name_lb);
row++;
#ifdef HAVE_PCAP_CREATE
/* create "monitor mode" label and button */
if_monitor_lb = gtk_label_new("Monitor mode:");
gtk_table_attach_defaults(GTK_TABLE(main_tb), if_monitor_lb, 0, 1, row, row+1);
gtk_misc_set_alignment(GTK_MISC(if_monitor_lb), 1.0f, 0.5f);
gtk_widget_show(if_monitor_lb);
if_monitor_cb = gtk_check_button_new();
g_signal_connect(if_monitor_cb, "toggled", G_CALLBACK(ifopts_edit_monitor_changed_cb),
cur_list);
gtk_table_attach_defaults(GTK_TABLE(main_tb), if_monitor_cb, 1, 2, row, row+1);
gtk_widget_show(if_monitor_cb);
row++;
#endif
if_linktype_lb = gtk_label_new("Default link-layer header type:");
gtk_table_attach_defaults(GTK_TABLE(main_tb), if_linktype_lb, 0, 1, row, row+1);
gtk_misc_set_alignment(GTK_MISC(if_linktype_lb), 1.0f, 0.5f);
@ -561,6 +614,11 @@ static void
ifopts_edit_ok_cb(GtkWidget *w _U_, gpointer parent_w)
{
if (if_selection){ /* XXX: Cannot be NULL ?? */
#ifdef HAVE_PCAP_CREATE
/* create/write new monitor-mode interfaces string */
ifopts_write_new_monitor_mode();
#endif
/* create/write new interfaces link-layer string */
ifopts_write_new_linklayer();
@ -596,12 +654,13 @@ ifopts_edit_destroy_cb(GtkWidget *win, gpointer data _U_)
}
static gint
ifopts_description_to_val (const char *if_name, const char *descr)
ifopts_description_to_val (const char *if_name, gboolean monitor_mode,
const char *descr)
{
if_capabilities_t *caps;
int dlt = -1;
caps = capture_get_if_capabilities(if_name, FALSE, NULL);
caps = capture_get_if_capabilities(if_name, monitor_mode, NULL);
if (caps != NULL) {
if (caps->data_link_types != NULL) {
GList *lt_entry;
@ -639,8 +698,11 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_,
GtkTreeModel *model;
gchar *desc, *comment, *text;
gchar *if_name, *linktype;
#ifdef HAVE_PCAP_CREATE
gboolean monitor_mode;
#endif
gboolean hide;
if_capabilities_t *caps;
if_capabilities_t *caps;
gint selected = 0;
/* Get list_store data for currently selected interface */
@ -648,11 +710,14 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_,
return;
}
gtk_tree_model_get(model, &iter,
DEVICE_COLUMN, &if_name,
DESC_COLUMN, &desc,
DEF_LINK_LAYER_COLUMN, &linktype,
COMMENT_COLUMN, &comment,
HIDE_COLUMN, &hide,
DEVICE_COLUMN, &if_name,
DESC_COLUMN, &desc,
#ifdef HAVE_PCAP_CREATE
DEF_MONITOR_MODE_COLUMN, &monitor_mode,
#endif
DEF_LINK_LAYER_COLUMN, &linktype,
COMMENT_COLUMN, &comment,
HIDE_COLUMN, &hide,
-1);
/* display the interface device from current interfaces selection */
@ -671,9 +736,20 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_,
gtk_combo_box_remove_text (GTK_COMBO_BOX(if_linktype_cb), num_linktypes);
}
/* -- build and add to the ComboBox a linktype list for the current interfaces selection */
/*
* -- set the sensitivity of the monitor-mode checkbox, and
* build and add to the ComboBox a linktype list for the current
* interfaces selection, based on the interface capabilities
*/
#ifdef HAVE_PCAP_CREATE
caps = capture_get_if_capabilities(if_name, monitor_mode, NULL);
#else
caps = capture_get_if_capabilities(if_name, FALSE, NULL);
#endif
if (caps != NULL) {
#ifdef HAVE_PCAP_CREATE
gtk_widget_set_sensitive(if_monitor_cb, caps->can_set_rfmon);
#endif
if (caps->data_link_types != NULL) {
GList *lt_entry;
for (lt_entry = caps->data_link_types; lt_entry != NULL;
@ -691,6 +767,10 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_,
}
free_if_capabilities(caps);
}
#ifdef HAVE_PCAP_CREATE
else
gtk_widget_set_sensitive(if_monitor_cb, FALSE);
#endif
/* display the interface description from current interfaces selection */
gtk_entry_set_text(GTK_ENTRY(if_descr_te), comment);
@ -709,6 +789,93 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_,
g_free(comment);
}
#ifdef HAVE_PCAP_CREATE
/*
* Monitor-mode toggle button changed callback; update displayed widgets
* (the list of link-layer types might change) and list_store for currently
* selected interface.
*/
static void
ifopts_edit_monitor_changed_cb(GtkToggleButton *tbt, gpointer udata)
{
GtkTreeModel *list_model;
GtkTreeIter list_iter;
GtkListStore *list_store;
gchar *if_name, *text;
gboolean monitor_mode;
if_capabilities_t *caps;
if (interfaces_info_nochange)
return;
if (if_selection == NULL) /* XXX: Cannot be NULL ?? */
return;
if (!gtk_tree_selection_get_selected (if_selection, &list_model, &list_iter)){
return;
}
gtk_tree_model_get(list_model, &list_iter,
DEVICE_COLUMN, &if_name,
-1);
/* Ignore "changed" callbacks while we update the Properties widgets */
interfaces_info_nochange = TRUE;
/* display the link-layer header type from current interfaces selection */
/* -- remove old linktype list (if any) from the ComboBox */
while (num_linktypes > 0) {
num_linktypes--;
gtk_combo_box_remove_text (GTK_COMBO_BOX(if_linktype_cb), num_linktypes);
}
list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (udata))); /* Get store */
#ifdef HAVE_PCAP_CREATE
/* get "monitor mode" button state and set status in list_store for currently selected interface */
monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tbt));
gtk_list_store_set (list_store, &list_iter,
DEF_MONITOR_MODE_COLUMN, monitor_mode,
-1);
caps = capture_get_if_capabilities(if_name, monitor_mode, NULL);
#else
/* no monitor-mode support */
caps = capture_get_if_capabilities(if_name, FALSE, NULL);
#endif
/*
* -- set the sensitivity of the monitor-mode checkbox, and
* build and add to the ComboBox a linktype list for the current
* interfaces selection, based on the interface capabilities
*/
if (caps != NULL) {
#ifdef HAVE_PCAP_CREATE
gtk_widget_set_sensitive(if_monitor_cb, caps->can_set_rfmon);
#endif
if (caps->data_link_types != NULL) {
GList *lt_entry;
for (lt_entry = caps->data_link_types; lt_entry != NULL;
lt_entry = g_list_next(lt_entry)) {
data_link_info_t *dli_p = lt_entry->data;
text = (dli_p->description != NULL) ? dli_p->description : dli_p->name;
gtk_combo_box_append_text(GTK_COMBO_BOX(if_linktype_cb), text);
num_linktypes++;
}
gtk_widget_set_sensitive(if_linktype_cb, num_linktypes >= 2);
gtk_combo_box_set_active(GTK_COMBO_BOX(if_linktype_cb), 0);
}
free_if_capabilities(caps);
}
#ifdef HAVE_PCAP_CREATE
else
gtk_widget_set_sensitive(if_monitor_cb, FALSE);
#endif
interfaces_info_nochange = FALSE;
g_free(if_name);
}
#endif
/*
* Link-layer entry changed callback; update list_store for currently selected interface.
*/
@ -716,6 +883,9 @@ static void
ifopts_edit_linktype_changed_cb(GtkComboBox *cb, gpointer udata)
{
gchar *ifnm, *text;
#ifdef HAVE_PCAP_CREATE
gboolean monitor_mode;
#endif
gint linktype;
GtkTreeModel *list_model;
#if ! GTK_CHECK_VERSION(2,6,0)
@ -736,7 +906,10 @@ ifopts_edit_linktype_changed_cb(GtkComboBox *cb, gpointer udata)
}
gtk_tree_model_get(list_model, &list_iter,
DEVICE_COLUMN, &ifnm,
DEVICE_COLUMN, &ifnm,
#ifdef HAVE_PCAP_CREATE
DEF_MONITOR_MODE_COLUMN, &monitor_mode,
#endif
-1);
/* get current description text and set value in list_store for currently selected interface */
@ -748,7 +921,11 @@ ifopts_edit_linktype_changed_cb(GtkComboBox *cb, gpointer udata)
model = gtk_combo_box_get_model(GTK_COMBO_BOX(cb));
gtk_tree_model_get(model, &iter, 0, &text, -1);
#endif
linktype = ifopts_description_to_val(ifnm, text);
#ifdef HAVE_PCAP_CREATE
linktype = ifopts_description_to_val(ifnm, monitor_mode, text);
#else
linktype = ifopts_description_to_val(ifnm, FALSE, text);
#endif
list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (udata))); /* Get store */
gtk_list_store_set (list_store, &list_iter,
DEF_LINK_LAYER_COLUMN, text,
@ -842,6 +1019,9 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info)
gchar *pr_descr;
gchar *text[] = { NULL, NULL, NULL, NULL };
if_capabilities_t *caps;
#ifdef HAVE_PCAP_CREATE
gboolean monitor_mode;
#endif
gint linktype;
gboolean hide;
GtkTreeIter iter;
@ -855,9 +1035,17 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info)
else
text[1] = g_strdup("");
#ifdef HAVE_PCAP_CREATE
/* get default monitor mode setting */
monitor_mode = prefs_capture_device_monitor_mode(if_info->name);
caps = capture_get_if_capabilities(if_info->name, monitor_mode, NULL);
#else
/* no monitor-mode support */
caps = capture_get_if_capabilities(if_info->name, FALSE, NULL);
#endif
/* set default link-layer header type */
linktype = capture_dev_user_linktype_find(if_info->name);
caps = capture_get_if_capabilities(if_info->name, FALSE, NULL);
if (caps != NULL) {
if (caps->data_link_types != NULL) {
GList *lt_entry;
@ -930,11 +1118,7 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info)
text[3] = g_strdup("");
/* check if interface is "hidden" */
if ((prefs.capture_devices_hide != NULL) &&
(strstr(prefs.capture_devices_hide, if_info->name) != NULL))
hide = TRUE;
else
hide = FALSE;
hide = prefs_is_capture_device_hidden(if_info->name);
/* add row to ListStore */
@ -944,12 +1128,15 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info)
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter,
#endif
DEVICE_COLUMN, text[0],
DESC_COLUMN, text[1],
DEF_LINK_LAYER_COLUMN, text[2],
COMMENT_COLUMN, text[3],
HIDE_COLUMN, hide,
DLT_COLUMN, linktype,
DEVICE_COLUMN, text[0],
DESC_COLUMN, text[1],
#ifdef HAVE_PCAP_CREATE
DEF_MONITOR_MODE_COLUMN, monitor_mode,
#endif
DEF_LINK_LAYER_COLUMN, text[2],
COMMENT_COLUMN, text[3],
HIDE_COLUMN, hide,
DLT_COLUMN, linktype,
-1);
ifopts_options_free(text);
@ -1000,6 +1187,69 @@ ifopts_if_liststore_add(void)
free_interface_list(if_list);
}
#ifdef HAVE_PCAP_CREATE
/*
* Create/write new "monitor mode" interfaces string based on current CList.
* Put it into the preferences value.
*/
static void
ifopts_write_new_monitor_mode(void)
{
GtkListStore *store;
GtkTreeIter iter;
GtkTreeModel *model;
gboolean more_items = TRUE;
gint first_if = TRUE; /* flag to check if first in list */
gchar *ifnm;
gboolean monitor_mode;
gchar *new_monitor_mode;
/* new preferences "monitor mode" interfaces string */
new_monitor_mode = g_malloc0(MAX_VAL_LEN);
/* get "monitor mode" flag text for each row (interface) */
model = gtk_tree_view_get_model(GTK_TREE_VIEW(cur_list));
store = GTK_LIST_STORE(model);
if( gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter) ) {
while (more_items) {
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
DEVICE_COLUMN, &ifnm,
DEF_MONITOR_MODE_COLUMN, &monitor_mode,
-1);
/* if flag text is "No", skip this interface */
if (!monitor_mode){
more_items = gtk_tree_model_iter_next (model,&iter);
continue;
}
/*
* create/cat interface to new string
*/
if (first_if != TRUE)
g_strlcat (new_monitor_mode, ",", MAX_VAL_LEN);
g_strlcat (new_monitor_mode, ifnm, MAX_VAL_LEN);
/* set first-in-list flag to false */
first_if = FALSE;
more_items = gtk_tree_model_iter_next (model,&iter);
}
/* write new "hidden" string to preferences */
if (strlen(new_monitor_mode) > 0) {
g_free(prefs.capture_devices_monitor_mode);
prefs.capture_devices_monitor_mode = new_monitor_mode;
}
/* no "hidden" interfaces */
else {
g_free(prefs.capture_devices_monitor_mode);
g_free(new_monitor_mode);
prefs.capture_devices_monitor_mode = NULL;
}
}
}
#endif
/*
* Create/write new interfaces link-layer string based on current CList.
* Put it into the preferences value.