aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/prefs.c87
-rw-r--r--epan/prefs.h6
-rw-r--r--gtk/capture_dlg.c112
-rw-r--r--gtk/capture_dlg.h20
-rw-r--r--gtk/main_welcome.c6
-rw-r--r--gtk/prefs_capture.c300
6 files changed, 430 insertions, 101 deletions
diff --git a/epan/prefs.c b/epan/prefs.c
index a33e80672f..1465bb9976 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -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;
}
-
-
diff --git a/epan/prefs.h b/epan/prefs.h
index 68c97cbc14..c15b966afa 100644
--- a/epan/prefs.h
+++ b/epan/prefs.h
@@ -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 */
diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c
index 0c94883144..50d9d2b13b 100644
--- a/gtk/capture_dlg.c
+++ b/gtk/capture_dlg.c
@@ -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 */
-#endif
-#ifdef HAVE_PCAP_CREATE
- monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb));
-#else
- monitor_mode = FALSE;
+ if (iftype == CAPTURE_IFREMOTE) {
+ /* Not able to get interface capabilities for remote interfaces */
+ caps = NULL;
+ } else
#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
diff --git a/gtk/capture_dlg.h b/gtk/capture_dlg.h
index 96a8e4e878..c74792c43f 100644
--- a/gtk/capture_dlg.h
+++ b/gtk/capture_dlg.h
@@ -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
diff --git a/gtk/main_welcome.c b/gtk/main_welcome.c
index 3a72f55980..0ea601ed94 100644
--- a/gtk/main_welcome.c
+++ b/gtk/main_welcome.c
@@ -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) {
diff --git a/gtk/prefs_capture.c b/gtk/prefs_capture.c
index 6debfe3ae9..b94e1f2088 100644
--- a/gtk/prefs_capture.c
+++ b/gtk/prefs_capture.c
@@ -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.