From Peter Hatina:
[metze/wireshark/wip.git] / ui / gtk / capture_dlg.c
1 /* capture_dlg.c
2  * Routines for the "Capture Options" dialog and dialog windows popped
3  * up from it
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include "config.h"
27
28 #ifdef HAVE_LIBPCAP
29
30 #include <string.h>
31
32 #include <stdio.h>
33
34 #include <gtk/gtk.h>
35
36 #include <epan/packet.h>
37 #include <epan/addr_resolv.h>
38 #include <epan/prefs.h>
39 #include <epan/filesystem.h>
40
41 #include "../capture.h"
42 #include "../capture_ifinfo.h"
43 #include "../capture-pcap-util.h"
44 #include "../capture_ui_utils.h"
45 #include "../ringbuffer.h"
46
47 #include "ui/capture_globals.h"
48 #include "ui/iface_lists.h"
49 #include "ui/preference_utils.h"
50 #include "ui/recent.h"
51 #include "ui/recent_utils.h"
52 #include "ui/simple_dialog.h"
53
54 #include "ui/gtk/main.h"
55 #include "ui/gtk/gui_utils.h"
56 #include "ui/gtk/capture_dlg.h"
57 #include "ui/gtk/filter_dlg.h"
58 #include "ui/gtk/dlg_utils.h"
59 #include "ui/gtk/file_dlg.h"
60 #include "ui/gtk/stock_icons.h"
61 #include "ui/gtk/capture_file_dlg.h"
62 #include "ui/gtk/help_dlg.h"
63 #include "ui/gtk/gtkglobals.h"
64 #include "ui/gtk/cfilter_combo_utils.h"
65 #include "ui/gtk/capture_if_dlg.h"
66 #include "ui/gtk/main_welcome.h"
67 #include "ui/gtk/network_icons.h"
68 #include "ui/gtk/menus.h"
69 #include "ui/gtk/prefs_dlg.h"
70 #include "ui/gtk/main_80211_toolbar.h"
71
72 #include "ui/gtk/keys.h"
73
74 #include "ui/gtk/old-gtk-compat.h"
75 #include "ui/gtk/expert_indicators.h"
76
77 #ifdef HAVE_AIRPCAP
78 #include <airpcap.h>
79 #include "airpcap_loader.h"
80 #include "airpcap_gui_utils.h"
81 #include "airpcap_dlg.h"
82 #endif
83
84 /*
85  * Symbolic names for column indices.
86  */
87 enum
88 {
89     CAPTURE = 0,
90     IFACE_HIDDEN_NAME,
91     INTERFACE,
92     LINK,
93     PMODE,
94     SNAPLEN,
95 #if defined(HAVE_PCAP_CREATE)
96     BUFFER,
97     MONITOR,
98 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
99     BUFFER,
100 #endif
101     FILTER,
102     NUM_COLUMNS
103 };
104
105 enum
106 {
107   COMPILE_ERROR = 0,
108   SIGN,
109   INAME
110 };
111
112 #ifdef _WIN32
113         #define LOCAL_OFFSET 1
114 #else
115         #define LOCAL_OFFSET 0
116 #endif
117
118 /* Capture callback data keys */
119 #define E_CAP_IFACE_KEY                 "cap_iface"
120 #define E_CAP_IFACE_IP_KEY              "cap_iface_ip"
121 #define E_CAP_SNAP_CB_KEY               "cap_snap_cb"
122 #define E_CAP_LT_CBX_KEY                "cap_lt_cbx"
123 #define E_CAP_LT_CBX_LABEL_KEY          "cap_lt_cbx_label"
124 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
125 #define E_CAP_BUFFER_SIZE_SB_KEY        "cap_buffer_size_sb"
126 #endif
127 #define E_CAP_SNAP_SB_KEY               "cap_snap_sb"
128 #define E_CAP_PROMISC_KEY               "cap_promisc"
129 #define E_CAP_PROMISC_KEY_ALL           "cap_promisc_all"
130 #define E_CAP_KEY_ALL                   "cap_all"
131 #ifdef HAVE_PCAP_CREATE
132 #define E_CAP_MONITOR_KEY               "cap_monitor"
133 #endif
134 #define E_CAP_PCAP_NG_KEY               "cap_pcap_ng"
135 #define E_CAP_FILT_KEY                  "cap_filter_te"
136 #define E_OPT_EDIT_DIALOG_PTR_KEY       "cap_edit_opt_dialog"
137 #define E_OPT_EDIT_CALLER_PTR_KEY       "cap_edit_opt_caller"
138 #define E_CAP_FILE_TE_KEY               "cap_file_te"
139 #define E_CAP_MULTI_FILES_ON_CB_KEY     "cap_multi_files_on_cb"
140 #define E_CAP_RING_FILESIZE_CB_KEY      "cap_ring_filesize_cb"
141 #define E_CAP_RING_FILESIZE_SB_KEY      "cap_ring_filesize_sb"
142 #define E_CAP_RING_FILESIZE_CBX_KEY     "cap_ring_filesize_cbx"
143 #define E_CAP_FILE_DURATION_CB_KEY      "cap_file_duration_cb"
144 #define E_CAP_FILE_DURATION_SB_KEY      "cap_file_duration_sb"
145 #define E_CAP_FILE_DURATION_CBX_KEY     "cap_file_duration_cbx"
146 #define E_CAP_RING_NBF_CB_KEY           "cap_ring_nbf_cb"
147 #define E_CAP_RING_NBF_SB_KEY           "cap_ring_nbf_sb"
148 #define E_CAP_RING_NBF_LB_KEY           "cap_ring_nbf_lb"
149 #define E_CAP_STOP_FILES_CB_KEY         "cap_stop_files_cb"
150 #define E_CAP_STOP_FILES_SB_KEY         "cap_stop_files_sb"
151 #define E_CAP_STOP_FILES_LB_KEY         "cap_stop_files_lb"
152 #define E_CAP_SYNC_KEY                  "cap_sync"
153 #define E_CAP_AUTO_SCROLL_KEY           "cap_auto_scroll"
154 #define E_CAP_HIDE_INFO_KEY             "cap_hide_info"
155 #define E_CAP_STOP_PACKETS_CB_KEY       "cap_stop_packets_cb"
156 #define E_CAP_STOP_PACKETS_SB_KEY       "cap_stop_packets_sb"
157 #define E_CAP_STOP_PACKETS_LB_KEY       "cap_stop_packets_lb"
158 #define E_CAP_STOP_FILESIZE_CB_KEY      "cap_stop_filesize_cb"
159 #define E_CAP_STOP_FILESIZE_SB_KEY      "cap_stop_filesize_sb"
160 #define E_CAP_STOP_FILESIZE_CBX_KEY     "cap_stop_filesize_cbx"
161 #define E_CAP_STOP_DURATION_CB_KEY      "cap_stop_duration_cb"
162 #define E_CAP_STOP_DURATION_SB_KEY      "cap_stop_duration_sb"
163 #define E_CAP_STOP_DURATION_CBX_KEY     "cap_stop_duration_cbx"
164 #define E_CAP_M_RESOLVE_KEY             "cap_m_resolve"
165 #define E_CAP_N_RESOLVE_KEY             "cap_n_resolve"
166 #define E_CAP_T_RESOLVE_KEY             "cap_t_resolve"
167 #define E_CAP_E_RESOLVE_KEY             "cap_e_resolve"
168
169 #define E_CAP_IFTYPE_CBX_KEY            "cap_iftype_cbx"
170 #ifdef HAVE_PCAP_REMOTE
171 #define E_CAP_IF_LIST_KEY               "cap_if_list"
172 #define E_CAP_DATATX_UDP_CB_KEY         "cap_datatx_udp_cb"
173 #define E_CAP_NOCAP_RPCAP_CB_KEY        "cap_nocap_rpcap_cb"
174 #define E_CAP_REMOTE_DIALOG_PTR_KEY     "cap_remote_dialog"
175 #define E_CAP_REMOTE_CALLER_PTR_KEY     "cap_remote_caller"
176 #define E_REMOTE_HOST_TE_KEY            "cap_remote_host"
177 #define E_REMOTE_PORT_TE_KEY            "cap_remote_port"
178 #define E_REMOTE_AUTH_NULL_KEY          "cap_remote_auth_null"
179 #define E_REMOTE_AUTH_PASSWD_KEY        "cap_remote_auth_passwd"
180 #define E_REMOTE_USERNAME_LB_KEY        "cap_remote_username_lb"
181 #define E_REMOTE_USERNAME_TE_KEY        "cap_remote_username_te"
182 #define E_REMOTE_PASSWD_LB_KEY          "cap_remote_passwd_lb"
183 #define E_REMOTE_PASSWD_TE_KEY          "cap_remote_passwd_te"
184 #define E_REMOTE_OK_BT_KEY              "cap_remote_ok_bt"
185 #define E_REMOTE_DEL_BT_KEY             "cap_remote_delete_bt"
186 #define E_CAP_CBX_IFTYPE_NOUPDATE_KEY   "cap_cbx_iftype_noupdate"
187 #define E_OPT_REMOTE_DIALOG_PTR_KEY     "cap_remote_opt_dialog"
188 #define E_OPT_REMOTE_CALLER_PTR_KEY     "cap_remote_opt_caller"
189 #endif
190 #ifdef HAVE_PCAP_SETSAMPLING
191 #define E_CAP_SAMP_NONE_RB_KEY          "cap_samp_none_rb"
192 #define E_CAP_SAMP_COUNT_RB_KEY         "cap_samp_count_rb"
193 #define E_CAP_SAMP_COUNT_SB_KEY         "cap_samp_count_sb"
194 #define E_CAP_SAMP_TIMER_RB_KEY         "cap_samp_timer_rb"
195 #define E_CAP_SAMP_TIMER_SB_KEY         "cap_samp_timer_sb"
196 #endif
197 #define E_CAP_PIPE_TE_KEY               "cap_pipe_te"
198 #define E_CAP_PIPE_L_KEY                "cap_pipe_list"
199 #define E_CAP_PIPE_DEL_KEY              "cap_pipe_delete_key"
200 #define E_CAP_LOCAL_L_KEY               "cap_local_list"
201 #define E_CAP_REMOTE_L_KEY              "cap_remote_list"
202
203 #define E_COMPILE_SW_SCROLLW_KEY        "compileScrolledWindowInterfaces"
204 #define E_COMPILE_TREE_VIEW_INTERFACES  "compileTreeViewInterfaces"
205
206 #define DUMMY_SNAPLENGTH                65535
207 #define DUMMY_NETMASK                   0xFF000000
208
209 enum
210 {
211   COL_NAME = 0,
212   COL_ADDRESS,
213   COL_LINK
214 } ;
215
216 /*
217  * Keep a static pointer to the current "Capture Options" window, if
218  * any, so that if somebody tries to do "Capture:Options" while there's
219  * already a "Capture Options" window up, we just pop up the existing
220  * one, rather than creating a new one.
221  * Also: Capture:Start obtains info from the "Capture Options" window
222  *       if it exists and if its creation is complete.
223  */
224 static GtkWidget *cap_open_w = NULL, *opt_edit_w = NULL, *ok_bt, *interface_management_w = NULL;
225 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
226 static GtkWidget *compile_bpf_w = NULL;
227 #endif
228 static gboolean   cap_open_complete;  /* valid only if cap_open_w != NULL */
229 static const gchar *pipe_name;
230 static const gchar *selected_name;
231 static GtkWidget *columns_menu_object;
232 static GtkUIManager *ui_manager_columns = NULL;
233 static GSList *popup_menu_list = NULL;
234 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
235 static GHashTable *compile_results = NULL;
236 static GtkWidget *all_compile_bt;
237 #endif
238
239 static gint marked_interface;
240 static gint marked_row;
241
242 #ifdef HAVE_PCAP_REMOTE
243 static GHashTable *remote_host_list=NULL;
244 static remote_options global_remote_opts;
245 static guint num_selected = 0;
246 #endif
247
248 static void
249 capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te);
250
251 static void
252 capture_prep_pipe_cb(GtkWidget *pipe_bt, GtkWidget *pipe_te);
253
254 static void
255 select_link_type_cb(GtkWidget *w, gpointer data);
256
257 #ifdef HAVE_PCAP_REMOTE
258 static void
259 capture_remote_cb(GtkWidget *w, gboolean focus_username);
260
261 static void
262 select_if_type_cb(GtkComboBox *iftype_cbx, gpointer data);
263
264 static void
265 fill_remote_list(void);
266 #endif
267
268 static void
269 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
270
271 static void
272 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
273
274 #ifdef HAVE_PCAP_CREATE
275 static void
276 capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp);
277 #endif
278
279 static gboolean
280 capture_dlg_prep(gpointer parent_w);
281
282 static GtkTreeModel*
283 create_and_fill_model(GtkTreeView *view);
284
285 static void
286 update_options_table(gint indx);
287
288 static void
289 update_properties_all(void);
290
291 static gboolean
292 query_tooltip_tree_view_cb (GtkWidget  *widget,
293                             gint        x,
294                             gint        y,
295                             gboolean    keyboard_tip,
296                             GtkTooltip *tooltip,
297                             gpointer    data);
298
299 static
300 gchar *col_index_to_name(gint indx)
301 {
302   gchar *col_name;
303
304   switch (indx)
305   {
306     case INTERFACE: col_name = g_strdup("INTERFACE");
307       break;
308     case LINK: col_name = g_strdup("LINK");
309       break;
310     case PMODE: col_name = g_strdup("PMODE");
311       break;
312     case SNAPLEN: col_name = g_strdup("SNAPLEN");
313       break;
314 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
315     case BUFFER: col_name = g_strdup("BUFFER");
316       break;
317 #endif
318 #if defined (HAVE_PCAP_CREATE)
319     case MONITOR: col_name = g_strdup("MONITOR");
320       break;
321 #endif
322     case FILTER: col_name = g_strdup("FILTER");
323       break;
324     default: return NULL;
325     }
326     return col_name;
327 }
328
329 static void
330 set_capture_column_visible(gchar *col, gboolean visible _U_)
331 {
332   GList *curr;
333   gchar *col_name;
334
335   if (visible && !prefs_capture_options_dialog_column_is_visible(col)) {
336     prefs.capture_columns = g_list_append(prefs.capture_columns, col);
337   } else if (!visible && prefs_capture_options_dialog_column_is_visible(col)) {
338     for (curr = g_list_first(prefs.capture_columns); curr; curr = g_list_next(curr)) {
339       col_name = (gchar *)curr->data;
340       if (col_name && (g_ascii_strcasecmp(col_name, col) == 0)) {
341         prefs.capture_columns = g_list_remove(prefs.capture_columns, curr->data);
342         break;
343       }
344     }
345   }
346 }
347
348 static void
349 toggle_visible_column_cb (GtkWidget *w _U_, gpointer data)
350 {
351   GtkTreeView       *view;
352   GtkTreeViewColumn *col;
353   gchar             *col_name;
354   gint               col_id;
355
356   col_id = GPOINTER_TO_INT(data);
357   view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
358   col = gtk_tree_view_get_column(GTK_TREE_VIEW(view), col_id);
359   col_name = col_index_to_name(col_id);
360   gtk_tree_view_column_set_visible(col, prefs_capture_options_dialog_column_is_visible(col_name)?FALSE:TRUE);
361   set_capture_column_visible(col_name, prefs_capture_options_dialog_column_is_visible(col_name)?FALSE:TRUE);
362 }
363
364
365 static void
366 set_all_columns_visible (void)
367 {
368   GtkTreeViewColumn *col;
369   int                col_id;
370   GtkTreeView       *view;
371   gchar             *name;
372
373   view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
374   for (col_id = 2; col_id < NUM_COLUMNS; col_id++) {
375     col = gtk_tree_view_get_column(GTK_TREE_VIEW(view), col_id);
376     gtk_tree_view_column_set_visible(col, TRUE);
377     if ((name = col_index_to_name(col_id)) != NULL) {
378       set_capture_column_visible(name, TRUE);
379     }
380   }
381
382   if (!prefs.gui_use_pref_save) {
383     prefs_main_write();
384   }
385
386   update_visible_columns_menu ();
387 }
388
389 static void
390 columns_activate_all_columns_cb(GtkAction *action _U_, gpointer user_data _U_)
391 {
392   set_all_columns_visible ();
393 }
394
395 void
396 update_visible_tree_view_columns(void)
397 {
398   GtkTreeView       *view;
399   gint               col_id;
400   GtkTreeViewColumn *col;
401
402   view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
403   for (col_id = 2; col_id < NUM_COLUMNS; col_id++) {
404     col = gtk_tree_view_get_column(GTK_TREE_VIEW(view), col_id);
405     gtk_tree_view_column_set_visible(col, prefs_capture_options_dialog_column_is_visible(col_index_to_name(col_id))?TRUE:FALSE);
406   }
407 }
408
409
410 void
411 update_visible_columns_menu (void)
412 {
413   GtkWidget *menu_columns, *menu_item;
414   GtkWidget *sub_menu;
415   gchar     *title;
416   gint       col_id;
417
418   menu_columns = gtk_ui_manager_get_widget(ui_manager_columns, "/ColumnsPopup/DisplayedColumns");
419   /* Debug */
420   if (! menu_columns){
421     fprintf (stderr, "Warning: couldn't find menu_columns path=/ColumnsPopup/DisplayedColumns");
422   }
423
424   sub_menu = gtk_menu_new();
425   gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_columns), sub_menu);
426
427   for (col_id = 2; col_id < NUM_COLUMNS; col_id++) {
428     title = col_index_to_name(col_id);
429     menu_item = gtk_check_menu_item_new_with_label(title);
430     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), prefs_capture_options_dialog_column_is_visible(title));
431     g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(toggle_visible_column_cb), GINT_TO_POINTER(col_id));
432     gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
433     gtk_widget_show (menu_item);
434   }
435     menu_item = gtk_menu_item_new();
436     gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
437     gtk_widget_show (menu_item);
438
439     menu_item = gtk_menu_item_new_with_label ("Display All");
440     gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
441     g_signal_connect(menu_item, "activate", G_CALLBACK(columns_activate_all_columns_cb), NULL);
442     gtk_widget_show (menu_item);
443 }
444
445 static void
446 columns_pref_cb(GtkAction *action _U_, gpointer user_data)
447 {
448     GtkWidget *widget = gtk_ui_manager_get_widget(ui_manager_columns, "/ColumnsPopup/ColumnPreferences");
449     prefs_page_cb( widget , user_data, PREFS_PAGE_CAPTURE);
450 }
451
452 static void
453 columns_hide_col_cb(GtkAction *action _U_, gpointer user_data _U_)
454 {
455   GtkTreeView       *view;
456   GtkTreeViewColumn *col;
457   gint               num;
458   gchar             *name;
459
460   view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
461   col = (GtkTreeViewColumn *)g_object_get_data(G_OBJECT(view), E_MCAPTURE_COLUMNS_COLUMN_KEY);
462   gtk_tree_view_column_set_visible(col, FALSE);
463   num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(col), E_MCAPTURE_COLUMNS_COL_KEY));
464   if ((name = col_index_to_name(num)) != NULL) {
465     set_capture_column_visible(name, FALSE);
466     if (!prefs.gui_use_pref_save) {
467       prefs_main_write();
468     }
469     update_visible_columns_menu ();
470   }
471 }
472
473 static const char *ui_desc_columns_menu_popup =
474 "<ui>\n"
475 "  <popup name='ColumnsPopup' action='PopupAction'>\n"
476 "     <menuitem name='ColumnPreferences' action='/Column Preferences'/>\n"
477 "     <menu name='DisplayedColumns' action='/Displayed Columns'>\n"
478 "       <menuitem name='Display All' action='/Displayed Columns/Display All'/>\n"
479 "     </menu>\n"
480 "     <menuitem name='HideColumn' action='/Hide Column'/>\n"
481 "  </popup>\n"
482 "</ui>\n";
483
484 static const GtkActionEntry columns_menu_popup_action_entries[] = {
485   { "/Column Preferences",              GTK_STOCK_PREFERENCES,              "Column Preferences...",    NULL,   NULL,   G_CALLBACK(columns_pref_cb) },
486   { "/Displayed Columns",               NULL,                               "Displayed Columns",        NULL,   NULL,   NULL },
487   { "/Displayed Columns/Display All",               NULL,                   "Display All",              NULL,   NULL,   G_CALLBACK(columns_activate_all_columns_cb) },
488   { "/Hide Column",                     NULL,                               "Hide Column",              NULL,   NULL,   G_CALLBACK(columns_hide_col_cb) },
489 };
490
491 #ifdef HAVE_PCAP_CREATE
492 static void
493 activate_monitor(GtkTreeViewColumn *tree_column, GtkCellRenderer *renderer,
494                  GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data);
495 #endif
496
497 void
498 init_columns_menu(void)
499 {
500   GtkActionGroup *columns_action_group;
501   GError         *error = NULL;
502
503   columns_menu_object = gtk_menu_new();
504   /* columns pop-up menu */
505   columns_action_group = gtk_action_group_new ("ColumnsPopUpMenuActionGroup");
506
507   gtk_action_group_add_actions (columns_action_group,            /* the action group */
508       (GtkActionEntry *)columns_menu_popup_action_entries,       /* an array of action descriptions */
509       G_N_ELEMENTS(columns_menu_popup_action_entries),           /* the number of entries */
510       columns_menu_object);                                      /* data to pass to the action callbacks */
511
512   ui_manager_columns = gtk_ui_manager_new ();
513   gtk_ui_manager_insert_action_group (ui_manager_columns,
514       columns_action_group,
515       0); /* the position at which the group will be inserted.  */
516
517   gtk_ui_manager_add_ui_from_string (ui_manager_columns, ui_desc_columns_menu_popup, -1, &error);
518   if (error != NULL)
519   {
520     fprintf (stderr, "Warning: building Packet List Heading Pop-Up failed: %s\n", error->message);
521     g_error_free (error);
522     error = NULL;
523   }
524
525   g_object_set_data(G_OBJECT(columns_menu_object), PM_COLUMNS_KEY,
526       gtk_ui_manager_get_widget(ui_manager_columns, "/ColumnsPopup"));
527
528   popup_menu_list = g_slist_append((GSList *)popup_menu_list, ui_manager_columns);
529 }
530
531 /* stop the currently running capture */
532 void
533 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
534 {
535 #ifdef HAVE_AIRPCAP
536   if (airpcap_if_active)
537     airpcap_set_toolbar_stop_capture(airpcap_if_active);
538 #endif
539
540   capture_stop(&global_capture_opts);
541 }
542
543 /* restart (stop - delete old file - start) running capture */
544 void
545 capture_restart_cb(GtkWidget *w _U_, gpointer d _U_)
546 {
547 #ifdef HAVE_AIRPCAP
548   if (airpcap_if_active)
549     airpcap_set_toolbar_start_capture(airpcap_if_active);
550 #endif
551
552   capture_restart(&global_capture_opts);
553 }
554
555 enum cfc_state_t {
556   CFC_PENDING,
557   CFC_UNKNOWN,
558   CFC_VALID,
559   CFC_INVALID
560 };
561
562 typedef struct capture_filter_check {
563   enum cfc_state_t  state;
564   gchar            *filter_text;
565   GtkWidget        *filter_te;
566   int               dlt;
567 } capture_filter_check_t;
568
569 /* Valid states:
570  *
571  * Idle: filter_text = NULL, state = ?
572  * Pending: filter_text != NULL, state = CFC_PENDING
573  * Unknown: filter_text != NULL, state = CFC_UNKNOWN
574  * Known: filter_text != NULL, state = CFC_VALID || CFC_INVALID
575  *
576  * We assume that only one text entry is active at a time.
577  */
578
579 /* We could make this smarter by caching results */
580 capture_filter_check_t cfc_data;
581
582 static GMutex *pcap_compile_mtx;
583 static GCond *cfc_data_cond;
584 static GMutex *cfc_data_mtx;
585
586 #if 0
587 #define DEBUG_SYNTAX_CHECK(state1, state2) g_warning("CF state %s -> %s : %s", state1, state2, cfc_data.filter_text)
588 #else
589 #define DEBUG_SYNTAX_CHECK(state1, state2)
590 #endif
591
592 static void *
593 check_capture_filter_syntax(void *data _U_) {
594   struct bpf_program fcode;
595   int                pc_err;
596
597   while (1) {
598     g_mutex_lock(cfc_data_mtx);
599     while (!cfc_data.filter_text || cfc_data.state != CFC_PENDING) {
600       /* Do we really need to use a mutex here? We only have one thread... */
601       g_cond_wait(cfc_data_cond, cfc_data_mtx);
602     }
603     cfc_data.state = CFC_UNKNOWN;
604     DEBUG_SYNTAX_CHECK("pending", "unknown");
605
606     g_mutex_unlock(cfc_data_mtx);
607     g_mutex_lock(pcap_compile_mtx);
608
609     /* pcap_compile_nopcap will not alter the filter string, so the (char *) cast is "safe" */
610     pc_err = pcap_compile_nopcap(DUMMY_SNAPLENGTH /* use a dummy snaplength for syntax-checking */,
611             cfc_data.dlt, &fcode, cfc_data.filter_text, 1 /* Do optimize */,
612             DUMMY_NETMASK /* use a dummy netmask for syntax-checking */);
613
614     g_mutex_unlock(pcap_compile_mtx);
615     g_mutex_lock(cfc_data_mtx);
616
617     if (cfc_data.state == CFC_UNKNOWN) { /* No more input came in */
618       if (pc_err) {
619         DEBUG_SYNTAX_CHECK("unknown", "known bad");
620         cfc_data.state = CFC_INVALID;
621       } else {
622         DEBUG_SYNTAX_CHECK("unknown", "known good");
623         cfc_data.state = CFC_VALID;
624       }
625     }
626     g_mutex_unlock(cfc_data_mtx);
627   }
628   return NULL;
629 }
630
631 static gboolean
632 update_capture_filter_te(gpointer data _U_) {
633
634   g_mutex_lock(cfc_data_mtx);
635
636   if (cfc_data.filter_text && cfc_data.filter_te) {
637     if (cfc_data.state == CFC_VALID) {
638       colorize_filter_te_as_valid(cfc_data.filter_te);
639     } else if (cfc_data.state == CFC_INVALID) {
640       colorize_filter_te_as_invalid(cfc_data.filter_te);
641     } else {
642       colorize_filter_te_as_empty(cfc_data.filter_te);
643     }
644
645     if (cfc_data.state == CFC_VALID || cfc_data.state == CFC_INVALID) {
646         DEBUG_SYNTAX_CHECK("known", "idle");
647       /* Reset the current state to idle. */
648       if (cfc_data.filter_text != NULL) {
649         g_free(cfc_data.filter_text);
650       }
651       cfc_data.filter_text = NULL;
652       cfc_data.state = CFC_PENDING;
653     }
654   }
655   g_mutex_unlock(cfc_data_mtx);
656   return TRUE;
657 }
658
659 /** Initialize background capture filter syntax checking
660  */
661 void capture_filter_init(void) {
662   cfc_data.filter_text = NULL;
663   cfc_data.filter_te   = NULL;
664   cfc_data.state = CFC_PENDING;
665
666 #if GLIB_CHECK_VERSION(2,31,0)
667   pcap_compile_mtx = g_new(GMutex,1);
668   g_mutex_init(pcap_compile_mtx);
669   cfc_data_cond = g_new(GCond,1);
670   g_cond_init(cfc_data_cond);
671   cfc_data_mtx = g_new(GMutex,1);
672   g_mutex_init(cfc_data_mtx);
673   g_thread_new("Capture filter syntax", check_capture_filter_syntax, NULL);
674 #else
675   pcap_compile_mtx = g_mutex_new();
676   cfc_data_cond = g_cond_new();
677   cfc_data_mtx = g_mutex_new();
678   g_thread_create(check_capture_filter_syntax, NULL, FALSE, NULL);
679 #endif
680
681   g_timeout_add(200, update_capture_filter_te, NULL);
682 }
683
684 static void
685 update_filter_string(gchar *name, gchar *text)
686 {
687   GtkTreeIter   iter;
688   GtkTreeView  *if_cb;
689   GtkTreeModel *model;
690   gchar        *name_str;
691
692   if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
693   model = gtk_tree_view_get_model(if_cb);
694   gtk_tree_model_get_iter_first(model, &iter);
695   do {
696     gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &name_str, -1);
697     if (strcmp(name, name_str) == 0) {
698       gtk_list_store_set (GTK_LIST_STORE(model), &iter, FILTER, g_strdup(text), -1);
699       break;
700     }
701   } while (gtk_tree_model_iter_next(model, &iter));
702 }
703
704 static void
705 capture_all_filter_check_syntax_cb(GtkWidget *w _U_, gpointer user_data _U_)
706 {
707   GtkWidget *filter_cm, *filter_te;
708   gchar     *filter_text = NULL;
709   guint      i;
710
711   filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY);
712
713   if (!filter_cm)
714     return;
715
716   filter_te = gtk_bin_get_child(GTK_BIN(filter_cm));
717
718   if (!filter_te)
719     return;
720
721   if (global_capture_opts.num_selected > 0) {
722     interface_t device;
723
724     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
725       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
726       if (!device.selected) {
727         continue;
728       }
729       if (device.active_dlt == -1) {
730         colorize_filter_te_as_empty(filter_te);
731         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The link type of interface %s was not specified.", device.name);
732         continue;  /* Programming error: somehow managed to select an "unsupported" entry */
733       }
734       filter_text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(filter_cm));
735       if (strlen(filter_text) == 0) {
736         colorize_filter_te_as_empty(filter_te);
737         if (strlen(device.cfilter) == 1) {
738           g_array_remove_index(global_capture_opts.all_ifaces, i);
739           device.cfilter = g_strdup(filter_text);
740           g_array_insert_val(global_capture_opts.all_ifaces, i, device);
741           update_filter_string(device.name, filter_text);
742         }
743         g_free(filter_text);
744         continue;
745       }
746       g_assert(filter_text != NULL);
747       g_array_remove_index(global_capture_opts.all_ifaces, i);
748       device.cfilter = g_strdup(filter_text);
749       g_array_insert_val(global_capture_opts.all_ifaces, i, device);
750       g_mutex_lock(cfc_data_mtx);
751       /* Ruthlessly clobber the current state. */
752       g_free(cfc_data.filter_text);
753       cfc_data.dlt = device.active_dlt;
754       cfc_data.filter_text = filter_text;
755       cfc_data.filter_te = filter_te;
756       cfc_data.state = CFC_PENDING;
757       DEBUG_SYNTAX_CHECK("?", "pending");
758       g_cond_signal(cfc_data_cond);
759       g_mutex_unlock(cfc_data_mtx);
760       update_filter_string(device.name, filter_text);
761     }
762   }
763 }
764
765 static void
766 capture_filter_check_syntax_cb(GtkWidget *w _U_, gpointer user_data _U_)
767 {
768   GtkWidget *filter_cm, *filter_te, *linktype_combo_box;
769   gchar     *filter_text;
770   gpointer   dlt_ptr;
771
772   filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY);
773   if (!filter_cm)
774     return;
775   filter_te = gtk_bin_get_child(GTK_BIN(filter_cm));
776   if (!filter_te)
777     return;
778
779   linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
780
781   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &dlt_ptr)) {
782     /*
783      * There is no guarantee that we will even know the list of link-layer
784      * header types; we will not have it if, for example, we have a named
785      * pipe rather than an interface, as a named pipe doesn't *have* a
786      * link-layer header type until the capture is started and the
787      * pcap file header or pcap-ng interface description block is
788      * written, and we can't wait for that.  We won't have it if we can't
789      * open the interface, either.
790      *
791      * We also won't have an active pointer, even if we have the list of
792      * link-layer header types, if none of the types are supported.
793      *
794      * Just mark it as empty, as a way of saying "damned if I know whether
795      * this filter is valid".
796      */
797     colorize_filter_te_as_empty(filter_te);
798     return;
799   }
800   if ((cfc_data.dlt = GPOINTER_TO_INT(dlt_ptr)) == -1) {
801     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
802   }
803
804   filter_text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(filter_cm));
805
806   if (strlen(filter_text) == 0) {
807     colorize_filter_te_as_empty(filter_te);
808     g_free(filter_text);
809     return;
810   }
811
812   g_mutex_lock(cfc_data_mtx);
813   /* Ruthlessly clobber the current state. */
814   if (cfc_data.filter_text != NULL) {
815     g_free(cfc_data.filter_text);
816   }
817   cfc_data.filter_text = filter_text;
818   cfc_data.filter_te = filter_te;
819   cfc_data.state = CFC_PENDING;
820   DEBUG_SYNTAX_CHECK("?", "pending");
821   g_cond_signal(cfc_data_cond);
822   g_mutex_unlock(cfc_data_mtx);
823 }
824
825 static void
826 capture_filter_destroy_cb(GtkWidget *w _U_, gpointer user_data _U_)
827 {
828   g_mutex_lock(cfc_data_mtx);
829   /* Reset the current state to idle. */
830   if (cfc_data.filter_text != NULL) {
831     g_free(cfc_data.filter_text);
832   }
833   cfc_data.filter_text = NULL;
834   cfc_data.filter_te = NULL;
835   cfc_data.state = CFC_PENDING;
836   g_mutex_unlock(cfc_data_mtx);
837 }
838
839 #define TIME_UNIT_SECOND    0
840 #define TIME_UNIT_MINUTE    1
841 #define TIME_UNIT_HOUR      2
842 #define TIME_UNIT_DAY       3
843 #define MAX_TIME_UNITS 4
844 static const char *time_unit_name[MAX_TIME_UNITS] = {
845   "second(s)",
846   "minute(s)",
847   "hour(s)",
848   "day(s)",
849 };
850
851 /* create one of the duration options */
852 /* (and select the matching unit depending on the given value) */
853 static GtkWidget *time_unit_combo_box_new(guint32 value) {
854   GtkWidget *unit_combo_box;
855   int        i;
856
857   unit_combo_box = gtk_combo_box_text_new ();
858   for (i = 0; i < MAX_TIME_UNITS; i++) {
859     gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (unit_combo_box), time_unit_name[i]);
860   }
861   /* the selected combo_box item can't be changed, once the combo_box
862      is created, so set the matching combo_box item now */
863   /* days */
864   if (value >= 60 * 60 * 24) {
865     gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_DAY);
866   } else {
867     /* hours */
868     if (value >= 60 * 60) {
869       gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_HOUR);
870     } else {
871       /* minutes */
872       if (value >= 60) {
873         gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_MINUTE);
874       } else {
875         /* seconds */
876         gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_SECOND);
877       }
878     }
879   }
880   return unit_combo_box;
881 }
882
883 /* convert time value from raw to displayed (e.g. 60s -> 1min) */
884 static guint32 time_unit_combo_box_convert_value(
885 guint32 value)
886 {
887   /* days */
888   if (value >= 60 * 60 * 24) {
889     return value / (60 * 60 * 24);
890   }
891
892   /* hours */
893   if (value >= 60 * 60) {
894     return value / (60 * 60);
895   }
896
897   /* minutes */
898   if (value >= 60) {
899     return value / 60;
900   }
901
902   /* seconds */
903   return value;
904 }
905
906 /* get raw value from unit and value fields */
907 static guint32 time_unit_combo_box_get_value(
908 GtkWidget *unit_combo_box,
909 guint32 value)
910 {
911   int unit;
912
913   unit = gtk_combo_box_get_active (GTK_COMBO_BOX(unit_combo_box));
914
915   switch(unit) {
916   case(TIME_UNIT_SECOND):
917     return value;
918   case(TIME_UNIT_MINUTE):
919     return value * 60;
920   case(TIME_UNIT_HOUR):
921     return value * 60 * 60;
922   case(TIME_UNIT_DAY):
923     return value * 60 * 60 * 24;
924   default:
925     g_assert_not_reached();
926     return 0;
927   }
928 }
929
930
931 #define SIZE_UNIT_KILOBYTES 0
932 #define SIZE_UNIT_MEGABYTES 1
933 #define SIZE_UNIT_GIGABYTES 2
934 #define MAX_SIZE_UNITS 3
935 static const char *size_unit_name[MAX_SIZE_UNITS] = {
936   "kilobyte(s)",
937   "megabyte(s)",
938   "gigabyte(s)",
939 };
940
941 /* create one of the size options */
942 /* (and select the matching unit depending on the given value) */
943 static GtkWidget *size_unit_combo_box_new(guint32 value) {
944   GtkWidget *unit_combo_box;
945   int        i;
946
947   unit_combo_box=gtk_combo_box_text_new();
948   for (i=0; i<MAX_SIZE_UNITS; i++){
949     gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (unit_combo_box), size_unit_name[i]);
950   }
951   /* the selected combo_box item can't be changed, once the combo_box
952      is created, so set the matching combo_box item now */
953   /* gigabytes */
954   if (value >= 1024 * 1024) {
955     gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), SIZE_UNIT_GIGABYTES);
956   } else {
957     /* megabytes */
958     if (value >= 1024) {
959       gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), SIZE_UNIT_MEGABYTES);
960     } else {
961       /* kilobytes */
962       gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), SIZE_UNIT_KILOBYTES);
963     }
964   }
965   return unit_combo_box;
966 }
967
968 /* convert size value from raw to displayed (e.g. 1024 Bytes -> 1 KB) */
969 static guint32 size_unit_combo_box_set_value(
970 guint32 value)
971 {
972   /* gigabytes */
973   if (value >= 1024 * 1024) {
974     return value / (1024 * 1024);
975   }
976
977   /* megabytes */
978   if (value >= 1024) {
979     return value / (1024);
980   }
981
982   /* kilobytes */
983   return value;
984 }
985
986 /* get raw value from unit and value fields */
987 static guint32 size_unit_combo_box_convert_value(
988   GtkWidget *unit_combo_box,
989 guint32 value)
990 {
991   int unit;
992
993   unit = gtk_combo_box_get_active (GTK_COMBO_BOX(unit_combo_box));
994
995   switch(unit) {
996   case(SIZE_UNIT_KILOBYTES):
997     return value;
998   case(SIZE_UNIT_MEGABYTES):
999     if (value > G_MAXINT / 1024) {
1000       return 0;
1001     } else {
1002       return value * 1024;
1003     }
1004   case(SIZE_UNIT_GIGABYTES):
1005     if (value > G_MAXINT / (1024 * 1024)) {
1006       return 0;
1007     } else {
1008       return value * 1024 * 1024;
1009     }
1010   default:
1011     g_assert_not_reached();
1012     return 0;
1013   }
1014 }
1015
1016 #ifdef HAVE_AIRPCAP
1017 /*
1018  * Sets the toolbar before calling the advanced dialog with for the right interface
1019  */
1020 static void
1021 options_airpcap_advanced_cb(GtkWidget *w, gpointer d)
1022 {
1023   int *from_widget;
1024
1025   from_widget  = (gint*)g_malloc(sizeof(gint));
1026   *from_widget = AIRPCAP_ADVANCED_FROM_OPTIONS;
1027   g_object_set_data(G_OBJECT(wireless_tb),AIRPCAP_ADVANCED_FROM_KEY,from_widget);
1028
1029   airpcap_if_active = airpcap_if_selected;
1030   airpcap_enable_toolbar_widgets(wireless_tb,FALSE);
1031   display_airpcap_advanced_cb(w,d);
1032 }
1033 #endif
1034
1035 #ifdef HAVE_PCAP_REMOTE
1036 /* PCAP interface type menu item */
1037 struct iftype_info {
1038   capture_source  id;
1039   const char     *name;
1040 };
1041
1042 /* List of available types of PCAP interface */
1043 static struct iftype_info iftype[] = {
1044   { CAPTURE_IFLOCAL, "Local" },
1045   { CAPTURE_IFREMOTE, "Remote..." }
1046 };
1047
1048 #define REMOTE_HOST_START ((sizeof(iftype) / sizeof(iftype[0])) + 1)
1049 #define REMOTE_HOST_SEPARATOR "---"
1050
1051 static void
1052 iftype_combo_box_add_remote_separators (GtkWidget *iftype_cbx)
1053 {
1054   gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(iftype_cbx), REMOTE_HOST_SEPARATOR);
1055   gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(iftype_cbx), "Clear list");
1056 }
1057
1058 static void
1059 iftype_combo_box_add (GtkWidget *iftype_cbx, interface_t *device)
1060 {
1061   GtkTreeModel *model;
1062   GtkTreeIter   iter;
1063   gboolean      create_new = FALSE;
1064   gchar        *string;
1065   guint         i, pos     = REMOTE_HOST_START;
1066   struct remote_host_info *rh;
1067
1068   rh = g_hash_table_lookup (remote_host_list, device->remote_opts.remote_host_opts.remote_host);
1069   if (!rh) {
1070     rh = g_malloc0 (sizeof (*rh));
1071     if (g_hash_table_size (remote_host_list) == 0) {
1072       iftype_combo_box_add_remote_separators (iftype_cbx);
1073     }
1074     gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(iftype_cbx), pos, device->remote_opts.remote_host_opts.remote_host);
1075     rh->remote_host = g_strdup (device->remote_opts.remote_host_opts.remote_host);
1076     create_new = TRUE;
1077   } else {
1078     model = gtk_combo_box_get_model(GTK_COMBO_BOX(iftype_cbx));
1079     if (gtk_tree_model_get_iter_first(model, &iter)) {
1080       /* Skip the first entries */
1081       for (i = 0; i < REMOTE_HOST_START; i++)
1082         gtk_tree_model_iter_next(model, &iter);
1083       do {
1084         gtk_tree_model_get(model, &iter, 0, &string, -1);
1085         if (string) {
1086           if (strcmp (device->remote_opts.remote_host_opts.remote_host, string) == 0) {
1087             /* Found match, show this position in combo box */
1088             g_free (string);
1089             break;
1090           }
1091           g_free (string);
1092         }
1093         pos++;
1094       } while (gtk_tree_model_iter_next(model, &iter));
1095     }
1096
1097     g_free (rh->remote_port);
1098     g_free (rh->auth_username);
1099     g_free (rh->auth_password);
1100   }
1101
1102   rh->remote_port = g_strdup (device->remote_opts.remote_host_opts.remote_port);
1103   rh->auth_type = device->remote_opts.remote_host_opts.auth_type;
1104   rh->auth_username = g_strdup (device->remote_opts.remote_host_opts.auth_username);
1105   rh->auth_password = g_strdup (device->remote_opts.remote_host_opts.auth_password);
1106
1107   if (create_new) {
1108     g_hash_table_insert (remote_host_list, g_strdup (device->remote_opts.remote_host_opts.remote_host), rh);
1109   }
1110
1111   g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_NOUPDATE_KEY, GINT_TO_POINTER(1));
1112   gtk_combo_box_set_active(GTK_COMBO_BOX(iftype_cbx), pos);
1113   g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_NOUPDATE_KEY, GINT_TO_POINTER(0));
1114 }
1115
1116 static void
1117 iftype_combo_box_add_remote_host (gpointer key, gpointer value _U_, gpointer user_data)
1118 {
1119   gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(user_data), REMOTE_HOST_START, key);
1120
1121 /*  if (g_array_index(global_capture_opts.ifaces, interface_options, 0).src_type == CAPTURE_IFREMOTE) {*/
1122     /* Ensure we select the correct entry */
1123  /*   if (strcmp ((char *)key, g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_host) == 0) {
1124       gtk_combo_box_set_active(GTK_COMBO_BOX(user_data), REMOTE_HOST_START);
1125     }
1126   }*/
1127 }
1128
1129 /* Fill the menu of available types of interfaces */
1130 static GtkWidget *
1131 iftype_combo_box_new(void)
1132 {
1133   GtkWidget *iftype_cbx;
1134
1135   iftype_cbx = gtk_combo_box_text_new_with_entry();
1136
1137  /* for (i = 0; i < sizeof(iftype) / sizeof(iftype[0]); i++) {
1138     gtk_combo_box_text_append_text(GTK_COMBO_BOX(iftype_cbx), iftype[i].name);
1139   }*/
1140
1141   if (g_hash_table_size (remote_host_list) > 0) {
1142     /* Add remote hosts */
1143     g_hash_table_foreach (remote_host_list, iftype_combo_box_add_remote_host, iftype_cbx);
1144     iftype_combo_box_add_remote_separators (iftype_cbx);
1145   }
1146
1147   g_signal_connect(iftype_cbx, "changed", G_CALLBACK(select_if_type_cb), NULL);
1148
1149   return iftype_cbx;
1150 }
1151
1152 static gboolean
1153 iftype_combo_is_separator (GtkTreeModel *model, GtkTreeIter *iter, gpointer data _U_)
1154 {
1155   gboolean  result = FALSE;
1156   gchar    *string;
1157
1158   gtk_tree_model_get(model, iter, 0, &string, -1);
1159   if (string) {
1160     result = !strcmp (string, REMOTE_HOST_SEPARATOR);
1161     g_free (string);
1162   }
1163
1164   return result;
1165
1166 }
1167 #endif
1168
1169 #ifdef HAVE_PCAP_REMOTE
1170 static void
1171 error_list_remote_interface_cb (gpointer dialog _U_, gint btn _U_, gpointer data)
1172 {
1173   capture_remote_cb(GTK_WIDGET(data), FALSE);
1174 }
1175
1176 static void
1177 insert_new_rows(GList *list)
1178 {
1179   interface_t        device;
1180   GtkTreeIter        iter;
1181   GList             *if_entry;
1182   if_info_t         *if_info;
1183   char              *if_string = NULL, *temp = NULL, *snaplen_string;
1184   gchar             *descr;
1185   if_capabilities_t *caps;
1186   gint               linktype_count;
1187   gboolean           monitor_mode;
1188   GSList            *curr_addr;
1189   int                ips       = 0;
1190   guint              i;
1191   if_addr_t         *addr;
1192   GList             *lt_entry;
1193   data_link_info_t  *data_link_info;
1194   gchar             *str       = NULL, *link_type_name = NULL;
1195   gboolean           found     = FALSE;
1196   GString           *ip_str;
1197   GtkTreeView       *if_cb;
1198   GtkTreeModel      *model;
1199   link_row          *linkr     = NULL;
1200
1201   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
1202   model = gtk_tree_view_get_model(if_cb);
1203   /* Scan through the list and build a list of strings to display. */
1204   for (if_entry = g_list_first(list); if_entry != NULL; if_entry = g_list_next(if_entry)) {
1205     if_info = (if_info_t *)if_entry->data;
1206 #ifdef HAVE_PCAP_REMOTE
1207     add_interface_to_remote_list(if_info);
1208 #endif
1209     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1210       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1211       if (strcmp(device.name, if_info->name) == 0) {
1212         found = TRUE;
1213         break;
1214       }
1215     }
1216     if (found) {
1217       found = FALSE;
1218       continue;
1219     }
1220     ip_str = g_string_new("");
1221     str = "";
1222     ips = 0;
1223     device.name = g_strdup(if_info->name);
1224     /* Is this interface hidden and, if so, should we include it
1225        anyway? */
1226     descr = capture_dev_user_descr_find(if_info->name);
1227     if (descr != NULL) {
1228       /* Yes, we have a user-supplied description; use it. */
1229       if_string = g_strdup_printf("%s: %s", descr, if_info->name);
1230       g_free(descr);
1231     } else {
1232       /* No, we don't have a user-supplied description; did we get
1233          one from the OS or libpcap? */
1234       if (if_info->vendor_description != NULL) {
1235         /* Yes - use it. */
1236         if_string = g_strdup_printf("%s: %s", if_info->vendor_description, if_info->name);
1237       } else {
1238         /* No. */
1239         if_string = g_strdup(if_info->name);
1240       }
1241     } /* else descr != NULL */
1242     if (if_info->loopback) {
1243       device.display_name = g_strdup_printf("%s (loopback)", if_string);
1244     } else {
1245       device.display_name = g_strdup(if_string);
1246     }
1247 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1248     if ((device.buffer = capture_dev_user_buffersize_find(if_string)) == -1) {
1249       device.buffer = global_capture_opts.default_options.buffer_size;
1250     }
1251 #endif
1252     if ((device.pmode = capture_dev_user_pmode_find(if_string)) == -1) {
1253       device.pmode = global_capture_opts.default_options.promisc_mode;
1254     }
1255     device.has_snaplen = global_capture_opts.default_options.has_snaplen;
1256     if ((device.snaplen = capture_dev_user_snaplen_find(if_string)) == -1) {
1257       device.snaplen = global_capture_opts.default_options.snaplen;
1258     }
1259     device.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
1260     monitor_mode = prefs_capture_device_monitor_mode(if_string);
1261     caps = capture_get_if_capabilities(if_string, monitor_mode, NULL);
1262     gtk_list_store_append (GTK_LIST_STORE(model), &iter);
1263     for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
1264       if (ips != 0) {
1265         g_string_append(ip_str, "\n");
1266       }
1267       addr = (if_addr_t *)curr_addr->data;
1268
1269       switch (addr->ifat_type) {
1270         case IF_AT_IPv4:
1271           g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
1272           break;
1273         case IF_AT_IPv6:
1274           g_string_append(ip_str,  ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
1275           break;
1276         default:
1277           /* In case we add non-IP addresses */
1278           break;
1279       }
1280     } /* for curr_addr */
1281     linktype_count = 0;
1282     device.links = NULL;
1283     if (caps != NULL) {
1284 #ifdef HAVE_PCAP_CREATE
1285       device.monitor_mode_enabled = monitor_mode;
1286       device.monitor_mode_supported = caps->can_set_rfmon;
1287 #endif
1288       for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
1289         data_link_info = (data_link_info_t *)lt_entry->data;
1290         linkr = (link_row *)g_malloc(sizeof(link_row));
1291         if (data_link_info->description != NULL) {
1292           str = g_strdup_printf("%s", data_link_info->description);
1293           linkr->dlt = data_link_info->dlt;
1294         } else {
1295           str = g_strdup_printf("%s (not supported)", data_link_info->name);
1296           linkr->dlt = -1;
1297         }
1298         if (linktype_count == 0) {
1299           link_type_name = g_strdup(str);
1300           device.active_dlt = data_link_info->dlt;
1301         }
1302         linkr->name = g_strdup(str);
1303         g_free(str);
1304         device.links = g_list_append(device.links, linkr);
1305         linktype_count++;
1306       } /* for link_types */
1307     } else {
1308 #if defined(HAVE_PCAP_CREATE)
1309       device.monitor_mode_enabled = FALSE;
1310       device.monitor_mode_supported = FALSE;
1311 #endif
1312       device.active_dlt = -1;
1313       link_type_name = g_strdup("default");
1314     }
1315     device.addresses = g_strdup(ip_str->str);
1316     device.no_addresses = ips;
1317     if (ips == 0) {
1318       temp = g_strdup_printf("<b>%s</b>", device.display_name);
1319     } else {
1320       temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", device.display_name, device.addresses);
1321     }
1322 #ifdef HAVE_PCAP_REMOTE
1323     device.remote_opts.src_type= global_remote_opts.src_type;
1324     if (device.remote_opts.src_type == CAPTURE_IFREMOTE) {
1325       device.local = FALSE;
1326     }
1327     device.remote_opts.remote_host_opts.remote_host = g_strdup(global_remote_opts.remote_host_opts.remote_host);
1328     device.remote_opts.remote_host_opts.remote_port = g_strdup(global_remote_opts.remote_host_opts.remote_port);
1329     device.remote_opts.remote_host_opts.auth_type = global_remote_opts.remote_host_opts.auth_type;
1330     device.remote_opts.remote_host_opts.auth_username = g_strdup(global_remote_opts.remote_host_opts.auth_username);
1331     device.remote_opts.remote_host_opts.auth_password = g_strdup(global_remote_opts.remote_host_opts.auth_password);
1332     device.remote_opts.remote_host_opts.datatx_udp = global_remote_opts.remote_host_opts.datatx_udp;
1333     device.remote_opts.remote_host_opts.nocap_rpcap = global_remote_opts.remote_host_opts.nocap_rpcap;
1334     device.remote_opts.remote_host_opts.nocap_local = global_remote_opts.remote_host_opts.nocap_local;
1335 #else
1336     device.local = TRUE;
1337 #endif
1338 #ifdef HAVE_PCAP_SETSAMPLING
1339     device.remote_opts.sampling_method = global_remote_opts.sampling_method;
1340     device.remote_opts.sampling_param = global_remote_opts.sampling_param;
1341 #endif
1342     g_array_append_val(global_capture_opts.all_ifaces, device);
1343     if (device.has_snaplen) {
1344       snaplen_string = g_strdup_printf("%d", device.snaplen);
1345     } else {
1346       snaplen_string = g_strdup("default");
1347     }
1348
1349 #if defined(HAVE_PCAP_CREATE)
1350     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, device.buffer, MONITOR, "no",FILTER, "",-1);
1351 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
1352     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, device.buffer, FILTER, "",-1);
1353  #else
1354     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, link_type_name, PMODE, (device.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, -1);
1355 #endif
1356     g_string_free(ip_str, TRUE);
1357 #ifdef HAVE_PCAP_REMOTE
1358     add_interface_to_list(global_capture_opts.all_ifaces->len-1);
1359 #endif
1360   } /*for*/
1361   gtk_tree_view_set_model(GTK_TREE_VIEW(if_cb), model);
1362 }
1363 #endif
1364
1365 #ifdef HAVE_PCAP_REMOTE
1366 /* Retrieve the list of local or remote interfaces according to selected
1367  * options and re-fill interface name combobox */
1368 static void
1369 update_interface_list(void)
1370 {
1371   GtkWidget *iftype_cbx;
1372   GList     *if_list, *if_r_list;
1373   int        iftype_id, err;
1374   gchar     *err_str;
1375
1376   if (cap_open_w == NULL)
1377     return;
1378   iftype_cbx = (GtkWidget *)g_object_get_data(G_OBJECT(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY)), E_REMOTE_HOST_TE_KEY);
1379   iftype_id = CAPTURE_IFREMOTE;
1380   if (iftype_id >= CAPTURE_IFREMOTE) {
1381     if_r_list = get_remote_interface_list(global_remote_opts.remote_host_opts.remote_host,
1382                                         global_remote_opts.remote_host_opts.remote_port,
1383                                         global_remote_opts.remote_host_opts.auth_type,
1384                                         global_remote_opts.remote_host_opts.auth_username,
1385                                         global_remote_opts.remote_host_opts.auth_password,
1386                                         &err, &err_str);
1387
1388     if_list = if_r_list;
1389   } else {
1390     if_list = capture_interface_list(&err, &err_str);   /* Warning: see capture_prep_cb() */
1391     g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IF_LIST_KEY, NULL);
1392   }
1393
1394   if (if_list == NULL &&
1395       (err == CANT_GET_INTERFACE_LIST || err == DONT_HAVE_PCAP)) {
1396     gpointer dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
1397     g_free(err_str);
1398
1399     if (iftype_id >= CAPTURE_IFREMOTE) {
1400       /* Fall back to previous interface list */
1401       simple_dialog_set_cb(dialog, error_list_remote_interface_cb, iftype_cbx);
1402       return;
1403     }
1404   } else if (iftype_id == CAPTURE_IFREMOTE) {
1405     /* New remote interface */
1406     insert_new_rows(if_list);
1407     refresh_non_local_interface_lists();
1408   }
1409 }
1410
1411 /* User changed an interface entry of "Remote interface" dialog */
1412 static void
1413 capture_remote_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1414 {
1415   GtkWidget *auth_passwd_rb,
1416             *username_lb, *username_te,
1417             *passwd_lb, *passwd_te;
1418   gboolean   state;
1419
1420   auth_passwd_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
1421                                                   E_REMOTE_AUTH_PASSWD_KEY);
1422   username_lb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
1423                                                E_REMOTE_USERNAME_LB_KEY);
1424   username_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
1425                                                E_REMOTE_USERNAME_TE_KEY);
1426   passwd_lb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_REMOTE_PASSWD_LB_KEY);
1427   passwd_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_REMOTE_PASSWD_TE_KEY);
1428
1429   state =  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auth_passwd_rb));
1430   gtk_widget_set_sensitive(GTK_WIDGET(username_lb), state);
1431   gtk_widget_set_sensitive(GTK_WIDGET(username_te), state);
1432   gtk_widget_set_sensitive(GTK_WIDGET(passwd_lb), state);
1433   gtk_widget_set_sensitive(GTK_WIDGET(passwd_te), state);
1434 }
1435
1436 /* user requested to destroy the dialog */
1437 static void
1438 capture_remote_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1439 {
1440   g_object_set_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY, NULL);
1441 }
1442
1443 /* user requested to accept remote interface options */
1444 static void
1445 capture_remote_ok_cb(GtkWidget *win _U_, GtkWidget *remote_w)
1446 {
1447   GtkWidget *host_te, *port_te, *username_te, *passwd_te, *auth_passwd_rb;
1448   gchar     *hostname;
1449
1450   if (remote_w == NULL) {
1451     return;
1452   }
1453
1454   host_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_HOST_TE_KEY);
1455   hostname = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(host_te));
1456   port_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_PORT_TE_KEY);
1457   username_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w),
1458                                                E_REMOTE_USERNAME_TE_KEY);
1459   passwd_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_PASSWD_TE_KEY);
1460   auth_passwd_rb = (GtkWidget *) g_object_get_data(G_OBJECT(remote_w), E_REMOTE_AUTH_PASSWD_KEY);
1461   g_free(global_remote_opts.remote_host_opts.remote_host);
1462   global_remote_opts.remote_host_opts.remote_host = hostname;
1463   g_free(global_remote_opts.remote_host_opts.remote_port);
1464   global_remote_opts.remote_host_opts.remote_port = g_strdup(gtk_entry_get_text(GTK_ENTRY(port_te)));
1465   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auth_passwd_rb)))
1466     global_remote_opts.remote_host_opts.auth_type = CAPTURE_AUTH_PWD;
1467   else
1468     global_remote_opts.remote_host_opts.auth_type = CAPTURE_AUTH_NULL;
1469   g_free(global_remote_opts.remote_host_opts.auth_username);
1470   global_remote_opts.remote_host_opts.auth_username =
1471     g_strdup(gtk_entry_get_text(GTK_ENTRY(username_te)));
1472
1473   g_free(global_remote_opts.remote_host_opts.auth_password);
1474   global_remote_opts.remote_host_opts.auth_password =
1475     g_strdup(gtk_entry_get_text(GTK_ENTRY(passwd_te)));
1476
1477   window_destroy(GTK_WIDGET(remote_w));
1478   update_interface_list();
1479   fill_remote_list();
1480 }
1481
1482 static void
1483 capture_remote_cancel_cb(GtkWidget *win, gpointer data)
1484 {
1485   window_cancel_button_cb (win, data);
1486 }
1487
1488 static gboolean
1489 free_remote_host (gpointer key _U_, gpointer value, gpointer user _U_)
1490 {
1491   struct remote_host *rh = value;
1492
1493   g_free (rh->remote_host);
1494   g_free (rh->remote_port);
1495   g_free (rh->auth_username);
1496   g_free (rh->auth_password);
1497
1498   return TRUE;
1499 }
1500
1501 static void
1502 select_if_type_cb(GtkComboBox *iftype_cbx, gpointer data _U_)
1503 {
1504   gchar     *string;
1505   GtkWidget *port_te, *auth_rb, *user_te, *pass_te;
1506   GtkWidget *remote_w;
1507   struct remote_host *rh;
1508
1509   int new_iftype = gtk_combo_box_get_active(GTK_COMBO_BOX(iftype_cbx));
1510   gint num_remote = g_hash_table_size (remote_host_list);
1511
1512   if (new_iftype != -1 && new_iftype == num_remote+1) {
1513     g_hash_table_foreach_remove (remote_host_list, free_remote_host, NULL);
1514     num_remote += 2;
1515     while (num_remote--) { /* Remove separator lines and "Clear" item */
1516       gtk_combo_box_text_remove (GTK_COMBO_BOX_TEXT(iftype_cbx), num_remote);
1517     }
1518     remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY);
1519     window_destroy(GTK_WIDGET(remote_w));
1520     capture_remote_cb(GTK_WIDGET(iftype_cbx), FALSE);
1521   } else {
1522     string = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(iftype_cbx));
1523     rh = g_hash_table_lookup (remote_host_list, string);
1524     g_free (string);
1525     if (rh) {
1526       remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY);
1527       port_te = g_object_get_data(G_OBJECT(remote_w), E_REMOTE_PORT_TE_KEY);
1528       gtk_entry_set_text(GTK_ENTRY(port_te), rh->remote_port);
1529       auth_rb = g_object_get_data(G_OBJECT(remote_w), E_REMOTE_AUTH_PASSWD_KEY);
1530       if (rh->auth_type == CAPTURE_AUTH_PWD) {
1531         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_rb), TRUE);
1532       } else {
1533         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_rb), FALSE);
1534       }
1535       user_te = g_object_get_data(G_OBJECT(remote_w), E_REMOTE_USERNAME_TE_KEY);
1536       gtk_entry_set_text(GTK_ENTRY(user_te), rh->auth_username);
1537       pass_te = g_object_get_data(G_OBJECT(remote_w), E_REMOTE_PASSWD_TE_KEY);
1538       gtk_entry_set_text(GTK_ENTRY(pass_te), rh->auth_password);
1539     }
1540   }
1541 }
1542
1543 /* Show remote capture interface parameters dialog */
1544 static void
1545 capture_remote_cb(GtkWidget *w, gboolean focus_username)
1546 {
1547   GtkWidget *remote_w,
1548             *main_vb, *host_grid,
1549             *host_lb, *host_te, *port_lb, *port_te,
1550             *auth_fr, *auth_vb,
1551             *auth_null_rb, *auth_passwd_rb, *auth_passwd_grid,
1552             *user_lb, *user_te, *passwd_lb, *passwd_te,
1553             *bbox, *ok_but, *cancel_bt;
1554   gchar     *title;
1555   GSList    *auth_group;
1556
1557   title = create_user_window_title("Wireshark: Remote Interface");
1558   remote_w = dlg_window_new(title);
1559   g_object_set_data(G_OBJECT(remote_w), E_CAP_REMOTE_CALLER_PTR_KEY, interface_management_w);
1560   g_object_set_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY, remote_w);
1561   g_free(title);
1562
1563   main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
1564   gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
1565   gtk_container_add(GTK_CONTAINER(remote_w), main_vb);
1566
1567   /* Host/port table */
1568   host_grid = ws_gtk_grid_new();
1569   ws_gtk_grid_set_row_spacing(GTK_GRID(host_grid), DLG_LABEL_SPACING);
1570   ws_gtk_grid_set_column_spacing(GTK_GRID(host_grid), DLG_UNRELATED_SPACING);
1571   gtk_box_pack_start(GTK_BOX(main_vb), host_grid, FALSE, FALSE, 0);
1572
1573   /* Host row */
1574   host_lb = gtk_label_new("Host:");
1575   ws_gtk_grid_attach_defaults(GTK_GRID (host_grid), host_lb, 0, 0, 1, 1);
1576
1577   host_te = iftype_combo_box_new();
1578   ws_gtk_grid_attach_defaults(GTK_GRID (host_grid), host_te, 1, 0, 1, 1);
1579
1580   /* Port row */
1581   port_lb = gtk_label_new("Port:");
1582   ws_gtk_grid_attach_defaults(GTK_GRID (host_grid), port_lb, 0, 1, 1, 1);
1583
1584   port_te = gtk_entry_new();
1585   gtk_widget_set_tooltip_text(port_te, "Enter the TCP port number used by RPCAP server at remote host "
1586                               "(leave it empty for default port number).");
1587   ws_gtk_grid_attach_defaults(GTK_GRID (host_grid), port_te, 1, 1, 1, 1);
1588
1589   /* Authentication options frame */
1590   auth_fr = gtk_frame_new("Authentication");
1591   gtk_box_pack_start(GTK_BOX (main_vb), auth_fr, TRUE, TRUE, 0);
1592
1593   auth_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
1594   gtk_container_set_border_width(GTK_CONTAINER(auth_vb), 5);
1595   gtk_container_add(GTK_CONTAINER(auth_fr), auth_vb);
1596
1597   auth_null_rb = gtk_radio_button_new_with_label(NULL,
1598                                                  "Null authentication");
1599   gtk_box_pack_start(GTK_BOX(auth_vb), auth_null_rb, TRUE, TRUE, 0);
1600
1601   auth_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(auth_null_rb));
1602   auth_passwd_rb = gtk_radio_button_new_with_label(auth_group,
1603                                                    "Password authentication");
1604   gtk_box_pack_start(GTK_BOX(auth_vb), auth_passwd_rb, TRUE, TRUE, 0);
1605   g_signal_connect(auth_passwd_rb, "toggled",
1606                    G_CALLBACK(capture_remote_adjust_sensitivity), remote_w);
1607
1608   auth_passwd_grid = ws_gtk_grid_new();
1609   ws_gtk_grid_set_row_spacing(GTK_GRID(auth_passwd_grid), DLG_LABEL_SPACING);
1610   ws_gtk_grid_set_column_spacing(GTK_GRID(auth_passwd_grid), DLG_UNRELATED_SPACING);
1611
1612   gtk_box_pack_start(GTK_BOX(auth_vb), auth_passwd_grid, FALSE, FALSE, 0);
1613
1614   user_lb = gtk_label_new("Username:");
1615   ws_gtk_grid_attach_defaults(GTK_GRID (auth_passwd_grid), user_lb, 0, 0, 1, 1);
1616
1617   user_te = gtk_entry_new();
1618   ws_gtk_grid_attach_defaults(GTK_GRID (auth_passwd_grid), user_te, 1, 0, 1, 1);
1619
1620   passwd_lb = gtk_label_new("Password:");
1621   ws_gtk_grid_attach_defaults(GTK_GRID (auth_passwd_grid), passwd_lb, 0, 1, 1, 1);
1622
1623   passwd_te = gtk_entry_new();
1624   gtk_entry_set_visibility(GTK_ENTRY(passwd_te), FALSE);
1625   ws_gtk_grid_attach_defaults(GTK_GRID (auth_passwd_grid), passwd_te, 1, 1, 1, 1);
1626
1627   /* Button row: "Start" and "Cancel" buttons */
1628   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
1629   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
1630
1631   ok_but = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
1632   gtk_widget_set_can_default(ok_but, TRUE);
1633   g_signal_connect(ok_but, "clicked", G_CALLBACK(capture_remote_ok_cb), remote_w);
1634   gtk_widget_set_tooltip_text(ok_but,
1635                        "Accept remote host parameters and lookup "
1636                        "remote interfaces.");
1637   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_OK_BT_KEY, ok_but);
1638   cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
1639   gtk_widget_set_tooltip_text(cancel_bt, "Cancel and exit dialog.");
1640   window_set_cancel_button(remote_w, cancel_bt, capture_remote_cancel_cb);
1641
1642   if (focus_username) {
1643     /* Give the initial focus to the "Username" entry box. */
1644     gtk_widget_grab_focus(user_te);
1645   }
1646
1647   gtk_widget_grab_default(ok_but);
1648
1649   /* Catch the "activate" signal on the text
1650      entries, so that if the user types Return there, we act as if the
1651      "OK" button had been selected, as happens if Return is typed if some
1652      widget that *doesn't* handle the Return key has the input focus. */
1653   dlg_set_activate(host_te, ok_but);
1654   dlg_set_activate(port_te, ok_but);
1655   dlg_set_activate(user_te, ok_but);
1656   dlg_set_activate(passwd_te, ok_but);
1657
1658   g_signal_connect(remote_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
1659   g_signal_connect(remote_w, "destroy", G_CALLBACK(capture_remote_destroy_cb), NULL);
1660
1661   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_HOST_TE_KEY, host_te);
1662   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_PORT_TE_KEY, port_te);
1663   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_AUTH_NULL_KEY, auth_null_rb);
1664   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_AUTH_PASSWD_KEY, auth_passwd_rb);
1665   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_USERNAME_LB_KEY, user_lb);
1666   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_USERNAME_TE_KEY, user_te);
1667   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_PASSWD_LB_KEY, passwd_lb);
1668   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_PASSWD_TE_KEY, passwd_te);
1669
1670   if (global_remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD)
1671     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_passwd_rb), TRUE);
1672   else
1673     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_null_rb), TRUE);
1674   capture_remote_adjust_sensitivity(NULL, remote_w);
1675
1676   gtk_widget_show_all(remote_w);
1677   window_present(remote_w);
1678 }
1679
1680 /* user requested to destroy the dialog */
1681 static void
1682 options_remote_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1683 {
1684   GtkWidget *caller;
1685
1686   caller = g_object_get_data(G_OBJECT(win), E_OPT_REMOTE_CALLER_PTR_KEY);
1687   g_object_set_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY, NULL);
1688 }
1689
1690 /* user requested to accept remote interface options */
1691 static void
1692 options_remote_ok_cb(GtkWidget *win _U_, GtkWidget *parent_w)
1693 {
1694   GtkWidget   *datatx_udp_cb, *nocap_rpcap_cb;
1695 #ifdef HAVE_PCAP_SETSAMPLING
1696   GtkWidget   *samp_none_rb, *samp_count_rb, *samp_timer_rb,
1697               *samp_count_sb, *samp_timer_sb;
1698 #endif
1699   interface_t  device;
1700
1701   if (parent_w == NULL)
1702     return;
1703
1704   device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
1705   g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
1706   datatx_udp_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_DATATX_UDP_CB_KEY);
1707   nocap_rpcap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_NOCAP_RPCAP_CB_KEY);
1708
1709   device.remote_opts.remote_host_opts.datatx_udp =
1710     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(datatx_udp_cb));
1711   device.remote_opts.remote_host_opts.nocap_rpcap =
1712     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb));
1713
1714 #ifdef HAVE_PCAP_SETSAMPLING
1715   samp_none_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_NONE_RB_KEY);
1716   samp_count_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_RB_KEY);
1717   samp_timer_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_RB_KEY);
1718   samp_count_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_SB_KEY);
1719   samp_timer_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_SB_KEY);
1720
1721   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_none_rb)))
1722     device.remote_opts.sampling_method = CAPTURE_SAMP_NONE;
1723   else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb))) {
1724     device.remote_opts.sampling_method = CAPTURE_SAMP_BY_COUNT;
1725     device.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_count_sb));
1726   } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb))) {
1727     device.remote_opts.sampling_method = CAPTURE_SAMP_BY_TIMER;
1728     device.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_timer_sb));
1729   }
1730 #endif /* HAVE_PCAP_SETSAMPLING*/
1731   g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
1732   window_destroy(GTK_WIDGET(parent_w));
1733 }
1734 #endif /*HAVE_PCAP_REMOTE*/
1735
1736 #ifdef HAVE_PCAP_SETSAMPLING
1737 static void
1738 options_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1739 {
1740   GtkWidget *samp_count_rb, *samp_timer_rb,
1741             *samp_count_sb, *samp_timer_sb;
1742
1743   samp_count_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_RB_KEY);
1744   samp_timer_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_RB_KEY);
1745   samp_count_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_SB_KEY);
1746   samp_timer_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_SB_KEY);
1747
1748   if (samp_count_sb && samp_count_rb)
1749    gtk_widget_set_sensitive(GTK_WIDGET(samp_count_sb),
1750       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb)));
1751
1752   if (samp_timer_sb && samp_timer_rb)
1753    gtk_widget_set_sensitive(GTK_WIDGET(samp_timer_sb),
1754       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb)));
1755 }
1756
1757 #endif /*HAVE_PCAP_SETSAMPLING*/
1758 #ifdef HAVE_PCAP_REMOTE
1759 static void
1760 options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
1761 {
1762   GtkWidget     *opt_remote_w, *main_vb;
1763   GtkWidget     *caller, *bbox, *ok_but, *cancel_bt;
1764   GtkWidget     *capture_fr, *capture_vb;
1765   GtkWidget     *nocap_rpcap_cb, *datatx_udp_cb;
1766 #ifdef HAVE_PCAP_SETSAMPLING
1767   GtkWidget     *sampling_fr, *sampling_vb, *sampling_grid, *sampling_lb,
1768                 *samp_none_rb, *samp_count_rb, *samp_timer_rb,
1769                 *samp_count_sb, *samp_timer_sb;
1770   GtkAdjustment *samp_count_adj, *samp_timer_adj;
1771   GSList        *samp_group;
1772 #endif
1773   interface_t    device;
1774
1775   caller = gtk_widget_get_toplevel(w);
1776   opt_remote_w = g_object_get_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY);
1777   if (opt_remote_w != NULL) {
1778     reactivate_window(opt_remote_w);
1779     return;
1780   }
1781
1782   device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
1783   opt_remote_w = dlg_window_new("Remote Capture Settings");
1784   gtk_window_set_modal(GTK_WINDOW(opt_remote_w), TRUE);
1785   gtk_window_set_transient_for(GTK_WINDOW(opt_remote_w), GTK_WINDOW(caller));
1786   gtk_window_set_type_hint(GTK_WINDOW(opt_remote_w), GDK_WINDOW_TYPE_HINT_DIALOG);
1787
1788   g_object_set_data(G_OBJECT(opt_remote_w), E_OPT_REMOTE_CALLER_PTR_KEY, caller);
1789   g_object_set_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY, opt_remote_w);
1790
1791   main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
1792   gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
1793   gtk_container_add(GTK_CONTAINER(opt_remote_w), main_vb);
1794
1795   /* Remote capture options */
1796   capture_fr = gtk_frame_new("Capture Options");
1797   gtk_box_pack_start(GTK_BOX (main_vb), capture_fr, TRUE, TRUE, 0);
1798
1799   capture_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
1800   gtk_container_set_border_width(GTK_CONTAINER(capture_vb), 5);
1801   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
1802
1803   nocap_rpcap_cb = gtk_check_button_new_with_mnemonic("Do not capture own RPCAP traffic");
1804   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb),
1805           device.remote_opts.remote_host_opts.nocap_rpcap);
1806   gtk_box_pack_start(GTK_BOX (capture_vb), nocap_rpcap_cb, TRUE, TRUE, 0);
1807
1808   datatx_udp_cb = gtk_check_button_new_with_mnemonic("Use UDP for data transfer");
1809   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(datatx_udp_cb),
1810           device.remote_opts.remote_host_opts.datatx_udp);
1811   gtk_box_pack_start(GTK_BOX (capture_vb), datatx_udp_cb, TRUE, TRUE, 0);
1812
1813
1814 #ifdef HAVE_PCAP_SETSAMPLING
1815   /* Sampling options */
1816   sampling_fr = gtk_frame_new("Sampling Options");
1817   gtk_box_pack_start(GTK_BOX (main_vb), sampling_fr, TRUE, TRUE, 0);
1818
1819   sampling_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
1820   gtk_container_set_border_width(GTK_CONTAINER(sampling_vb), 5);
1821   gtk_container_add(GTK_CONTAINER(sampling_fr), sampling_vb);
1822
1823   sampling_grid = ws_gtk_grid_new();
1824   ws_gtk_grid_set_row_spacing(GTK_GRID(sampling_grid), DLG_LABEL_SPACING);
1825   ws_gtk_grid_set_column_spacing(GTK_GRID(sampling_grid), DLG_UNRELATED_SPACING);
1826   gtk_box_pack_start(GTK_BOX(sampling_vb), sampling_grid, FALSE, FALSE, 0);
1827
1828   /* "No sampling" row */
1829   samp_none_rb = gtk_radio_button_new_with_label(NULL, "None");
1830   if (device.remote_opts.sampling_method == CAPTURE_SAMP_NONE)
1831     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_none_rb), TRUE);
1832   g_signal_connect(samp_none_rb, "toggled",
1833                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
1834   ws_gtk_grid_attach_defaults(GTK_GRID (sampling_grid), samp_none_rb, 0, 0, 1, 1);
1835
1836   /* "Sampling by counter" row */
1837   samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_none_rb));
1838   samp_count_rb = gtk_radio_button_new_with_label(samp_group, "1 of");
1839   if (device.remote_opts.sampling_method == CAPTURE_SAMP_BY_COUNT)
1840     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_count_rb), TRUE);
1841   g_signal_connect(samp_count_rb, "toggled",
1842                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
1843   ws_gtk_grid_attach_defaults(GTK_GRID (sampling_grid), samp_count_rb, 0, 1, 1, 1);
1844
1845   samp_count_adj = (GtkAdjustment *) gtk_adjustment_new(
1846                         (gfloat)device.remote_opts.sampling_param,
1847                         1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
1848   samp_count_sb = gtk_spin_button_new(samp_count_adj, 0, 0);
1849   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_count_sb), TRUE);
1850   ws_gtk_grid_attach_defaults(GTK_GRID (sampling_grid), samp_count_sb, 1, 1, 1, 1);
1851
1852   sampling_lb = gtk_label_new("packets");
1853   gtk_misc_set_alignment(GTK_MISC(sampling_lb), 0, 0.5f);
1854   ws_gtk_grid_attach_defaults(GTK_GRID (sampling_grid), sampling_lb, 2, 1, 1, 1);
1855
1856   /* "Sampling by timer" row */
1857   samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_count_rb));
1858   samp_timer_rb = gtk_radio_button_new_with_label(samp_group, "1 every");
1859   if (device.remote_opts.sampling_method == CAPTURE_SAMP_BY_TIMER)
1860     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_timer_rb), TRUE);
1861   g_signal_connect(samp_timer_rb, "toggled",
1862                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
1863   ws_gtk_grid_attach_defaults(GTK_GRID (sampling_grid), samp_timer_rb, 0, 2, 1, 1);
1864
1865   samp_timer_adj = (GtkAdjustment *) gtk_adjustment_new(
1866                         (gfloat)device.remote_opts.sampling_param,
1867                         1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
1868   samp_timer_sb = gtk_spin_button_new(samp_timer_adj, 0, 0);
1869   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_timer_sb), TRUE);
1870   ws_gtk_grid_attach_defaults(GTK_GRID(sampling_grid), samp_timer_sb, 1, 2, 1, 1);
1871
1872   sampling_lb = gtk_label_new("milliseconds");
1873   gtk_misc_set_alignment(GTK_MISC(sampling_lb), 0, 0.5f);
1874   ws_gtk_grid_attach_defaults(GTK_GRID (sampling_grid), sampling_lb, 2, 2, 1, 1);
1875 #endif
1876
1877   /* Button row: "Start" and "Cancel" buttons */
1878   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
1879   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
1880
1881   ok_but = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
1882   g_signal_connect(ok_but, "clicked", G_CALLBACK(options_remote_ok_cb), opt_remote_w);
1883   gtk_widget_set_tooltip_text(ok_but, "Accept parameters and close dialog");
1884   cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
1885   gtk_widget_set_tooltip_text(cancel_bt, "Cancel and exit dialog.");
1886   window_set_cancel_button(opt_remote_w, cancel_bt, window_cancel_button_cb);
1887
1888   gtk_widget_grab_default(ok_but);
1889
1890   g_signal_connect(opt_remote_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
1891   g_signal_connect(opt_remote_w, "destroy", G_CALLBACK(options_remote_destroy_cb), NULL);
1892
1893   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_NOCAP_RPCAP_CB_KEY, nocap_rpcap_cb);
1894   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_DATATX_UDP_CB_KEY, datatx_udp_cb);
1895
1896 #ifdef HAVE_PCAP_SETSAMPLING
1897   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_NONE_RB_KEY, samp_none_rb);
1898   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_COUNT_RB_KEY, samp_count_rb);
1899   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_COUNT_SB_KEY, samp_count_sb);
1900   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_TIMER_RB_KEY, samp_timer_rb);
1901   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_TIMER_SB_KEY, samp_timer_sb);
1902 #endif
1903
1904 #ifdef HAVE_PCAP_SETSAMPLING
1905   /* Set the sensitivity of various widgets as per the settings of other
1906      widgets. */
1907   options_prep_adjust_sensitivity(NULL, opt_remote_w);
1908 #endif
1909
1910   gtk_widget_show_all(opt_remote_w);
1911   window_present(opt_remote_w);
1912 }
1913
1914 static void
1915 recent_print_remote_host (gpointer key _U_, gpointer value, gpointer user)
1916 {
1917   FILE *rf = user;
1918   struct remote_host_info *ri = value;
1919
1920   fprintf (rf, RECENT_KEY_REMOTE_HOST ": %s,%s,%d\n", ri->remote_host, ri->remote_port, ri->auth_type);
1921 }
1922
1923 void
1924 capture_remote_combo_recent_write_all(FILE *rf)
1925 {
1926   if (remote_host_list && g_hash_table_size (remote_host_list) > 0) {
1927     /* Write all remote interfaces to the recent file */
1928     g_hash_table_foreach (remote_host_list, recent_print_remote_host, rf);
1929   }
1930 }
1931
1932 gboolean
1933 capture_remote_combo_add_recent(const gchar *s)
1934 {
1935   GList *vals = prefs_get_string_list (s);
1936   GList *valp = vals;
1937   gint   auth_type;
1938   char  *p;
1939   struct remote_host_info *rh;
1940
1941   if (valp == NULL)
1942     return FALSE;
1943
1944   if (remote_host_list == NULL) {
1945     remote_host_list = g_hash_table_new (g_str_hash, g_str_equal);
1946   }
1947
1948   rh = g_malloc (sizeof (*rh));
1949
1950   /* First value is the host */
1951   rh->remote_host = g_strdup (valp->data);
1952   if (strlen(rh->remote_host) == 0) {
1953     /* Empty remote host */
1954     g_free(rh->remote_host);
1955     g_free(rh);
1956     return FALSE;
1957   }
1958   rh->auth_type = CAPTURE_AUTH_NULL;
1959   valp = valp->next;
1960
1961   if (valp) {
1962     /* Found value 2, this is the port number */
1963     rh->remote_port = g_strdup (valp->data);
1964     valp = valp->next;
1965   } else {
1966     /* Did not find a port number */
1967     rh->remote_port = g_strdup ("");
1968   }
1969
1970   if (valp) {
1971     /* Found value 3, this is the authentication type */
1972     auth_type = strtol(valp->data, &p, 0);
1973     if (p != valp->data && *p == '\0') {
1974       rh->auth_type = auth_type;
1975     }
1976   }
1977
1978   /* Do not store username and password */
1979   rh->auth_username = g_strdup ("");
1980   rh->auth_password = g_strdup ("");
1981
1982   prefs_clear_string_list(vals);
1983
1984   g_hash_table_insert (remote_host_list, g_strdup(rh->remote_host), rh);
1985
1986   return TRUE;
1987 }
1988
1989 #endif /* HAVE_PCAP_REMOTE */
1990
1991 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
1992
1993 static void
1994 compile_bpf_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
1995 {
1996   /* Note that we no longer have an "About Wireshark" dialog box. */
1997   compile_bpf_w = NULL;
1998 }
1999
2000 static void
2001 select_first_entry(void)
2002 {
2003   GtkWidget        *view;
2004   GtkTreeModel     *model;
2005   GtkTreeIter       iter;
2006   GtkTreeSelection *selection;
2007
2008   view = (GtkWidget *)g_object_get_data(G_OBJECT(compile_bpf_w), E_COMPILE_TREE_VIEW_INTERFACES);
2009   model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
2010   gtk_tree_model_get_iter_first(model, &iter);
2011   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
2012   gtk_tree_selection_select_iter(selection, &iter);
2013 }
2014
2015 static void
2016 add_page(gchar *name, gchar *text, gboolean error)
2017 {
2018   GtkWidget    *view, *icon;
2019   GtkTreeModel *model;
2020   GtkTreeIter   iter;
2021
2022   view = (GtkWidget *)g_object_get_data(G_OBJECT(compile_bpf_w), E_COMPILE_TREE_VIEW_INTERFACES);
2023   model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
2024   gtk_list_store_append (GTK_LIST_STORE(model), &iter);
2025   if (error) {
2026     icon = pixbuf_to_widget(expert_error_pb_data);
2027     gtk_list_store_set(GTK_LIST_STORE(model), &iter, COMPILE_ERROR, 1, SIGN, gtk_image_get_pixbuf(GTK_IMAGE(icon)), INAME, name, -1);
2028   } else {
2029     icon = pixbuf_to_widget(expert_ok_pb_data);
2030     gtk_list_store_set(GTK_LIST_STORE(model), &iter, COMPILE_ERROR, 0, SIGN, gtk_image_get_pixbuf(GTK_IMAGE(icon)), INAME, name, -1);
2031   }
2032   g_hash_table_insert(compile_results, name, text);
2033 }
2034
2035 static void
2036 compile_tree_select_cb(GtkTreeSelection *sel, gpointer dummy _U_)
2037 {
2038   gchar         *name,  *text;
2039   GtkTreeModel  *model;
2040   GtkTreeIter    iter;
2041   GtkWidget     *textview;
2042   GtkTextBuffer *buffer;
2043   guint          error;
2044
2045   if (gtk_tree_selection_get_selected(sel, &model, &iter))
2046   {
2047     gtk_tree_model_get(model, &iter, COMPILE_ERROR, &error, INAME, &name, -1);
2048     text = (gchar *)g_hash_table_lookup(compile_results, name);
2049     textview = (GtkWidget *)g_object_get_data(G_OBJECT(compile_bpf_w), CR_MAIN_NB);
2050     if (error == 1) {
2051       gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_CHAR);
2052     } else {
2053       gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_NONE);
2054     }
2055     buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
2056     gtk_text_buffer_set_text(buffer, text, -1);
2057     gtk_widget_show_all(compile_bpf_w);
2058   }
2059 }
2060
2061 static void
2062 compile_results_prep(GtkWidget *w _U_, gpointer data _U_)
2063 {
2064   GtkWidget            *main_box, *main_vb, *bbox, *ok_btn, *top_hb, *ct_sb;
2065   GtkListStore         *store;
2066   GtkWidget            *view, *scrolled_win, *textview;
2067   GtkTreeSelection     *selection;
2068   GtkCellRenderer      *renderer;
2069   GtkTreeViewColumn    *column;
2070   PangoFontDescription *font;
2071
2072   if (compile_bpf_w != NULL) {
2073     /* There's already an "About Wireshark" dialog box; reactivate it. */
2074     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The requested dialog is already open. Please close it first.");
2075     return;
2076   }
2077
2078   compile_bpf_w = dlg_window_new("Compile selected BPFs");
2079   /* set the initial position (must be done, before show is called!) */
2080   /* default position is not appropriate for the about dialog */
2081   gtk_window_set_position(GTK_WINDOW(compile_bpf_w), GTK_WIN_POS_CENTER_ON_PARENT);
2082   gtk_window_set_default_size(GTK_WINDOW(compile_bpf_w), 600, 400);
2083   gtk_window_set_modal(GTK_WINDOW(compile_bpf_w), TRUE);
2084   gtk_window_set_transient_for(GTK_WINDOW(compile_bpf_w), GTK_WINDOW(cap_open_w));
2085   gtk_container_set_border_width(GTK_CONTAINER(compile_bpf_w), 6);
2086
2087   main_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 12, FALSE);
2088   gtk_container_set_border_width(GTK_CONTAINER(main_box), 6);
2089   gtk_container_add(GTK_CONTAINER(compile_bpf_w), main_box);
2090   gtk_widget_show(main_box);
2091
2092   /* Top row: Interfaces tree and notebook */
2093   top_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10, FALSE);
2094   gtk_box_pack_start(GTK_BOX(main_box), top_hb, TRUE, TRUE, 0);
2095   gtk_widget_show(top_hb);
2096
2097   /* scrolled window on the left for the categories tree */
2098   ct_sb = scrolled_window_new(NULL, NULL);
2099   gtk_widget_set_size_request(GTK_WIDGET(ct_sb), 50, -1);
2100   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ct_sb),
2101                                    GTK_SHADOW_IN);
2102   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ct_sb),
2103                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2104   gtk_box_pack_start(GTK_BOX(top_hb), ct_sb, TRUE, TRUE, 0);
2105   gtk_widget_show(ct_sb);
2106   g_object_set_data(G_OBJECT(compile_bpf_w), E_COMPILE_SW_SCROLLW_KEY, ct_sb);
2107
2108   store = gtk_list_store_new(3, G_TYPE_UINT, GDK_TYPE_PIXBUF, G_TYPE_STRING);
2109   view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
2110   gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL (store));
2111   g_object_set(G_OBJECT(view), "headers-visible", FALSE, NULL);
2112   g_object_set_data(G_OBJECT(compile_bpf_w), E_COMPILE_TREE_VIEW_INTERFACES, view);
2113   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
2114   gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2115   column = gtk_tree_view_column_new();
2116   renderer = gtk_cell_renderer_text_new();
2117   gtk_tree_view_column_pack_start(column, renderer, TRUE);
2118   gtk_tree_view_column_set_attributes(column, renderer, "text", COMPILE_ERROR, NULL);
2119   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2120   gtk_tree_view_column_set_visible(column, FALSE);
2121   column = gtk_tree_view_column_new();
2122   renderer = gtk_cell_renderer_pixbuf_new();
2123   gtk_tree_view_column_pack_start(column, renderer, FALSE);
2124   gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", SIGN, NULL);
2125   renderer = gtk_cell_renderer_text_new();
2126   gtk_tree_view_column_pack_start(column, renderer, TRUE);
2127   gtk_tree_view_column_set_attributes(column, renderer, "text", INAME, NULL);
2128   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2129   gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(view), 0), TRUE);
2130
2131   g_signal_connect(selection, "changed", G_CALLBACK(compile_tree_select_cb), NULL);
2132   gtk_container_add(GTK_CONTAINER(ct_sb), view);
2133   gtk_widget_show(view);
2134
2135   main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 10, FALSE);
2136   gtk_box_pack_start(GTK_BOX(top_hb), main_vb, TRUE, TRUE, 0);
2137   gtk_widget_show(main_vb);
2138   g_object_set_data(G_OBJECT(compile_bpf_w), CR_MAIN_NB, main_vb);
2139
2140   font = pango_font_description_from_string("Monospace");
2141   textview = gtk_text_view_new();
2142   gtk_widget_modify_font(textview, font);
2143   scrolled_win = gtk_scrolled_window_new(NULL, NULL);
2144   gtk_widget_set_size_request(GTK_WIDGET(scrolled_win), 350, -1);
2145   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win),
2146                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2147   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_win),
2148                                    GTK_SHADOW_IN);
2149   gtk_container_add(GTK_CONTAINER(scrolled_win), textview);
2150   gtk_box_pack_start(GTK_BOX(main_vb), scrolled_win, TRUE, TRUE, 0);
2151   g_object_set_data(G_OBJECT(compile_bpf_w), CR_MAIN_NB, textview);
2152
2153   /* Button row */
2154   bbox = dlg_button_row_new(GTK_STOCK_OK, NULL);
2155   gtk_box_pack_start(GTK_BOX(main_box), bbox, FALSE, FALSE, 0);
2156
2157   ok_btn = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
2158   gtk_widget_grab_focus(ok_btn);
2159   gtk_widget_grab_default(ok_btn);
2160   window_set_cancel_button(compile_bpf_w, ok_btn, window_cancel_button_cb);
2161
2162   g_signal_connect(compile_bpf_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
2163   g_signal_connect(compile_bpf_w, "destroy", G_CALLBACK(compile_bpf_destroy_cb), NULL);
2164
2165   gtk_widget_show_all(compile_bpf_w);
2166   window_present(compile_bpf_w);
2167
2168   compile_results = g_hash_table_new(g_str_hash, g_str_equal);
2169 }
2170
2171 static void
2172 capture_all_filter_compile_cb(GtkWidget *w _U_, gpointer user_data _U_)
2173 {
2174   pcap_t    *pd;
2175   struct bpf_program fcode;
2176
2177   GtkWidget *filter_cm;
2178   gchar     *filter_text;
2179   guint      i;
2180   gboolean   set = FALSE;
2181
2182   filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY);
2183
2184   if (!filter_cm)
2185     return;
2186
2187   if (global_capture_opts.all_ifaces->len > 0) {
2188     interface_t device;
2189
2190     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2191       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2192       if (!device.selected || device.hidden) {
2193         continue;
2194       }
2195       if (device.active_dlt == -1) {
2196         g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
2197       }
2198       if (!set) {
2199         set = TRUE;
2200         compile_results_prep(NULL, NULL);
2201       }
2202       pd = pcap_open_dead(device.active_dlt, DUMMY_SNAPLENGTH);
2203
2204       filter_text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(filter_cm));
2205       g_mutex_lock(pcap_compile_mtx);
2206 #ifdef PCAP_NETMASK_UNKNOWN
2207       if (pcap_compile(pd, &fcode, filter_text, 1 /* Do optimize */, PCAP_NETMASK_UNKNOWN) < 0)
2208 #else
2209       if (pcap_compile(pd, &fcode, filter_text, 1 /* Do optimize */, 0) < 0)
2210 #endif
2211       {
2212           g_mutex_unlock(pcap_compile_mtx);
2213           add_page(device.name, g_strdup(pcap_geterr(pd)), TRUE);
2214       } else {
2215         GString         *bpf_code_dump = g_string_new("");
2216         struct bpf_insn *insn          = fcode.bf_insns;
2217         int              ii, n         = fcode.bf_len;
2218         gchar           *bpf_code_str;
2219
2220         for (ii = 0; ii < n; ++insn, ++ii) {
2221             g_string_append(bpf_code_dump, bpf_image(insn, ii));
2222             g_string_append(bpf_code_dump, "\n");
2223         }
2224         bpf_code_str = g_string_free(bpf_code_dump, FALSE);
2225         g_mutex_unlock(pcap_compile_mtx);
2226         add_page(device.name, g_strdup(bpf_code_str), FALSE);
2227         g_free(bpf_code_str);
2228       }
2229       g_free(filter_text);
2230       pcap_close(pd);
2231     }
2232   }
2233   select_first_entry();
2234 }
2235 #endif /* HAVE_PCAP_OPEN_DEAD && HAVE_BPF_IMAGE */
2236
2237
2238 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
2239 static void
2240 compile_results_win(gchar *text, gboolean error)
2241 {
2242   GtkWidget            *main_box, *bbox, *ok_btn, *results_w;
2243   GtkWidget            *scrolled_win, *textview;
2244   PangoFontDescription *font;
2245   GtkTextBuffer        *buffer;
2246
2247   results_w = dlg_window_new("Compile results");
2248   /* set the initial position (must be done, before show is called!) */
2249   /* default position is not appropriate for the about dialog */
2250   gtk_window_set_position(GTK_WINDOW(results_w), GTK_WIN_POS_CENTER_ON_PARENT);
2251   gtk_window_set_default_size(GTK_WINDOW(results_w), 400, 400);
2252   gtk_window_set_modal(GTK_WINDOW(results_w), TRUE);
2253   gtk_window_set_transient_for(GTK_WINDOW(results_w), GTK_WINDOW(opt_edit_w));
2254   gtk_container_set_border_width(GTK_CONTAINER(results_w), 6);
2255   main_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 12, FALSE);
2256   gtk_container_set_border_width(GTK_CONTAINER(main_box), 6);
2257   gtk_container_add(GTK_CONTAINER(results_w), main_box);
2258   gtk_widget_show(main_box);
2259   font = pango_font_description_from_string("Monospace");
2260   textview = gtk_text_view_new();
2261   gtk_widget_modify_font(textview, font);
2262   scrolled_win = gtk_scrolled_window_new(NULL, NULL);
2263   gtk_widget_set_size_request(GTK_WIDGET(scrolled_win), 350, -1);
2264   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win),
2265                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2266   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_win),
2267                                    GTK_SHADOW_IN);
2268   gtk_container_add(GTK_CONTAINER(scrolled_win), textview);
2269   gtk_box_pack_start(GTK_BOX(main_box), scrolled_win, TRUE, TRUE, 0);
2270   if (error == 1) {
2271     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_CHAR);
2272   } else {
2273     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_NONE);
2274   }
2275   buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
2276   gtk_text_buffer_set_text(buffer, g_strdup(text), -1);
2277   /* Button row */
2278   bbox = dlg_button_row_new(GTK_STOCK_OK, NULL);
2279   gtk_box_pack_start(GTK_BOX(main_box), bbox, FALSE, FALSE, 0);
2280
2281   ok_btn = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
2282   gtk_widget_grab_focus(ok_btn);
2283   gtk_widget_grab_default(ok_btn);
2284   window_set_cancel_button(results_w, ok_btn, window_cancel_button_cb);
2285
2286   g_signal_connect(results_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
2287   g_signal_connect(results_w, "destroy", G_CALLBACK(compile_bpf_destroy_cb), NULL);
2288
2289   gtk_widget_show_all(results_w);
2290   window_present(results_w);
2291 }
2292
2293
2294 static void
2295 capture_filter_compile_cb(GtkWidget *w _U_, gpointer user_data _U_)
2296 {
2297   pcap_t             *pd;
2298   struct bpf_program  fcode;
2299
2300   GtkWidget *filter_cm;
2301   gchar     *filter_text;
2302   gpointer   ptr;
2303   int        dlt;
2304   GtkWidget *linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
2305
2306   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
2307     g_assert_not_reached();  /* Programming error: somehow nothing is active */
2308   }
2309   if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
2310     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
2311   }
2312   pd = pcap_open_dead(dlt, DUMMY_SNAPLENGTH);
2313   filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY);
2314   filter_text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(filter_cm));
2315   g_mutex_lock(pcap_compile_mtx);
2316 #ifdef PCAP_NETMASK_UNKNOWN
2317   if (pcap_compile(pd, &fcode, filter_text, 1 /* Do optimize */, PCAP_NETMASK_UNKNOWN) < 0) {
2318 #else
2319   if (pcap_compile(pd, &fcode, filter_text, 1 /* Do optimize */, 0) < 0) {
2320 #endif
2321     g_mutex_unlock(pcap_compile_mtx);
2322     compile_results_win(g_strdup(pcap_geterr(pd)), 1);
2323   } else {
2324     GString         *bpf_code_dump = g_string_new("");
2325     struct bpf_insn *insn          = fcode.bf_insns;
2326     int              i, n          = fcode.bf_len;
2327
2328     gchar *bpf_code_str;
2329
2330     g_mutex_unlock(pcap_compile_mtx);
2331
2332     for (i = 0; i < n; ++insn, ++i) {
2333         g_string_append(bpf_code_dump, bpf_image(insn, i));
2334         g_string_append(bpf_code_dump, "\n");
2335     }
2336
2337     bpf_code_str = g_string_free(bpf_code_dump, FALSE);
2338     compile_results_win(g_strdup(bpf_code_str), 0);
2339
2340     g_free(bpf_code_str);
2341   }
2342   g_free(filter_text);
2343
2344   pcap_close(pd);
2345 }
2346 #endif /* HAVE_PCAP_OPEN_DEAD && HAVE_BPF_IMAGE */
2347
2348 static void
2349 options_edit_destroy_cb(GtkWidget *win, gpointer user_data _U_)
2350 {
2351   GtkWidget *caller;
2352
2353   caller = (GtkWidget *)g_object_get_data(G_OBJECT(win), E_OPT_EDIT_CALLER_PTR_KEY);
2354   g_object_set_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY, NULL);
2355 }
2356
2357 static void
2358 update_options_table(gint indx)
2359 {
2360   interface_t   device;
2361   GtkTreePath  *path;
2362   GtkTreeView  *if_cb;
2363   GtkTreeModel *model;
2364   GtkTreeIter   iter;
2365   gchar        *temp, *path_str, *snaplen_string, *linkname;
2366   GList        *list;
2367   link_row     *linkr = NULL;
2368   gboolean      enabled;
2369
2370   device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
2371
2372   if (!device.hidden) {
2373     if (device.no_addresses == 0) {
2374       temp = g_strdup_printf("<b>%s</b>", device.display_name);
2375     } else {
2376       temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", device.display_name, device.addresses);
2377     }
2378     linkname = NULL;
2379     for (list=device.links; list!=NULL; list=g_list_next(list))
2380     {
2381       linkr = (link_row*)(list->data);
2382       if (linkr->dlt == device.active_dlt) {
2383         linkname = g_strdup(linkr->name);
2384         break;
2385       }
2386     }
2387     if (device.has_snaplen) {
2388       snaplen_string = g_strdup_printf("%d", device.snaplen);
2389     } else {
2390       snaplen_string = g_strdup("default");
2391     }
2392     if (cap_open_w) {
2393       if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
2394       path_str = g_strdup_printf("%d", indx);
2395       path = gtk_tree_path_new_from_string(path_str);
2396       model = gtk_tree_view_get_model(if_cb);
2397       gtk_tree_model_get_iter(model, &iter, path);
2398       gtk_tree_model_get(model, &iter, CAPTURE, &enabled, -1);
2399       if (enabled == FALSE) {
2400         device.selected = TRUE;
2401         global_capture_opts.num_selected++;
2402         global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
2403         g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
2404       }
2405   #if defined(HAVE_PCAP_CREATE)
2406       gtk_list_store_set (GTK_LIST_STORE(model), &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);
2407   #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
2408       gtk_list_store_set (GTK_LIST_STORE(model), &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, FILTER, device.cfilter, -1);
2409   #else
2410       gtk_list_store_set (GTK_LIST_STORE(model), &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, FILTER, device.cfilter, -1);
2411   #endif
2412       if (global_capture_opts.num_selected > 0) {
2413         gtk_widget_set_sensitive(ok_bt, TRUE);
2414 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
2415         gtk_widget_set_sensitive(all_compile_bt, TRUE);
2416 #endif
2417       } else {
2418         gtk_widget_set_sensitive(ok_bt, FALSE);
2419 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
2420         gtk_widget_set_sensitive(all_compile_bt, FALSE);
2421 #endif
2422       }
2423       gtk_tree_path_free (path);
2424       g_free(path_str);
2425     }
2426     if (interfaces_dialog_window_present()) {
2427       update_selected_interface(g_strdup(device.name));
2428     }
2429     if (get_welcome_window() != NULL) {
2430       change_interface_selection(g_strdup(device.name), device.selected);
2431     }
2432   }
2433 }
2434
2435
2436 static void
2437 save_options_cb(GtkWidget *win _U_, gpointer user_data _U_)
2438 {
2439   GtkWidget *snap_cb, *snap_sb, *promisc_cb,
2440 #ifdef HAVE_PCAP_CREATE
2441             *monitor_cb,
2442 #endif
2443             *filter_cm, *linktype_combo_box;
2444 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2445   GtkWidget *buffer_size_sb;
2446 #endif
2447
2448   interface_t device;
2449   gpointer   ptr = NULL;
2450   int        dlt = -1;
2451   gchar     *filter_text;
2452
2453   device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
2454   global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
2455   snap_cb    = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY);
2456   snap_sb    = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY);
2457 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2458   buffer_size_sb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_BUFFER_SIZE_SB_KEY);
2459 #endif
2460   promisc_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_PROMISC_KEY);
2461 #ifdef HAVE_PCAP_CREATE
2462   monitor_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_MONITOR_KEY);
2463 #endif
2464   filter_cm  = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY);
2465
2466   linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
2467
2468   if (device.links != NULL) {
2469      if (ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
2470        /* Even though device.links != NULL, we might not have an active pointer
2471         * if all of the available links are unsupported, so the failure of
2472         * ws_combo_box_get_active_pointer() is not cause for
2473         * g_assert_not_reached().
2474         */
2475        if (ptr != NULL && (dlt = GPOINTER_TO_INT(ptr)) == -1)
2476          g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
2477      }
2478   }
2479   device.active_dlt = dlt;
2480 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2481   device.buffer = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb));
2482 #endif
2483   device.pmode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
2484   device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
2485   if (device.has_snaplen) {
2486     if (device.snaplen != (guint)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb))) {
2487     }
2488     device.snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
2489     if (device.snaplen < 1)
2490       device.snaplen = WTAP_MAX_PACKET_SIZE;
2491     else if (device.snaplen < MIN_PACKET_SIZE)
2492       device.snaplen = MIN_PACKET_SIZE;
2493   } else {
2494     device.snaplen = WTAP_MAX_PACKET_SIZE;
2495   }
2496   filter_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(filter_cm));
2497   if (device.cfilter)
2498     g_free(device.cfilter);
2499   g_assert(filter_text != NULL);
2500   device.cfilter = filter_text;
2501 #ifdef HAVE_PCAP_CREATE
2502   /* if dumpcap reported that the interface does not support monitor
2503      mode, we disable monitor mode even if the user explicitly selected it */
2504   device.monitor_mode_enabled = device.monitor_mode_supported ?
2505      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb)) : FALSE;
2506 #endif
2507   g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
2508   window_destroy(opt_edit_w);
2509   update_options_table(marked_row);
2510   update_properties_all();
2511 }
2512
2513 static void
2514 adjust_snap_sensitivity(GtkWidget *tb _U_, gpointer parent_w _U_)
2515 {
2516   GtkWidget   *snap_cb, *snap_sb;
2517   interface_t  device;
2518
2519   device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
2520   global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
2521
2522   snap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY);
2523   snap_sb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY);
2524
2525   /* The snapshot length spinbox is sensitive if the "Limit each packet
2526      to" checkbox is on. */
2527   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
2528       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
2529   device.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
2530   if (!device.has_snaplen) {
2531     gtk_spin_button_set_value(GTK_SPIN_BUTTON (snap_sb), WTAP_MAX_PACKET_SIZE);
2532     device.snaplen = WTAP_MAX_PACKET_SIZE;
2533   }
2534   g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
2535 }
2536
2537 void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column _U_, gpointer userdata)
2538 {
2539   GtkWidget       *caller, *window, *swindow = NULL, *if_view,
2540                   *main_vb, *if_hb, *if_lb, *if_lb_name,
2541                   *main_hb, *left_vb,
2542 #if defined (HAVE_AIRPCAP) || defined (HAVE_PCAP_REMOTE) || defined (HAVE_PCAP_CREATE)
2543                   *right_vb,
2544 #endif
2545                   *capture_fr, *capture_vb,
2546                   *if_ip_hb, *if_ip_lb         = NULL, *if_ip_name,
2547                   *if_vb_left, *if_vb_right,
2548                   *linktype_hb, *linktype_lb, *linktype_combo_box,
2549                   *snap_hb, *snap_cb, *snap_sb, *snap_lb,
2550                   *promisc_cb,
2551 #ifdef HAVE_PCAP_CREATE
2552                   *monitor_cb,
2553 #endif
2554                   *filter_hb, *filter_bt, *filter_te, *filter_cm,
2555 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
2556                   *compile_bt,
2557 #endif
2558                   *bbox, *ok_but, *cancel_bt,
2559                   *help_bt;
2560   GList           *cf_entry, *list, *cfilter_list;
2561   GtkAdjustment   *snap_adj;
2562 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2563   GtkAdjustment   *buffer_size_adj;
2564   GtkWidget       *buffer_size_lb, *buffer_size_sb, *buffer_size_hb;
2565 #endif
2566 #ifdef HAVE_PCAP_REMOTE
2567   GtkWidget       *remote_bt;
2568 #endif
2569  #ifdef HAVE_AIRPCAP
2570   GtkWidget       *advanced_bt;
2571 #endif
2572   interface_t      device;
2573   GtkTreeModel    *model;
2574   GtkTreeIter      iter;
2575   link_row        *temp;
2576   gboolean         found                     = FALSE;
2577   gint             num_link_types, num_supported_link_types, first_supported_index;
2578   guint            i;
2579   gchar           *tok, *name;
2580   GtkCellRenderer *renderer;
2581   GtkListStore    *store;
2582
2583   window = (GtkWidget *)userdata;
2584   caller = gtk_widget_get_toplevel(GTK_WIDGET(window));
2585   opt_edit_w = (GtkWidget *)g_object_get_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY);
2586   if (opt_edit_w != NULL) {
2587     reactivate_window(opt_edit_w);
2588     return;
2589   }
2590
2591   device.name = NULL;
2592   device.display_name = NULL;
2593   device.no_addresses = 0;
2594   device.addresses = NULL;
2595   device.links = NULL;
2596   device.active_dlt = -1;
2597   device.pmode = FALSE;
2598 #ifdef HAVE_PCAP_CREATE
2599   device.monitor_mode_enabled = FALSE;
2600   device.monitor_mode_supported = FALSE;
2601 #endif
2602   device.has_snaplen = FALSE;
2603   device.snaplen = 65535;
2604   device.cfilter = NULL;
2605 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2606   device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
2607 #endif
2608
2609   model = gtk_tree_view_get_model(view);
2610   gtk_tree_model_get_iter (model, &iter, path);
2611
2612   if (window == get_welcome_window()) {
2613     gtk_tree_model_get(model, &iter, IFACE_NAME, &name, -1);
2614   } else if (window == cap_open_w) {
2615     gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &name, -1);
2616   } else {
2617     return;
2618   }
2619
2620   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2621     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2622     if (strcmp(device.name, name) == 0) {
2623       marked_interface = i;
2624       break;
2625     }
2626   }
2627   marked_row = atoi(gtk_tree_path_to_string(path));
2628   opt_edit_w = dlg_window_new("Edit Interface Settings");
2629   gtk_window_set_modal(GTK_WINDOW(opt_edit_w), TRUE);
2630   gtk_window_set_type_hint (GTK_WINDOW (opt_edit_w), GDK_WINDOW_TYPE_HINT_DIALOG);
2631   g_object_set_data(G_OBJECT(opt_edit_w), E_OPT_EDIT_CALLER_PTR_KEY, caller);
2632   g_object_set_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY, opt_edit_w);
2633
2634   main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
2635   gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
2636   gtk_container_add(GTK_CONTAINER(opt_edit_w), main_vb);
2637
2638   /* Capture-related options frame */
2639   capture_fr = gtk_frame_new("Capture");
2640   gtk_box_pack_start(GTK_BOX (main_vb), capture_fr, TRUE, TRUE, 0);
2641
2642   capture_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
2643   gtk_container_set_border_width(GTK_CONTAINER(capture_vb), 5);
2644   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
2645
2646   /* Interface row */
2647   if_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
2648   gtk_box_pack_start(GTK_BOX(capture_vb), if_hb, FALSE, FALSE, 3);
2649
2650   if_lb = gtk_label_new("Interface:  ");
2651   gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 3);
2652
2653   if_lb_name = gtk_label_new(device.display_name);
2654   gtk_box_pack_start(GTK_BOX(if_hb), if_lb_name, FALSE, FALSE, 3);
2655
2656   /* IP addresses row */
2657   if_ip_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
2658
2659   gtk_widget_set_tooltip_text(if_ip_hb, "Lists the IP address(es) "
2660                        "assigned to the selected interface. ");
2661   if_vb_left = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
2662   gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_left, FALSE, FALSE, 3);
2663   if_vb_right = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
2664
2665   if_ip_lb = gtk_label_new("IP address:");
2666   gtk_misc_set_alignment(GTK_MISC(if_ip_lb), 0, 0); /* Left justified */
2667   gtk_box_pack_start(GTK_BOX(if_vb_left), if_ip_lb, FALSE, FALSE, 0);
2668   if (device.no_addresses > 0) {
2669     gchar *temp_addresses = g_strdup(device.addresses);
2670     gtk_box_pack_start(GTK_BOX(capture_vb), if_ip_hb, TRUE, TRUE, 0);
2671     gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, TRUE, TRUE, 3);
2672     swindow = gtk_scrolled_window_new (NULL, NULL);
2673     gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN);
2674     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2675     gtk_widget_set_size_request(GTK_WIDGET(swindow),-1, 50);
2676     if_view = gtk_tree_view_new ();
2677     g_object_set(G_OBJECT(if_view), "headers-visible", FALSE, NULL);
2678     renderer = gtk_cell_renderer_text_new();
2679     column = gtk_tree_view_column_new_with_attributes ("",
2680                     GTK_CELL_RENDERER(renderer),
2681                     "text", 0,
2682                     NULL);
2683     gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
2684     store = gtk_list_store_new(1, G_TYPE_STRING);
2685     for (tok = strtok (temp_addresses, "\n"); tok; tok = strtok(NULL, "\n")) {
2686       gtk_list_store_append (store, &iter);
2687       gtk_list_store_set (store, &iter, 0, tok, -1);
2688     }
2689     gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store));
2690     gtk_container_add (GTK_CONTAINER (swindow), if_view);
2691     gtk_box_pack_start(GTK_BOX(if_vb_right), swindow, TRUE, TRUE, 0);
2692     g_free(temp_addresses);
2693   } else {
2694     gtk_box_pack_start(GTK_BOX(capture_vb), if_ip_hb, FALSE, FALSE, 0);
2695     gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, FALSE, FALSE, 3);
2696     if_ip_name = gtk_label_new("none");
2697     gtk_misc_set_alignment(GTK_MISC(if_ip_name), 0, 0); /* Left justified */
2698     gtk_box_pack_start(GTK_BOX(if_vb_right), if_ip_name, FALSE, FALSE, 0);
2699   }
2700   main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE);
2701   gtk_container_set_border_width(GTK_CONTAINER(main_hb), 0);
2702   gtk_box_pack_start(GTK_BOX(capture_vb), main_hb, FALSE, FALSE, 3);
2703
2704   left_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
2705   gtk_container_set_border_width(GTK_CONTAINER(left_vb), 0);
2706   gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
2707
2708 #if defined (HAVE_AIRPCAP) || defined (HAVE_PCAP_REMOTE) || defined (HAVE_PCAP_CREATE)
2709   /* Avoid adding the right vbox if not needed, because it steals 3 pixels */
2710   right_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
2711   gtk_container_set_border_width(GTK_CONTAINER(right_vb), 0);
2712   gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 3);
2713 #endif
2714
2715   /* Linktype row */
2716   linktype_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
2717   gtk_box_pack_start(GTK_BOX(left_vb), linktype_hb, FALSE, FALSE, 0);
2718
2719   linktype_lb = gtk_label_new("Link-layer header type:");
2720   gtk_box_pack_start(GTK_BOX(linktype_hb), linktype_lb, FALSE, FALSE, 3);
2721
2722   linktype_combo_box = ws_combo_box_new_text_and_pointer();
2723   g_object_set_data(G_OBJECT(linktype_combo_box), E_CAP_LT_CBX_LABEL_KEY, linktype_lb);
2724   /* Default to "use the default" */
2725   /* Datalink menu index is not reset; it will be restored with last used value */
2726
2727   g_object_set_data(G_OBJECT(linktype_combo_box), E_CAP_IFACE_IP_KEY, if_ip_lb);
2728   /*
2729    * XXX - in some cases, this is "multiple link-layer header types", e.g.
2730    * some 802.11 interfaces on FreeBSD 5.2 and later, where you can request
2731    * fake Ethernet, 802.11, or 802.11-plus-radio-information headers.
2732    *
2733    * In other cases, it's "multiple link-layer types", e.g., with recent
2734    * versions of libpcap, a DAG card on an "HDLC" WAN, where you can
2735    * request Cisco HDLC or PPP depending on what type of traffic is going
2736    * over the WAN, or an Ethernet interface, where you can request Ethernet
2737    * or DOCSIS, the latter being for some Cisco cable modem equipment that
2738    * can be configured to send raw DOCSIS frames over an Ethernet inside
2739    * Ethernet low-level framing, for traffic capture purposes.
2740    *
2741    * We leave it as "multiple link-layer types" for now.
2742    */
2743   gtk_widget_set_tooltip_text(linktype_combo_box, "The selected interface supports multiple link-layer types; select the desired one.");
2744   gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_combo_box, FALSE, FALSE, 0);
2745   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY, linktype_combo_box);
2746   num_link_types = 0;
2747   num_supported_link_types = 0;
2748   first_supported_index = -1;
2749   for (list=device.links; list!=NULL; list=g_list_next(list))
2750   {
2751     temp = (link_row*)(list->data);
2752     if (temp->dlt == -1)
2753     {
2754       ws_combo_box_append_text_and_pointer_full(GTK_COMBO_BOX(linktype_combo_box),
2755                                                 NULL,
2756                                                 temp->name,
2757                                                 GINT_TO_POINTER(-1),  /* Flag as "not supported" */
2758                                                 FALSE);
2759     }
2760     else
2761     {
2762       ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box),
2763                                            temp->name,
2764                                            GINT_TO_POINTER(temp->dlt));
2765       /* Record the index of the first supported link type (and thus the first
2766        * one in the list to be active) for use determining the default selected
2767        * element. */
2768       if (first_supported_index == -1)
2769       {
2770         first_supported_index = num_link_types;
2771       }
2772       if (temp->dlt == device.active_dlt)
2773       {
2774         ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box), num_link_types);
2775         found = TRUE;
2776       }
2777       num_supported_link_types++;
2778     }
2779     num_link_types++;
2780   }
2781   gtk_widget_set_sensitive(linktype_lb, num_link_types >= 2);
2782   gtk_widget_set_sensitive(linktype_combo_box, num_link_types >= 2);
2783   if (!found && first_supported_index >= 0)
2784   {
2785     ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box),first_supported_index);
2786   }
2787   g_signal_connect(linktype_combo_box, "changed", G_CALLBACK(select_link_type_cb), NULL);
2788
2789   /* Promiscuous mode row */
2790   promisc_cb = gtk_check_button_new_with_mnemonic(
2791       "Capture packets in _promiscuous mode");
2792   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb),
2793                                device.pmode);
2794   gtk_widget_set_tooltip_text(promisc_cb,
2795     "Usually a network adapter will only capture the traffic sent to its own network address. "
2796     "If you want to capture all traffic that the network adapter can \"see\", mark this option. "
2797     "See the FAQ for some more details of capturing packets from a switched network.");
2798   gtk_box_pack_start (GTK_BOX(left_vb), promisc_cb, FALSE, FALSE, 0);
2799   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_PROMISC_KEY, promisc_cb);
2800
2801 #ifdef HAVE_PCAP_CREATE
2802   /* Monitor mode row */
2803   monitor_cb = gtk_check_button_new_with_mnemonic( "Capture packets in monitor mode");
2804   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor_cb), device.monitor_mode_enabled);
2805   gtk_widget_set_sensitive(monitor_cb, device.monitor_mode_supported);
2806   g_signal_connect(monitor_cb, "toggled", G_CALLBACK(capture_prep_monitor_changed_cb), NULL);
2807
2808   gtk_widget_set_tooltip_text(monitor_cb,
2809     "Usually a Wi-Fi adapter will, even in promiscuous mode, only capture the traffic on the BSS to which it's associated. "
2810     "If you want to capture all traffic that the Wi-Fi adapter can \"receive\", mark this option. "
2811     "In order to see IEEE 802.11 headers or to see radio information for captured packets, "
2812     "it might be necessary to turn this option on.\n\n"
2813     "Note that, in monitor mode, the adapter might disassociate from the network to which it's associated.");
2814   gtk_box_pack_start (GTK_BOX(left_vb), monitor_cb, FALSE, FALSE, 0);
2815
2816   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_MONITOR_KEY, monitor_cb);
2817 #endif
2818
2819   /*
2820    * This controls the sensitivity of both the link-type list and, if
2821    * you have it, the monitor mode checkbox.  That's why we do this
2822    * now.
2823    */
2824
2825   /* Capture length row */
2826   snap_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
2827   gtk_box_pack_start (GTK_BOX(left_vb), snap_hb, FALSE, FALSE, 0);
2828
2829   snap_cb = gtk_check_button_new_with_mnemonic("_Limit each packet to");
2830   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(snap_cb),
2831                                device.has_snaplen);
2832   g_signal_connect(snap_cb, "toggled", G_CALLBACK(adjust_snap_sensitivity), NULL);
2833   gtk_widget_set_tooltip_text(snap_cb,
2834     "Limit the maximum number of bytes to be captured from each packet. This size includes the "
2835     "link-layer header and all subsequent headers. ");
2836   gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
2837
2838   snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) device.snaplen,
2839     MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
2840   snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
2841   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
2842   gtk_widget_set_size_request(snap_sb, 80, -1);
2843   gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
2844
2845   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY, snap_cb);
2846   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY, snap_sb);
2847   snap_lb = gtk_label_new("bytes");
2848   gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5f);
2849   gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
2850   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), device.has_snaplen);
2851
2852   /* Filter row */
2853   filter_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
2854   gtk_box_pack_start(GTK_BOX(capture_vb), filter_hb, FALSE, FALSE, 0);
2855
2856   filter_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_CAPTURE_FILTER_ENTRY);
2857   g_signal_connect(filter_bt, "clicked", G_CALLBACK(capture_filter_construct_cb), NULL);
2858   g_signal_connect(filter_bt, "destroy", G_CALLBACK(filter_button_destroy_cb), NULL);
2859   gtk_widget_set_tooltip_text(filter_bt,
2860     "Select a capture filter to reduce the amount of packets to be captured. "
2861     "See \"Capture Filters\" in the online help for further information how to use it."
2862     );
2863   gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
2864
2865   /* Create the capture filter combo box*/
2866   filter_cm = gtk_combo_box_text_new_with_entry();
2867   cfilter_list = (GList *)g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_FL_KEY);
2868   g_object_set_data(G_OBJECT(opt_edit_w), E_CFILTER_FL_KEY, cfilter_list);
2869   g_object_set_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY, filter_cm);
2870   filter_te = gtk_bin_get_child(GTK_BIN(filter_cm));
2871   colorize_filter_te_as_empty(filter_te);
2872   g_signal_connect(filter_te, "changed", G_CALLBACK(capture_filter_check_syntax_cb), NULL);
2873   g_signal_connect(filter_te, "destroy", G_CALLBACK(capture_filter_destroy_cb), NULL);
2874
2875   for (cf_entry = cfilter_list; cf_entry != NULL; cf_entry = g_list_next(cf_entry)) {
2876     if (cf_entry->data && (strlen((const char *)cf_entry->data) > 0)) {
2877       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(filter_cm), (const gchar *)cf_entry->data);
2878     }
2879   }
2880   if (global_capture_opts.default_options.cfilter && (strlen(global_capture_opts.default_options.cfilter) > 0)) {
2881     gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), global_capture_opts.default_options.cfilter);
2882   }
2883   if (device.cfilter && (strlen(device.cfilter) > 0)) {
2884     gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), device.cfilter);
2885     gtk_combo_box_set_active(GTK_COMBO_BOX(filter_cm), 0);
2886   }
2887
2888   gtk_widget_set_tooltip_text(filter_cm,
2889     "Enter a capture filter to reduce the amount of packets to be captured. "
2890     "See \"Capture Filters\" in the online help for further information how to use it. "
2891     "Syntax checking can be disabled in Preferences -> Capture -> Syntax check capture filter."
2892     );
2893   gtk_box_pack_start(GTK_BOX(filter_hb), filter_cm, TRUE, TRUE, 3);
2894
2895   /* let an eventually capture filters dialog know the text entry to fill in */
2896   g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
2897
2898 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
2899   compile_bt = gtk_button_new_with_label("Compile BPF");
2900   g_signal_connect(compile_bt, "clicked", G_CALLBACK(capture_filter_compile_cb), NULL);
2901   gtk_widget_set_tooltip_text(compile_bt,
2902    "Compile the capture filter expression and show the BPF (Berkeley Packet Filter) code.");
2903   /* We can't compile without any supported link-types, so disable the button in that case */
2904   gtk_widget_set_sensitive(compile_bt, (num_supported_link_types >= 1));
2905   gtk_box_pack_start(GTK_BOX(filter_hb), compile_bt, FALSE, FALSE, 3);
2906 #endif
2907
2908 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2909   buffer_size_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
2910   buffer_size_lb = gtk_label_new("Buffer size:");
2911   gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_lb, FALSE, FALSE, 0);
2912
2913   buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) device.buffer,
2914     1, 65535, 1.0, 10.0, 0.0);
2915   buffer_size_sb = gtk_spin_button_new (buffer_size_adj, 0, 0);
2916   gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) device.buffer);
2917   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (buffer_size_sb), TRUE);
2918   gtk_widget_set_size_request(buffer_size_sb, 80, -1);
2919   gtk_widget_set_tooltip_text(buffer_size_sb,
2920    "The memory buffer size used while capturing. If you notice packet drops, you can try to increase this size.");
2921   gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_sb, FALSE, FALSE, 0);
2922   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_BUFFER_SIZE_SB_KEY, buffer_size_sb);
2923   buffer_size_lb = gtk_label_new("megabyte(s)");
2924   gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_lb, FALSE, FALSE, 3);
2925   gtk_misc_set_alignment(GTK_MISC(buffer_size_lb), 1, 0);
2926 #ifdef HAVE_PCAP_REMOTE
2927   gtk_box_pack_start (GTK_BOX(left_vb), buffer_size_hb, FALSE, FALSE, 0);
2928 #else
2929   gtk_box_pack_start (GTK_BOX(right_vb), buffer_size_hb, FALSE, FALSE, 0);
2930 #endif
2931 #endif
2932
2933 #ifdef HAVE_PCAP_REMOTE
2934   /*
2935    * *IF* this is a remote interface, add the "Remote Settings"
2936    * button.  Do *not* add it for other interfaces, as that could
2937    * lead users to believe that it could somehow be enabled.
2938    */
2939   /* Both the callback and the data are global */
2940   if (strncmp (device.name, "rpcap://", 8) == 0)  {
2941     remote_bt = gtk_button_new_with_label("Remote Settings");
2942     gtk_widget_set_tooltip_text(remote_bt, "Various settings for remote capture.");
2943
2944     g_signal_connect(remote_bt, "clicked", G_CALLBACK(options_remote_cb), NULL);
2945
2946     gtk_box_pack_start(GTK_BOX(right_vb), remote_bt, FALSE, FALSE, 0);
2947     gtk_widget_show(remote_bt);
2948   }
2949 #endif
2950
2951 #ifdef HAVE_AIRPCAP
2952   /*
2953    * *IF* this is an AirPcap interface, add the "Wireless Settings"
2954    * button.  Do *not* add it for other interfaces, as that can
2955    * confuse users, so that they ask why this is grayed out on
2956    * their non-Windows machine and ask how to enable it.
2957    */
2958   airpcap_if_selected = get_airpcap_if_from_name(airpcap_if_list, device.name);
2959   if (airpcap_if_selected != NULL) {
2960     advanced_bt = gtk_button_new_with_label("Wireless Settings");
2961
2962     /* Both the callback and the data are global */
2963     g_signal_connect(advanced_bt,"clicked", G_CALLBACK(options_airpcap_advanced_cb), wireless_tb);
2964
2965     gtk_box_pack_start(GTK_BOX(right_vb), advanced_bt, FALSE, FALSE, 0);
2966     gtk_widget_show(advanced_bt);
2967   }
2968 #endif
2969
2970 /* Button row: "Start", "Cancel" and "Help" buttons */
2971   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
2972   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
2973
2974   ok_but = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
2975   g_signal_connect(ok_but, "clicked", G_CALLBACK(save_options_cb), NULL);
2976   gtk_widget_set_tooltip_text(ok_but,
2977     "Accept interface settings.");
2978   cancel_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
2979   gtk_widget_set_tooltip_text(cancel_bt,
2980     "Cancel and exit dialog.");
2981   window_set_cancel_button(opt_edit_w, cancel_bt, window_cancel_button_cb);
2982   help_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
2983   gtk_widget_set_tooltip_text(help_bt,
2984     "Show help about capturing.");
2985   g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_CAPTURE_OPTIONS_DIALOG);
2986   dlg_set_activate(filter_te, ok_but);
2987   gtk_widget_grab_focus(filter_te);
2988   g_signal_connect(opt_edit_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
2989   g_signal_connect(opt_edit_w, "destroy", G_CALLBACK(options_edit_destroy_cb), NULL);
2990   gtk_widget_show_all(opt_edit_w);
2991   window_present(opt_edit_w);
2992 }
2993
2994 static void toggle_callback(GtkCellRendererToggle *cell _U_,
2995                gchar *path_str,
2996                gpointer data _U_)
2997 {
2998   /* get the treemodel from somewhere */
2999   GtkTreeIter   iter;
3000   GtkTreeView  *if_cb;
3001   GtkTreeModel *model;
3002   GtkTreePath  *path  = gtk_tree_path_new_from_string (path_str);
3003   gboolean      enabled;
3004   GtkWidget    *pcap_ng_cb, *filter_cm;
3005   interface_t   device;
3006   gchar        *name;
3007   gint          indx = -1;
3008   guint         i;
3009
3010   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3011   model = gtk_tree_view_get_model(if_cb);
3012   gtk_tree_model_get_iter (model, &iter, path);
3013   gtk_tree_model_get (model, &iter, CAPTURE, &enabled, IFACE_HIDDEN_NAME, &name, -1);
3014   /* Look for the right interface. The number of interfaces shown might be less
3015    * than the real number. Therefore the path index does not correspond
3016    * necessarily to the position in the list */
3017   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3018     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3019     if (strcmp(device.name, name) == 0) {
3020       indx = i;
3021       break;
3022     }
3023   }
3024   if (!device.locked) {
3025     if (enabled == FALSE) {
3026       device.selected = TRUE;
3027       global_capture_opts.num_selected++;
3028     } else {
3029       device.selected = FALSE;
3030       global_capture_opts.num_selected--;
3031     }
3032     device.locked = TRUE;
3033   }
3034   if (indx != -1) {
3035     global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, indx);
3036     g_array_insert_val(global_capture_opts.all_ifaces, indx, device);
3037     pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY);
3038     if (global_capture_opts.num_selected >= 2) {
3039       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE);
3040       gtk_widget_set_sensitive(pcap_ng_cb, FALSE);
3041     } else {
3042       gtk_widget_set_sensitive(pcap_ng_cb, TRUE);
3043     }
3044     if (global_capture_opts.num_selected > 0) {
3045       gtk_widget_set_sensitive(ok_bt, TRUE);
3046 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3047       gtk_widget_set_sensitive(all_compile_bt, TRUE);
3048 #endif
3049     } else {
3050       gtk_widget_set_sensitive(ok_bt, FALSE);
3051 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3052       gtk_widget_set_sensitive(all_compile_bt, FALSE);
3053 #endif
3054     }
3055   /* do something with the new enabled value, and set the new
3056      enabled value in your treemodel */
3057     gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, -1);
3058     if (interfaces_dialog_window_present()) {
3059       update_selected_interface(g_strdup(device.name));
3060     }
3061     if (get_welcome_window() != NULL) {
3062       change_interface_selection(g_strdup(device.name), device.selected);
3063     }
3064   }
3065   if (device.cfilter != NULL) {
3066     g_free(device.cfilter);
3067     device.cfilter = NULL;
3068     update_filter_string(device.name, NULL);
3069   }
3070   device.locked = FALSE;
3071   global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, indx);
3072   g_array_insert_val(global_capture_opts.all_ifaces, indx, device);
3073   gtk_tree_path_free (path);
3074   filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY);
3075   if (strcmp(gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(filter_cm)),"") != 0) {
3076     capture_all_filter_check_syntax_cb(NULL, NULL);
3077   }
3078   update_properties_all();
3079 }
3080
3081 void enable_selected_interface(gchar *name, gboolean selected)
3082 {
3083   GtkTreeIter   iter;
3084   GtkTreeView  *if_cb;
3085   GtkTreeModel *model;
3086   gchar        *name_str;
3087
3088   if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3089   model = gtk_tree_view_get_model(if_cb);
3090   gtk_tree_model_get_iter_first(model, &iter);
3091   do {
3092     gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &name_str, -1);
3093     if (strcmp(name, name_str) == 0) {
3094       gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, selected, -1);
3095       break;
3096     }
3097   }
3098   while (gtk_tree_model_iter_next(model, &iter));
3099   if (global_capture_opts.num_selected > 0) {
3100     gtk_widget_set_sensitive(ok_bt, TRUE);
3101 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3102     gtk_widget_set_sensitive(all_compile_bt, TRUE);
3103 #endif
3104   } else {
3105     gtk_widget_set_sensitive(ok_bt, FALSE);
3106 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3107     gtk_widget_set_sensitive(all_compile_bt, FALSE);
3108 #endif
3109   }
3110 }
3111
3112
3113 static void capture_all_cb(GtkToggleButton *button, gpointer d _U_)
3114 {
3115   GtkTreeIter   iter;
3116   GtkTreeView  *if_cb;
3117   GtkTreeModel *model;
3118   GtkWidget    *pcap_ng_cb;
3119   gboolean      enabled = FALSE, capture_set = FALSE;
3120
3121   if (gtk_toggle_button_get_active(button))
3122     enabled = TRUE;
3123   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3124   model = gtk_tree_view_get_model(if_cb);
3125   pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY);
3126   if (gtk_tree_model_get_iter_first(model, &iter)) {
3127     do {
3128       gtk_tree_model_get (model, &iter, CAPTURE, &capture_set, -1);
3129       if (!capture_set && enabled) {
3130         global_capture_opts.num_selected++;
3131       } else if (capture_set && !enabled) {
3132         global_capture_opts.num_selected--;
3133       }
3134       gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enabled, -1);
3135     } while (gtk_tree_model_iter_next(model, &iter));
3136   }
3137   if (global_capture_opts.num_selected >= 2) {
3138     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE);
3139     gtk_widget_set_sensitive(pcap_ng_cb, FALSE);
3140   } else if (global_capture_opts.num_selected <= 1) {
3141     gtk_widget_set_sensitive(pcap_ng_cb, TRUE);
3142   }
3143   if (interfaces_dialog_window_present()) {
3144     select_all_interfaces(enabled);
3145   }
3146   if (get_welcome_window() != NULL) {
3147     change_selection_for_all(enabled);
3148   }
3149   if (global_capture_opts.num_selected > 0) {
3150     gtk_widget_set_sensitive(ok_bt, TRUE);
3151 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3152     gtk_widget_set_sensitive(all_compile_bt, TRUE);
3153 #endif
3154   } else {
3155     gtk_widget_set_sensitive(ok_bt, FALSE);
3156 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3157     gtk_widget_set_sensitive(all_compile_bt, FALSE);
3158 #endif
3159   }
3160 }
3161
3162
3163 static gboolean get_all_prom_mode(void)
3164 {
3165   interface_options  interface_opts;
3166   guint i;
3167
3168   for (i = 0; i < global_capture_opts.ifaces->len; i++) {
3169     interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
3170     if (!interface_opts.promisc_mode) {
3171       return FALSE;
3172     }
3173   }
3174   return TRUE;
3175 }
3176
3177 static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_)
3178 {
3179   GtkTreeIter        iter;
3180   GtkTreeView       *if_cb;
3181   GtkTreeModel      *model;
3182   gboolean           enabled = FALSE, set;
3183   interface_t        device;
3184   interface_options  interface_opts;
3185   guint              i;
3186
3187   set = gtk_toggle_button_get_active(button);
3188   gtk_toggle_button_set_active(button, (set?FALSE:TRUE));
3189   if (gtk_toggle_button_get_active(button))
3190     enabled = TRUE;
3191
3192   if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3193   model = gtk_tree_view_get_model(if_cb);
3194   if (gtk_tree_model_get_iter_first(model, &iter)) {
3195     do {
3196       gtk_list_store_set(GTK_LIST_STORE(model), &iter, PMODE, enabled?"enabled":"disabled", -1);
3197     } while (gtk_tree_model_iter_next(model, &iter));
3198   }
3199
3200   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3201     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3202     global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
3203     device.pmode = (enabled?TRUE:FALSE);
3204     g_array_insert_val(global_capture_opts.all_ifaces, i, device);
3205   }
3206
3207   for (i = 0; i < global_capture_opts.ifaces->len; i++) {
3208     interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
3209     global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
3210     interface_opts.promisc_mode = (enabled?TRUE:FALSE);
3211     g_array_insert_val(global_capture_opts.ifaces, i, interface_opts);
3212   }
3213 }
3214
3215 #if defined (HAVE_PCAP_REMOTE)
3216 static void
3217 show_remote_dialog(GtkWidget *w)
3218 {
3219
3220   g_free(global_remote_opts.remote_host_opts.remote_host);
3221   g_free(global_remote_opts.remote_host_opts.remote_port);
3222   g_free(global_remote_opts.remote_host_opts.auth_username);
3223   g_free(global_remote_opts.remote_host_opts.auth_password);
3224   global_remote_opts.src_type = CAPTURE_IFREMOTE;
3225   global_remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
3226   global_remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
3227   global_remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
3228   global_remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
3229   global_remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
3230   global_remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
3231   global_remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
3232   global_remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
3233 #ifdef HAVE_PCAP_SETSAMPLING
3234   global_remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
3235   global_remote_opts.sampling_param = global_capture_opts.default_options.sampling_param;
3236 #endif
3237   capture_remote_cb(GTK_WIDGET(w), FALSE);
3238 }
3239 #endif
3240
3241 static void change_pipe_name_cb(gpointer dialog _U_, gint btn, gpointer data)
3242 {
3243   guint         i;
3244   interface_t   device;
3245   gchar        *temp, *optname, *snaplen_string/*, *oldname = ""*/;
3246   GtkTreeView  *if_cb;
3247   GtkTreeModel *model;
3248   GtkTreeIter   iter;
3249   GtkWidget    *pipe_te;
3250
3251   switch(btn) {
3252   case(ESD_BTN_OK):
3253     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3254       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3255         if (strcmp((gchar *)data, device.name) == 0) {
3256           simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3257                         "%sA pipe with this name already exists.%s",
3258                         simple_dialog_primary_start(), simple_dialog_primary_end());
3259           if_cb = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY));
3260           pipe_te             = (GtkWidget *) g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY);
3261           model = gtk_tree_view_get_model(if_cb);
3262           if (gtk_tree_model_get_iter_first (model, &iter)) {
3263             do {
3264               gtk_tree_model_get(model, &iter, 0, &optname, -1);
3265               if (strcmp(optname, (gchar *) data) == 0) {
3266                 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, pipe_name, -1);
3267                 gtk_entry_set_text(GTK_ENTRY(pipe_te), pipe_name);
3268                 break;
3269               }
3270             } while (gtk_tree_model_iter_next(model, &iter));
3271             g_free(optname);
3272           }
3273           return;
3274         }
3275       }
3276       for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3277         device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3278         if (strcmp(pipe_name, device.name) == 0) {
3279           device.name = g_strdup((gchar *)data);
3280           device.display_name = g_strdup_printf("%s", device.name);
3281           g_array_remove_index(global_capture_opts.all_ifaces, i);
3282           g_array_insert_val(global_capture_opts.all_ifaces, i, device);
3283           temp = g_strdup_printf("<b>%s</b>", device.display_name);
3284           if (device.has_snaplen) {
3285             snaplen_string = g_strdup_printf("%d", device.snaplen);
3286           } else {
3287             snaplen_string = g_strdup("default");
3288           }
3289           if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3290           model = gtk_tree_view_get_model(if_cb);
3291           if (gtk_tree_model_get_iter_first (model, &iter)) {
3292             do {
3293               gtk_tree_model_get(model, &iter, IFACE_HIDDEN_NAME, &optname, -1);
3294               if (strcmp(optname, pipe_name) == 0) {
3295 #if defined(HAVE_PCAP_CREATE)
3296                 gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, "",  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);
3297 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
3298                 gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, "",  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, FILTER, device.cfilter, -1);
3299 #else
3300                 gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, "",  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, device.cfilter, -1);
3301 #endif
3302 #if 0
3303                 oldname = g_strdup(pipe_name);
3304 #endif
3305                 pipe_name = g_strdup(device.name);
3306                 break;
3307               }
3308             } while (gtk_tree_model_iter_next(model, &iter));
3309
3310             g_free(optname);
3311           }
3312           if (global_capture_opts.num_selected > 0) {
3313             gtk_widget_set_sensitive(ok_bt, TRUE);
3314 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3315             gtk_widget_set_sensitive(all_compile_bt, TRUE);
3316 #endif
3317           } else {
3318             gtk_widget_set_sensitive(ok_bt, FALSE);
3319 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3320             gtk_widget_set_sensitive(all_compile_bt, FALSE);
3321 #endif
3322           }
3323           refresh_non_local_interface_lists();
3324           break;
3325         }
3326       }
3327       break;
3328     case(ESD_BTN_CANCEL): {
3329       if_cb = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY));
3330       pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY);
3331       model = gtk_tree_view_get_model(if_cb);
3332
3333       if (gtk_tree_model_get_iter_first (model, &iter)) {
3334         do {
3335           gtk_tree_model_get(model, &iter, 0, &optname, -1);
3336           if (strcmp(optname, (gchar *) data) == 0) {
3337             gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, pipe_name, -1);
3338             gtk_entry_set_text(GTK_ENTRY(pipe_te), pipe_name);
3339             break;
3340           }
3341         } while (gtk_tree_model_iter_next(model, &iter));
3342         g_free(optname);
3343       }
3344       break;
3345     }
3346     default:
3347       g_assert_not_reached();
3348   }
3349 }
3350
3351 static void
3352 add_pipe_cb(gpointer w _U_)
3353 {
3354   interface_t   device;
3355   gint          indx;
3356   GtkTreeView  *if_cb;
3357   GtkTreeModel *model;
3358   GtkTreeIter   iter;
3359   gchar        *temp, *path_str, *snaplen_string;
3360   GtkWidget    *pipe_te;
3361   const gchar  *g_save_file;
3362   gchar        *name;
3363   guint         i;
3364   gpointer      dialog;
3365
3366   pipe_te = (GtkWidget *) g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY);
3367   g_save_file = gtk_entry_get_text(GTK_ENTRY(pipe_te));
3368   name = g_strdup(g_save_file);
3369   if (strcmp(name, "New pipe") == 0 || strcmp(name, "") == 0) {
3370     g_free(name);
3371     return;
3372   }
3373   if (strcmp(pipe_name, "New pipe") != 0) {
3374     if (strcmp(pipe_name, name) != 0) {
3375       dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
3376                             "%sDo you want to change %s to %s?%s",
3377                             simple_dialog_primary_start(), pipe_name, name, simple_dialog_primary_end());
3378       simple_dialog_set_cb(dialog, change_pipe_name_cb, name);
3379     }
3380   } else {
3381     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3382       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3383       if (strcmp(name, device.name) == 0) {
3384         g_free(name);
3385         return;
3386       }
3387     }
3388     pipe_name           = g_strdup(g_save_file);
3389     device.name         = g_strdup(g_save_file);
3390     device.display_name = g_strdup_printf("%s", device.name);
3391     device.hidden       = FALSE;
3392     device.selected     = TRUE;
3393     device.type         = IF_PIPE;
3394     device.pmode        = global_capture_opts.default_options.promisc_mode;
3395     device.has_snaplen  = global_capture_opts.default_options.has_snaplen;
3396     device.snaplen      = global_capture_opts.default_options.snaplen;
3397     device.cfilter      = g_strdup(global_capture_opts.default_options.cfilter);
3398     device.addresses    = NULL;
3399     device.no_addresses = 0;
3400     device.last_packets = 0;
3401     device.links        = NULL;
3402 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
3403     device.buffer       = DEFAULT_CAPTURE_BUFFER_SIZE;
3404 #endif
3405     device.active_dlt   = -1;
3406     device.locked       = FALSE;
3407     device.if_info.name = g_strdup(g_save_file);
3408     device.if_info.friendly_name = NULL;
3409     device.if_info.vendor_description = NULL;
3410     device.if_info.addrs = NULL;
3411     device.if_info.loopback = FALSE;
3412 #if defined(HAVE_PCAP_CREATE)
3413     device.monitor_mode_enabled   = FALSE;
3414     device.monitor_mode_supported = FALSE;
3415 #endif
3416     global_capture_opts.num_selected++;
3417
3418     indx = global_capture_opts.all_ifaces->len;
3419     temp = g_strdup_printf("<b>%s</b>", device.display_name);
3420
3421     if (device.has_snaplen) {
3422       snaplen_string = g_strdup_printf("%d", device.snaplen);
3423     } else {
3424       snaplen_string = g_strdup("default");
3425     }
3426
3427     if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3428     path_str = g_strdup_printf("%d", indx);
3429     model = gtk_tree_view_get_model(if_cb);
3430     gtk_tree_model_get_iter_from_string(model, &iter, path_str);
3431     g_array_append_val(global_capture_opts.all_ifaces, device);
3432     gtk_list_store_append (GTK_LIST_STORE(model), &iter);
3433 #if defined(HAVE_PCAP_CREATE)
3434     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp, LINK, "",  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);
3435 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
3436     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, "",  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) device.buffer, FILTER, device.cfilter, -1);
3437 #else
3438     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, device.selected, IFACE_HIDDEN_NAME, device.name, INTERFACE, temp,LINK, "",  PMODE, device.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, device.cfilter, -1);
3439 #endif
3440     if (global_capture_opts.num_selected > 0) {
3441       gtk_widget_set_sensitive(ok_bt, TRUE);
3442 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3443       gtk_widget_set_sensitive(all_compile_bt, TRUE);
3444 #endif
3445     } else {
3446       gtk_widget_set_sensitive(ok_bt, FALSE);
3447 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
3448       gtk_widget_set_sensitive(all_compile_bt, FALSE);
3449 #endif
3450     }
3451
3452     /* Refresh all places that are displaying an interface list
3453        that includes interfaces other than local interfaces
3454        (such as pipes). */
3455     refresh_non_local_interface_lists();
3456
3457     g_free(name);
3458   }
3459 }
3460
3461 static void
3462 pipe_new_bt_clicked_cb(GtkWidget *w _U_, gpointer data _U_)
3463 {
3464   GtkWidget    *name_te = (GtkWidget *)g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY);
3465   GtkTreeView  *pipe_l  = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY));
3466   GtkListStore *store;
3467   GtkTreeIter   iter;
3468
3469   /* Add a new entry to the pipe list. */
3470
3471   store = GTK_LIST_STORE(gtk_tree_view_get_model(pipe_l));
3472   gtk_list_store_append(store, &iter);
3473
3474   gtk_list_store_set(store, &iter, 0, "New pipe", -1);
3475   pipe_name = "New pipe";
3476
3477   /* Select the item. */
3478   gtk_tree_selection_select_iter(gtk_tree_view_get_selection(pipe_l), &iter);
3479
3480   gtk_editable_select_region(GTK_EDITABLE(name_te), 0, -1);
3481
3482   gtk_widget_grab_focus(name_te);
3483 }
3484
3485 static void
3486 pipe_del_bt_clicked_cb(GtkWidget *w _U_, gpointer data _U_)
3487 {
3488   GtkWidget        *pipe_l  = (GtkWidget *)g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY);
3489   GtkWidget        *name_te = (GtkWidget *)g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY);
3490   GtkTreeSelection *sel;
3491   GtkTreeModel     *model, *optmodel;
3492   GtkTreeIter       iter, optiter;
3493   GtkTreeView      *if_cb;
3494   gchar            *name, *optname = NULL;
3495   guint             i;
3496
3497   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(pipe_l));
3498   /* If something was selected */
3499
3500   if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
3501     gtk_tree_model_get(model, &iter, 0, &name, -1);
3502     if (name != NULL && atoi(gtk_tree_model_get_string_from_iter(model, &iter)) < (gint)global_capture_opts.all_ifaces->len) {
3503       for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3504         if (strcmp(g_array_index(global_capture_opts.all_ifaces, interface_t, i).name, name) == 0) {
3505           g_array_remove_index(global_capture_opts.all_ifaces, i);
3506           break;
3507         }
3508       }
3509       gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3510       gtk_entry_set_text(GTK_ENTRY(name_te), "");
3511       if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3512       optmodel = gtk_tree_view_get_model(if_cb);
3513       if (gtk_tree_model_get_iter_first (optmodel, &optiter)) {
3514         do {
3515           gtk_tree_model_get(optmodel, &optiter, IFACE_HIDDEN_NAME, &optname, -1);
3516           if (optname != NULL && strcmp(optname, name) == 0) {
3517             gtk_list_store_remove(GTK_LIST_STORE(gtk_tree_view_get_model(if_cb)), &optiter);
3518             break;
3519           }
3520         } while (gtk_tree_model_iter_next(optmodel, &optiter));
3521         g_free(optname);
3522       }
3523     }
3524     g_free(name);
3525   }
3526
3527   if (gtk_tree_model_get_iter_first (model, &iter)) {
3528     gtk_tree_selection_select_iter(sel, &iter);
3529   } else {
3530     gtk_widget_set_sensitive(name_te, FALSE);
3531   }
3532
3533   /* Refresh all places that are displaying an interface list
3534      that includes interfaces other than local interfaces
3535      (such as pipes). */
3536   refresh_non_local_interface_lists();
3537 }
3538
3539 static void
3540 pipe_name_te_changed_cb(GtkWidget *w _U_, gpointer data _U_)
3541 {
3542   GtkWidget        *name_te = (GtkWidget *)g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY);
3543   GtkWidget        *pipe_l  = (GtkWidget *)g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY);
3544   const gchar      *name;
3545   GtkTreeSelection *sel;
3546   GtkTreeModel     *model;
3547   GtkTreeIter       iter;
3548
3549   sel  = gtk_tree_view_get_selection(GTK_TREE_VIEW(pipe_l));
3550   name = gtk_entry_get_text(GTK_ENTRY(name_te));
3551
3552   /* if something was selected */
3553   if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
3554     gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, name, -1);
3555   }
3556 }
3557
3558 static void
3559 fill_pipe_list(void)
3560 {
3561   guint         i;
3562   interface_t   device;
3563   GtkTreeIter   iter;
3564   GtkTreeView  *pipe_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY));
3565   GtkListStore *store  = GTK_LIST_STORE(gtk_tree_view_get_model(pipe_l));
3566
3567   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3568     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3569     if (device.type == IF_PIPE) {
3570       gtk_list_store_append(store, &iter);
3571       gtk_list_store_set(store, &iter, 0, device.name, -1);
3572     } else {
3573       continue;
3574     }
3575   }
3576 }
3577
3578 static void
3579 pipe_sel_list_cb(GtkTreeSelection *sel, gpointer data _U_)
3580 {
3581  /* GtkWidget    *pipe_l   = GTK_WIDGET(gtk_tree_selection_get_tree_view(sel));*/
3582   GtkTreeModel *model;
3583   GtkTreeIter   iter;
3584   GtkWidget    *name_te = (GtkWidget *)g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY);
3585   GtkWidget    *del_bt  = (GtkWidget *)g_object_get_data(G_OBJECT(interface_management_w), E_CAP_PIPE_DEL_KEY);
3586   gchar        *name    = NULL;
3587
3588   if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
3589     gtk_tree_model_get(model, &iter, 0, &name, -1);
3590     if (name) {
3591       if (name_te != NULL) {
3592         gtk_entry_set_text(GTK_ENTRY(name_te), name ? name : "");
3593         gtk_widget_set_sensitive(name_te, TRUE);
3594         selected_name = gtk_entry_get_text(GTK_ENTRY(name_te));
3595         pipe_name = g_strdup(selected_name);
3596       }
3597       if (del_bt != NULL) {
3598         gtk_widget_set_sensitive(del_bt, TRUE);
3599       }
3600       g_free(name);
3601     }
3602   }
3603 }
3604
3605 static void
3606 cancel_pipe_cb (gpointer w _U_)
3607 {
3608   window_destroy(GTK_WIDGET(interface_management_w));
3609 }
3610
3611 static void
3612 fill_local_list(void)
3613 {
3614   guint         i;
3615   interface_t   device;
3616   GtkTreeIter   iter;
3617   GtkListStore *store;
3618   GtkTreeView  *local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY));
3619
3620 #ifdef _WIN32
3621   store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
3622 #else
3623   store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3624 #endif
3625
3626   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3627     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3628     if (device.local && device.type != IF_PIPE && device.type != IF_STDIN) {
3629       gtk_list_store_append(store, &iter);
3630
3631 #ifdef _WIN32
3632       gtk_list_store_set(store, &iter, 0, device.friendly_name, 1, device.name,  2, device.hidden, -1);
3633 #else
3634       gtk_list_store_set(store, &iter, 0, device.name, 1, device.hidden, -1);
3635 #endif
3636     } else {
3637       continue;
3638     }
3639   }
3640   gtk_tree_view_set_model(GTK_TREE_VIEW(local_l), GTK_TREE_MODEL(store));
3641 }
3642
3643 static void local_hide_cb(GtkCellRendererToggle *cell _U_,
3644                           gchar *path_str,
3645                           gpointer data _U_)
3646 {
3647   gboolean      hide, hide_enabled = TRUE;
3648   gchar        *name;
3649   GtkTreeModel *model;
3650   GtkTreeIter   iter;
3651   GtkTreePath  *path    = gtk_tree_path_new_from_string (path_str);
3652   GtkTreeView  *local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY));
3653
3654   model = gtk_tree_view_get_model(local_l);
3655   gtk_tree_model_get_iter (model, &iter, path);
3656   gtk_tree_model_get (model, &iter, 0+LOCAL_OFFSET, &name, 1+LOCAL_OFFSET, &hide, -1);
3657
3658   /* See if this is the currently selected capturing device */
3659   if ((prefs.capture_device != NULL) && (*prefs.capture_device != '\0')) {
3660      guint i;
3661      interface_t device;
3662      for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3663         device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3664         if ((strcmp(device.display_name, prefs.capture_device) == 0) &&
3665             (strcmp(device.name, name) == 0)) {
3666                /* Don't allow current interface to be hidden */
3667                hide_enabled = FALSE;
3668                break;
3669         }
3670      }
3671   }
3672
3673   if (hide_enabled) {
3674      if (hide) {
3675         gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1+LOCAL_OFFSET, FALSE, -1);
3676       } else {
3677         gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1+LOCAL_OFFSET, TRUE, -1);
3678       }
3679   } else {
3680     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Default interface cannot be hidden");
3681   }
3682 }
3683
3684 static void
3685 apply_local_cb(GtkWidget *win _U_, gpointer *data _U_)
3686 {
3687   GtkTreeIter   iter;
3688   GtkTreeModel *model;
3689   gchar        *name, *new_hide;
3690   gboolean      hide;
3691   gint          first_if = TRUE;
3692   GtkTreeView  *local_l;
3693
3694   if (global_capture_opts.all_ifaces->len > 0) {
3695     local_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY));
3696     model = gtk_tree_view_get_model(local_l);
3697
3698     new_hide = (gchar*)g_malloc0(MAX_VAL_LEN);
3699
3700     if (gtk_tree_model_get_iter_first (model, &iter)) {
3701       do {
3702         gtk_tree_model_get(model, &iter, 0+LOCAL_OFFSET, &name, 1+LOCAL_OFFSET, &hide, -1);
3703         if (!hide) {
3704           continue;
3705         } else {
3706           if (first_if != TRUE) {
3707             g_strlcat (new_hide, ",", MAX_VAL_LEN);
3708           }
3709           g_strlcat (new_hide, name, MAX_VAL_LEN);
3710           first_if = FALSE;
3711         }
3712       } while (gtk_tree_model_iter_next(model, &iter));
3713       g_free(name);
3714     }
3715     /* write new "hidden" string to preferences */
3716     g_free(prefs.capture_devices_hide);
3717     prefs.capture_devices_hide = new_hide;
3718     hide_interface(g_strdup(new_hide));
3719
3720     /* Refresh all places that are displaying an interface list
3721        that includes local interfaces. */
3722     refresh_local_interface_lists();
3723
3724     /* save changes to the preferences file */
3725     if (!prefs.gui_use_pref_save) {
3726       prefs_main_write();
3727     }
3728   }
3729 }
3730
3731 void
3732 capture_dlg_refresh_if (void)
3733 {
3734   GtkTreeView *view;
3735
3736   fill_local_list();
3737
3738   view = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
3739   create_and_fill_model(GTK_TREE_VIEW(view));
3740   update_properties_all();
3741 }
3742
3743 static void
3744 rescan_local_cb(GtkWidget *button _U_, gpointer *data _U_)
3745 {
3746   /* Refresh all places that are displaying an interface list
3747      that includes local interfaces. */
3748   refresh_local_interface_lists();
3749 }
3750
3751 #if defined(HAVE_PCAP_REMOTE)
3752 static void
3753 fill_remote_list(void)
3754 {
3755   guint         i;
3756   interface_t   device;
3757   GtkTreeIter   iter, child;
3758   gchar        *host = "";
3759   GtkTreeView  *remote_l;
3760   GtkTreeStore *store;
3761   GtkWidget    *host_te, *remote_w;
3762
3763   num_selected = 0;
3764   gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY), FALSE);
3765   remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY));
3766   store = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING);
3767   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3768     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3769     if (device.local) {
3770       continue;
3771     } else {
3772       /* fill the store */
3773       if (strcmp(host, device.remote_opts.remote_host_opts.remote_host) != 0) {
3774         remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY);
3775         host_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_HOST_TE_KEY);
3776         iftype_combo_box_add (host_te, &device);
3777         host = g_strdup(device.remote_opts.remote_host_opts.remote_host);
3778         gtk_tree_store_append(store, &iter, NULL);
3779         gtk_tree_store_set(store, &iter, 0, host, 3, "FALSE", -1);
3780         gtk_tree_store_append(store, &child, &iter);
3781         gtk_tree_store_set(store, &child, 1, device.name, 2, device.hidden, 3, "TRUE", -1);
3782       } else {
3783         gtk_tree_store_append(store, &child, &iter);
3784         gtk_tree_store_set(store, &child, 1, device.name, 2, device.hidden, 3, "TRUE", -1);
3785       }
3786     }
3787   }
3788   gtk_tree_view_set_model(GTK_TREE_VIEW(remote_l), GTK_TREE_MODEL(store));
3789   gtk_tree_view_expand_all(GTK_TREE_VIEW(remote_l));
3790 }
3791
3792 static void
3793 button_hide_cb(GtkTreeViewColumn *column, GtkCellRenderer *renderer,
3794                GtkTreeModel *model, GtkTreeIter *iter, gpointer data _U_)
3795 {
3796   gchar *enabled;
3797
3798   gtk_tree_model_get(model, iter, 3, &enabled, -1);
3799   if (strcmp(enabled, "TRUE") == 0) {
3800     g_object_set(G_OBJECT(renderer), "visible", TRUE, NULL);
3801   } else if (strcmp(enabled, "FALSE") == 0){
3802     g_object_set(G_OBJECT(renderer), "visible", FALSE, NULL);
3803   }
3804 }
3805
3806 static void remote_hide_cb(GtkCellRendererToggle *cell _U_,
3807                            gchar *path_str,
3808                            gpointer data _U_)
3809 {
3810   gboolean      hide;
3811   GtkTreeModel *model;
3812   GtkTreeIter   iter;
3813   GtkTreePath  *path     = gtk_tree_path_new_from_string (path_str);
3814   GtkTreeView  *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY));
3815
3816   model = gtk_tree_view_get_model(remote_l);
3817   gtk_tree_model_get_iter (model, &iter, path);
3818   gtk_tree_model_get (model, &iter, 2, &hide, -1);
3819
3820   if (hide) {
3821     gtk_tree_store_set(GTK_TREE_STORE(model), &iter, 2, FALSE, -1);
3822   } else {
3823     gtk_tree_store_set(GTK_TREE_STORE(model), &iter, 2, TRUE, -1);
3824   }
3825 }
3826
3827 static void
3828 ok_remote_cb(GtkWidget *win _U_, gpointer *data _U_)
3829 {
3830   GtkTreeIter   iter, child;
3831   GtkTreeModel *model;
3832   gchar        *name, *new_hide;
3833   gboolean      hide;
3834   gint          first_if = TRUE;
3835
3836   GtkTreeView   *remote_l = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY));
3837   model = gtk_tree_view_get_model(remote_l);
3838
3839   new_hide = g_malloc0(MAX_VAL_LEN);
3840
3841   if (gtk_tree_model_get_iter_first (model, &iter)) {
3842     do {
3843       gtk_tree_model_get(model, &iter, 1, &name, 2, &hide, -1);
3844       if (!name && gtk_tree_model_iter_children(model, &child, &iter)) {
3845         do {
3846           gtk_tree_model_get(model, &child, 1, &name, 2, &hide, -1);
3847           if (!hide) {
3848             continue;
3849           } else {
3850             if (first_if != TRUE) {
3851               g_strlcat (new_hide, ",", MAX_VAL_LEN);
3852             }
3853             g_strlcat (new_hide, name, MAX_VAL_LEN);
3854             first_if = FALSE;
3855           }
3856         } while (gtk_tree_model_iter_next(model, &child));
3857       }
3858     } while (gtk_tree_model_iter_next(model, &iter));
3859     g_free(name);
3860   }
3861   hide_interface(g_strdup(new_hide));
3862
3863   /* Refresh all places that are displaying an interface list
3864      that includes interfaces other than local interfaces
3865      (such as remote interfaces). */
3866   refresh_non_local_interface_lists();
3867 }
3868
3869 static gboolean
3870 select_host_cb(GtkTreeSelection *selection _U_,
3871                GtkTreeModel *model,
3872                GtkTreePath *path,
3873                gboolean path_currently_selected _U_,
3874                gpointer data _U_)
3875 {
3876   GtkTreeIter  iter;
3877
3878   gtk_tree_model_get_iter (model, &iter, path);
3879   if (gtk_tree_model_iter_has_child(model, &iter)) {
3880     num_selected++;
3881     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY), TRUE);
3882     return TRUE;
3883   } else {
3884     return FALSE;
3885   }
3886 }
3887
3888 static void
3889 remove_remote_host(GtkWidget *w _U_, gpointer data _U_)
3890 {
3891   GtkTreeIter       iter, child;
3892   GtkTreeModel     *model;
3893   gchar            *host;
3894   gint              num_children, i;
3895   interface_t       device;
3896   GtkTreeView      *remote_l  = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY));
3897   GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(remote_l));
3898
3899   model = gtk_tree_view_get_model(remote_l);
3900   if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
3901     gtk_tree_model_get(model, &iter, 0, &host, -1);
3902     if ((num_children = gtk_tree_model_iter_n_children(model, &iter)) > 0) {
3903       for (i = num_children-1; i >= 0; i--) {
3904         if (gtk_tree_model_iter_nth_child(model, &child, &iter, i)) {
3905           gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
3906         }
3907       }
3908     }
3909     gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
3910     if (--num_selected == 0) {
3911       gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY), FALSE);
3912     }
3913     for (i = global_capture_opts.all_ifaces->len-1; i >= 0; i--) {
3914       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3915       if (device.local) {
3916         continue;
3917       } else {
3918         if (strcmp(host, device.remote_opts.remote_host_opts.remote_host) == 0) {
3919           g_array_remove_index(global_capture_opts.all_ifaces, i);
3920         }
3921       }
3922     }
3923
3924     /* Refresh all places that are displaying an interface list
3925        that includes interfaces other than local interfaces
3926        (such as remote interfaces). */
3927     refresh_non_local_interface_lists();
3928   }
3929 }
3930 #endif
3931
3932 static void
3933 show_add_interfaces_dialog(GtkWidget *bt _U_, GtkWidget *parent_win)
3934 {
3935   GtkWidget         *vbox, *top_hb;
3936   GtkWidget         *hbox, *bbox, *list_bb, *edit_fr, *pipe_fr, *pipe_sc, *pipe_l, *props_fr, *props_vb;
3937   GtkWidget         *main_nb;
3938   GtkWidget         *temp_page, *tmp;
3939   GtkWidget         *pipe_hb, *pipe_bt, *pipe_lb, *pipe_te, *pipe_vb;
3940   GtkWidget         *add_bt, *cancel_bt, *new_bt, *del_bt, *middle_hb;
3941   GtkWidget         *local_fr, *local_l, *local_sc, *local_vb;
3942   GtkWidget         *apply_bt, *refresh_bt;
3943   GtkCellRenderer   *renderer, *toggle_renderer;
3944   GtkTreeViewColumn *column;
3945   GtkTreeSelection  *sel;
3946   GtkListStore      *store;
3947 #if defined(HAVE_PCAP_REMOTE)
3948   GtkWidget         *remote_fr, *remote_l, *remote_sc, *remote_vb;
3949   GtkWidget         *delete_bt, *add_but, *ok_but;
3950   GtkWidget         *button_hbox, *help_hbox;
3951   GtkTreeSelection  *selection;
3952 #endif
3953
3954   interface_management_w = window_new(GTK_WINDOW_TOPLEVEL, "Interface Management");
3955   gtk_window_set_transient_for(GTK_WINDOW(interface_management_w), GTK_WINDOW(parent_win));
3956   gtk_window_set_destroy_with_parent(GTK_WINDOW(interface_management_w), TRUE);
3957
3958   gtk_window_set_default_size(GTK_WINDOW(interface_management_w), 700, 300);
3959
3960   vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
3961   gtk_container_add(GTK_CONTAINER(interface_management_w), vbox);
3962   gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
3963
3964   main_nb = gtk_notebook_new();
3965   gtk_box_pack_start(GTK_BOX(vbox), main_nb, TRUE, TRUE, 0);
3966
3967   /* --- Pipes --- */
3968   temp_page = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
3969   tmp = gtk_label_new("Pipes");
3970   gtk_widget_show(tmp);
3971   hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
3972   gtk_box_pack_start(GTK_BOX (hbox), tmp, TRUE, TRUE, 0);
3973
3974   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
3975
3976   /* Pipe row */
3977   pipe_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 20, FALSE);
3978   gtk_container_set_border_width(GTK_CONTAINER(pipe_hb), 5);
3979   gtk_box_pack_start(GTK_BOX(temp_page), pipe_hb, TRUE, TRUE, 0);
3980
3981   /* Container for each row of widgets */
3982   pipe_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
3983   gtk_container_set_border_width(GTK_CONTAINER(pipe_vb), 0);
3984   gtk_box_pack_start(GTK_BOX (pipe_hb), pipe_vb, TRUE, TRUE, 0);
3985   gtk_widget_show(pipe_vb);
3986
3987   /* Top row: Buttons and pipe list */
3988   top_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
3989   gtk_box_pack_start(GTK_BOX (pipe_vb), top_hb, TRUE, TRUE, 0);
3990   gtk_widget_show(top_hb);
3991
3992   edit_fr = gtk_frame_new("");
3993   gtk_box_pack_start(GTK_BOX(top_hb), edit_fr, FALSE, FALSE, 0);
3994   gtk_widget_show(edit_fr);
3995
3996   list_bb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, TRUE);
3997   gtk_container_set_border_width(GTK_CONTAINER(list_bb), 5);
3998   gtk_container_add(GTK_CONTAINER(edit_fr), list_bb);
3999   gtk_widget_show(list_bb);
4000
4001   new_bt = gtk_button_new_from_stock(GTK_STOCK_NEW);
4002   g_signal_connect(new_bt, "clicked", G_CALLBACK(pipe_new_bt_clicked_cb), NULL);
4003   gtk_widget_show(new_bt);
4004   gtk_box_pack_start (GTK_BOX (list_bb), new_bt, FALSE, FALSE, 0);
4005   gtk_widget_set_tooltip_text (new_bt, "Add a new pipe (with default properties)");
4006
4007   del_bt = gtk_button_new_from_stock(GTK_STOCK_DELETE);
4008   g_signal_connect(del_bt, "clicked", G_CALLBACK(pipe_del_bt_clicked_cb), NULL);
4009   gtk_widget_show(del_bt);
4010   gtk_widget_set_sensitive(del_bt, FALSE);
4011   gtk_box_pack_start (GTK_BOX (list_bb), del_bt, FALSE, FALSE, 0);
4012   gtk_widget_set_tooltip_text (del_bt, "Remove the selected pipe from the list");
4013   g_object_set_data(G_OBJECT(interface_management_w), E_CAP_PIPE_DEL_KEY,  del_bt);
4014
4015   pipe_fr = gtk_frame_new("Pipes");
4016   gtk_box_pack_start(GTK_BOX(top_hb), pipe_fr, TRUE, TRUE, 0);
4017   gtk_widget_show(pipe_fr);
4018
4019   pipe_sc = scrolled_window_new(NULL, NULL);
4020   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(pipe_sc),
4021                                       GTK_SHADOW_IN);
4022
4023   gtk_container_set_border_width  (GTK_CONTAINER (pipe_sc), 5);
4024   gtk_container_add(GTK_CONTAINER(pipe_fr), pipe_sc);
4025   gtk_widget_show(pipe_sc);
4026
4027   store = gtk_list_store_new(1, G_TYPE_STRING);
4028   pipe_l = tree_view_new(GTK_TREE_MODEL(store));
4029   gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pipe_l), FALSE);
4030
4031   renderer = gtk_cell_renderer_text_new();
4032   column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
4033   gtk_tree_view_column_set_expand(column, TRUE);
4034   gtk_tree_view_column_set_sort_column_id(column, 0);
4035   gtk_tree_view_append_column(GTK_TREE_VIEW(pipe_l), column);
4036
4037   sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(pipe_l));
4038   gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
4039   g_object_set_data(G_OBJECT(interface_management_w), E_CAP_PIPE_L_KEY, pipe_l);
4040   g_signal_connect(sel, "changed", G_CALLBACK(pipe_sel_list_cb), pipe_vb);
4041   gtk_container_add(GTK_CONTAINER(pipe_sc), pipe_l);
4042   gtk_widget_show(pipe_l);
4043
4044   fill_pipe_list();
4045
4046   g_object_unref(G_OBJECT(store));
4047
4048   props_fr = gtk_frame_new("");
4049   gtk_box_pack_start(GTK_BOX(pipe_vb), props_fr, FALSE, FALSE, 0);
4050   gtk_widget_show(props_fr);
4051
4052   props_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
4053   gtk_container_set_border_width(GTK_CONTAINER(props_vb), 5);
4054   gtk_container_add(GTK_CONTAINER(props_fr), props_vb);
4055   gtk_widget_show(props_vb);
4056
4057   middle_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
4058   gtk_box_pack_start(GTK_BOX (props_vb), middle_hb, TRUE, TRUE, 0);
4059   gtk_widget_show(middle_hb);
4060
4061   pipe_lb = gtk_label_new("Pipe:");
4062   gtk_box_pack_start(GTK_BOX(middle_hb), pipe_lb, FALSE, FALSE, 3);
4063   pipe_te = gtk_entry_new();
4064   gtk_widget_set_tooltip_text(GTK_WIDGET(pipe_te),
4065     "Enter the name of the pipe data should be captured from. "
4066      );
4067   gtk_box_pack_start(GTK_BOX(middle_hb), pipe_te, TRUE, TRUE, 3);
4068   gtk_widget_set_sensitive(pipe_te, FALSE);
4069   pipe_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_BROWSE);
4070   gtk_widget_set_tooltip_text(GTK_WIDGET(pipe_bt),
4071     "Select a pipe from which data should be captured, "
4072     "instead of entering the pipe name directly. "
4073     );
4074   gtk_box_pack_start(GTK_BOX(middle_hb), pipe_bt, FALSE, FALSE, 0);
4075   g_signal_connect(pipe_te, "changed", G_CALLBACK(pipe_name_te_changed_cb), NULL);
4076   g_signal_connect(pipe_bt, "clicked", G_CALLBACK(capture_prep_pipe_cb), pipe_te);
4077
4078   bbox = dlg_button_row_new(GTK_STOCK_SAVE, GTK_STOCK_CLOSE, NULL);
4079   gtk_box_pack_start(GTK_BOX(temp_page), bbox, FALSE, FALSE, 5);
4080
4081   add_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE);
4082   g_signal_connect(add_bt, "clicked", G_CALLBACK(add_pipe_cb), interface_management_w);
4083   gtk_widget_set_tooltip_text(GTK_WIDGET(add_bt), "Add pipe to the list of interfaces.");
4084
4085   cancel_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
4086   g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), interface_management_w);
4087   gtk_widget_set_tooltip_text(GTK_WIDGET(cancel_bt), "Cancel and exit dialog.");
4088
4089   gtk_widget_show(bbox);
4090   gtk_widget_show(temp_page);
4091
4092   g_object_set_data(G_OBJECT(interface_management_w), E_CAP_PIPE_TE_KEY,  pipe_te);
4093
4094   /* --- Local interfaces --- */
4095   temp_page = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
4096   tmp = gtk_label_new("Local Interfaces");
4097   gtk_widget_show(tmp);
4098   hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
4099   gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 0);
4100   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
4101
4102   local_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
4103   gtk_container_set_border_width(GTK_CONTAINER(local_vb), 0);
4104   gtk_box_pack_start(GTK_BOX(temp_page), local_vb, TRUE, TRUE, 0);
4105   gtk_widget_show(local_vb);
4106
4107   local_fr = gtk_frame_new("Local Interfaces");
4108   gtk_box_pack_start(GTK_BOX(local_vb), local_fr, TRUE, TRUE, 0);
4109   gtk_widget_show(local_fr);
4110
4111   local_sc = scrolled_window_new(NULL, NULL);
4112   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(local_sc),
4113                                       GTK_SHADOW_IN);
4114
4115   gtk_container_set_border_width  (GTK_CONTAINER (local_sc), 5);
4116   gtk_container_add(GTK_CONTAINER(local_fr), local_sc);
4117   gtk_widget_show(local_sc);
4118
4119   local_l = gtk_tree_view_new();
4120
4121 #ifdef _WIN32
4122   renderer = gtk_cell_renderer_text_new();
4123   column = gtk_tree_view_column_new_with_attributes("Friendly Name", renderer, "text", 0, NULL);
4124   gtk_tree_view_column_set_expand(column, TRUE);
4125   gtk_tree_view_column_set_sort_column_id(column, 0);
4126   gtk_tree_view_append_column(GTK_TREE_VIEW(local_l), column);
4127 #endif
4128
4129   renderer = gtk_cell_renderer_text_new();
4130   column = gtk_tree_view_column_new_with_attributes("Interface Name", renderer, "text", 0+LOCAL_OFFSET, NULL);
4131   gtk_tree_view_column_set_expand(column, TRUE);
4132   gtk_tree_view_column_set_sort_column_id(column, 0+LOCAL_OFFSET);
4133   gtk_tree_view_append_column(GTK_TREE_VIEW(local_l), column);
4134
4135   toggle_renderer = gtk_cell_renderer_toggle_new();
4136   column = gtk_tree_view_column_new_with_attributes("Hide", GTK_CELL_RENDERER(toggle_renderer), "active", 1+LOCAL_OFFSET, NULL);
4137   g_signal_connect (G_OBJECT(toggle_renderer), "toggled", G_CALLBACK (local_hide_cb), NULL);
4138   gtk_tree_view_append_column(GTK_TREE_VIEW(local_l), column);
4139   gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(toggle_renderer), TRUE);
4140
4141   g_object_set_data(G_OBJECT(interface_management_w), E_CAP_LOCAL_L_KEY, local_l);
4142   gtk_container_add(GTK_CONTAINER(local_sc), local_l);
4143   gtk_widget_show(local_l);
4144
4145   fill_local_list();
4146
4147   bbox = dlg_button_row_new(GTK_STOCK_REFRESH, GTK_STOCK_APPLY, GTK_STOCK_CLOSE, NULL);
4148
4149   gtk_box_pack_start(GTK_BOX(temp_page), bbox, FALSE, FALSE, 5);
4150   refresh_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_REFRESH);
4151   g_signal_connect(refresh_bt, "clicked", G_CALLBACK(rescan_local_cb), NULL);
4152   gtk_widget_set_tooltip_text(GTK_WIDGET(refresh_bt), "Rescan the local interfaces and refresh the list");
4153
4154   cancel_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
4155   g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), interface_management_w);
4156   gtk_widget_set_tooltip_text(GTK_WIDGET(cancel_bt), "Cancel and exit dialog.");
4157
4158   apply_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_APPLY);
4159   g_signal_connect(GTK_WIDGET(apply_bt), "clicked", G_CALLBACK(apply_local_cb), NULL);
4160   gtk_widget_set_tooltip_text(GTK_WIDGET(apply_bt), "Apply the changes to the general list of local interfaces");
4161
4162   gtk_widget_show(bbox);
4163   gtk_widget_show(temp_page);
4164
4165
4166 #if defined (HAVE_PCAP_REMOTE)
4167   /* --- remote interfaces --- */
4168   temp_page = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
4169   tmp = gtk_label_new("Remote Interfaces");
4170   gtk_widget_show(tmp);
4171   hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
4172   gtk_box_pack_start(GTK_BOX (hbox), tmp, TRUE, TRUE, 0);
4173   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
4174
4175   remote_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
4176   gtk_container_set_border_width(GTK_CONTAINER(remote_vb), 0);
4177   gtk_box_pack_start(GTK_BOX(temp_page), remote_vb, TRUE, TRUE, 0);
4178   gtk_widget_show(remote_vb);
4179
4180   remote_fr = gtk_frame_new("Remote Interfaces");
4181   gtk_box_pack_start(GTK_BOX(remote_vb), remote_fr, TRUE, TRUE, 0);
4182   gtk_widget_show(remote_fr);
4183
4184   remote_sc = scrolled_window_new(NULL, NULL);
4185   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(remote_sc),
4186                                       GTK_SHADOW_IN);
4187
4188   gtk_container_set_border_width  (GTK_CONTAINER (remote_sc), 5);
4189   gtk_container_add(GTK_CONTAINER(remote_fr), remote_sc);
4190   gtk_widget_show(remote_sc);
4191
4192   remote_l = gtk_tree_view_new();
4193
4194   renderer = gtk_cell_renderer_text_new();
4195   column = gtk_tree_view_column_new_with_attributes("Host", renderer, "text", 0, NULL);
4196   gtk_tree_view_column_set_expand(column, TRUE);
4197   gtk_tree_view_column_set_sort_column_id(column, 0);
4198   gtk_tree_view_append_column(GTK_TREE_VIEW(remote_l), column);
4199
4200   renderer = gtk_cell_renderer_text_new();
4201   column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", 1, NULL);
4202   gtk_tree_view_column_set_expand(column, TRUE);
4203   gtk_tree_view_column_set_sort_column_id(column, 1);
4204   gtk_tree_view_append_column(GTK_TREE_VIEW(remote_l), column);
4205
4206   toggle_renderer = gtk_cell_renderer_toggle_new();
4207   column = gtk_tree_view_column_new_with_attributes("Hide", GTK_CELL_RENDERER(toggle_renderer), "active", 2, NULL);
4208   g_signal_connect (G_OBJECT(toggle_renderer), "toggled", G_CALLBACK (remote_hide_cb), NULL);
4209   gtk_tree_view_column_set_cell_data_func(column, toggle_renderer, button_hide_cb, NULL, FALSE);
4210   gtk_tree_view_append_column(GTK_TREE_VIEW(remote_l), column);
4211   gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(toggle_renderer), TRUE);
4212
4213   renderer = gtk_cell_renderer_text_new();
4214   column = gtk_tree_view_column_new_with_attributes("Control", renderer, "text", 3, NULL);
4215   gtk_tree_view_column_set_visible(column, FALSE);
4216   gtk_tree_view_append_column(GTK_TREE_VIEW(remote_l), column);
4217
4218   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(remote_l));
4219   gtk_tree_selection_set_select_function(selection, select_host_cb, NULL, FALSE);
4220
4221   g_object_set_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_L_KEY, remote_l);
4222   gtk_container_add(GTK_CONTAINER(remote_sc), remote_l);
4223   gtk_widget_show(remote_l);
4224
4225   fill_remote_list();
4226
4227   bbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
4228   gtk_box_pack_start(GTK_BOX(temp_page), bbox, FALSE, FALSE, 5);
4229   gtk_widget_show(bbox);
4230
4231   button_hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
4232   gtk_box_pack_end(GTK_BOX(bbox), button_hbox, FALSE, FALSE, 0);
4233   gtk_widget_show(button_hbox);
4234   gtk_box_set_spacing(GTK_BOX(button_hbox), DLG_BUTTON_SPACING);
4235
4236   help_hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
4237   gtk_box_pack_start(GTK_BOX(bbox), help_hbox, FALSE, FALSE, 0);
4238   gtk_widget_show(help_hbox);
4239   gtk_box_set_spacing(GTK_BOX(help_hbox), DLG_BUTTON_SPACING);
4240
4241   add_but = gtk_button_new_from_stock(GTK_STOCK_ADD);
4242   g_object_set_data(G_OBJECT(bbox), GTK_STOCK_ADD, add_but);
4243   gtk_box_pack_start(GTK_BOX(help_hbox), add_but, FALSE, FALSE, 0);
4244   g_signal_connect(add_but, "clicked", G_CALLBACK(show_remote_dialog), NULL);
4245   gtk_widget_set_tooltip_text(GTK_WIDGET(add_but), "Add a remote host to the list");
4246   gtk_widget_show(add_but);
4247
4248   delete_bt = gtk_button_new_from_stock(GTK_STOCK_DELETE);
4249   g_object_set_data(G_OBJECT(bbox), GTK_STOCK_DELETE, delete_bt);
4250   gtk_box_pack_start(GTK_BOX(help_hbox), delete_bt, FALSE, FALSE, 0);
4251   g_signal_connect(delete_bt, "clicked", G_CALLBACK(remove_remote_host), NULL);
4252   gtk_widget_set_tooltip_text(GTK_WIDGET(delete_bt), "Remove a remote host from the list");
4253   gtk_widget_set_sensitive(GTK_WIDGET(delete_bt), FALSE);
4254   g_object_set_data(G_OBJECT(interface_management_w), E_REMOTE_DEL_BT_KEY, delete_bt);
4255   gtk_widget_show(delete_bt);
4256
4257   ok_but = gtk_button_new_from_stock(GTK_STOCK_APPLY);
4258   gtk_box_pack_end(GTK_BOX(button_hbox), ok_but, FALSE, FALSE, 0);
4259   g_signal_connect(GTK_WIDGET(ok_but), "clicked", G_CALLBACK(ok_remote_cb), NULL);
4260   gtk_widget_set_tooltip_text(GTK_WIDGET(ok_but), "Apply the changes to the general list of local interfaces");
4261   gtk_widget_show(ok_but);
4262
4263   cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
4264   gtk_box_pack_end(GTK_BOX(button_hbox), cancel_bt, FALSE, FALSE, 0);
4265   g_signal_connect(GTK_WIDGET(cancel_bt), "clicked", G_CALLBACK(cancel_pipe_cb), interface_management_w);
4266   gtk_widget_set_tooltip_text(GTK_WIDGET(cancel_bt), "Cancel and exit dialog.");
4267   gtk_widget_show(cancel_bt);
4268
4269   gtk_widget_show(temp_page);
4270
4271 #endif
4272   gtk_widget_show_all(interface_management_w);
4273 }
4274
4275 /* show capture prepare (options) dialog */
4276
4277 /* XXX: Warning:
4278         Note that capture_interface_list() is called directly (or indirectly) during the
4279          creation of (and changes to) the capture options dialog window.
4280
4281         Also note that capture_interface_list() indirectly runs the gtk main loop temporarily
4282          to process queued events (which may include button-presses, key-presses, etc).
4283          (This is done while awaiting a response from dumpcap which is invoked to obtain
4284           the capture interface list).
4285         This means other Wireshark callbacks can be invoked while the capture options window
4286          is being created or updated (in effect an "interrupt" can occur).
4287
4288         Needless to say, "race conditions" may occur in "interrupt" code which depends upon the exact
4289         state of the capture options dialog window and which may be invoked during the
4290         creation of (or changes to) the capture options dialog window.
4291
4292         For example: if a user hits "Capture:Options" and then immediately hits "Capture:Start",
4293          capture_start_cb() may be invoked before capture_prep_cb() has been completed (i.e., during
4294          a call to capture_interface_list() in the code which creates the capture options window).
4295         capture_start_cb() depends upon certain properties of the capture options window having been
4296          initialized and thus fails if the properties have not (yet) been initialized.
4297
4298         An interlock has been added to handle this particular situation;
4299         Ideally a more general solution should be implemented since it's probably difficult
4300          (if not nearly impossible) to identify all the possible "race conditions".
4301
4302         ? Prevent the temporary running of the gtk main loop in cases wherein dumpcap is invoked for a
4303           simple request/reply ? (e.g., capture_interface_list()) ??
4304
4305         ? Other ??
4306 */
4307
4308 static gboolean
4309 columns_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
4310 {
4311   GtkWidget      *menu         = (GtkWidget *)data;
4312   GdkEventButton *event_button = NULL;
4313
4314   /* context menu handler */
4315   if (event->type == GDK_BUTTON_PRESS) {
4316     event_button = (GdkEventButton *) event;
4317
4318     /* To quote the "Gdk Event Structures" doc:
4319      * "Normally button 1 is the left mouse button, 2 is the middle button, and 3 is the right button" */
4320     if (event_button->button == 3) {
4321       gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, widget,
4322                      event_button->button,
4323                      event_button->time);
4324       g_signal_stop_emission_by_name(widget, "button_press_event");
4325       return TRUE;
4326     }
4327   }
4328   return FALSE;
4329 }
4330
4331 static void
4332 update_properties_all(void) {
4333   unsigned int i;
4334   interface_t device;
4335   gchar * filter_str = NULL;
4336   gboolean filter_all = TRUE;
4337   gboolean capture_all = TRUE;
4338   gboolean promisc_all = TRUE;
4339   GtkWidget *promisc_b;
4340   GtkWidget *capture_b;
4341
4342   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
4343     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
4344     if (!device.hidden) {
4345       if (!device.selected) {
4346         capture_all = FALSE;
4347       } else if (device.cfilter != NULL && filter_all) {
4348         if (filter_str == NULL) {
4349           filter_str = g_strdup(device.cfilter);
4350         } else if (strcmp(device.cfilter, filter_str)) {
4351           filter_str = NULL;
4352           filter_all = FALSE;
4353         }
4354       }
4355       if (!device.pmode) {
4356         promisc_all = FALSE;
4357       }
4358     }
4359   }
4360   promisc_b = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PROMISC_KEY_ALL);
4361   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_b), promisc_all);
4362
4363   if (capture_all) {
4364     capture_b = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_KEY_ALL);
4365     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(capture_b), TRUE);
4366   }
4367   if (filter_all && filter_str != NULL) {
4368     gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY)), 0, filter_str);
4369     gtk_combo_box_set_active(GTK_COMBO_BOX(g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY)), 0);
4370   } else {
4371     gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY)), 0, "");
4372     gtk_combo_box_set_active(GTK_COMBO_BOX(g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY)), 0);
4373   }
4374 }
4375
4376
4377 static gboolean
4378 column_button_pressed_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
4379 {
4380   GtkWidget   *col  = (GtkWidget *) data;
4381   GtkTreeView *view;
4382   GtkWidget   *menu = (GtkWidget *)g_object_get_data(G_OBJECT(columns_menu_object), PM_COLUMNS_KEY);
4383
4384   view = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
4385   g_object_set_data(G_OBJECT(view), E_MCAPTURE_COLUMNS_COLUMN_KEY, col);
4386   return columns_menu_handler (widget, event, menu);
4387 }
4388
4389
4390 void
4391 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
4392 {
4393   GtkWidget         *main_vb,
4394                     *main_hb, *left_vb, *right_vb,
4395                     *capture_fr, *capture_vb,
4396                     *all_hb, *all_cb,
4397                     *promisc_cb, *pcap_ng_cb,
4398                     *file_fr, *file_vb,
4399                     *file_hb, *file_bt, *file_lb, *file_te,
4400                     *multi_hb, *multi_grid, *multi_files_on_cb,
4401                     *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_cbx,
4402                     *file_duration_cb, *file_duration_sb, *file_duration_cbx,
4403                     *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
4404                     *stop_files_cb, *stop_files_sb, *stop_files_lb,
4405                     *limit_fr, *limit_vb, *limit_hb, *limit_grid,
4406                     *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
4407                     *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_cbx,
4408                     *stop_duration_cb, *stop_duration_sb, *stop_duration_cbx,
4409                     *display_fr, *display_vb,
4410                     *sync_cb, *auto_scroll_cb, *hide_info_cb,
4411                     *resolv_fr, *resolv_vb,
4412                     *m_resolv_cb, *n_resolv_cb, *t_resolv_cb, *e_resolv_cb,
4413                     *bbox, *close_bt,
4414                     *all_filter_cm, *all_filter_te, *all_filter_bt, *all_filter_hb,
4415                     *all_vb,
4416                     *help_bt;
4417 #ifdef HAVE_AIRPCAP
4418   GtkWidget         *decryption_cb;
4419   int                err;
4420   gchar             *err_str;
4421 #endif
4422   GtkWidget         *iftype_cbx;
4423
4424   GtkAdjustment     *ringbuffer_nbf_adj,
4425                     *stop_packets_adj, *stop_filesize_adj, *stop_duration_adj, *stop_files_adj,
4426                     *ring_filesize_adj, *file_duration_adj;
4427   int                row;
4428   guint32            value;
4429   gchar             *cap_title;
4430   GtkWidget         *view;
4431   GtkWidget         *swindow;
4432   GtkCellRenderer   *renderer;
4433   GtkCellRenderer   *toggle_renderer;
4434   GtkTreeSelection  *selection;
4435   GtkTreeViewColumn *column;
4436   gboolean           if_present = TRUE;
4437   GList             *all_cfilter_list, *cf_entry;
4438   window_geometry_t  tl_geom;
4439
4440   if (interfaces_dialog_window_present()) {
4441     destroy_if_window();
4442   }
4443   if (cap_open_w != NULL) {
4444     /* There's already a "Capture Options" dialog box; reactivate it. */
4445     reactivate_window(cap_open_w);
4446     return;
4447   }
4448   init_columns_menu();
4449
4450   /* use user-defined title if preference is set */
4451
4452   cap_title = create_user_window_title("Wireshark: Capture Options");
4453
4454   cap_open_complete = FALSE;
4455   cap_open_w = dlg_window_new(cap_title);
4456   g_free(cap_title);
4457
4458 #ifdef HAVE_AIRPCAP
4459   /* update airpcap interface list */
4460
4461   /* load the airpcap interfaces */
4462   airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
4463
4464   /* If we don't get a list don't do any thing.
4465    * If the error is AIRPCAP_NOT_LOADED it avoids a unneccessay rescan of the packet list
4466    * ( see airpcap_loader.h for error codes).
4467    */
4468   if (airpcap_if_list == NULL) {
4469     if (err == CANT_GET_AIRPCAP_INTERFACE_LIST) {
4470       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
4471       g_free(err_str);
4472     }
4473   }else{
4474     decryption_cb = (GtkWidget *)g_object_get_data(G_OBJECT(wireless_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY);
4475     /* XXXX update_decryption_mode_list() trigers a rescan, should only be done if the mode is changed */
4476     update_decryption_mode_list(decryption_cb);
4477     /* select the first as default (THIS SHOULD BE CHANGED) */
4478     airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
4479   }
4480 #endif
4481
4482   main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
4483   gtk_container_set_border_width(GTK_CONTAINER(main_vb), DLG_OUTER_MARGIN);
4484   gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
4485
4486   /* Capture-related options frame */
4487   capture_fr = frame_new("Capture");
4488   gtk_box_pack_start(GTK_BOX (main_vb), capture_fr, TRUE, TRUE, 0);
4489
4490   capture_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_UNRELATED_SPACING, FALSE);
4491   gtk_container_set_border_width(GTK_CONTAINER(capture_vb), DLG_OUTER_MARGIN);
4492   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
4493
4494 #if defined (HAVE_PCAP_REMOTE)
4495   if (remote_host_list == NULL) {
4496     remote_host_list = g_hash_table_new (g_str_hash, g_str_equal);
4497   }
4498 #endif
4499
4500   swindow = gtk_scrolled_window_new (NULL, NULL);
4501   gtk_widget_set_size_request(swindow, 676, 180);
4502   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN);
4503
4504   view = gtk_tree_view_new ();
4505   gtk_tree_view_set_rules_hint(GTK_TREE_VIEW (view), TRUE);
4506   g_signal_connect(view, "row-activated", G_CALLBACK(options_interface_cb), (gpointer)cap_open_w);
4507
4508   toggle_renderer = gtk_cell_renderer_toggle_new();
4509   column = gtk_tree_view_column_new_with_attributes("Capture", GTK_CELL_RENDERER(toggle_renderer), "active", CAPTURE, NULL);
4510   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4511   g_signal_connect (G_OBJECT(toggle_renderer), "toggled", G_CALLBACK (toggle_callback), NULL);
4512   g_object_set (GTK_TREE_VIEW(view), "has-tooltip", TRUE, NULL);
4513   g_signal_connect (GTK_TREE_VIEW(view), "query-tooltip", G_CALLBACK (query_tooltip_tree_view_cb), NULL);
4514
4515   renderer = gtk_cell_renderer_text_new();
4516   column = gtk_tree_view_column_new_with_attributes ("",
4517                                                GTK_CELL_RENDERER(renderer),
4518                                                "text", IFACE_HIDDEN_NAME,
4519                                                NULL);
4520   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4521   gtk_tree_view_column_set_visible(column, FALSE);
4522
4523   renderer = gtk_cell_renderer_text_new ();
4524   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view), -1, "Interface", renderer, "markup", INTERFACE, NULL);
4525   column = gtk_tree_view_get_column(GTK_TREE_VIEW (view), INTERFACE);
4526   gtk_tree_view_column_set_min_width(column, 200);
4527   gtk_tree_view_column_set_resizable(column, TRUE );
4528   gtk_tree_view_column_set_alignment(column, 0.5f);
4529   g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(INTERFACE));
4530   gtk_tree_view_column_set_clickable(column, TRUE);
4531   gtk_tree_view_column_set_reorderable(column, TRUE);
4532   g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
4533                    G_CALLBACK(column_button_pressed_cb), column);
4534   if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("INTERFACE"))
4535     gtk_tree_view_column_set_visible(column, TRUE);
4536   else
4537     gtk_tree_view_column_set_visible(column, FALSE);
4538   g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
4539
4540   renderer = gtk_cell_renderer_text_new();
4541   column = gtk_tree_view_column_new_with_attributes ("Link-layer header", renderer, "text", LINK, NULL);
4542   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4543   gtk_tree_view_column_set_clickable(column, TRUE);
4544   gtk_tree_view_column_set_reorderable(column, TRUE);
4545   gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW (view),LINK), TRUE );
4546   g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(LINK));
4547   g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
4548                    G_CALLBACK(column_button_pressed_cb), column);
4549   if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("LINK"))
4550     gtk_tree_view_column_set_visible(column, TRUE);
4551   else
4552     gtk_tree_view_column_set_visible(column, FALSE);
4553   gtk_tree_view_column_set_alignment(column, 0.5f);
4554
4555   renderer = gtk_cell_renderer_text_new();
4556   column = gtk_tree_view_column_new_with_attributes("Prom. Mode", renderer, "text", PMODE, NULL);
4557   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4558   g_object_set(renderer, "xalign", 0.5f, NULL);
4559   gtk_tree_view_column_set_clickable(column, TRUE);
4560   gtk_tree_view_column_set_reorderable(column, TRUE);
4561   g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(PMODE));
4562   g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
4563                    G_CALLBACK(column_button_pressed_cb), column);
4564   if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("PMODE"))
4565     gtk_tree_view_column_set_visible(column, TRUE);
4566   else
4567     gtk_tree_view_column_set_visible(column, FALSE);
4568   gtk_tree_view_column_set_alignment(column, 0.5f);
4569
4570   renderer = gtk_cell_renderer_text_new();
4571   column = gtk_tree_view_column_new_with_attributes("Snaplen [B]", renderer, "text", SNAPLEN, NULL);
4572   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4573   gtk_tree_view_column_set_clickable(column, TRUE);
4574   gtk_tree_view_column_set_reorderable(column, TRUE);
4575   g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(SNAPLEN));
4576   g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
4577                    G_CALLBACK(column_button_pressed_cb), column);
4578   if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("SNAPLEN"))
4579     gtk_tree_view_column_set_visible(column, TRUE);
4580   else
4581     gtk_tree_view_column_set_visible(column, FALSE);
4582   g_object_set(renderer, "xalign", 0.5f, NULL);
4583
4584 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
4585   renderer = gtk_cell_renderer_text_new();
4586   column = gtk_tree_view_column_new_with_attributes("Buffer [MB]", renderer, "text", BUFFER, NULL);
4587   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4588   gtk_tree_view_column_set_reorderable(column, TRUE);
4589   g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(BUFFER));
4590   gtk_tree_view_column_set_clickable(column, TRUE);
4591   g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
4592                    G_CALLBACK(column_button_pressed_cb), column);
4593   if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("BUFFER"))
4594     gtk_tree_view_column_set_visible(column, TRUE);
4595   else
4596     gtk_tree_view_column_set_visible(column, FALSE);
4597   g_object_set(renderer, "xalign", 0.5f, NULL);
4598 #endif
4599
4600 #if defined (HAVE_PCAP_CREATE)
4601   renderer = gtk_cell_renderer_text_new();
4602   column = gtk_tree_view_column_new_with_attributes ("Mon. Mode", renderer, "text", MONITOR, NULL);
4603   gtk_tree_view_column_set_cell_data_func(column, renderer, activate_monitor, NULL, FALSE);
4604   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4605   gtk_tree_view_column_set_reorderable(column, TRUE);
4606   g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(MONITOR));
4607   gtk_tree_view_column_set_clickable(column, TRUE);
4608   g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
4609                    G_CALLBACK(column_button_pressed_cb), column);
4610   if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("MONITOR"))
4611     gtk_tree_view_column_set_visible(column, TRUE);
4612   else
4613     gtk_tree_view_column_set_visible(column, FALSE);
4614   g_object_set(renderer, "xalign", 0.5f, NULL);
4615 #endif
4616
4617   renderer = gtk_cell_renderer_text_new();
4618   column = gtk_tree_view_column_new_with_attributes("Capture Filter", renderer, "text", FILTER, NULL);
4619   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
4620   gtk_tree_view_column_set_alignment(column, 0.5f);
4621   create_and_fill_model(GTK_TREE_VIEW(view));
4622   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
4623   gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
4624   gtk_tree_view_column_set_clickable(column, TRUE);
4625   gtk_tree_view_column_set_reorderable(column, TRUE);
4626   g_object_set_data(G_OBJECT(column), E_MCAPTURE_COLUMNS_COL_KEY, GINT_TO_POINTER(FILTER));
4627   g_signal_connect(gtk_tree_view_column_get_button(column), "button_press_event",
4628                    G_CALLBACK(column_button_pressed_cb), column);
4629   if (!prefs.capture_columns || prefs_capture_options_dialog_column_is_visible("FILTER"))
4630     gtk_tree_view_column_set_visible(column, TRUE);
4631   else
4632     gtk_tree_view_column_set_visible(column, FALSE);
4633   gtk_container_add (GTK_CONTAINER (swindow), view);
4634   gtk_box_pack_start(GTK_BOX(capture_vb), swindow, TRUE, TRUE, 0);
4635
4636   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY, view);
4637
4638   main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_UNRELATED_SPACING, FALSE);
4639   gtk_container_set_border_width(GTK_CONTAINER(main_hb), 0);
4640   gtk_box_pack_start(GTK_BOX(capture_vb), main_hb, FALSE, FALSE, 0);
4641   all_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
4642   gtk_container_set_border_width(GTK_CONTAINER(all_vb), 0);
4643   gtk_box_pack_start(GTK_BOX(main_hb), all_vb, TRUE, TRUE, 0);
4644
4645   all_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_UNRELATED_SPACING, FALSE);
4646   gtk_container_set_border_width(GTK_CONTAINER(all_hb), 0);
4647   gtk_box_pack_start(GTK_BOX(all_vb), all_hb, TRUE, TRUE, 0);
4648
4649   left_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
4650   gtk_container_set_border_width(GTK_CONTAINER(left_vb), 0);
4651   gtk_box_pack_start(GTK_BOX(all_hb), left_vb, TRUE, TRUE, 0);
4652
4653   right_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
4654   gtk_container_set_border_width(GTK_CONTAINER(right_vb), 0);
4655   gtk_box_pack_start(GTK_BOX(all_hb), right_vb, FALSE, FALSE, 3);
4656
4657   all_cb = gtk_check_button_new_with_mnemonic( "Capture on all interfaces");
4658   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(all_cb), FALSE);
4659   g_signal_connect(all_cb, "toggled", G_CALLBACK(capture_all_cb), NULL);
4660   gtk_widget_set_tooltip_text(all_cb, "Activate the box to capture on all interfaces. "
4661     "Deactivate it to capture on none and set the interfaces individually.");
4662   gtk_box_pack_start(GTK_BOX(left_vb), all_cb, TRUE, TRUE, 0);
4663
4664   gtk_widget_set_sensitive(GTK_WIDGET(all_cb), if_present);
4665   /* Promiscuous mode row */
4666   promisc_cb = gtk_check_button_new_with_mnemonic("Capture all in _promiscuous mode");
4667   if (!global_capture_opts.session_started) {
4668     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb), prefs.capture_prom_mode);
4669   } else {
4670     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb), get_all_prom_mode());
4671   }
4672   g_signal_connect(promisc_cb, "button-press-event", G_CALLBACK(promisc_mode_callback), NULL);
4673
4674   gtk_widget_set_tooltip_text(promisc_cb,
4675     "Usually a network adapter will only capture the traffic sent to its own network address. "
4676     "If you want to capture all traffic that all network adapters can \"see\", mark this option. "
4677     "If you want to set this option on a per interface basis, unmark this button and set the "
4678     "option individually."
4679     "See the FAQ for some more details of capturing packets from a switched network.");
4680   gtk_box_pack_start(GTK_BOX(left_vb), promisc_cb, TRUE, TRUE, DLG_LABEL_SPACING);
4681
4682   iftype_cbx = gtk_button_new_with_label("Manage Interfaces");
4683   gtk_widget_set_tooltip_text(iftype_cbx, "Add a new interface or pipe to capture from or remove "
4684                                           "an interface from the list.");
4685   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IFTYPE_CBX_KEY, iftype_cbx);
4686
4687   gtk_box_pack_start(GTK_BOX(right_vb), iftype_cbx, FALSE, FALSE, 0);
4688   g_signal_connect(iftype_cbx, "clicked", G_CALLBACK(show_add_interfaces_dialog), cap_open_w);
4689   gtk_widget_show(iftype_cbx);
4690
4691   main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_UNRELATED_SPACING, FALSE);
4692   gtk_container_set_border_width(GTK_CONTAINER(main_hb), 0);
4693   gtk_box_pack_start(GTK_BOX(main_vb), main_hb, FALSE, FALSE, 0);
4694
4695   left_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
4696   gtk_container_set_border_width(GTK_CONTAINER(left_vb), 0);
4697   gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
4698
4699   right_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
4700   gtk_container_set_border_width(GTK_CONTAINER(right_vb), 0);
4701   gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 0);
4702
4703   /* Filter row */
4704   all_filter_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
4705   gtk_box_pack_start(GTK_BOX(all_vb), all_filter_hb, FALSE, FALSE, DLG_LABEL_SPACING);
4706
4707   all_filter_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_CAPTURE_FILTER_ENTRY);
4708   g_signal_connect(all_filter_bt, "clicked", G_CALLBACK(capture_filter_construct_cb), NULL);
4709   g_signal_connect(all_filter_bt, "destroy", G_CALLBACK(filter_button_destroy_cb), NULL);
4710   gtk_widget_set_tooltip_text(all_filter_bt,
4711     "Select a capture filter for all selected interfaces to reduce the amount of packets to be captured. "
4712     "See \"Capture Filters\" in the online help for further information how to use it."
4713     );
4714   gtk_box_pack_start(GTK_BOX(all_filter_hb), all_filter_bt, FALSE, FALSE, 0);
4715
4716   /* Create the capture filter combo box*/
4717   all_filter_cm = gtk_combo_box_text_new_with_entry();
4718   all_cfilter_list = (GList *)g_object_get_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_FL_KEY);
4719   g_object_set_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_FL_KEY, all_cfilter_list);
4720   g_object_set_data(G_OBJECT(cap_open_w), E_ALL_CFILTER_CM_KEY, all_filter_cm);
4721   all_filter_te = gtk_bin_get_child(GTK_BIN(all_filter_cm));
4722   colorize_filter_te_as_empty(all_filter_te);
4723   g_signal_connect(all_filter_te, "changed", G_CALLBACK(capture_all_filter_check_syntax_cb), NULL);
4724   g_signal_connect(all_filter_te, "destroy", G_CALLBACK(capture_filter_destroy_cb), NULL);
4725
4726   for (cf_entry = all_cfilter_list; cf_entry != NULL; cf_entry = g_list_next(cf_entry)) {
4727     if (cf_entry->data && (strlen((const char *)cf_entry->data) > 0)) {
4728       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(all_filter_cm), (const gchar *)cf_entry->data);
4729     }
4730   }
4731   if (global_capture_opts.default_options.cfilter && (strlen(global_capture_opts.default_options.cfilter) > 0)) {
4732     gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(all_filter_cm), global_capture_opts.default_options.cfilter);
4733     gtk_combo_box_set_active(GTK_COMBO_BOX(all_filter_cm), 0);
4734   }
4735
4736   gtk_widget_set_tooltip_text(all_filter_cm,
4737     "Enter a capture filter for all selected interfaces to reduce the amount of packets to be captured. "
4738     "See \"Capture Filters\" in the online help for further information how to use it. "
4739     "Syntax checking can be disabled in Preferences -> Capture -> Syntax check capture filter."
4740     );
4741   gtk_box_pack_start(GTK_BOX(all_filter_hb), all_filter_cm, TRUE, TRUE, DLG_BUTTON_SPACING);
4742
4743   /* let an eventually capture filters dialog know the text entry to fill in */
4744   g_object_set_data(G_OBJECT(all_filter_bt), E_FILT_TE_PTR_KEY, all_filter_te);
4745
4746 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
4747   all_compile_bt = gtk_button_new_with_label("Compile selected BPFs");
4748   g_signal_connect(all_compile_bt, "clicked", G_CALLBACK(capture_all_filter_compile_cb), NULL);
4749   gtk_widget_set_tooltip_text(all_compile_bt,
4750    "Compile the capture filter expression and show the BPF (Berkeley Packet Filter) code.");
4751   /* We can't compile without any supported link-types, so disable the button in that case */
4752   gtk_box_pack_start(GTK_BOX(all_filter_hb), all_compile_bt, FALSE, FALSE, DLG_BUTTON_SPACING);
4753   if (global_capture_opts.num_selected > 0) {
4754     gtk_widget_set_sensitive(all_compile_bt, TRUE);
4755   } else {
4756     gtk_widget_set_sensitive(all_compile_bt, FALSE);
4757   }
4758 #endif
4759
4760   /* Capture file-related options frame */
4761   file_fr = frame_new("Capture Files");
4762   gtk_box_pack_start(GTK_BOX (left_vb), file_fr, TRUE, TRUE, 0);
4763
4764   file_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_UNRELATED_SPACING, FALSE);
4765   gtk_container_set_border_width(GTK_CONTAINER(file_vb), DLG_OUTER_MARGIN);
4766   gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
4767
4768   /* File row */
4769   file_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
4770   gtk_box_pack_start(GTK_BOX(file_vb), file_hb, FALSE, FALSE, 0);
4771
4772   file_lb = gtk_label_new("File:");
4773   gtk_box_pack_start(GTK_BOX(file_hb), file_lb, FALSE, FALSE, 3);
4774
4775   file_te = gtk_entry_new();
4776   gtk_widget_set_tooltip_text(file_te,
4777     "Enter the file name to which captured data will be written. "
4778     "If you don't enter something here, a temporary file will be used."
4779      );
4780   gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
4781
4782   file_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_BROWSE);
4783   gtk_widget_set_tooltip_text(file_bt,
4784     "Select a file to which captured data will be written, "
4785     "instead of entering the file name directly. "
4786     );
4787   gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 0);
4788
4789   g_signal_connect(file_bt, "clicked", G_CALLBACK(capture_prep_file_cb), file_te);
4790
4791   /* multiple files table */
4792   /* XXX We want multi_grid to shrink to its minimum size horizontally
4793    * and be left-aligned within file_fr. Using a horizontal GtkBox works
4794    * in Gtk2 but not Gtk3. The situation gets sillier below with limit_fr
4795    * and limit_grid because we have both horizontal and vertical GtkBoxes.
4796    */
4797   multi_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
4798   gtk_box_pack_start(GTK_BOX(file_vb), multi_hb, FALSE, FALSE, 0);
4799   multi_grid = ws_gtk_grid_new();
4800   ws_gtk_grid_set_row_spacing(GTK_GRID(multi_grid), DLG_LABEL_SPACING);
4801   ws_gtk_grid_set_column_spacing(GTK_GRID(multi_grid), DLG_UNRELATED_SPACING);
4802   gtk_box_pack_start(GTK_BOX(multi_hb), multi_grid, FALSE, FALSE, 0);
4803   row = 0;
4804
4805   /* multiple files row */
4806   multi_files_on_cb = gtk_check_button_new_with_mnemonic("Use _multiple files");
4807   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(multi_files_on_cb),
4808                                global_capture_opts.multi_files_on);
4809   g_signal_connect(multi_files_on_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity),
4810                  cap_open_w);
4811   gtk_widget_set_tooltip_text(multi_files_on_cb,
4812     "Instead of using a single capture file, multiple files will be created. "
4813     "The generated file names will contain an incrementing number and the start time of the capture.");
4814   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), multi_files_on_cb, 0, row, 1, 1);
4815
4816   /* Pcap-NG row */
4817   pcap_ng_cb = gtk_check_button_new_with_mnemonic("Use pcap-ng format");
4818   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), global_capture_opts.use_pcapng);
4819   gtk_widget_set_tooltip_text(pcap_ng_cb, "Capture packets in the next-generation capture file format. "
4820                        "This is still experimental.");
4821   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), pcap_ng_cb, 2, row, 1, 1);
4822   row++;
4823
4824   /* Ring buffer filesize row */
4825   ring_filesize_cb = gtk_check_button_new_with_label("Next file every");
4826   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb),
4827                                global_capture_opts.has_autostop_filesize || !global_capture_opts.has_file_duration);
4828   g_signal_connect(ring_filesize_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4829   gtk_widget_set_tooltip_text(ring_filesize_cb,
4830     "If the selected file size is exceeded, capturing switches to the next file.\n"
4831     "PLEASE NOTE: at least one of the \"Next file every\" options MUST be selected.");
4832   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), ring_filesize_cb, 0, row, 1, 1);
4833
4834   ring_filesize_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
4835     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
4836   ring_filesize_sb = gtk_spin_button_new (ring_filesize_adj, 0, 0);
4837   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_filesize_sb), TRUE);
4838   gtk_widget_set_size_request(ring_filesize_sb, 80, -1);
4839   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), ring_filesize_sb, 1, row, 1, 1);
4840
4841   ring_filesize_cbx = size_unit_combo_box_new(global_capture_opts.autostop_filesize);
4842   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), ring_filesize_cbx, 2, row, 1, 1);
4843
4844   value = size_unit_combo_box_set_value(global_capture_opts.autostop_filesize);
4845   gtk_adjustment_set_value(ring_filesize_adj, (gfloat) value);
4846
4847   row++;
4848
4849   /* Ring buffer duration row */
4850   file_duration_cb = gtk_check_button_new_with_label("Next file every");
4851   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(file_duration_cb),
4852                                global_capture_opts.has_file_duration);
4853   g_signal_connect(file_duration_cb, "toggled",
4854                    G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4855   gtk_widget_set_tooltip_text(file_duration_cb,
4856     "If the selected duration is exceeded, capturing switches to the next file.\n"
4857     "PLEASE NOTE: at least one of the \"Next file every\" options MUST be selected.");
4858   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), file_duration_cb, 0, row, 1, 1);
4859
4860   file_duration_adj = (GtkAdjustment *)gtk_adjustment_new(0.0,
4861     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
4862   file_duration_sb = gtk_spin_button_new (file_duration_adj, 0, 0);
4863   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (file_duration_sb), TRUE);
4864   gtk_widget_set_size_request(file_duration_sb, 80, -1);
4865   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), file_duration_sb, 1, row, 1, 1);
4866
4867   file_duration_cbx = time_unit_combo_box_new(global_capture_opts.file_duration);
4868   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), file_duration_cbx, 2, row, 1, 1);
4869
4870   value = time_unit_combo_box_convert_value(global_capture_opts.file_duration);
4871   gtk_adjustment_set_value(file_duration_adj, (gfloat) value);
4872   row++;
4873
4874   /* Ring buffer files row */
4875   ringbuffer_nbf_cb = gtk_check_button_new_with_label("Ring buffer with");
4876   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb),
4877                                global_capture_opts.has_ring_num_files);
4878   g_signal_connect(ringbuffer_nbf_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4879   gtk_widget_set_tooltip_text(ringbuffer_nbf_cb,
4880     "After capturing has switched to the next file and the given number of files has exceeded, "
4881     "the oldest file will be removed."
4882     );
4883   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), ringbuffer_nbf_cb, 0, row, 1, 1);
4884
4885   ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) global_capture_opts.ring_num_files,
4886     2/*RINGBUFFER_MIN_NUM_FILES*/, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
4887   ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
4888   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
4889   gtk_widget_set_size_request(ringbuffer_nbf_sb, 80, -1);
4890   g_signal_connect(ringbuffer_nbf_sb, "changed", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4891   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), ringbuffer_nbf_sb, 1, row, 1, 1);
4892
4893   ringbuffer_nbf_lb = gtk_label_new("files");
4894   gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 0, 0.5f);
4895   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), ringbuffer_nbf_lb, 2, row, 1, 1);
4896   row++;
4897
4898   /* Files row */
4899   stop_files_cb = gtk_check_button_new_with_label("Stop capture after");
4900   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_files_cb),
4901                                global_capture_opts.has_autostop_files);
4902   g_signal_connect(stop_files_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4903   gtk_widget_set_tooltip_text(stop_files_cb, "Stop capturing after the given number of \"file switches\" have been done.");
4904   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), stop_files_cb, 0, row, 1, 1);
4905
4906   stop_files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)global_capture_opts.autostop_files,
4907     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
4908   stop_files_sb = gtk_spin_button_new (stop_files_adj, 0, 0);
4909   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_files_sb), TRUE);
4910   gtk_widget_set_size_request(stop_files_sb, 80, -1);
4911   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), stop_files_sb, 1, row, 1, 1);
4912
4913   stop_files_lb = gtk_label_new("file(s)");
4914   gtk_misc_set_alignment(GTK_MISC(stop_files_lb), 0, 0.5f);
4915   ws_gtk_grid_attach_defaults(GTK_GRID (multi_grid), stop_files_lb, 2, row, 1, 1);
4916   row++;
4917
4918   /* Capture limits frame */
4919   limit_fr = frame_new("Stop Capture...");
4920   gtk_box_pack_start(GTK_BOX (left_vb), limit_fr, TRUE, TRUE, 0);
4921
4922   limit_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_UNRELATED_SPACING, FALSE);
4923   gtk_container_set_border_width(GTK_CONTAINER(limit_vb), DLG_OUTER_MARGIN);
4924   gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
4925
4926   /* limits table */
4927   limit_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
4928   gtk_box_pack_start(GTK_BOX(limit_vb), limit_hb, FALSE, FALSE, 0);
4929   limit_grid = ws_gtk_grid_new();
4930   ws_gtk_grid_set_row_spacing(GTK_GRID(limit_grid), DLG_LABEL_SPACING);
4931   ws_gtk_grid_set_column_spacing(GTK_GRID(limit_grid), DLG_UNRELATED_SPACING);
4932   gtk_box_pack_start(GTK_BOX(limit_hb), limit_grid, FALSE, FALSE, 0);
4933   row = 0;
4934
4935   /* Packet count row */
4936   stop_packets_cb = gtk_check_button_new_with_label("after");
4937   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_packets_cb),
4938                                global_capture_opts.has_autostop_packets);
4939   g_signal_connect(stop_packets_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4940   gtk_widget_set_tooltip_text(stop_packets_cb, "Stop capturing after the given number of packets have been captured.");
4941   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_packets_cb, 0, row, 1, 1);
4942
4943   stop_packets_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)global_capture_opts.autostop_packets,
4944     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
4945   stop_packets_sb = gtk_spin_button_new (stop_packets_adj, 0, 0);
4946   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_packets_sb), TRUE);
4947   gtk_widget_set_size_request(stop_packets_sb, 80, -1);
4948   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_packets_sb, 1, row, 1, 1);
4949
4950   stop_packets_lb = gtk_label_new("packet(s)");
4951   gtk_misc_set_alignment(GTK_MISC(stop_packets_lb), 0, 0.5f);
4952   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_packets_lb, 2, row, 1, 1);
4953   row++;
4954
4955   /* Filesize row */
4956   stop_filesize_cb = gtk_check_button_new_with_label("after");
4957   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_filesize_cb),
4958                                global_capture_opts.has_autostop_filesize);
4959   g_signal_connect(stop_filesize_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4960   gtk_widget_set_tooltip_text(stop_filesize_cb, "Stop capturing after the given amount of capture data has been captured.");
4961   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_filesize_cb, 0, row, 1, 1);
4962
4963   stop_filesize_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
4964     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
4965   stop_filesize_sb = gtk_spin_button_new (stop_filesize_adj, 0, 0);
4966   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_filesize_sb), TRUE);
4967   gtk_widget_set_size_request(stop_filesize_sb, 80, -1);
4968   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_filesize_sb, 1, row, 1, 1);
4969
4970   stop_filesize_cbx = size_unit_combo_box_new(global_capture_opts.autostop_filesize);
4971   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_filesize_cbx, 2, row, 1, 1);
4972
4973   value = size_unit_combo_box_set_value(global_capture_opts.autostop_filesize);
4974   gtk_adjustment_set_value(stop_filesize_adj, (gfloat) value);
4975
4976   row++;
4977
4978   /* Duration row */
4979   stop_duration_cb = gtk_check_button_new_with_label("after");
4980   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_duration_cb),
4981                                global_capture_opts.has_autostop_duration);
4982   g_signal_connect(stop_duration_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
4983   gtk_widget_set_tooltip_text(stop_duration_cb, "Stop capturing after the given time is exceeded.");
4984   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_duration_cb, 0, row, 1, 1);
4985
4986   stop_duration_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
4987     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
4988   stop_duration_sb = gtk_spin_button_new (stop_duration_adj, 0, 0);
4989   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_duration_sb), TRUE);
4990   gtk_widget_set_size_request(stop_duration_sb, 80, -1);
4991   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_duration_sb, 1, row, 1, 1);
4992
4993   stop_duration_cbx = time_unit_combo_box_new(global_capture_opts.autostop_duration);
4994   ws_gtk_grid_attach_defaults(GTK_GRID (limit_grid), stop_duration_cbx, 2, row, 1, 1);
4995
4996   value = time_unit_combo_box_convert_value(global_capture_opts.autostop_duration);
4997   gtk_adjustment_set_value(stop_duration_adj, (gfloat) value);
4998   row++;
4999
5000   /* Display-related options frame */
5001   display_fr = frame_new("Display Options");
5002   gtk_box_pack_start(GTK_BOX (right_vb), display_fr, TRUE, TRUE, 0);
5003
5004   display_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_UNRELATED_SPACING, FALSE);
5005   gtk_container_set_border_width(GTK_CONTAINER(display_vb), DLG_OUTER_MARGIN);
5006   gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
5007
5008   /* "Update display in real time" row */
5009   sync_cb = gtk_check_button_new_with_mnemonic(
5010       "_Update list of packets in real time");
5011   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sync_cb),
5012                                global_capture_opts.real_time_mode);
5013   g_signal_connect(sync_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
5014   gtk_widget_set_tooltip_text(sync_cb,
5015     "Using this option will show the captured packets immediately on the main screen. "
5016     "Please note: this will slow down capturing, so increased packet drops might appear.");
5017   gtk_box_pack_start(GTK_BOX (display_vb), sync_cb, TRUE, TRUE, 0);
5018
5019   /* "Auto-scroll live update" row */
5020   auto_scroll_cb = gtk_check_button_new_with_mnemonic("_Automatic scrolling in live capture");
5021   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
5022   gtk_widget_set_tooltip_text(auto_scroll_cb,
5023     "This will scroll the \"Packet List\" automatically to the latest captured packet, "
5024     "when the \"Update List of packets in real time\" option is used.");
5025   gtk_box_pack_start(GTK_BOX (display_vb), auto_scroll_cb, TRUE, TRUE, 0);
5026
5027   /* "Hide capture info" row */
5028   hide_info_cb = gtk_check_button_new_with_mnemonic("_Hide capture info dialog");
5029   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hide_info_cb), !global_capture_opts.show_info);
5030   gtk_widget_set_tooltip_text(hide_info_cb, "Hide the capture info dialog while capturing.");
5031   gtk_box_pack_start(GTK_BOX (display_vb), hide_info_cb, TRUE, TRUE, 0);
5032
5033   /* Name Resolution frame */
5034   resolv_fr = frame_new("Name Resolution");
5035   gtk_box_pack_start(GTK_BOX (right_vb), resolv_fr, TRUE, TRUE, 0);
5036
5037   resolv_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_UNRELATED_SPACING, FALSE);
5038   gtk_container_set_border_width(GTK_CONTAINER(resolv_vb), DLG_OUTER_MARGIN);
5039   gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
5040
5041   m_resolv_cb = gtk_check_button_new_with_mnemonic(
5042                 "Enable _MAC name resolution");
5043   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_resolv_cb),
5044                 gbl_resolv_flags.mac_name);
5045   gtk_widget_set_tooltip_text(m_resolv_cb, "Perform MAC layer name resolution while capturing.");
5046   gtk_box_pack_start(GTK_BOX (resolv_vb), m_resolv_cb, TRUE, TRUE, 0);
5047
5048   t_resolv_cb = gtk_check_button_new_with_mnemonic(
5049                 "Enable _transport name resolution");
5050   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_resolv_cb),
5051                 gbl_resolv_flags.transport_name);
5052   gtk_widget_set_tooltip_text(t_resolv_cb,
5053     "Perform transport layer name resolution while capturing.");
5054   gtk_box_pack_start(GTK_BOX (resolv_vb), t_resolv_cb, TRUE, TRUE, 0);
5055
5056   n_resolv_cb = gtk_check_button_new_with_mnemonic(
5057                 "Enable _network name resolution");
5058   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(n_resolv_cb),
5059                 gbl_resolv_flags.network_name);
5060   gtk_widget_set_tooltip_text(n_resolv_cb, "Perform network layer name resolution while capturing.");
5061   gtk_box_pack_start(GTK_BOX (resolv_vb), n_resolv_cb, TRUE, TRUE, 0);
5062
5063   e_resolv_cb = gtk_check_button_new_with_mnemonic(
5064                 "Use _external network name resolver");
5065   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e_resolv_cb),
5066                 gbl_resolv_flags.use_external_net_name_resolver);
5067   gtk_widget_set_tooltip_text(e_resolv_cb,
5068                 "Use the (system's) configured name resolver (e.g., DNS) to resolve network names.");
5069   gtk_box_pack_start(GTK_BOX (resolv_vb), e_resolv_cb, TRUE, TRUE, 0);
5070
5071   /* Button row: "Start", "Cancel" and "Help" buttons */
5072   bbox = dlg_button_row_new(WIRESHARK_STOCK_CAPTURE_START, GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
5073   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
5074
5075   ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_START);
5076   g_signal_connect(ok_bt, "clicked", G_CALLBACK(capture_start_cb), NULL);
5077   gtk_widget_set_tooltip_text(ok_bt, "Start the capture process.");
5078   if (global_capture_opts.num_selected > 0) {
5079     gtk_widget_set_sensitive(ok_bt, TRUE);
5080   } else {
5081     gtk_widget_set_sensitive(ok_bt, FALSE);
5082   }
5083
5084   close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
5085   gtk_widget_set_tooltip_text(close_bt,
5086     "Exit dialog.");
5087   window_set_cancel_button(cap_open_w, close_bt, window_cancel_button_cb);
5088
5089   help_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
5090   gtk_widget_set_tooltip_text(help_bt,
5091     "Show help about capturing.");
5092   g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), GUINT_TO_POINTER(HELP_CAPTURE_OPTIONS_DIALOG));
5093   gtk_widget_grab_default(ok_bt);
5094
5095   /* Attach pointers to needed widgets to the capture prefs window/object */
5096 #if defined(HAVE_PCAP_REMOTE)
5097   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_REMOTE_DIALOG_PTR_KEY, NULL);
5098 #endif
5099   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_KEY_ALL, all_cb);
5100   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_PROMISC_KEY_ALL, promisc_cb);
5101   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY, pcap_ng_cb);
5102   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_TE_KEY,  file_te);
5103   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_MULTI_FILES_ON_CB_KEY,  multi_files_on_cb);
5104   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_NBF_CB_KEY,  ringbuffer_nbf_cb);
5105   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_NBF_SB_KEY,  ringbuffer_nbf_sb);
5106   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_NBF_LB_KEY,  ringbuffer_nbf_lb);
5107   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_FILESIZE_CB_KEY,  ring_filesize_cb);
5108   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_FILESIZE_SB_KEY,  ring_filesize_sb);
5109   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_FILESIZE_CBX_KEY,  ring_filesize_cbx);
5110   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_DURATION_CB_KEY,  file_duration_cb);
5111   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_DURATION_SB_KEY,  file_duration_sb);
5112   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_DURATION_CBX_KEY,  file_duration_cbx);
5113   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_SYNC_KEY,  sync_cb);
5114   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
5115   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_HIDE_INFO_KEY, hide_info_cb);
5116   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_PACKETS_CB_KEY, stop_packets_cb);
5117   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_PACKETS_SB_KEY, stop_packets_sb);
5118   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_PACKETS_LB_KEY, stop_packets_lb);
5119   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILESIZE_CB_KEY, stop_filesize_cb);
5120   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILESIZE_SB_KEY, stop_filesize_sb);
5121   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILESIZE_CBX_KEY, stop_filesize_cbx);
5122   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_DURATION_CB_KEY,  stop_duration_cb);
5123   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_DURATION_SB_KEY,  stop_duration_sb);
5124   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_DURATION_CBX_KEY,  stop_duration_cbx);
5125   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILES_CB_KEY, stop_files_cb);
5126   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILES_SB_KEY, stop_files_sb);
5127   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILES_LB_KEY, stop_files_lb);
5128   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
5129   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
5130   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
5131   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_E_RESOLVE_KEY,  e_resolv_cb);
5132
5133   /* Set the sensitivity of various widgets as per the settings of other
5134      widgets. */
5135   capture_prep_adjust_sensitivity(NULL, cap_open_w);
5136
5137   update_properties_all();
5138   update_visible_columns_menu ();
5139
5140   /* Catch the "activate" signal on the text
5141      entries, so that if the user types Return there, we act as if the
5142      "OK" button had been selected, as happens if Return is typed if some
5143      widget that *doesn't* handle the Return key has the input focus. */
5144   /*dlg_set_activate(gtk_bin_get_child(GTK_BIN(if_cb)), ok_bt);*/
5145   dlg_set_activate(file_te, ok_bt);
5146   dlg_set_activate(all_filter_te, ok_bt);
5147   gtk_widget_grab_focus(all_filter_te);
5148
5149   g_signal_connect(cap_open_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
5150   g_signal_connect(cap_open_w, "destroy", G_CALLBACK(capture_prep_destroy_cb), NULL);
5151
5152   window_get_geometry(top_level, &tl_geom);
5153   gtk_window_set_default_size(GTK_WINDOW(cap_open_w), tl_geom.width * 8 / 10, -1);
5154   
5155   gtk_widget_show_all(cap_open_w);
5156   window_present(cap_open_w);
5157
5158   cap_open_complete = TRUE;   /* "Capture:Start" is now OK */
5159   global_capture_opts.session_started = TRUE;
5160 }
5161
5162 /* everythings prepared, now it's really time to start the capture */
5163 static void
5164 capture_start_confirmed(void)
5165 {
5166   interface_options interface_opts;
5167   guint             i;
5168
5169   /* did the user ever select a capture interface before? */
5170   if (global_capture_opts.num_selected == 0 &&
5171       ((prefs.capture_device == NULL) || (*prefs.capture_device != '\0'))) {
5172     simple_dialog(ESD_TYPE_CONFIRMATION,
5173                   ESD_BTN_OK,
5174                   "%sNo capture interface selected!%s\n\n"
5175                   "To select an interface use:\n\n"
5176                   "Capture->Options (until Wireshark is stopped)\n"
5177                   "Edit->Preferences/Capture (permanent, if saved)",
5178                   simple_dialog_primary_start(), simple_dialog_primary_end());
5179     return;
5180   }
5181
5182   /* XXX - we might need to init other pref data as well... */
5183   main_auto_scroll_live_changed(auto_scroll_live);
5184
5185   /* XXX - can this ever happen? */
5186   if (global_capture_opts.state != CAPTURE_STOPPED)
5187     return;
5188
5189   /* close the currently loaded capture file */
5190   cf_close((capture_file *)global_capture_opts.cf);
5191
5192   /* Copy the selected interfaces to the set of interfaces to use for
5193      this capture. */
5194   collect_ifaces(&global_capture_opts);
5195
5196   if (capture_start(&global_capture_opts)) {
5197     /* The capture succeeded, which means the capture filter syntax is
5198        valid; add this capture filter to the recent capture filter list. */
5199     for (i = 0; i < global_capture_opts.ifaces->len; i++) {
5200       interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
5201       if (interface_opts.cfilter) {
5202         cfilter_combo_add_recent(interface_opts.cfilter);
5203       }
5204     }
5205   }
5206 }
5207
5208 /* user pressed the "Start" button (in dialog or toolbar) */
5209 void
5210 capture_start_cb(GtkWidget *w _U_, gpointer d _U_)
5211 {
5212 #ifdef HAVE_AIRPCAP
5213   airpcap_if_active = airpcap_if_selected;
5214   if (airpcap_if_active)
5215     airpcap_set_toolbar_start_capture(airpcap_if_active);
5216 #endif
5217
5218   /* XXX - will closing this remove a temporary file? */
5219   if(!do_file_close(&cfile, FALSE, " before starting a new capture")){
5220           return;
5221   }
5222   if (cap_open_w) {
5223     /*
5224      * There's an options dialog; get the values from it and close it.
5225      */
5226     gboolean success;
5227
5228     /* Determine if "capture start" while building of the "capture options" window */
5229     /*  is in progress. If so, ignore the "capture start.                          */
5230     /* XXX: Would it be better/cleaner for the "capture options" window code to    */
5231     /*      disable the capture start button temporarily ?                         */
5232     if (cap_open_complete == FALSE) {
5233       return;  /* Building options window: ignore "capture start" */
5234     }
5235     success = capture_dlg_prep(cap_open_w);
5236     window_destroy(GTK_WIDGET(cap_open_w));
5237     if (!success)
5238       return;   /* error in options dialog */
5239   }
5240   if (global_capture_opts.num_selected == 0) {
5241     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
5242         "You didn't specify an interface on which to capture packets.");
5243     return;
5244   }
5245   
5246   capture_start_confirmed();
5247 }
5248
5249
5250 /* user change linktype selection;, convert to internal DLT value */
5251 static void
5252 select_link_type_cb(GtkWidget *linktype_combo_box, gpointer data _U_)
5253 {
5254   gpointer    ptr;
5255   int         dlt;
5256   interface_t device;
5257
5258   device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
5259   global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
5260   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
5261     g_assert_not_reached();  /* Programming error: somehow nothing is active */
5262   }
5263   if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
5264     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
5265   }
5266   device.active_dlt = dlt;
5267   g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
5268   capture_filter_check_syntax_cb(linktype_combo_box, data);
5269 }
5270
5271 /* user pressed "File" button */
5272 static void
5273 capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te)
5274 {
5275   file_selection_browse(file_bt, file_te, "Wireshark: Specify a Capture File", FILE_SELECTION_WRITE_BROWSE);
5276 }
5277
5278 /* user pressed "Pipe" button */
5279 static void
5280 capture_prep_pipe_cb(GtkWidget *pipe_bt, GtkWidget *pipe_te)
5281 {
5282   file_selection_browse(pipe_bt, pipe_te, "Wireshark: Specify a Pipe", FILE_SELECTION_WRITE_BROWSE);
5283 }
5284
5285
5286 /* convert dialog settings into capture_opts values */
5287 static gboolean
5288 capture_dlg_prep(gpointer parent_w) {
5289   GtkWidget   *pcap_ng_cb,
5290               *file_te, *multi_files_on_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_cb,
5291               *sync_cb, *auto_scroll_cb, *hide_info_cb,
5292               *stop_packets_cb, *stop_packets_sb,
5293               *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_cbx,
5294               *stop_duration_cb, *stop_duration_sb, *stop_duration_cbx,
5295               *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_cbx,
5296               *file_duration_cb, *file_duration_sb, *file_duration_cbx,
5297               *stop_files_cb, *stop_files_sb,
5298               *m_resolv_cb, *n_resolv_cb, *t_resolv_cb, *e_resolv_cb;
5299   const gchar *g_save_file;
5300   gchar       *cf_name;
5301   gchar       *dirname;
5302   gint32       tmp;
5303
5304   pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_PCAP_NG_KEY);
5305   file_te    = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_TE_KEY);
5306   multi_files_on_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_MULTI_FILES_ON_CB_KEY);
5307   ringbuffer_nbf_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_CB_KEY);
5308   ringbuffer_nbf_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
5309   ring_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CB_KEY);
5310   ring_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_SB_KEY);
5311   ring_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CBX_KEY);
5312   file_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CB_KEY);
5313   file_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_SB_KEY);
5314   file_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CBX_KEY);
5315   sync_cb   = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SYNC_KEY);
5316   auto_scroll_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
5317   hide_info_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_HIDE_INFO_KEY);
5318   stop_packets_cb   = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_CB_KEY);
5319   stop_packets_sb   = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_SB_KEY);
5320   stop_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CB_KEY);
5321   stop_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_SB_KEY);
5322   stop_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CBX_KEY);
5323   stop_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CB_KEY);
5324   stop_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_SB_KEY);
5325   stop_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CBX_KEY);
5326   stop_files_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_CB_KEY);
5327   stop_files_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_SB_KEY);
5328   m_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_M_RESOLVE_KEY);
5329   n_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY);
5330   t_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY);
5331   e_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_E_RESOLVE_KEY);
5332
5333   if (global_capture_opts.num_selected == 0) {
5334     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
5335       "You didn't specify an interface on which to capture packets.");
5336     return FALSE;
5337   }
5338   global_capture_opts.use_pcapng =
5339     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pcap_ng_cb));
5340   /* Wireshark always saves to a capture file. */
5341   global_capture_opts.saving_to_file = TRUE;
5342   g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
5343   if (g_save_file && g_save_file[0]) {
5344     /* User specified a file to which the capture should be written. */
5345     global_capture_opts.save_file = g_strdup(g_save_file);
5346     /* Save the directory name for future file dialogs. */
5347     cf_name = g_strdup(g_save_file);
5348     dirname = get_dirname(cf_name);  /* Overwrites cf_name */
5349     set_last_open_dir(dirname);
5350     g_free(cf_name);
5351   } else {
5352     /* User didn't specify a file; save to a temporary file. */
5353     global_capture_opts.save_file = NULL;
5354   }
5355
5356   global_capture_opts.has_autostop_packets =
5357     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb));
5358   if (global_capture_opts.has_autostop_packets)
5359     global_capture_opts.autostop_packets =
5360       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_packets_sb));
5361
5362   global_capture_opts.has_autostop_duration =
5363     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb));
5364   if (global_capture_opts.has_autostop_duration) {
5365     global_capture_opts.autostop_duration =
5366       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_duration_sb));
5367     global_capture_opts.autostop_duration =
5368       time_unit_combo_box_get_value(stop_duration_cbx, global_capture_opts.autostop_duration);
5369   }
5370
5371   global_capture_opts.real_time_mode =
5372     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
5373
5374   auto_scroll_live =
5375       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
5376
5377   global_capture_opts.show_info =
5378       !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hide_info_cb));
5379
5380   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
5381     gbl_resolv_flags.mac_name = TRUE;
5382   else
5383     gbl_resolv_flags.mac_name = FALSE;
5384   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
5385     gbl_resolv_flags.network_name = TRUE;
5386   else
5387     gbl_resolv_flags.network_name = FALSE;
5388   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
5389     gbl_resolv_flags.transport_name = TRUE;
5390   else
5391     gbl_resolv_flags.transport_name = FALSE;
5392   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(e_resolv_cb)))
5393     gbl_resolv_flags.use_external_net_name_resolver = TRUE;
5394   else
5395     gbl_resolv_flags.use_external_net_name_resolver = FALSE;
5396
5397   global_capture_opts.has_ring_num_files =
5398     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb));
5399
5400   global_capture_opts.ring_num_files =
5401     gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
5402   if (global_capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES)
5403     global_capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES;
5404 #if RINGBUFFER_MIN_NUM_FILES > 0
5405   else if (global_capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES)
5406     global_capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES;
5407 #endif
5408
5409   global_capture_opts.multi_files_on =
5410     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb));
5411
5412   global_capture_opts.has_file_duration =
5413     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb));
5414   if (global_capture_opts.has_file_duration) {
5415     global_capture_opts.file_duration =
5416       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(file_duration_sb));
5417     global_capture_opts.file_duration =
5418       time_unit_combo_box_get_value(file_duration_cbx, global_capture_opts.file_duration);
5419   }
5420
5421   global_capture_opts.has_autostop_files =
5422     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb));
5423   if (global_capture_opts.has_autostop_files)
5424     global_capture_opts.autostop_files =
5425       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_files_sb));
5426
5427   if (global_capture_opts.multi_files_on) {
5428     global_capture_opts.has_autostop_filesize =
5429       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb));
5430     if (global_capture_opts.has_autostop_filesize) {
5431       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_filesize_sb));
5432       tmp = size_unit_combo_box_convert_value(ring_filesize_cbx, tmp);
5433       if (tmp != 0) {
5434         global_capture_opts.autostop_filesize = tmp;
5435       } else {
5436         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
5437           "%sMultiple files: Requested filesize too large!%s\n\n"
5438           "The setting \"Next file every x byte(s)\" can't be greater than %u bytes (2GB).",
5439           simple_dialog_primary_start(), simple_dialog_primary_end(), G_MAXINT);
5440         return FALSE;
5441       }
5442     }
5443
5444     /* test if the settings are ok for a ringbuffer */
5445     if (global_capture_opts.save_file == NULL) {
5446       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
5447         "%sMultiple files: No capture file name given!%s\n\n"
5448         "You must specify a filename if you want to use multiple files.",
5449         simple_dialog_primary_start(), simple_dialog_primary_end());
5450       return FALSE;
5451     } else if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
5452       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
5453         "%sMultiple files: No file limit given!%s\n\n"
5454         "You must specify a file size or duration at which is switched to the next capture file\n"
5455         "if you want to use multiple files.",
5456         simple_dialog_primary_start(), simple_dialog_primary_end());
5457       g_free(global_capture_opts.save_file);
5458       global_capture_opts.save_file = NULL;
5459       return FALSE;
5460     }
5461   } else {
5462     global_capture_opts.has_autostop_filesize =
5463       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb));
5464     if (global_capture_opts.has_autostop_filesize) {
5465       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_filesize_sb));
5466       tmp = size_unit_combo_box_convert_value(stop_filesize_cbx, tmp);
5467       if (tmp != 0) {
5468         global_capture_opts.autostop_filesize = tmp;
5469       } else {
5470         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
5471           "%sStop Capture: Requested filesize too large!%s\n\n"
5472           "The setting \"after x byte(s)\" can't be greater than %u bytes (2GB).",
5473           simple_dialog_primary_start(), simple_dialog_primary_end(), G_MAXINT);
5474         return FALSE;
5475       }
5476     }
5477   } /* multi_files_on */
5478   return TRUE;
5479 }
5480
5481 static GtkTreeModel *
5482 create_and_fill_model(GtkTreeView *view)
5483 {
5484   GtkListStore *store;
5485   GtkTreeIter   iter;
5486   GList        *list;
5487   char         *temp, *snaplen_string, *linkname;
5488   guint         i;
5489   link_row     *linkr = NULL;
5490   interface_t   device;
5491 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
5492   gint          buffer;
5493 #endif
5494   gint          snaplen;
5495   gboolean      hassnap, pmode;
5496
5497 #if defined(HAVE_PCAP_CREATE)
5498   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);
5499 #elif defined(_WIN32) && !defined (HAVE_PCAP_CREATE)
5500   store = gtk_list_store_new (8, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
5501 #else
5502   store = gtk_list_store_new (7, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
5503 #endif
5504
5505   for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
5506     device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
5507     if (!device.hidden) {
5508       if (device.no_addresses == 0) {
5509         temp = g_strdup_printf("<b>%s</b>", device.display_name);
5510       } else {
5511         temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", device.display_name, device.addresses);
5512       }
5513       linkname = NULL;
5514       if(global_capture_opts.session_started == FALSE && capture_dev_user_linktype_find(device.name) != -1) {
5515         device.active_dlt = capture_dev_user_linktype_find(device.name);
5516       }
5517       for (list = device.links; list != NULL; list = g_list_next(list)) {
5518         linkr = (link_row*)(list->data);
5519         if (linkr->dlt == device.active_dlt) {
5520           linkname = g_strdup(linkr->name);
5521           break;
5522         }
5523       }
5524       pmode = capture_dev_user_pmode_find(device.name);
5525       if (global_capture_opts.session_started == FALSE && pmode != -1) {
5526         device.pmode = pmode;
5527       }
5528       if(global_capture_opts.session_started == FALSE) {
5529         hassnap = capture_dev_user_hassnap_find(device.name);
5530         snaplen = capture_dev_user_snaplen_find(device.name);
5531         if(snaplen != -1 && hassnap != -1) {
5532           /* Default snap lenght set in preferences */
5533           device.snaplen = snaplen;
5534           device.has_snaplen = hassnap;
5535         } else {
5536           /* No preferences set yet, use default values */
5537           device.snaplen = WTAP_MAX_PACKET_SIZE;
5538           device.has_snaplen = FALSE;
5539         }
5540       }
5541       if (device.has_snaplen) {
5542         snaplen_string = g_strdup_printf("%d", device.snaplen);
5543       } else {
5544         snaplen_string = g_strdup("default");
5545       }
5546
5547 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
5548       if (global_capture_opts.session_started == FALSE && capture_dev_user_buffersize_find(device.name) != -1) {
5549         buffer = capture_dev_user_buffersize_find(device.name);
5550         device.buffer = buffer;
5551       } else if (global_capture_opts.session_started == FALSE) {
5552         device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
5553       } 
5554 #endif
5555       global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
5556       g_array_insert_val(global_capture_opts.all_ifaces, i, device);
5557       gtk_list_store_append (store, &iter);
5558 #if defined(HAVE_PCAP_CREATE)
5559       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);
5560 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
5561       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, FILTER, device.cfilter, -1);
5562 #else
5563       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, FILTER, device.cfilter, -1);
5564 #endif
5565     }
5566   }
5567   gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
5568   return GTK_TREE_MODEL(store);
5569 }
5570
5571 static gboolean
5572 query_tooltip_tree_view_cb (GtkWidget  *widget,
5573                             gint        x,
5574                             gint        y,
5575                             gboolean    keyboard_tip,
5576                             GtkTooltip *tooltip,
5577                             gpointer    data _U_)
5578 {
5579   GtkTreeIter        iter;
5580   GtkTreeView       *tree_view = GTK_TREE_VIEW (widget);
5581   GtkTreeModel      *model     = gtk_tree_view_get_model (tree_view);
5582   GtkTreePath       *path      = NULL;
5583   gchar             *tmp;
5584   gchar             *pathstring;
5585   GtkTreeViewColumn *column;
5586   int                col;
5587   GtkCellRenderer*   renderer  = NULL;
5588   GList             *renderer_list;
5589
5590   char               buffer[512];
5591
5592    if (!gtk_tree_view_get_tooltip_context (tree_view, &x, &y, keyboard_tip, &model, &path, &iter))
5593     return FALSE;
5594
5595   gtk_tree_model_get (model, &iter, 0, &tmp, -1);
5596   pathstring = gtk_tree_path_to_string (path);
5597
5598   if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tree_view), (gint) x, (gint) y, NULL, &column, NULL, NULL)) {
5599     for (col = 0; col < NUM_COLUMNS; col++) {
5600       if (gtk_tree_view_get_column(tree_view, col) == column)
5601         break;
5602     }
5603     switch (col)
5604     {
5605       case 0: g_snprintf (buffer, sizeof(buffer), "Choose which interface (network adapter) will be used to capture packets from. "
5606                 "Be sure to select the correct one, as it's a common mistake to select the wrong interface.");
5607               break;
5608       case 2: g_snprintf (buffer, sizeof(buffer), "Lists the interface name and the IP address(es) assigned to it. ");
5609               break;
5610       case 3: g_snprintf (buffer, sizeof(buffer), "Link-layer type the interface supports.");
5611               break;
5612       case 4: g_snprintf (buffer, sizeof(buffer), "Usually a network adapter will only capture the traffic sent to its own network address. "
5613                 "If you want to capture all traffic that the network adapter can \"see\", promiscuous mode should be configured.");
5614               break;
5615       case 5: g_snprintf(buffer, sizeof(buffer), "Limit the maximum number of bytes to be captured from each packet. This size includes the "
5616                 "link-layer header and all subsequent headers.");
5617               break;
5618       case 6: g_snprintf (buffer, sizeof(buffer), "The memory buffer size used while capturing. "
5619                 "If you notice packet drops, you can try increasing this size.");
5620               break;
5621       case 7: g_snprintf (buffer, sizeof(buffer), "Usually a Wi-Fi adapter will, even in promiscuous mode, only capture "
5622                 "the traffic on the BSS to which it's associated. "
5623                 "If you want to capture all traffic that the Wi-Fi adapter can \"receive\", select this option. "
5624                 "In order to see IEEE 802.11 headers or to see radio information for captured packets, "
5625                 "it might be necessary to turn this option on.\n\n"
5626                 "Note that, in monitor mode, the adapter might disassociate from the network to which it's associated.");
5627               break;
5628       case 8: g_snprintf(buffer, sizeof(buffer), "Selected capture filter to reduce the amount of packets to be captured.");
5629               break;
5630       default: g_snprintf(buffer, sizeof(buffer), "another option");
5631     }
5632
5633     gtk_tooltip_set_markup (tooltip, buffer);
5634     renderer_list = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
5635     /* get the first renderer */
5636     if (g_list_first(renderer_list)) {
5637       renderer = (GtkCellRenderer*)g_list_nth_data(renderer_list, 0);
5638       gtk_tree_view_set_tooltip_cell (tree_view, tooltip, path, column, renderer);
5639     }
5640   }
5641   gtk_tree_path_free (path);
5642   g_free (pathstring);
5643
5644   return TRUE;
5645 }
5646
5647 #if defined (HAVE_PCAP_CREATE)
5648 static void
5649 activate_monitor(GtkTreeViewColumn *tree_column _U_, GtkCellRenderer *renderer,
5650                  GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data _U_)
5651 {
5652   interface_t  device;
5653   GtkTreePath *path  = gtk_tree_model_get_path(tree_model, iter);
5654   int          indx = atoi(gtk_tree_path_to_string(path));
5655
5656   device = g_array_index(global_capture_opts.all_ifaces, interface_t, indx);
5657
5658   if (device.monitor_mode_supported == TRUE) {
5659     g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
5660   } else {
5661     g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
5662   }
5663 }
5664 #endif
5665
5666 /* user requested to destroy the dialog */
5667 static void
5668 capture_prep_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
5669 {
5670   GtkWidget *fs;
5671 #ifdef HAVE_PCAP_REMOTE
5672   GList     *if_list;
5673   GtkWidget *remote_w;
5674 #endif
5675
5676   /* Is there a file selection dialog associated with this
5677      Capture Options dialog? */
5678   fs = (GtkWidget *)g_object_get_data(G_OBJECT(cap_open_w), E_FILE_SEL_DIALOG_PTR_KEY);
5679
5680 #ifdef HAVE_PCAP_REMOTE
5681   if_list = (GList *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IF_LIST_KEY);
5682   if (if_list && g_list_length(if_list)>0) {
5683       free_interface_list(if_list);
5684   }
5685 #endif
5686
5687   if (fs != NULL) {
5688     /* Yes.  Destroy it. */
5689     window_destroy(fs);
5690   }
5691
5692   /* Note that we no longer have a "Capture Options" dialog box. */
5693   cap_open_w = NULL;
5694
5695 #ifdef HAVE_AIRPCAP
5696   /* update airpcap toolbar */
5697   if (airpcap_if_active)
5698     airpcap_set_toolbar_stop_capture(airpcap_if_active);
5699 #endif
5700
5701 #ifdef HAVE_PCAP_REMOTE
5702   remote_w = g_object_get_data(G_OBJECT(interface_management_w), E_CAP_REMOTE_DIALOG_PTR_KEY);
5703   if (remote_w != NULL)
5704       window_destroy(remote_w);
5705 #endif
5706 }
5707
5708
5709 #ifdef HAVE_PCAP_CREATE
5710 /* user changed the setting of the monitor-mode checkbox */
5711 static void
5712 capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_)
5713 {
5714   GList             *lt_entry;
5715   gchar             *if_string;
5716   gboolean           monitor_mode;
5717   if_capabilities_t *caps;
5718   gint               linktype_count     = 0, i;
5719   data_link_info_t  *data_link_info;
5720   interface_t        device;
5721   link_row          *linkr;
5722   GtkWidget         *linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
5723   GtkWidget         *linktype_lb        = (GtkWidget *)g_object_get_data(G_OBJECT(linktype_combo_box), E_CAP_LT_CBX_LABEL_KEY);
5724
5725   device = g_array_index(global_capture_opts.all_ifaces, interface_t, marked_interface);
5726   global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, marked_interface);
5727
5728
5729   if_string = g_strdup(device.name);
5730   monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor));
5731   caps = capture_get_if_capabilities(if_string, monitor_mode, NULL);
5732
5733   if (caps != NULL) {
5734     g_signal_handlers_disconnect_by_func(linktype_combo_box, G_CALLBACK(select_link_type_cb), NULL );
5735     ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box));
5736     for (i = (gint)g_list_length(device.links)-1; i >= 0; i--) {
5737       GList* rem = g_list_nth(device.links, i);
5738       device.links = g_list_remove_link(device.links, rem);
5739       g_list_free_1(rem);
5740     }
5741     device.active_dlt = -1;
5742     linktype_count = 0;
5743     device.monitor_mode_supported = caps->can_set_rfmon;
5744     device.monitor_mode_enabled = monitor_mode;
5745     for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
5746       linkr = (link_row *)g_malloc(sizeof(link_row));
5747       data_link_info = (data_link_info_t *)lt_entry->data;
5748       if (data_link_info->description != NULL) {
5749         ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box),
5750                                              data_link_info->description,
5751                                              GINT_TO_POINTER(data_link_info->dlt));
5752         linkr->dlt = data_link_info->dlt;
5753         if (linktype_count == 0) {
5754           device.active_dlt = data_link_info->dlt;
5755         }
5756         linkr->name = g_strdup(data_link_info->description);
5757       } else {
5758         gchar *str;
5759         /* Not supported - tell them about it but don't let them select it. */
5760         str = g_strdup_printf("%s (not supported)", data_link_info->name);
5761         ws_combo_box_append_text_and_pointer_full(GTK_COMBO_BOX(linktype_combo_box),
5762                                                   NULL,
5763                                                   str,
5764                                                   GINT_TO_POINTER(-1),  /* Flag as "not supported" */
5765                                                   FALSE);
5766         linkr->dlt = -1;
5767         linkr->name = g_strdup(str);
5768         g_free(str);
5769       }
5770       device.links = g_list_append(device.links, linkr);
5771       linktype_count++;
5772     }
5773     free_if_capabilities(caps);
5774   } else {
5775     /* We don't know whether this supports monitor mode or not;
5776     don't ask for monitor mode. */
5777     device.monitor_mode_enabled = FALSE;
5778     device.monitor_mode_supported = FALSE;
5779   }
5780   gtk_widget_set_sensitive(linktype_lb, linktype_count >= 2);
5781   gtk_widget_set_sensitive(linktype_combo_box, linktype_count >= 2);
5782   ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box),0);
5783   g_array_insert_val(global_capture_opts.all_ifaces, marked_interface, device);
5784 }
5785 #endif
5786
5787 /*
5788  * Adjust the sensitivity of various widgets as per the current setting
5789  * of other widgets.
5790  */
5791 static void
5792 capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
5793 {
5794   GtkWidget *multi_files_on_cb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
5795             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_cbx,
5796             *file_duration_cb, *file_duration_sb, *file_duration_cbx,
5797             *sync_cb, *auto_scroll_cb,
5798             *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
5799             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_cbx,
5800             *stop_duration_cb, *stop_duration_sb, *stop_duration_cbx,
5801             *stop_files_cb, *stop_files_sb, *stop_files_lb;
5802
5803   multi_files_on_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_MULTI_FILES_ON_CB_KEY);
5804   ringbuffer_nbf_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_CB_KEY);
5805   ringbuffer_nbf_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
5806   ringbuffer_nbf_lb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_LB_KEY);
5807   ring_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CB_KEY);
5808   ring_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_SB_KEY);
5809   ring_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CBX_KEY);
5810   file_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CB_KEY);
5811   file_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_SB_KEY);
5812   file_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CBX_KEY);
5813   sync_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SYNC_KEY);
5814   auto_scroll_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
5815   stop_packets_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_CB_KEY);
5816   stop_packets_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_SB_KEY);
5817   stop_packets_lb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_LB_KEY);
5818   stop_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CB_KEY);
5819   stop_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_SB_KEY);
5820   stop_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CBX_KEY);
5821   stop_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CB_KEY);
5822   stop_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_SB_KEY);
5823   stop_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CBX_KEY);
5824   stop_files_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_CB_KEY);
5825   stop_files_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_SB_KEY);
5826   stop_files_lb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_LB_KEY);
5827
5828   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
5829     /* "Update list of packets in real time" captures enabled; we don't
5830        support ring buffer mode for those captures, so turn ring buffer
5831        mode off if it's on, and make its toggle button, and the spin
5832        button for the number of ring buffer files (and the spin button's
5833        label), insensitive. */
5834 #if 0
5835     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(multi_files_on_cb), FALSE);
5836     gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), FALSE);
5837 #endif
5838
5839     /* Auto-scroll mode is meaningful only in "Update list of packets
5840        in real time" captures, so make its toggle button sensitive. */
5841     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
5842
5843     /*gtk_widget_set_sensitive(GTK_WIDGET(hide_info_cb), TRUE);*/
5844   } else {
5845     /* "Update list of packets in real time" captures disabled; that
5846        means ring buffer mode is OK, so make its toggle button
5847        sensitive. */
5848 /*    gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), TRUE);*/
5849
5850     /* Auto-scroll mode is meaningful only in "Update list of packets
5851        in real time" captures, so make its toggle button insensitive. */
5852     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
5853
5854     /*gtk_widget_set_sensitive(GTK_WIDGET(hide_info_cb), FALSE);*/
5855   }
5856
5857   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb))) {
5858     /* Ring buffer mode enabled. */
5859
5860     /* Force at least one of the "file switch" conditions (we need at least one) */
5861       if ((gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)) == FALSE) &&
5862           (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)) == FALSE)) {
5863       if (tb == ring_filesize_cb)
5864         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(file_duration_cb), TRUE);
5865       else
5866         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb), TRUE);
5867     }
5868
5869     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), TRUE);
5870     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb),
5871           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
5872     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb),
5873           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
5874
5875     /* The ring filesize spinbox is sensitive if the "Next capture file
5876          after N kilobytes" checkbox is on. */
5877     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), TRUE);
5878     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),
5879           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
5880     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cbx),
5881           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
5882
5883     /* The ring duration spinbox is sensitive if the "Next capture file
5884          after N seconds" checkbox is on. */
5885     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), TRUE);
5886     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),
5887           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
5888     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cbx),
5889           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
5890
5891     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), FALSE);
5892     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb), FALSE);
5893     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cbx), FALSE);
5894
5895     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), TRUE);
5896     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb),
5897           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
5898     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb),
5899           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
5900   } else {
5901     /* Ring buffer mode disabled. */
5902     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), FALSE);
5903     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
5904     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
5905
5906     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), FALSE);
5907     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),FALSE);
5908     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cbx),FALSE);
5909
5910     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), FALSE);
5911     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),FALSE);
5912     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cbx),FALSE);
5913
5914     /* The maximum file size spinbox is sensitive if the "Stop capture
5915          after N kilobytes" checkbox is on. */
5916     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), TRUE);
5917     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb),
5918           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
5919     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cbx),
5920           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
5921
5922     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), FALSE);
5923     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb), FALSE);
5924     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb), FALSE);
5925   }
5926
5927   /* The maximum packet count spinbox is sensitive if the "Stop capture
5928      after N packets" checkbox is on. */
5929   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_sb),
5930       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
5931   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_lb),
5932       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
5933
5934   /* The capture duration spinbox is sensitive if the "Stop capture
5935      after N seconds" checkbox is on. */
5936   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_sb),
5937       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
5938   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_cbx),
5939       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
5940 }
5941
5942 gboolean capture_dlg_window_present(void)
5943 {
5944   return (cap_open_w?TRUE:FALSE);
5945 }
5946
5947 /*
5948  * Refresh everything visible that shows an interface list that
5949  * includes local interfaces.
5950  */
5951 void
5952 refresh_local_interface_lists(void)
5953 {
5954   /* Reload the local interface list. */
5955   if (global_capture_opts.session_started == FALSE)
5956     scan_local_interfaces();
5957
5958   /* If there's an interfaces dialog up, refresh it. */
5959   if (interfaces_dialog_window_present())
5960     refresh_if_window();
5961
5962   /* If there's a capture options dialog up, refresh it. */
5963   if (capture_dlg_window_present())
5964     capture_dlg_refresh_if();
5965
5966   /* If the welcome screen is up, refresh its interface list. */
5967   if (get_welcome_window() != NULL)
5968     welcome_if_panel_reload();
5969
5970   /* Refresh the 802.11 toolbar. */
5971   tb80211_refresh_interfaces();
5972 }
5973
5974 /*
5975  * Refresh everything visible that shows an interface list that
5976  * includes non-local interfaces.
5977  */
5978 void
5979 refresh_non_local_interface_lists(void)
5980 {
5981   /* If there's a capture options dialog up, refresh it. */
5982   if (capture_dlg_window_present())
5983     capture_dlg_refresh_if();
5984
5985   /* If the welcome screen is up, refresh its interface list. */
5986   if (get_welcome_window() != NULL)
5987     welcome_if_panel_reload();
5988 }
5989
5990 #endif /* HAVE_LIBPCAP */
5991
5992 /*
5993  * Editor modelines
5994  *
5995  * Local Variables:
5996  * c-basic-offset: 2
5997  * tab-width: 8
5998  * indent-tabs-mode: nil
5999  * End:
6000  *
6001  * ex: set shiftwidth=2 tabstop=8 expandtab:
6002  * :indentSize=2:tabSize=8:noTabs=true:
6003  */