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