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