From 44e6a88b134b0b35ea6c7d76dd76647f357b86c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Irene=20R=C3=BCngeler?= Date: Wed, 13 Mar 2013 12:38:08 +0000 Subject: [PATCH] Add interface options preferences. svn path=/trunk/; revision=48275 --- capture_opts.c | 1 + capture_opts.h | 2 +- capture_ui_utils.c | 25 ++++++ capture_ui_utils.h | 6 ++ epan/prefs.c | 4 + epan/prefs.h | 1 + ui/gtk/capture_dlg.c | 98 ++++++++++++++------- ui/gtk/main_welcome.c | 3 +- ui/gtk/prefs_capture.c | 192 ++++++++++++++++++++++++++++++++++++----- ui/iface_lists.c | 18 +++- 10 files changed, 288 insertions(+), 62 deletions(-) diff --git a/capture_opts.c b/capture_opts.c index c297b1396f..e3d6b5a246 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -127,6 +127,7 @@ capture_opts_init(capture_options *capture_opts, void *cf) capture_opts->owner = getuid(); capture_opts->group = getgid(); #endif + capture_opts->session_started = FALSE; } diff --git a/capture_opts.h b/capture_opts.h index 7714b15b4a..67a5bfe349 100644 --- a/capture_opts.h +++ b/capture_opts.h @@ -123,7 +123,6 @@ typedef struct interface_tag { gint active_dlt; gboolean pmode; gboolean has_snaplen; - gboolean snap_pref; guint snaplen; gboolean local; #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) @@ -233,6 +232,7 @@ typedef struct capture_options_tag { uid_t owner; /**< owner of the cfile */ gid_t group; /**< group of the cfile */ #endif + gboolean session_started; } capture_options; /* initialize the capture_options with some reasonable values */ diff --git a/capture_ui_utils.c b/capture_ui_utils.c index 6f525f108e..06b3268bfa 100644 --- a/capture_ui_utils.c +++ b/capture_ui_utils.c @@ -223,6 +223,31 @@ capture_dev_user_hassnap_find(const gchar *if_name) return (gboolean)hassnap; } +gboolean +capture_dev_user_pmode_find(const gchar *if_name) +{ + gchar *p, *next; + gboolean pmode; + + if ((prefs.capture_devices_pmode == NULL) || + (*prefs.capture_devices_pmode == '\0')) { + /* There is no promiscuous mode defined */ + return -1; + } + + if ((p = strstr(prefs.capture_devices_pmode, if_name)) == NULL) { + /* There are, but there isn't one for this interface. */ + return -1; + } + + p += strlen(if_name) + 1; + pmode = (gboolean)strtol(p, &next, 10); + if (next == p || *next != ')') { + /* Syntax error */ + return -1; + } + return (gboolean)pmode; +} /* * Return as descriptive a name for an interface as we can get. diff --git a/capture_ui_utils.h b/capture_ui_utils.h index d95a792b1c..7b9c3b2af7 100644 --- a/capture_ui_utils.h +++ b/capture_ui_utils.h @@ -62,6 +62,12 @@ gint capture_dev_user_buffersize_find(const gchar *if_name); gint capture_dev_user_snaplen_find(const gchar *if_name); gboolean capture_dev_user_hassnap_find(const gchar *if_name); +/** + * Find user-specified promiscuous mode that matches interface + * name, if any. + */ +gboolean capture_dev_user_pmode_find(const gchar *if_name); + /** Return as descriptive a name for an interface as we can get. * If the user has specified a comment, use that. Otherwise, * if capture_interface_list() supplies a description, use that, diff --git a/epan/prefs.c b/epan/prefs.c index 9f8461cc54..1f8e906dcf 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -2190,6 +2190,10 @@ prefs_register_modules(void) "Interface snap length (Ex: en0(65535),en1(1430),...)", (const char**)(&prefs.capture_devices_snaplen)); + prefs_register_string_preference(capture_module, "devices_pmode", "Interface promiscuous mode", + "Interface promiscuous mode (Ex: en0(0),en1(1),...)", + (const char**)(&prefs.capture_devices_pmode)); + prefs_register_bool_preference(capture_module, "prom_mode", "Capture in promiscuous mode", "Capture in promiscuous mode?", &prefs.capture_prom_mode); diff --git a/epan/prefs.h b/epan/prefs.h index 241a16f5e7..174a081b5f 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -186,6 +186,7 @@ typedef struct _e_prefs { gchar *capture_devices_buffersize; #endif gchar *capture_devices_snaplen; + gchar *capture_devices_pmode; gboolean capture_prom_mode; gboolean capture_pcap_ng; gboolean capture_real_time; diff --git a/ui/gtk/capture_dlg.c b/ui/gtk/capture_dlg.c index 0f20b6a153..2a40be1040 100644 --- a/ui/gtk/capture_dlg.c +++ b/ui/gtk/capture_dlg.c @@ -1249,9 +1249,10 @@ insert_new_rows(GList *list) device.buffer = global_capture_opts.default_options.buffer_size; } #endif - device.pmode = global_capture_opts.default_options.promisc_mode; + if ((device.pmode = capture_dev_user_pmode_find(if_string)) == -1) { + device.pmode = global_capture_opts.default_options.promisc_mode; + } device.has_snaplen = global_capture_opts.default_options.has_snaplen; - device.snap_pref = TRUE; if ((device.snaplen = capture_dev_user_snaplen_find(if_string)) == -1) { device.snaplen = global_capture_opts.default_options.snaplen; } @@ -2479,7 +2480,6 @@ save_options_cb(GtkWidget *win _U_, gpointer user_data _U_) device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); if (device.has_snaplen) { if (device.snaplen != (guint)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb))) { - device.snap_pref = FALSE; } device.snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb)); if (device.snaplen < 1) @@ -2523,7 +2523,10 @@ adjust_snap_sensitivity(GtkWidget *tb _U_, gpointer parent_w _U_) gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb))); device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); - device.snap_pref = FALSE; + if (!device.has_snaplen) { + gtk_spin_button_set_value(GTK_SPIN_BUTTON (snap_sb), WTAP_MAX_PACKET_SIZE); + device.snaplen = WTAP_MAX_PACKET_SIZE; + } g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device); } @@ -3152,16 +3155,32 @@ static void capture_all_cb(GtkToggleButton *button, gpointer d _U_) } +static gboolean get_all_prom_mode(void) +{ + interface_options interface_opts; + guint i; + + for (i = 0; i < global_capture_opts.ifaces->len; i++) { + interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); + if (!interface_opts.promisc_mode) { + return FALSE; + } + } + return TRUE; +} + static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_) { GtkTreeIter iter; GtkTreeView *if_cb; GtkTreeModel *model; - gboolean enabled = FALSE; + gboolean enabled = FALSE, set; interface_t device; interface_options interface_opts; guint i; + set = gtk_toggle_button_get_active(button); + gtk_toggle_button_set_active(button, (set?FALSE:TRUE)); if (gtk_toggle_button_get_active(button)) enabled = TRUE; @@ -4333,11 +4352,9 @@ update_properties_all(void) { } } } + promisc_b = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PROMISC_KEY_ALL); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_b), promisc_all); - if (promisc_all) { - promisc_b = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PROMISC_KEY_ALL); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_b), TRUE); - } if (capture_all) { capture_b = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_KEY_ALL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(capture_b), TRUE); @@ -4641,11 +4658,12 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) gtk_widget_set_sensitive(GTK_WIDGET(all_cb), if_present); /* Promiscuous mode row */ promisc_cb = gtk_check_button_new_with_mnemonic("Capture all in _promiscuous mode"); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb), - global_capture_opts.default_options.promisc_mode); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb))) - promisc_mode_callback(GTK_TOGGLE_BUTTON(promisc_cb), NULL); - g_signal_connect(promisc_cb, "toggled", G_CALLBACK(promisc_mode_callback), NULL); + if (!global_capture_opts.session_started) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb), prefs.capture_prom_mode); + } else { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb), get_all_prom_mode()); + } + g_signal_connect(promisc_cb, "button-press-event", G_CALLBACK(promisc_mode_callback), NULL); gtk_widget_set_tooltip_text(promisc_cb, "Usually a network adapter will only capture the traffic sent to its own network address. " @@ -4654,7 +4672,6 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) "option individually." "See the FAQ for some more details of capturing packets from a switched network."); gtk_box_pack_start(GTK_BOX(left_vb), promisc_cb, TRUE, TRUE, 0); - gtk_widget_set_sensitive(GTK_WIDGET(promisc_cb), if_present); iftype_cbx = gtk_button_new_with_label("Manage Interfaces"); gtk_widget_set_tooltip_text(iftype_cbx, "Add a new interface or pipe to capture from or remove " @@ -5121,6 +5138,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) window_present(cap_open_w); cap_open_complete = TRUE; /* "Capture:Start" is now OK */ + global_capture_opts.session_started = TRUE; } /* everythings prepared, now it's really time to start the capture */ @@ -5454,7 +5472,7 @@ create_and_fill_model(GtkTreeView *view) gint buffer; #endif gint snaplen; - gboolean hassnap; + gboolean hassnap, pmode; #if defined(HAVE_PCAP_CREATE) store = gtk_list_store_new (9, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); @@ -5473,6 +5491,9 @@ create_and_fill_model(GtkTreeView *view) temp = g_strdup_printf("%s\n%s", device.display_name, device.addresses); } linkname = NULL; + if(global_capture_opts.session_started == FALSE && capture_dev_user_linktype_find(device.name) != -1) { + device.active_dlt = capture_dev_user_linktype_find(device.name); + } for (list = device.links; list != NULL; list = g_list_next(list)) { linkr = (link_row*)(list->data); if (linkr->dlt == device.active_dlt) { @@ -5480,29 +5501,39 @@ create_and_fill_model(GtkTreeView *view) break; } } - hassnap = capture_dev_user_hassnap_find(device.name); - snaplen = capture_dev_user_snaplen_find(device.name); - if((snaplen>0)&&(hassnap>0)){ + pmode = capture_dev_user_pmode_find(device.name); + if (global_capture_opts.session_started == FALSE && pmode != -1) { + device.pmode = pmode; + } + if(global_capture_opts.session_started == FALSE) { + hassnap = capture_dev_user_hassnap_find(device.name); + snaplen = capture_dev_user_snaplen_find(device.name); + if(snaplen != -1 && hassnap != -1) { /* Default snap lenght set in preferences */ device.snaplen = snaplen; - device.has_snaplen = TRUE; - 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); - snaplen_string = g_strdup_printf("%d", device.snaplen); - }else if (device.has_snaplen) { - snaplen_string = g_strdup_printf("%d", device.snaplen); - }else{ - snaplen_string = g_strdup("default"); + device.has_snaplen = hassnap; + } else { + /* No preferences set yet, use default values */ + device.snaplen = WTAP_MAX_PACKET_SIZE; + device.has_snaplen = FALSE; + } } + if (device.has_snaplen) { + snaplen_string = g_strdup_printf("%d", device.snaplen); + } else { + snaplen_string = g_strdup("default"); + } + #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - buffer = device.buffer; - if (buffer == DEFAULT_CAPTURE_BUFFER_SIZE && capture_dev_user_buffersize_find(device.name) != DEFAULT_CAPTURE_BUFFER_SIZE && capture_dev_user_buffersize_find(device.name) != -1) { + if (global_capture_opts.session_started == FALSE && capture_dev_user_buffersize_find(device.name) != -1) { buffer = capture_dev_user_buffersize_find(device.name); device.buffer = buffer; - 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); - } + } else if (global_capture_opts.session_started == FALSE) { + device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE; + } #endif + 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); gtk_list_store_append (store, &iter); #if defined(HAVE_PCAP_CREATE) gtk_list_store_set (store, &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, linkname?linkname:"This should not happen", PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, MONITOR, device.monitor_mode_supported?(device.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, device.cfilter, -1); @@ -5901,7 +5932,8 @@ void refresh_local_interface_lists(void) { /* Reload the local interface list. */ - scan_local_interfaces(); + if (global_capture_opts.session_started == FALSE) + scan_local_interfaces(); /* If there's an interfaces dialog up, refresh it. */ if (interfaces_dialog_window_present()) diff --git a/ui/gtk/main_welcome.c b/ui/gtk/main_welcome.c index cc76a1264b..f4868d003f 100644 --- a/ui/gtk/main_welcome.c +++ b/ui/gtk/main_welcome.c @@ -926,12 +926,11 @@ update_capture_box(void) interface_t device; gboolean changed = FALSE; - entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(if_view)); - gtk_tree_selection_unselect_all(GTK_TREE_SELECTION(entry)); store = gtk_list_store_new(NUMCOLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); gtk_list_store_clear(store); gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store)); + entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(if_view)); for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); if (!device.hidden) { diff --git a/ui/gtk/prefs_capture.c b/ui/gtk/prefs_capture.c index 098498a07e..acb4c5b5ce 100644 --- a/ui/gtk/prefs_capture.c +++ b/ui/gtk/prefs_capture.c @@ -64,6 +64,8 @@ #define COLOPTS_CALLER_PTR_KEY "colopts_caller_ptr" #define COLOPTS_DIALOG_PTR_KEY "colopts_dialog_ptr" +static GtkWidget *capture_window; + /* interface options dialog */ static GtkWidget *cur_list, *if_dev_lb, *if_name_lb, *if_linktype_lb, *if_linktype_cb, *if_descr_te, *if_hide_cb, *if_default_if_lb; #ifdef HAVE_PCAP_CREATE @@ -72,7 +74,7 @@ static GtkWidget *if_monitor_lb, *if_monitor_cb; #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) static GtkWidget *if_buffersize_lb, *if_buffersize_cb; #endif -static GtkWidget *if_snaplen_lb, *if_snaplen_cb, *if_snaplen_tg; +static GtkWidget *if_snaplen_lb, *if_snaplen_cb, *if_snaplen_tg, *if_pmode_lb, *if_pmode_cb; static GtkTreeSelection *if_selection; /* current interface row selected */ static int num_linktypes; static gboolean interfaces_info_nochange; /* TRUE to ignore Interface Options Properties */ @@ -93,6 +95,7 @@ static void ifopts_edit_buffersize_changed_cb(GtkSpinButton *ed, gpointer udata) #endif static void ifopts_edit_snaplen_changed_cb(GtkSpinButton *ed, gpointer udata); static void ifopts_edit_hassnap_changed_cb(GtkToggleButton *tbt, gpointer udata); +static void ifopts_edit_pmode_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); @@ -106,6 +109,8 @@ static void ifopts_write_new_buffersize(void); static void ifopts_write_new_snaplen(void); static void ifopts_write_new_descr(void); static void ifopts_write_new_hide(void); +static void ifopts_write_new_pmode(void); +static void prom_mode_cb(GtkToggleButton *tbt, gpointer udata); /* Columns options dialog */ #ifdef HAVE_PCAP_CREATE @@ -123,7 +128,7 @@ static void colopts_edit_ok_cb(GtkWidget *w, gpointer parent_w); GtkWidget* capture_prefs_show(void) { - GtkWidget *main_grid, *main_vb; + GtkWidget *main_grid; GtkWidget *if_cbxe, *if_lb, *promisc_cb, *pcap_ng_cb, *sync_cb, *auto_scroll_cb, *show_info_cb; GtkWidget *ifopts_lb, *ifopts_bt, *colopts_lb, *colopts_bt; GList *if_list, *combo_list; @@ -132,12 +137,12 @@ capture_prefs_show(void) const gchar *tooltips_text; /* Main vertical box */ - main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 7, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5); + capture_window = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 7, FALSE); + gtk_container_set_border_width(GTK_CONTAINER(capture_window), 5); /* Main grid */ main_grid = ws_gtk_grid_new(); - gtk_box_pack_start(GTK_BOX(main_vb), main_grid, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(capture_window), main_grid, FALSE, FALSE, 0); ws_gtk_grid_set_row_spacing(GTK_GRID(main_grid), 10); ws_gtk_grid_set_column_spacing(GTK_GRID(main_grid), 15); gtk_widget_show(main_grid); @@ -175,7 +180,7 @@ capture_prefs_show(void) gtk_widget_set_tooltip_text(if_lb, tooltips_text); gtk_widget_set_tooltip_text(gtk_bin_get_child(GTK_BIN(if_cbxe)), tooltips_text); gtk_widget_show(if_cbxe); - g_object_set_data(G_OBJECT(main_vb), DEVICE_KEY, if_cbxe); + g_object_set_data(G_OBJECT(capture_window), DEVICE_KEY, if_cbxe); row++; /* Interface properties */ @@ -194,20 +199,21 @@ capture_prefs_show(void) /* Promiscuous mode */ promisc_cb = create_preference_check_button(main_grid, row++, - "Capture packets in promiscuous mode:", - "You probably want to enable this. " + "Capture packets in promiscuous mode on all network cards:", + "To set this mode on a per interface basis, select the interface first." "Usually a network card will only capture the traffic sent to its own network address. " "If you want to capture all traffic that the network card can \"see\", mark this option. " "See the FAQ for some more details of capturing packets from a switched network. ", prefs.capture_prom_mode); - g_object_set_data(G_OBJECT(main_vb), PROM_MODE_KEY, promisc_cb); + g_signal_connect(promisc_cb, "toggled", G_CALLBACK(prom_mode_cb), NULL); + g_object_set_data(G_OBJECT(capture_window), PROM_MODE_KEY, promisc_cb); /* Pcap-NG format */ pcap_ng_cb = create_preference_check_button(main_grid, row++, "Capture packets in pcap-ng format:", "Capture packets in the next-generation capture file format.", prefs.capture_pcap_ng); - g_object_set_data(G_OBJECT(main_vb), PCAP_NG_KEY, pcap_ng_cb); + g_object_set_data(G_OBJECT(capture_window), PCAP_NG_KEY, pcap_ng_cb); /* Real-time capture */ sync_cb = create_preference_check_button(main_grid, row++, @@ -215,21 +221,21 @@ capture_prefs_show(void) "Update the list of packets while capture is in progress. " "This can result in dropped packets on high-speed networks.", prefs.capture_real_time); - g_object_set_data(G_OBJECT(main_vb), CAPTURE_REAL_TIME_KEY, sync_cb); + g_object_set_data(G_OBJECT(capture_window), CAPTURE_REAL_TIME_KEY, sync_cb); /* Auto-scroll real-time capture */ auto_scroll_cb = create_preference_check_button(main_grid, row++, "Automatic scrolling in live capture:", "Keep the packet list scrolled to the bottom while capturing.", prefs.capture_auto_scroll); - g_object_set_data(G_OBJECT(main_vb), AUTO_SCROLL_KEY, auto_scroll_cb); + g_object_set_data(G_OBJECT(capture_window), AUTO_SCROLL_KEY, auto_scroll_cb); /* Show capture info dialog */ show_info_cb = create_preference_check_button(main_grid, row++, "Hide capture info dialog:", "Hide the capture info dialog while capturing. ", !prefs.capture_show_info); - g_object_set_data(G_OBJECT(main_vb), SHOW_INFO_KEY, show_info_cb); + g_object_set_data(G_OBJECT(capture_window), SHOW_INFO_KEY, show_info_cb); /* Column properties */ colopts_lb = gtk_label_new("Columns:"); @@ -246,9 +252,9 @@ capture_prefs_show(void) row++; /* Show 'em what we got */ - gtk_widget_show_all(main_vb); + gtk_widget_show_all(capture_window); - return(main_vb); + return(capture_window); } void @@ -340,6 +346,7 @@ enum #endif HASSNAP_COLUMN, SNAPLEN_COLUMN, + PMODE_COLUMN, DEF_LINK_LAYER_COLUMN, COMMENT_COLUMN, HIDE_COLUMN, @@ -565,8 +572,8 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_) *if_hide_lb, *bbox, *ok_bt, *cancel_bt, *help_bt; - GtkListStore *list_store; - GtkWidget *list; + GtkListStore *list_store; + GtkWidget *list; GtkTreeViewColumn *column; GtkCellRenderer *renderer; GtkTreeView *list_view; @@ -590,7 +597,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), 1000, 440); + gtk_window_set_default_size(GTK_WINDOW(ifopts_edit_dlg), 1000, 500); main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE); gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5); @@ -622,6 +629,7 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_) #endif G_TYPE_BOOLEAN, /* Has snap length */ G_TYPE_INT, /* Snap length */ + G_TYPE_BOOLEAN, /* Promiscuous mode */ G_TYPE_STRING, /* Default link-layer */ G_TYPE_STRING, /* Comment */ G_TYPE_BOOLEAN, /* Hide? */ @@ -705,7 +713,12 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_) "text", SNAPLEN_COLUMN, NULL); - gtk_tree_view_column_set_resizable(column, TRUE); + renderer = gtk_cell_renderer_toggle_new (); + column = gtk_tree_view_column_new_with_attributes ("Default to promiscuous mode", renderer, + "active", PMODE_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); @@ -858,6 +871,19 @@ ifopts_edit_cb(GtkWidget *w, gpointer data _U_) ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), if_snaplen_cb, 1, row, 1, 1); gtk_widget_show(if_snaplen_cb); row++; + + /* create "promiscuous mode" label and button */ + if_pmode_lb = gtk_label_new("Promiscuous mode:"); + ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), if_pmode_lb, 0, row, 1, 1); + gtk_misc_set_alignment(GTK_MISC(if_pmode_lb), 1.0f, 0.5f); + gtk_widget_show(if_pmode_lb); + + if_pmode_cb = gtk_check_button_new(); + g_signal_connect(if_pmode_cb, "toggled", G_CALLBACK(ifopts_edit_pmode_changed_cb), + cur_list); + ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), if_pmode_cb, 1, row, 1, 1); + gtk_widget_show(if_pmode_cb); + row++; if_linktype_lb = gtk_label_new("Default link-layer header type:"); ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), if_linktype_lb, 0, row, 1, 1); @@ -1010,6 +1036,8 @@ ifopts_edit_ok_cb(GtkWidget *w _U_, gpointer parent_w) /* create/write new "snaplen" interfaces string */ ifopts_write_new_snaplen(); + /* create/write new promiscuous mode interfaces string */ + ifopts_write_new_pmode(); } /* Update everything that shows an interface list that includes @@ -1105,7 +1133,7 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_, gint buffersize; #endif gint snaplen; - gboolean hide, hide_enabled = TRUE, hassnap = FALSE; + gboolean hide, hide_enabled = TRUE, hassnap = FALSE, pmode; if_capabilities_t *caps; gint selected = 0; @@ -1124,6 +1152,7 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_, #endif HASSNAP_COLUMN, &hassnap, SNAPLEN_COLUMN, &snaplen, + PMODE_COLUMN, &pmode, DEF_LINK_LAYER_COLUMN, &linktype, COMMENT_COLUMN, &comment, HIDE_COLUMN, &hide, @@ -1145,6 +1174,14 @@ ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_, gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_snaplen_tg), hassnap); gtk_widget_set_sensitive(GTK_WIDGET(if_snaplen_cb), hassnap); + if (prefs.capture_prom_mode) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_pmode_cb), TRUE); + } else if (capture_dev_user_pmode_find(if_name) != -1) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_pmode_cb), capture_dev_user_pmode_find(if_name)); + } else { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_pmode_cb), FALSE); + } + /* Ignore "changed" callbacks while we update the Properties widgets */ interfaces_info_nochange = TRUE; @@ -1454,7 +1491,7 @@ ifopts_edit_hassnap_changed_cb(GtkToggleButton *tbt, gpointer udata) return; } hassnap = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tbt)); - + list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (udata))); gtk_list_store_set (list_store, &list_iter, HASSNAP_COLUMN, hassnap, @@ -1462,6 +1499,32 @@ ifopts_edit_hassnap_changed_cb(GtkToggleButton *tbt, gpointer udata) gtk_widget_set_sensitive(GTK_WIDGET(if_snaplen_cb), hassnap); } +/* + * Checkbutton for the promiscuous mode changed callback; update list_store for currently selected interface. + */ +static void +ifopts_edit_pmode_changed_cb(GtkToggleButton *tbt, gpointer udata) +{ + gboolean pmode; + GtkTreeModel *list_model; + GtkTreeIter list_iter; + GtkListStore *list_store; + + if (if_selection == NULL) /* XXX: Cannot be NULL ?? */ + return; + + if (!gtk_tree_selection_get_selected (if_selection, &list_model, &list_iter)){ + return; + } + pmode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tbt)); + + list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (udata))); + gtk_list_store_set (list_store, &list_iter, + PMODE_COLUMN, pmode, + -1); +} + + /* * Comment text entry changed callback; update list_store for currently selected interface. */ @@ -1554,7 +1617,7 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info) gint buffersize; #endif gint snaplen; - gboolean hide, hassnap = TRUE; + gboolean hide, hassnap = TRUE, pmode; GtkTreeIter iter; /* set device name text */ @@ -1611,6 +1674,15 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info) hassnap = FALSE; } + if (prefs.capture_prom_mode) { + pmode = TRUE; + } else { + if ((pmode = capture_dev_user_pmode_find(if_info->name)) != -1) { + pmode = capture_dev_user_pmode_find(if_info->name); + } else { + pmode = FALSE; + } + } /* if we have no link-layer */ if (text[2] == NULL) @@ -1681,6 +1753,7 @@ ifopts_options_add(GtkListStore *list_store, if_info_t *if_info) #endif HASSNAP_COLUMN, hassnap, SNAPLEN_COLUMN, snaplen, + PMODE_COLUMN, pmode, DEF_LINK_LAYER_COLUMN, text[2], COMMENT_COLUMN, text[3], HIDE_COLUMN, hide, @@ -1965,6 +2038,76 @@ ifopts_write_new_snaplen(void) } } +/* + * Create/write new promiscuous mode string based on current CList. + * Put it into the preferences value. + */ +static void +ifopts_write_new_pmode(void) +{ + GtkListStore *store; + GtkTreeIter iter; + GtkTreeModel *model; + GtkWidget *promisc_cb; + + gboolean more_items = TRUE, first_if = TRUE; /* flag to check if first in list */ + gchar *ifnm; + gboolean pmode, all_pmode, off = FALSE; + gchar *tmp_pmode; + gchar *new_pmode; + + /* new preferences interfaces promiscuous mode string */ + new_pmode = g_malloc0(MAX_VAL_LEN); + + all_pmode = prefs.capture_prom_mode; + + /* get promiscuous mode 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, + PMODE_COLUMN, &pmode, + -1); + if (pmode == -1){ + more_items = gtk_tree_model_iter_next (model,&iter); + continue; + } + + if (first_if != TRUE) { + g_strlcat (new_pmode, ",", MAX_VAL_LEN); + } + /* + * create/cat interface promiscuous mode to new string + * (leave space for parens, comma and terminator) + */ + if (!pmode) { + off = TRUE; + } + tmp_pmode = g_strdup_printf("%s(%d)", ifnm, pmode); + g_strlcat(new_pmode, tmp_pmode, MAX_VAL_LEN); + g_free(tmp_pmode); + g_free(ifnm); + /* set first-in-list flag to false */ + first_if = FALSE; + more_items = gtk_tree_model_iter_next (model,&iter); + } + + /* write new promiscuous mode string to preferences */ + g_free(prefs.capture_devices_pmode); + prefs.capture_devices_pmode = new_pmode; + if (off) { + prefs.capture_prom_mode = FALSE; + } else { + prefs.capture_prom_mode = TRUE; + } + promisc_cb = (GtkWidget *)g_object_get_data(G_OBJECT(capture_window), PROM_MODE_KEY); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb), prefs.capture_prom_mode); + } +} + /* * Create/write new interfaces description string based on current CList. * Put it into the preferences value. @@ -2077,4 +2220,9 @@ ifopts_write_new_hide(void) } } +static void +prom_mode_cb(GtkToggleButton *tbt, gpointer udata _U_) { + prefs.capture_prom_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tbt)); +} + #endif /* HAVE_LIBPCAP */ diff --git a/ui/iface_lists.c b/ui/iface_lists.c index b0537d251d..7fbdf7e8ec 100644 --- a/ui/iface_lists.c +++ b/ui/iface_lists.c @@ -242,12 +242,22 @@ scan_local_interfaces(void) device.local = TRUE; device.if_info = *temp; device.last_packets = 0; - device.pmode = global_capture_opts.default_options.promisc_mode; - device.has_snaplen = global_capture_opts.default_options.has_snaplen; - device.snaplen = global_capture_opts.default_options.snaplen; + if ((device.pmode = capture_dev_user_pmode_find(if_info->name)) == -1) { + device.pmode = global_capture_opts.default_options.promisc_mode; + } + if ((device.has_snaplen = capture_dev_user_hassnap_find(if_info->name)) == -1) { + device.has_snaplen = global_capture_opts.default_options.has_snaplen; + } + if (capture_dev_user_snaplen_find(if_info->name) == -1) { + device.snaplen = global_capture_opts.default_options.snaplen; + } else { + device.snaplen = (guint)capture_dev_user_snaplen_find(if_info->name); + } device.cfilter = g_strdup(global_capture_opts.default_options.cfilter); #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) - device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE; + if ((device.buffer = capture_dev_user_buffersize_find(if_info->name)) == -1) { + device.buffer = global_capture_opts.default_options.buffer_size; + } #endif if (global_capture_opts.ifaces->len > 0) {