diff options
author | Jörg Mayer <jmayer@loplof.de> | 2012-01-15 21:59:11 +0000 |
---|---|---|
committer | Jörg Mayer <jmayer@loplof.de> | 2012-01-15 21:59:11 +0000 |
commit | be706c63801fb98d42fb743b27b16cc36273651e (patch) | |
tree | 62ed0b552191eb0753d26a3edcbab73459a15f7f /ui/gtk/prefs_capture.c | |
parent | 6d69ef093cd6868ab51f8b52477a510172033353 (diff) | |
download | wireshark-be706c63801fb98d42fb743b27b16cc36273651e.tar.gz |
Move gtk to ui/gtk.
This looses the last checkin to gtk, will add this manually back.
svn path=/trunk/; revision=40518
Diffstat (limited to 'ui/gtk/prefs_capture.c')
-rw-r--r-- | ui/gtk/prefs_capture.c | 1430 |
1 files changed, 1430 insertions, 0 deletions
diff --git a/ui/gtk/prefs_capture.c b/ui/gtk/prefs_capture.c new file mode 100644 index 0000000000..a5a5bbd44d --- /dev/null +++ b/ui/gtk/prefs_capture.c @@ -0,0 +1,1430 @@ +/* capture_prefs.c + * Dialog box for capture preferences + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_LIBPCAP + +#include <string.h> +#include <gtk/gtk.h> + +#include <epan/prefs.h> + +#include "../simple_dialog.h" +#include "../capture_ifinfo.h" +#include "../capture_ui_utils.h" + +#include "ui/gtk/prefs_capture.h" +#include "ui/gtk/prefs_dlg.h" +#include "ui/gtk/gui_utils.h" +#include "ui/gtk/dlg_utils.h" +#include "ui/gtk/main.h" +#include "ui/gtk/main_welcome.h" +#include "ui/gtk/help_dlg.h" +#include "ui/gtk/stock_icons.h" +#include "ui/gtk/old-gtk-compat.h" +#include <epan/strutil.h> + + +#define DEVICE_KEY "device" +#define PROM_MODE_KEY "prom_mode" +#define PCAP_NG_KEY "pcap_ng" +#define CAPTURE_REAL_TIME_KEY "capture_real_time" +#define AUTO_SCROLL_KEY "auto_scroll" +#define SHOW_INFO_KEY "show_info" + +#define CAPTURE_TABLE_ROWS 6 + +#define IFOPTS_CALLER_PTR_KEY "ifopts_caller_ptr" +#define IFOPTS_DIALOG_PTR_KEY "ifopts_dialog_ptr" +#define IFOPTS_TABLE_ROWS 2 +#define IFOPTS_LIST_TEXT_COLS 4 +#define IFOPTS_MAX_DESCR_LEN 128 +#define IFOPTS_IF_NOSEL -1 + +/* 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; +#ifdef HAVE_PCAP_CREATE +static GtkWidget *if_monitor_lb, *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 */ + /* widgets "changed" callbacks. */ + +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); + +GtkWidget* +capture_prefs_show(void) +{ + GtkWidget *main_tb, *main_vb; + GtkWidget *if_cbxe, *if_lb, *promisc_cb, *pcap_ng_cb, *sync_cb, *auto_scroll_cb, *show_info_cb; + GtkWidget *ifopts_lb, *ifopts_bt; + GList *if_list, *combo_list; + int err; + int row = 0; + gchar *tooltips_text; + + /* Main vertical box */ + main_vb = gtk_vbox_new(FALSE, 7); + gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5); + + /* Main table */ + main_tb = gtk_table_new(CAPTURE_TABLE_ROWS, 2, FALSE); + gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0); + gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10); + gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15); + gtk_widget_show(main_tb); + + /* Default device */ + if_lb = gtk_label_new("Default interface:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_lb, 0, 1, row, row+1); + gtk_misc_set_alignment(GTK_MISC(if_lb), 1.0f, 0.5f); + gtk_widget_show(if_lb); + + if_cbxe = gtk_combo_box_text_new_with_entry(); + /* + * XXX - what if we can't get the list? + */ + if_list = capture_interface_list(&err, NULL); + combo_list = build_capture_combo_list(if_list, FALSE); + free_interface_list(if_list); + if (combo_list != NULL) { + GList *combo_entry; + for (combo_entry = combo_list; combo_entry != NULL; combo_entry = g_list_next(combo_entry)) { + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(if_cbxe), combo_entry->data); + } + } + if (prefs.capture_device) { + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(if_cbxe))), + prefs.capture_device); + } + else if (combo_list != NULL) { + gtk_combo_box_set_active(GTK_COMBO_BOX(if_cbxe), 0); + } + free_capture_combo_list(combo_list); + + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_cbxe, 1, 2, row, row+1); + tooltips_text = "The default interface to be captured from."; + 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); + row++; + + /* Interface properties */ + ifopts_lb = gtk_label_new("Interfaces:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), ifopts_lb, 0, 1, row, row+1); + gtk_misc_set_alignment(GTK_MISC(ifopts_lb), 1.0f, 0.5f); + gtk_widget_show(ifopts_lb); + + ifopts_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_EDIT); + tooltips_text = "Open a dialog box to set various interface options."; + gtk_widget_set_tooltip_text(ifopts_lb, tooltips_text); + gtk_widget_set_tooltip_text(ifopts_bt, tooltips_text); + g_signal_connect(ifopts_bt, "clicked", G_CALLBACK(ifopts_edit_cb), NULL); + gtk_table_attach_defaults(GTK_TABLE(main_tb), ifopts_bt, 1, 2, row, row+1); + row++; + + /* Promiscuous mode */ + promisc_cb = create_preference_check_button(main_tb, row++, + "Capture packets in promiscuous mode:", + "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); + + /* Pcap-NG format */ + pcap_ng_cb = create_preference_check_button(main_tb, 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); + + /* Real-time capture */ + sync_cb = create_preference_check_button(main_tb, row++, + "Update list of packets in real time:", + "Update the list of packets while capture is in progress. " + "Don't use this option if you notice packet drops.", + prefs.capture_real_time); + g_object_set_data(G_OBJECT(main_vb), CAPTURE_REAL_TIME_KEY, sync_cb); + + /* Auto-scroll real-time capture */ + auto_scroll_cb = create_preference_check_button(main_tb, row++, + "Automatic scrolling in live capture:", + "Automatic scrolling of the packet list while live capture is in progress. ", + prefs.capture_auto_scroll); + g_object_set_data(G_OBJECT(main_vb), AUTO_SCROLL_KEY, auto_scroll_cb); + + /* Show capture info dialog */ + show_info_cb = create_preference_check_button(main_tb, 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); + + /* Show 'em what we got */ + gtk_widget_show_all(main_vb); + + return(main_vb); +} + +void +capture_prefs_fetch(GtkWidget *w) +{ + GtkWidget *if_cbxe, *promisc_cb, *pcap_ng_cb, *sync_cb, *auto_scroll_cb, *show_info_cb; + gchar *if_text; + + if_cbxe = (GtkWidget *)g_object_get_data(G_OBJECT(w), DEVICE_KEY); + promisc_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), PROM_MODE_KEY); + pcap_ng_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), PCAP_NG_KEY); + sync_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), CAPTURE_REAL_TIME_KEY); + auto_scroll_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), AUTO_SCROLL_KEY); + show_info_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), SHOW_INFO_KEY); + + if (prefs.capture_device != NULL) { + g_free(prefs.capture_device); + prefs.capture_device = NULL; + } + if_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(if_cbxe))))); + /* Strip out white space */ + g_strstrip(if_text); + /* If there was nothing but white space, treat that as an + indication that the user doesn't want to wire in a default + device, and just wants the first device in the list chosen. */ + if (*if_text == '\0') { + g_free(if_text); + if_text = NULL; + } + prefs.capture_device = if_text; + + prefs.capture_prom_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb)); + + prefs.capture_pcap_ng = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pcap_ng_cb)); + + prefs.capture_real_time = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb)); + + prefs.capture_auto_scroll = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb)); + + prefs.capture_show_info = !(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(show_info_cb))); +} + +void +capture_prefs_apply(GtkWidget *w _U_) +{ +} + +void +capture_prefs_destroy(GtkWidget *w) +{ + GtkWidget *caller = gtk_widget_get_toplevel(w); + GtkWidget *dlg; + + /* Is there an interface descriptions dialog associated with this + Preferences dialog? */ + dlg = g_object_get_data(G_OBJECT(caller), IFOPTS_DIALOG_PTR_KEY); + + if (dlg != NULL) { + /* Yes. Destroy it. */ + window_destroy(dlg); + } +} + +/* + * Create an edit interface options dialog. + */ +enum +{ + DEVICE_COLUMN, + DESC_COLUMN, +#ifdef HAVE_PCAP_CREATE + DEF_MONITOR_MODE_COLUMN, +#endif + DEF_LINK_LAYER_COLUMN, + COMMENT_COLUMN, + HIDE_COLUMN, + DLT_COLUMN, + N_COLUMN /* The number of columns */ +}; + +static void +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_descr_lb, + *if_hide_lb, + *bbox, *ok_bt, *cancel_bt, *help_bt; + + GtkListStore *list_store; + GtkWidget *list; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + GtkTreeView *list_view; + GtkTreeSelection *selection; + + int row = 0; + + GtkWidget *caller = gtk_widget_get_toplevel(w); + + /* Has an edit dialog box already been opened for that top-level + widget? */ + ifopts_edit_dlg = g_object_get_data(G_OBJECT(caller), IFOPTS_DIALOG_PTR_KEY); + if (ifopts_edit_dlg != NULL) { + /* Yes. Just re-activate that dialog box. */ + reactivate_window(ifopts_edit_dlg); + return; + } + + /* 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); + + main_vb = gtk_vbox_new(FALSE, 1); + gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5); + gtk_container_add(GTK_CONTAINER(ifopts_edit_dlg), main_vb); + gtk_widget_show(main_vb); + + /* create current options frame */ + cur_opts_fr = gtk_frame_new("Interfaces"); + gtk_container_add(GTK_CONTAINER(main_vb), cur_opts_fr); + gtk_widget_show(cur_opts_fr); + + /* create a scrolled window to pack the current options TreeView widget into */ + cur_scr_win = scrolled_window_new(NULL, NULL); + gtk_container_set_border_width(GTK_CONTAINER(cur_scr_win), 3); + gtk_container_add(GTK_CONTAINER(cur_opts_fr), cur_scr_win); + gtk_widget_show(cur_scr_win); + + /* + * Create current options TreeView. + */ + 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? */ + G_TYPE_INT); /* Dlt */ + + list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store)); + + list_view = GTK_TREE_VIEW(list); + + /* The view now holds a reference. We can get rid of our own reference */ + g_object_unref (G_OBJECT (list_store)); + + /* + * Create the first column packet, associating the "text" attribute of the + * cell_renderer to the first column of the model + */ + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Device", renderer, + "text", DEVICE_COLUMN, + NULL); + + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); +#ifdef _WIN32 + gtk_tree_view_column_set_min_width(column, 230); +#else + gtk_tree_view_column_set_min_width(column, 70); +#endif + /* 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); + + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_min_width(column, 260); + /* 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); + + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_min_width(column, 230); + /* 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); + + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_min_width(column, 100); + /* Add the column to the view. */ + gtk_tree_view_append_column (list_view, column); + + renderer = gtk_cell_renderer_toggle_new (); + column = gtk_tree_view_column_new_with_attributes ("Hide?", renderer, + "active", HIDE_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); + +#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); + + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_min_width(column, 40); + /* Add the column to the view. */ + gtk_tree_view_append_column (list_view, column); +#endif + /* Setup the selection handler */ + selection = gtk_tree_view_get_selection(list_view); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + + cur_list = list; + gtk_container_add(GTK_CONTAINER(cur_scr_win), cur_list); + + if_selection = selection; + + g_signal_connect (G_OBJECT (selection), "changed", /* select_row */ + G_CALLBACK (ifopts_edit_ifsel_cb), + NULL); + + gtk_widget_show(cur_list); + + /* add interface names to cell */ + ifopts_if_liststore_add(); + + /* create edit options frame */ + ed_opts_fr = gtk_frame_new("Properties"); + gtk_box_pack_start(GTK_BOX(main_vb), ed_opts_fr, FALSE, FALSE, 0); + gtk_widget_show(ed_opts_fr); + + main_hb = gtk_hbox_new(TRUE, 5); + gtk_container_set_border_width(GTK_CONTAINER(main_hb), 3); + gtk_container_add(GTK_CONTAINER(ed_opts_fr), main_hb); + gtk_widget_show(main_hb); + + /* table to hold description text entry and hide button */ + main_tb = gtk_table_new(IFOPTS_TABLE_ROWS, 4, FALSE); + gtk_box_pack_start(GTK_BOX(main_hb), main_tb, TRUE, FALSE, 10); + gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10); + gtk_table_set_col_spacings(GTK_TABLE(main_tb), 10); + gtk_widget_show(main_tb); + + if_dev_lb = gtk_label_new("Device:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_dev_lb, 0, 1, row, row+1); + gtk_misc_set_alignment(GTK_MISC(if_dev_lb), 1.0f, 0.5f); + gtk_widget_show(if_dev_lb); + + if_dev_lb = gtk_label_new(""); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_dev_lb, 1, 2, row, row+1); + gtk_misc_set_alignment(GTK_MISC(if_dev_lb), 0.0f, 0.5f); + gtk_widget_show(if_dev_lb); + row++; + + if_name_lb = gtk_label_new("Description:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_name_lb, 0, 1, row, row+1); + gtk_misc_set_alignment(GTK_MISC(if_name_lb), 1.0f, 0.5f); + gtk_widget_show(if_name_lb); + + if_name_lb = gtk_label_new(""); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_name_lb, 1, 2, row, row+1); + gtk_misc_set_alignment(GTK_MISC(if_name_lb), 0.0f, 0.5f); + 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); + gtk_widget_show(if_linktype_lb); + + if_linktype_cb = gtk_combo_box_text_new(); + num_linktypes = 0; + interfaces_info_nochange = FALSE; + g_signal_connect(if_linktype_cb, "changed", G_CALLBACK(ifopts_edit_linktype_changed_cb), + cur_list); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_linktype_cb, 1, 2, row, row+1); + gtk_widget_show(if_linktype_cb); + row++; + + /* create interface description label and text entry */ + if_descr_lb = gtk_label_new("Comment:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_descr_lb, 0, 1, row, row+1); + gtk_misc_set_alignment(GTK_MISC(if_descr_lb), 1.0f, 0.5f); + gtk_widget_show(if_descr_lb); + + if_descr_te = gtk_entry_new(); + g_signal_connect(if_descr_te, "changed", G_CALLBACK(ifopts_edit_descr_changed_cb), + cur_list); + gtk_entry_set_max_length(GTK_ENTRY(if_descr_te), IFOPTS_MAX_DESCR_LEN); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_descr_te, 1, 2, row, row+1); + gtk_widget_show(if_descr_te); + row++; + + /* create "hide interface" label and button */ + if_hide_lb = gtk_label_new("Hide interface?:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_hide_lb, 0, 1, row, row+1); + gtk_misc_set_alignment(GTK_MISC(if_hide_lb), 1.0f, 0.5f); + gtk_widget_show(if_hide_lb); + + if_hide_cb = gtk_check_button_new(); + g_signal_connect(if_hide_cb, "toggled", G_CALLBACK(ifopts_edit_hide_changed_cb), + cur_list); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_hide_cb, 1, 2, row, row+1); + gtk_widget_show(if_hide_cb); + row++; + + /* button row: OK and Cancel buttons */ + bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL); + gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0); + gtk_widget_show(bbox); + + ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK); + gtk_widget_set_tooltip_text(ok_bt, "Save changes and exit dialog"); + g_signal_connect(ok_bt, "clicked", G_CALLBACK(ifopts_edit_ok_cb), ifopts_edit_dlg); + + cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL); + gtk_widget_set_tooltip_text(cancel_bt, "Cancel and exit dialog"); + window_set_cancel_button(ifopts_edit_dlg, cancel_bt, window_cancel_button_cb); + + help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP); + g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), + (gpointer)HELP_CAPTURE_INTERFACE_OPTIONS_DIALOG); + gtk_widget_set_tooltip_text (help_bt, "Show topic specific help"); + + gtk_widget_grab_default(ok_bt); + + g_signal_connect(ifopts_edit_dlg, "delete_event", G_CALLBACK(window_delete_event_cb), + NULL); + /* Call a handler when we're destroyed, so we can inform + our caller, if any, that we've been destroyed. */ + g_signal_connect(ifopts_edit_dlg, "destroy", G_CALLBACK(ifopts_edit_destroy_cb), NULL); + + /* Set the key for the new dialog to point to our caller. */ + g_object_set_data(G_OBJECT(ifopts_edit_dlg), IFOPTS_CALLER_PTR_KEY, caller); + /* Set the key for the caller to point to us */ + g_object_set_data(G_OBJECT(caller), IFOPTS_DIALOG_PTR_KEY, ifopts_edit_dlg); + + gtk_widget_show(ifopts_edit_dlg); /* triggers ifopts_edit_ifsel_cb() with the */ + /* "interfaces" TreeView first row selected */ + window_present(ifopts_edit_dlg); +} + +/* + * User selected "OK". Create/write preferences strings. + */ +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(); + + /* create/write new interfaces description string */ + ifopts_write_new_descr(); + + /* create/write new "hidden" interfaces string */ + ifopts_write_new_hide(); + } + + /* Update welcome page */ + welcome_if_panel_reload (); + + /* Now nuke this window. */ + gtk_grab_remove(GTK_WIDGET(parent_w)); + window_destroy(GTK_WIDGET(parent_w)); +} + +static void +ifopts_edit_destroy_cb(GtkWidget *win, gpointer data _U_) +{ + GtkWidget *caller; + + /* Get the widget that requested that we be popped up, if any. + (It should arrange to destroy us if it's destroyed, so + that we don't get a pointer to a non-existent window here.) */ + caller = g_object_get_data(G_OBJECT(win), IFOPTS_CALLER_PTR_KEY); + + if (caller != NULL) { + /* Tell it we no longer exist. */ + g_object_set_data(G_OBJECT(caller), IFOPTS_DIALOG_PTR_KEY, NULL); + } +} + +static gint +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, monitor_mode, NULL); + if (caps != NULL) { + if (caps->data_link_types != NULL) { + GList *lt_entry; + /* XXX: Code skips first entry because that's the default ??? */ + for (lt_entry = g_list_next(caps->data_link_types); + lt_entry != NULL; + lt_entry = g_list_next(lt_entry)) { + data_link_info_t *dli_p = lt_entry->data; + if (dli_p->description) { + if (strcmp(dli_p->description, descr) == 0) { + dlt = dli_p->dlt; + break; + } + } else { + if (strcmp(dli_p->name, descr) == 0) { + dlt = dli_p->dlt; + break; + } + } + } + } + free_if_capabilities(caps); + } + return dlt; +} + +/* + * Interface selected callback; update displayed widgets. + */ +static void +ifopts_edit_ifsel_cb(GtkTreeSelection *selection _U_, + gpointer data _U_) +{ + GtkTreeIter iter; + GtkTreeModel *model; + gchar *desc, *comment, *text; + gchar *if_name, *linktype; +#ifdef HAVE_PCAP_CREATE + gboolean monitor_mode; +#endif + gboolean hide; + if_capabilities_t *caps; + gint selected = 0; + + /* Get list_store data for currently selected interface */ + if (!gtk_tree_selection_get_selected (if_selection, &model, &iter)){ + return; + } + gtk_tree_model_get(model, &iter, + 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 */ + gtk_label_set_text(GTK_LABEL(if_dev_lb), if_name); + + /* display the interface name from current interfaces selection */ + gtk_label_set_text(GTK_LABEL(if_name_lb), desc); + + /* 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_text_remove(GTK_COMBO_BOX_TEXT(if_linktype_cb), num_linktypes); + } + + /* + * -- set the state and sensitivity of the monitor-mode checkbox, + * and build and add to the ComboBox a linktype list, corresponding + * to the interface capabilities of the selected interface + */ +#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_lb, caps->can_set_rfmon); + gtk_widget_set_sensitive(if_monitor_cb, caps->can_set_rfmon); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_monitor_cb), monitor_mode); +#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; + if (strcmp(linktype, text) == 0) { + selected = num_linktypes; + } + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(if_linktype_cb), text); + num_linktypes++; + } + gtk_widget_set_sensitive(if_linktype_lb, num_linktypes >= 2); + gtk_widget_set_sensitive(if_linktype_cb, num_linktypes >= 2); + gtk_combo_box_set_active(GTK_COMBO_BOX(if_linktype_cb), selected); + } + free_if_capabilities(caps); + } +#ifdef HAVE_PCAP_CREATE + else { + gtk_widget_set_sensitive(if_monitor_lb, FALSE); + gtk_widget_set_sensitive(if_monitor_cb, FALSE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_monitor_cb), FALSE); + } +#endif + + /* display the interface description from current interfaces selection */ + gtk_entry_set_text(GTK_ENTRY(if_descr_te), comment); + + /* display the "hide interface" button state from current interfaces selection */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_hide_cb), hide); + + interfaces_info_nochange = FALSE; + + g_free(if_name); + g_free(desc); + g_free(linktype); + 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_text_remove(GTK_COMBO_BOX_TEXT(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_lb, caps->can_set_rfmon); + 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_text_append_text (GTK_COMBO_BOX_TEXT(if_linktype_cb), text); + num_linktypes++; + } + gtk_widget_set_sensitive(if_linktype_lb, num_linktypes >= 2); + 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_lb, FALSE); + gtk_widget_set_sensitive(if_monitor_cb, FALSE); + } +#endif + + interfaces_info_nochange = FALSE; + g_signal_emit_by_name(if_linktype_cb, "changed"); + + g_free(if_name); +} +#endif + +/* + * Link-layer entry changed callback; update list_store for currently selected interface. + */ +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; + GtkTreeIter list_iter; + GtkListStore *list_store; + + 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, &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 */ + text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(cb)); + if (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, + DLT_COLUMN, linktype, + -1); + g_free(text); + } +} + +/* + * Comment text entry changed callback; update list_store for currently selected interface. + */ +static void +ifopts_edit_descr_changed_cb(GtkEditable *ed, gpointer udata) +{ + gchar *text; + GtkTreeModel *list_model; + GtkTreeIter list_iter; + GtkListStore *list_store; + + 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; + } + + /* get current description text and set value in list_store for currently selected interface */ + text = gtk_editable_get_chars(GTK_EDITABLE(ed), 0, -1); + /* replace any reserved formatting characters "()," with spaces */ + g_strdelimit(text, "(),", ' '); + + list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (udata))); /* Get store */ + gtk_list_store_set (list_store, &list_iter, + COMMENT_COLUMN, text, + -1); + + g_free(text); +} + +/* + * Hide toggle button changed callback; update list_store for currently selected interface . + */ +static void +ifopts_edit_hide_changed_cb(GtkToggleButton *tbt, gpointer udata) +{ + GtkTreeModel *list_model; + GtkTreeIter list_iter; + GtkListStore *list_store; + + 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; + } + + list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (udata))); /* Get store */ + /* get "hide" button state and set status in list_store for currently selected interface */ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tbt)) == TRUE) + gtk_list_store_set (list_store, &list_iter, + HIDE_COLUMN, TRUE, + -1); + else + gtk_list_store_set (list_store, &list_iter, + HIDE_COLUMN, FALSE, + -1); +} + +/* + * Add any saved interface options that apply to interfaces ListStore. + * + * NOTE: + * Interfaces that have been removed from the machine or disabled and + * no longer apply are ignored. Therefore, if the user subsequently + * selects "OK", the options for these interfaces are lost (they're + * lost permanently if "Save" is selected). + */ +static void +ifopts_options_add(GtkListStore *list_store, if_info_t *if_info) +{ + gchar *p; + gchar *ifnm; + gchar *desc; + 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; + + /* set device name text */ + text[0] = g_strdup(if_info->name); + + /* set OS description */ + if (if_info->description != NULL) + text[1] = g_strdup(if_info->description); + 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); + if (caps != NULL) { + 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; + /* If we have no previous link-layer header type we use the first one */ + if (linktype == -1 || linktype == dli_p->dlt) { + if (dli_p->description) { + text[2] = g_strdup(dli_p->description); + } else { + text[2] = g_strdup(dli_p->name); + } + break; + } + } + } + free_if_capabilities(caps); + } + /* if we have no link-layer */ + if (text[2] == NULL) + text[2] = g_strdup(""); + + /* add interface descriptions */ + if (prefs.capture_devices_descr != NULL) { + /* create working copy of device descriptions */ + pr_descr = g_strdup(prefs.capture_devices_descr); + + /* if we find a description for this interface */ + if ((ifnm = strstr(pr_descr, if_info->name)) != NULL) { + p = ifnm; + while (*p != '\0') { + /* found left parenthesis, start of description */ + if (*p == '(') { + p++; + /* if syntax error */ + if ((*p == '\0') || (*p == ',') || (*p == '(') || (*p == ')')) + break; + + /* save pointer to beginning of description */ + desc = p; + p++; + /* skip to end of description */ + while (*p != '\0') { + /* if syntax error */ + if ((*p == ',') || (*p == '(')) + break; + + /* end of description */ + else if (*p == ')') { + /* terminate and set description text */ + *p = '\0'; + text[3] = g_strdup(desc); + break; + } + p++; + } + /* get out */ + break; + } else + p++; + } + } + + g_free(pr_descr); + } + + /* if we have no description */ + if (text[3] == NULL) + text[3] = g_strdup(""); + + /* check if interface is "hidden" */ + hide = prefs_is_capture_device_hidden(if_info->name); + + /* add row to ListStore */ + + gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT, + 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); +} + +static void +ifopts_options_free(gchar *text[]) +{ + gint i; + + for (i=0; i < IFOPTS_LIST_TEXT_COLS; i++) { + if (text[i] != NULL) { + g_free(text[i]); + text[i] = NULL; + } + } +} + +/* + * Add all interfaces to interfaces ListStore. + */ +static void +ifopts_if_liststore_add(void) +{ + GList *if_list, *ifl_p; + int err; + gchar *err_str; + + if_list = capture_interface_list(&err, &err_str); /* if_list = ptr to first element of list (or NULL) */ + if (if_list == NULL) { + if (err != NO_INTERFACES_FOUND) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); + } + g_free(err_str); + return; + } + + /* We have an interface list. */ + /* add OS description + interface name text to ListStore */ + for (ifl_p = if_list; ifl_p != NULL; ifl_p = g_list_next(ifl_p)) { + /* should never happen, but just in case */ + if ((ifl_p->data) == NULL) + continue; + /* fill current options ListStore with current preference values */ + ifopts_options_add(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (cur_list))), + (if_info_t *)ifl_p->data); + } + 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. + */ +static void +ifopts_write_new_linklayer(void) +{ + GtkListStore *store; + GtkTreeIter iter; + GtkTreeModel *model; + + gboolean more_items = TRUE, first_if = TRUE; /* flag to check if first in list */ + gchar *ifnm; + gint linktype; + gchar *tmp_linklayer; + gchar *new_linklayer; + + /* new preferences interfaces link-layer string */ + new_linklayer = g_malloc0(MAX_VAL_LEN); + + /* get link-layer 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, + DLT_COLUMN, &linktype, + -1); + + if (linktype == -1){ + more_items = gtk_tree_model_iter_next (model,&iter); + continue; + } + + if (first_if != TRUE) { + g_strlcat (new_linklayer, ",", MAX_VAL_LEN); + } + /* + * create/cat interface link-layer to new string + * (leave space for parens, comma and terminator) + */ + tmp_linklayer = g_strdup_printf("%s(%d)", ifnm, linktype); + g_strlcat(new_linklayer, tmp_linklayer, MAX_VAL_LEN); + g_free(tmp_linklayer); + g_free(ifnm); + /* set first-in-list flag to false */ + first_if = FALSE; + more_items = gtk_tree_model_iter_next (model,&iter); + } + + /* write new link-layer string to preferences */ + if (strlen(new_linklayer) > 0) { + g_free(prefs.capture_devices_linktypes); + prefs.capture_devices_linktypes = new_linklayer; + } + /* no link-layers */ + else { + g_free(prefs.capture_devices_linktypes); + g_free(new_linklayer); + prefs.capture_devices_linktypes = NULL; + } + } +} + +/* + * Create/write new interfaces description string based on current CList. + * Put it into the preferences value. + */ +static void +ifopts_write_new_descr(void) +{ + GtkListStore *store; + GtkTreeIter iter; + GtkTreeModel *model; + gboolean more_items = TRUE; + gboolean first_if = TRUE; /* flag to check if first in list */ + gchar *ifnm; + gchar *desc; + gchar *tmp_descr; + gchar *new_descr; + + /* new preferences interfaces description string */ + new_descr = g_malloc0(MAX_VAL_LEN); + + /* get description 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, + COMMENT_COLUMN, &desc, + -1); + + /* if no description, skip this interface */ + if (strlen(desc) == 0){ + more_items = gtk_tree_model_iter_next (model,&iter); + continue; + } + /* + * create/cat interface description to new string + * (leave space for parens, comma and terminator) + */ + if (first_if != TRUE) { + g_strlcat (new_descr, ",", MAX_VAL_LEN); + } + + tmp_descr = g_strdup_printf("%s(%s)", ifnm, desc); + g_strlcat(new_descr, tmp_descr, MAX_VAL_LEN); + g_free(tmp_descr); + + /* set first-in-list flag to false */ + first_if = FALSE; + more_items = gtk_tree_model_iter_next (model,&iter); + } + + /* write new description string to preferences */ + if (strlen(new_descr) > 0) { + g_free(prefs.capture_devices_descr); + prefs.capture_devices_descr = new_descr; + } + /* no descriptions */ + else { + g_free(prefs.capture_devices_descr); + g_free(new_descr); + prefs.capture_devices_descr = NULL; + } + } +} + +/* + * Create/write new "hidden" interfaces string based on current CList. + * Put it into the preferences value. + */ +static void +ifopts_write_new_hide(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 hide; + gchar *new_hide; + + /* new preferences "hidden" interfaces string */ + new_hide = g_malloc0(MAX_VAL_LEN); + + /* get "hide" 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, + HIDE_COLUMN, &hide, + -1); + + /* if flag text is "No", skip this interface */ + if (!hide){ + more_items = gtk_tree_model_iter_next (model,&iter); + continue; + } + + /* + * create/cat interface to new string + */ + if (first_if != TRUE) + g_strlcat (new_hide, ",", MAX_VAL_LEN); + g_strlcat (new_hide, 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_hide) > 0) { + g_free(prefs.capture_devices_hide); + prefs.capture_devices_hide = new_hide; + } + /* no "hidden" interfaces */ + else { + g_free(prefs.capture_devices_hide); + g_free(new_hide); + prefs.capture_devices_hide = NULL; + } + } +} + +#endif /* HAVE_LIBPCAP */ |