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