df419ba94b11ec80a94a9528ffb06cbce293f72f
[obnox/wireshark/wip.git] / gtk / capture_dlg.c
1 /* capture_dlg.c
2  * Routines for packet capture windows
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #ifdef HAVE_SYS_TYPES_H
32 #include <sys/types.h>
33 #endif
34
35 #include <string.h>
36
37 #include <stdio.h>
38
39 #include <gtk/gtk.h>
40
41 #include <epan/packet.h>
42 #include <epan/addr_resolv.h>
43 #include <epan/prefs.h>
44 #include <epan/filesystem.h>
45
46 #include "../capture.h"
47 #include "../capture_errs.h"
48 #include "../capture_ifinfo.h"
49 #include "../simple_dialog.h"
50 #include "../capture-pcap-util.h"
51 #include "../capture_ui_utils.h"
52 #include "../ringbuffer.h"
53
54 #include "gtk/main.h"
55 #include "gtk/menus.h"
56 #include "gtk/gui_utils.h"
57 #include "gtk/capture_dlg.h"
58 #include "gtk/filter_dlg.h"
59 #include "gtk/dlg_utils.h"
60 #include "gtk/file_dlg.h"
61 #include "gtk/stock_icons.h"
62 #include "gtk/capture_file_dlg.h"
63 #include "gtk/help_dlg.h"
64 #include "gtk/gtkglobals.h"
65 #include "gtk/capture_globals.h"
66 #include "gtk/cfilter_combo_utils.h"
67 #include "gtk/capture_if_dlg.h"
68 #include "gtk/main_welcome.h"
69 #include "gtk/network_icons.h"
70
71 #ifdef _WIN32
72 #include "../capture-wpcap.h"
73 #endif
74
75 #include "gtk/keys.h"
76
77 #include "gtk/old-gtk-compat.h"
78
79 #ifdef HAVE_AIRPCAP
80 #include <airpcap.h>
81 #include "airpcap_loader.h"
82 #include "airpcap_gui_utils.h"
83 #include "airpcap_dlg.h"
84 #endif
85
86 /* Capture callback data keys */
87 #define E_CAP_IFACE_KEY                 "cap_iface"
88 #define E_CAP_IFACE_IP_KEY              "cap_iface_ip"
89 #define E_CAP_SNAP_CB_KEY               "cap_snap_cb"
90 #define E_CAP_LT_CBX_KEY                "cap_lt_cbx"
91 #define E_CAP_LT_CBX_LABEL_KEY          "cap_lt_cbx_label"
92 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
93 #define E_CAP_BUFFER_SIZE_SB_KEY        "cap_buffer_size_sb"
94 #endif
95 #define E_CAP_SNAP_SB_KEY               "cap_snap_sb"
96 #define E_CAP_PROMISC_KEY               "cap_promisc"
97 #define E_CAP_PROMISC_KEY_ALL           "cap_promisc_all"
98 #ifdef HAVE_PCAP_CREATE
99 #define E_CAP_MONITOR_KEY               "cap_monitor"
100 #endif
101 #define E_CAP_PCAP_NG_KEY               "cap_pcap_ng"
102 #define E_CAP_FILT_KEY                  "cap_filter_te"
103 #define E_OPT_EDIT_DIALOG_PTR_KEY       "cap_edit_opt_dialog"
104 #define E_OPT_EDIT_CALLER_PTR_KEY       "cap_edit_opt_caller"
105 #define E_CAP_FILE_TE_KEY               "cap_file_te"
106 #define E_CAP_MULTI_FILES_ON_CB_KEY     "cap_multi_files_on_cb"
107 #define E_CAP_RING_FILESIZE_CB_KEY      "cap_ring_filesize_cb"
108 #define E_CAP_RING_FILESIZE_SB_KEY      "cap_ring_filesize_sb"
109 #define E_CAP_RING_FILESIZE_CBX_KEY     "cap_ring_filesize_cbx"
110 #define E_CAP_FILE_DURATION_CB_KEY      "cap_file_duration_cb"
111 #define E_CAP_FILE_DURATION_SB_KEY      "cap_file_duration_sb"
112 #define E_CAP_FILE_DURATION_CBX_KEY     "cap_file_duration_cbx"
113 #define E_CAP_RING_NBF_CB_KEY           "cap_ring_nbf_cb"
114 #define E_CAP_RING_NBF_SB_KEY           "cap_ring_nbf_sb"
115 #define E_CAP_RING_NBF_LB_KEY           "cap_ring_nbf_lb"
116 #define E_CAP_STOP_FILES_CB_KEY         "cap_stop_files_cb"
117 #define E_CAP_STOP_FILES_SB_KEY         "cap_stop_files_sb"
118 #define E_CAP_STOP_FILES_LB_KEY         "cap_stop_files_lb"
119 #define E_CAP_SYNC_KEY                  "cap_sync"
120 #define E_CAP_AUTO_SCROLL_KEY           "cap_auto_scroll"
121 #define E_CAP_HIDE_INFO_KEY             "cap_hide_info"
122 #define E_CAP_STOP_PACKETS_CB_KEY       "cap_stop_packets_cb"
123 #define E_CAP_STOP_PACKETS_SB_KEY       "cap_stop_packets_sb"
124 #define E_CAP_STOP_PACKETS_LB_KEY       "cap_stop_packets_lb"
125 #define E_CAP_STOP_FILESIZE_CB_KEY      "cap_stop_filesize_cb"
126 #define E_CAP_STOP_FILESIZE_SB_KEY      "cap_stop_filesize_sb"
127 #define E_CAP_STOP_FILESIZE_CBX_KEY     "cap_stop_filesize_cbx"
128 #define E_CAP_STOP_DURATION_CB_KEY      "cap_stop_duration_cb"
129 #define E_CAP_STOP_DURATION_SB_KEY      "cap_stop_duration_sb"
130 #define E_CAP_STOP_DURATION_CBX_KEY     "cap_stop_duration_cbx"
131 #define E_CAP_M_RESOLVE_KEY             "cap_m_resolve"
132 #define E_CAP_N_RESOLVE_KEY             "cap_n_resolve"
133 #define E_CAP_T_RESOLVE_KEY             "cap_t_resolve"
134
135 #ifdef HAVE_PCAP_REMOTE
136 #define E_CAP_IFTYPE_CBX_KEY            "cap_iftype_cbx"
137 #define E_CAP_IF_LIST_KEY               "cap_if_list"
138 #define E_CAP_DATATX_UDP_CB_KEY         "cap_datatx_udp_cb"
139 #define E_CAP_NOCAP_RPCAP_CB_KEY        "cap_nocap_rpcap_cb"
140 #define E_CAP_REMOTE_DIALOG_PTR_KEY     "cap_remote_dialog"
141 #define E_CAP_REMOTE_CALLER_PTR_KEY     "cap_remote_caller"
142 #define E_REMOTE_HOST_TE_KEY            "cap_remote_host"
143 #define E_REMOTE_PORT_TE_KEY            "cap_remote_port"
144 #define E_REMOTE_AUTH_NULL_KEY          "cap_remote_auth_null"
145 #define E_REMOTE_AUTH_PASSWD_KEY        "cap_remote_auth_passwd"
146 #define E_REMOTE_USERNAME_LB_KEY        "cap_remote_username_lb"
147 #define E_REMOTE_USERNAME_TE_KEY        "cap_remote_username_te"
148 #define E_REMOTE_PASSWD_LB_KEY          "cap_remote_passwd_lb"
149 #define E_REMOTE_PASSWD_TE_KEY          "cap_remote_passwd_te"
150 #define E_CAP_CBX_IFTYPE_VALUE_KEY      "cap_cbx_iftype_value"
151 #define E_CAP_CBX_PREV_IFTYPE_VALUE_KEY "cap_cbx_prev_iftype_value"
152 #define E_CAP_CBX_IFTYPE_NOUPDATE_KEY   "cap_cbx_iftype_noupdate"
153 #define E_OPT_REMOTE_BT_KEY             "cap_remote_opt_bt"
154 #define E_OPT_REMOTE_DIALOG_PTR_KEY     "cap_remote_opt_dialog"
155 #define E_OPT_REMOTE_CALLER_PTR_KEY     "cap_remote_opt_caller"
156 #endif
157 #ifdef HAVE_PCAP_SETSAMPLING
158 #define E_CAP_SAMP_NONE_RB_KEY          "cap_samp_none_rb"
159 #define E_CAP_SAMP_COUNT_RB_KEY         "cap_samp_count_rb"
160 #define E_CAP_SAMP_COUNT_SB_KEY         "cap_samp_count_sb"
161 #define E_CAP_SAMP_TIMER_RB_KEY         "cap_samp_timer_rb"
162 #define E_CAP_SAMP_TIMER_SB_KEY         "cap_samp_timer_sb"
163 #endif
164
165 #define DUMMY_SNAPLENGTH                65535
166 #define DUMMY_NETMASK                   0xFF000000
167
168 enum
169 {
170   COL_NAME = 0,
171   COL_ADDRESS,
172   COL_LINK
173 } ;
174
175 /*
176  * Keep a static pointer to the current "Capture Options" window, if
177  * any, so that if somebody tries to do "Capture:Options" while there's
178  * already a "Capture Options" window up, we just pop up the existing
179  * one, rather than creating a new one.
180  * Also: Capture:Start obtains info from the "Capture Options" window
181  *       if it exists and if its creation is complete.
182  */
183 static GtkWidget *cap_open_w = NULL, *opt_edit_w = NULL, *ok_bt;
184 static gboolean   cap_open_complete;  /* valid only if cap_open_w != NULL */
185
186 static GHashTable *cap_settings_history=NULL;
187 static gint16 num_selected;
188 static GArray *rows = NULL;
189 static gint marked_row;
190
191 #ifdef HAVE_PCAP_REMOTE
192 static GHashTable *remote_host_list=NULL;
193 static remote_options global_remote_opts;
194 #endif
195
196 static void
197 capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te);
198
199 static void
200 select_link_type_cb(GtkWidget *w, gpointer data);
201
202 #ifdef HAVE_PCAP_REMOTE
203 static void
204 capture_remote_cb(GtkWidget *w, gboolean focus_username);
205 #endif
206
207 static void
208 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
209
210 static void
211 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
212
213 #ifdef HAVE_PCAP_CREATE
214 static void
215 capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp);
216 #endif
217
218 static gboolean
219 capture_dlg_prep(gpointer parent_w);
220
221 extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg);
222
223 /* stop the currently running capture */
224 void
225 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
226 {
227 #ifdef HAVE_AIRPCAP
228   airpcap_set_toolbar_stop_capture(airpcap_if_active);
229 #endif
230
231   capture_stop(&global_capture_opts);
232 }
233
234 /* restart (stop - delete old file - start) running capture */
235 void
236 capture_restart_cb(GtkWidget *w _U_, gpointer d _U_)
237 {
238 #ifdef HAVE_AIRPCAP
239   airpcap_set_toolbar_start_capture(airpcap_if_active);
240 #endif
241
242   capture_restart(&global_capture_opts);
243 }
244
245 cap_settings_t
246 capture_get_cap_settings (gchar *if_name)
247 {
248   cap_settings_t cap_settings, *cap_settings_p;
249
250   if (cap_settings_history) {
251     cap_settings_p = g_hash_table_lookup(cap_settings_history, if_name);
252   } else {
253     cap_settings_p = NULL;
254   }
255
256   if (cap_settings_p) {
257     cap_settings = *cap_settings_p;
258   } else {
259     cap_settings.monitor_mode = prefs_capture_device_monitor_mode(if_name);
260     cap_settings.linktype = capture_dev_user_linktype_find(if_name);
261   }
262
263   return cap_settings;
264 }
265
266 static void
267 capture_filter_check_syntax_cb(GtkWidget *w _U_, gpointer user_data _U_)
268 {
269   struct bpf_program fcode;
270   GtkWidget *filter_cm, *filter_te;
271   const gchar *filter_text;
272   gpointer  ptr;
273   int       dlt;
274
275   GtkWidget *linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
276
277   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
278     g_assert_not_reached();  /* Programming error: somehow nothing is active */
279   }
280   if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
281     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
282   }
283
284   if (!prefs.capture_syntax_check_filter)
285     return;
286
287   filter_cm = g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY);
288   filter_te = gtk_bin_get_child(GTK_BIN(filter_cm));
289   filter_text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(filter_cm));
290   if (strlen(filter_text) == 0) {
291     colorize_filter_te_as_empty(filter_te);
292     return;
293   }
294
295   /* pcap_compile_nopcap will not alter the filter string, so the (char *) cast is "safe" */
296   if (pcap_compile_nopcap(DUMMY_SNAPLENGTH /* use a dummy snaplength for syntax-checking */,
297           dlt, &fcode, (char *)filter_text, 1 /* Do optimize */,
298           DUMMY_NETMASK /* use a dummy netmask for syntax-checking */) < 0) {
299     colorize_filter_te_as_invalid(filter_te);
300   } else {
301     colorize_filter_te_as_valid(filter_te);
302   }
303 }
304
305 #define TIME_UNIT_SECOND    0
306 #define TIME_UNIT_MINUTE    1
307 #define TIME_UNIT_HOUR      2
308 #define TIME_UNIT_DAY       3
309 #define MAX_TIME_UNITS 4
310 static const char *time_unit_name[MAX_TIME_UNITS] = {
311   "second(s)",
312   "minute(s)",
313   "hour(s)",
314   "day(s)",
315 };
316
317 /* create one of the duration options */
318 /* (and select the matching unit depending on the given value) */
319 static GtkWidget *time_unit_combo_box_new(guint32 value) {
320   GtkWidget *unit_combo_box;
321   int i;
322   unit_combo_box = gtk_combo_box_text_new ();
323   for(i = 0; i < MAX_TIME_UNITS; i++) {
324     gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (unit_combo_box), time_unit_name[i]);
325   }
326   /* the selected combo_box item can't be changed, once the combo_box
327      is created, so set the matching combo_box item now */
328   /* days */
329   if(value >= 60 * 60 * 24) {
330     gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_DAY);
331   } else {
332     /* hours */
333     if(value >= 60 * 60) {
334       gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_HOUR);
335     } else {
336       /* minutes */
337       if(value >= 60) {
338         gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_MINUTE);
339       } else {
340         /* seconds */
341         gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), TIME_UNIT_SECOND);
342       }
343     }
344   }
345   return unit_combo_box;
346 }
347
348 /* convert time value from raw to displayed (e.g. 60s -> 1min) */
349 static guint32 time_unit_combo_box_convert_value(
350 guint32 value)
351 {
352   /* days */
353   if(value >= 60 * 60 * 24) {
354     return value / (60 * 60 * 24);
355   }
356
357   /* hours */
358   if(value >= 60 * 60) {
359     return value / (60 * 60);
360   }
361
362   /* minutes */
363   if(value >= 60) {
364     return value / 60;
365   }
366
367   /* seconds */
368   return value;
369 }
370
371 /* get raw value from unit and value fields */
372 static guint32 time_unit_combo_box_get_value(
373 GtkWidget *unit_combo_box,
374 guint32 value)
375 {
376   int unit;
377
378   unit = gtk_combo_box_get_active (GTK_COMBO_BOX(unit_combo_box));
379
380   switch(unit) {
381   case(TIME_UNIT_SECOND):
382     return value;
383   case(TIME_UNIT_MINUTE):
384     return value * 60;
385   case(TIME_UNIT_HOUR):
386     return value * 60 * 60;
387   case(TIME_UNIT_DAY):
388     return value * 60 * 60 * 24;
389   default:
390     g_assert_not_reached();
391     return 0;
392   }
393 }
394
395
396 #define SIZE_UNIT_KILOBYTES 0
397 #define SIZE_UNIT_MEGABYTES 1
398 #define SIZE_UNIT_GIGABYTES 2
399 #define MAX_SIZE_UNITS 3
400 static const char *size_unit_name[MAX_SIZE_UNITS] = {
401   "kilobyte(s)",
402   "megabyte(s)",
403   "gigabyte(s)",
404 };
405
406 /* create one of the size options */
407 /* (and select the matching unit depending on the given value) */
408 static GtkWidget *size_unit_combo_box_new(guint32 value) {
409   GtkWidget *unit_combo_box;
410   int i;
411   unit_combo_box=gtk_combo_box_text_new();
412   for(i=0;i<MAX_SIZE_UNITS;i++){
413     gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (unit_combo_box), size_unit_name[i]);
414   }
415   /* the selected combo_box item can't be changed, once the combo_box
416      is created, so set the matching combo_box item now */
417   /* gigabytes */
418   if(value >= 1024 * 1024) {
419     gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), SIZE_UNIT_GIGABYTES);
420   } else {
421     /* megabytes */
422     if(value >= 1024) {
423       gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), SIZE_UNIT_MEGABYTES);
424     } else {
425       /* kilobytes */
426       gtk_combo_box_set_active(GTK_COMBO_BOX(unit_combo_box), SIZE_UNIT_KILOBYTES);
427     }
428   }
429   return unit_combo_box;
430 }
431
432 /* convert size value from raw to displayed (e.g. 1024 Bytes -> 1 KB) */
433 static guint32 size_unit_combo_box_set_value(
434 guint32 value)
435 {
436   /* gigabytes */
437   if(value >= 1024 * 1024) {
438     return value / (1024 * 1024);
439   }
440
441   /* megabytes */
442   if(value >= 1024) {
443     return value / (1024);
444   }
445
446   /* kilobytes */
447   return value;
448 }
449
450 /* get raw value from unit and value fields */
451 static guint32 size_unit_combo_box_convert_value(
452 GtkWidget *unit_combo_box,
453 guint32 value)
454 {
455   int unit;
456
457   unit = gtk_combo_box_get_active (GTK_COMBO_BOX(unit_combo_box));
458
459   switch(unit) {
460   case(SIZE_UNIT_KILOBYTES):
461     return value;
462   case(SIZE_UNIT_MEGABYTES):
463     if(value > G_MAXINT / 1024) {
464       return 0;
465     } else {
466       return value * 1024;
467     }
468   case(SIZE_UNIT_GIGABYTES):
469     if(value > G_MAXINT / (1024 * 1024)) {
470       return 0;
471     } else {
472       return value * 1024 * 1024;
473     }
474   default:
475     g_assert_not_reached();
476     return 0;
477   }
478 }
479
480 #ifdef HAVE_AIRPCAP
481 /*
482  * Sets the toolbar before calling the advanced dialog with for the right interface
483  */
484 static void
485 options_airpcap_advanced_cb(GtkWidget *w, gpointer d)
486 {
487   int *from_widget;
488
489   from_widget = (gint*)g_malloc(sizeof(gint));
490   *from_widget = AIRPCAP_ADVANCED_FROM_OPTIONS;
491   g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_ADVANCED_FROM_KEY,from_widget);
492
493   airpcap_if_active = airpcap_if_selected;
494   airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
495   display_airpcap_advanced_cb(w,d);
496 }
497 #endif
498
499 #ifdef HAVE_PCAP_REMOTE_NEVER
500 /* PCAP interface type menu item */
501 struct iftype_info {
502   capture_source  id;
503   const char     *name;
504 };
505
506 /* List of available types of PCAP interface */
507 static struct iftype_info iftype[] = {
508   { CAPTURE_IFLOCAL, "Local" },
509   { CAPTURE_IFREMOTE, "Remote..." }
510 };
511
512 #define REMOTE_HOST_START ((sizeof(iftype) / sizeof(iftype[0])) + 1)
513 #define REMOTE_HOST_SEPARATOR "---"
514
515 static void
516 iftype_combo_box_add_remote_separators (GtkWidget *iftype_cbx)
517 {
518   gtk_combo_box_text_append_text(GTK_COMBO_BOX(iftype_cbx), REMOTE_HOST_SEPARATOR);
519   gtk_combo_box_text_append_text(GTK_COMBO_BOX(iftype_cbx), REMOTE_HOST_SEPARATOR);
520   gtk_combo_box_text_append_text(GTK_COMBO_BOX(iftype_cbx), "Clear list");
521 }
522
523 static void
524 iftype_combo_box_add (GtkWidget *iftype_cbx)
525 {
526   GtkTreeModel *model;
527   GtkTreeIter iter;
528   struct remote_host *rh;
529   gboolean create_new = FALSE;
530   gchar *string;
531   guint i, pos = REMOTE_HOST_START;
532
533   rh = g_hash_table_lookup (remote_host_list, g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_host);
534   if (!rh) {
535     rh = g_malloc0 (sizeof (*rh));
536     if (g_hash_table_size (remote_host_list) == 0) {
537       iftype_combo_box_add_remote_separators (iftype_cbx);
538     }
539     gtk_combo_box_text_insert_text(GTK_COMBO_BOX(iftype_cbx), pos, g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_host);
540     rh->remote_host = g_strdup (g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_host);
541     create_new = TRUE;
542   } else {
543     model = gtk_combo_box_get_model(GTK_COMBO_BOX(iftype_cbx));
544     if (gtk_tree_model_get_iter_first(model, &iter)) {
545       /* Skip the first entries */
546       for (i = 0; i < REMOTE_HOST_START; i++)
547         gtk_tree_model_iter_next(model, &iter);
548       do {
549         gtk_tree_model_get(model, &iter, 0, &string, -1);
550         if (string) {
551           if (strcmp (g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_host, string) == 0) {
552             /* Found match, show this position in combo box */
553             g_free (string);
554             break;
555           }
556           g_free (string);
557         }
558         pos++;
559       } while (gtk_tree_model_iter_next(model, &iter));
560     }
561
562     g_free (rh->remote_port);
563     g_free (rh->auth_username);
564     g_free (rh->auth_password);
565   }
566
567   rh->remote_port = g_strdup (g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_port);
568   rh->auth_type = g_array_index(global_capture_opts.ifaces, interface_options, 0).auth_type;
569   rh->auth_username = g_strdup (g_array_index(global_capture_opts.ifaces, interface_options, 0).auth_username);
570   rh->auth_password = g_strdup (g_array_index(global_capture_opts.ifaces, interface_options, 0).auth_password);
571
572   if (create_new) {
573     g_hash_table_insert (remote_host_list, g_strdup (g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_host), rh);
574   }
575
576   g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_VALUE_KEY, GINT_TO_POINTER(pos));
577   g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_NOUPDATE_KEY, GINT_TO_POINTER(1));
578   gtk_combo_box_set_active(GTK_COMBO_BOX(iftype_cbx), pos);
579   g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_NOUPDATE_KEY, GINT_TO_POINTER(0));
580 }
581
582 static void
583 iftype_combo_box_add_remote_host (gpointer key, gpointer value _U_, gpointer user_data)
584 {
585   gtk_combo_box_text_insert_text(GTK_COMBO_BOX(user_data), REMOTE_HOST_START, key);
586
587   if (g_array_index(global_capture_opts.ifaces, interface_options, 0).src_type == CAPTURE_IFREMOTE) {
588     /* Ensure we select the correct entry */
589     if (strcmp ((char *)key, g_array_index(global_capture_opts.ifaces, interface_options, 0).remote_host) == 0) {
590       gtk_combo_box_set_active(GTK_COMBO_BOX(user_data), REMOTE_HOST_START);
591     }
592   }
593 }
594
595 /* Fill the menu of available types of interfaces */
596 static GtkWidget *
597 iftype_combo_box_new(void)
598 {
599   GtkWidget *iftype_cbx;
600   unsigned int i;
601
602   iftype_cbx = gtk_combo_box_text_new();
603
604   for (i = 0; i < sizeof(iftype) / sizeof(iftype[0]); i++) {
605     gtk_combo_box_text_append_text(GTK_COMBO_BOX(iftype_cbx), iftype[i].name);
606   }
607
608   if (g_hash_table_size (remote_host_list) > 0) {
609     /* Add remote hosts */
610     iftype_combo_box_add_remote_separators (iftype_cbx);
611     g_hash_table_foreach (remote_host_list, iftype_combo_box_add_remote_host, iftype_cbx);
612   }
613
614   if (g_array_index(global_capture_opts.ifaces, interface_options, 0).src_type == CAPTURE_IFLOCAL) {
615     gtk_combo_box_set_active(GTK_COMBO_BOX(iftype_cbx), CAPTURE_IFLOCAL);
616   } else {
617     int iftype = gtk_combo_box_get_active(GTK_COMBO_BOX(iftype_cbx));
618     g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_VALUE_KEY, GINT_TO_POINTER(iftype));
619   }
620   g_signal_connect(iftype_cbx, "changed", G_CALLBACK(select_if_type_cb), NULL);
621
622   return iftype_cbx;
623 }
624
625 static gboolean
626 iftype_combo_is_separator (GtkTreeModel *model, GtkTreeIter *iter, gpointer data _U_)
627 {
628   gboolean result = FALSE;
629   gchar *string;
630
631   gtk_tree_model_get(model, iter, 0, &string, -1);
632   if (string) {
633     result = !strcmp (string, REMOTE_HOST_SEPARATOR);
634     g_free (string);
635   }
636
637   return result;
638
639 }
640 #endif
641
642 #ifdef HAVE_PCAP_REMOTE
643 static void
644 error_list_remote_interface_cb (gpointer dialog _U_, gint btn _U_, gpointer data)
645 {
646   capture_remote_cb(GTK_WIDGET(data), FALSE);
647 }
648 #endif
649
650 void insert_new_rows(GList *list)
651 {
652   interface_row row;
653   GtkTreeIter iter;
654   GList *if_entry;
655   if_info_t *if_info;
656   char *if_string="", *temp="", *snaplen_string;
657   gchar *descr;
658   if_capabilities_t *caps;
659   gint linktype_count;
660   cap_settings_t cap_settings;
661   GSList *curr_addr;
662   int ips = 0;
663   guint i, count=0;
664   if_addr_t *addr;
665   GList *lt_entry;
666   data_link_info_t *data_link_info;
667   gchar *str, *link_type_name = NULL;
668   gboolean found = FALSE;
669   GString *ip_str;
670   GtkTreeView  *if_cb;
671   GtkTreeModel *model;
672   interface_options interface_opts;
673   link_row *link = NULL;
674
675   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
676   model = gtk_tree_view_get_model(if_cb);
677   count = rows->len;
678   /* Scan through the list and build a list of strings to display. */
679   for (if_entry = g_list_first(list); if_entry != NULL; if_entry = g_list_next(if_entry)) {
680     if_info = if_entry->data;
681 #ifdef HAVE_PCAP_REMOTE
682     add_interface_to_remote_list(if_info);
683 #endif
684     for (i = 0; i < count; i++) {
685       row = g_array_index(rows, interface_row, i);
686       if (strcmp(row.name, if_info->name) == 0) {
687         found = TRUE;
688         break;
689       }
690     }
691     if (found) {
692       found = FALSE;
693       continue;
694     }
695     ip_str = g_string_new("");
696     str = "";
697     ips = 0;
698     row.name = g_strdup(if_info->name);
699     /* Is this interface hidden and, if so, should we include it
700        anyway? */
701     descr = capture_dev_user_descr_find(if_info->name);
702     if (descr != NULL) {
703       /* Yes, we have a user-supplied description; use it. */
704       if_string = g_strdup_printf("%s: %s", descr, if_info->name);
705       g_free(descr);
706     } else {
707       /* No, we don't have a user-supplied description; did we get
708          one from the OS or libpcap? */
709       if (if_info->description != NULL) {
710         /* Yes - use it. */
711         if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
712       } else {
713         /* No. */
714         if_string = g_strdup(if_info->name);
715       }
716     } /* else descr != NULL */
717     if (if_info->loopback) {
718       row.display_name = g_strdup_printf("%s (loopback)", if_string);
719     } else {
720       row.display_name = g_strdup(if_string);
721     }
722     found = FALSE;
723     for (i = 0; i < global_capture_opts.ifaces->len; i++) {
724       interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
725       if (strcmp(interface_opts.name, (char*)row.name)!=0)
726         continue;
727       else {
728         found = TRUE;
729         break;
730       }
731     }
732     if (found) {
733 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
734       row.buffer = interface_opts.buffer_size;
735 #endif
736       row.pmode = interface_opts.promisc_mode;
737       row.has_snaplen = interface_opts.has_snaplen;
738       row.snaplen = interface_opts.snaplen;
739       row.cfilter = g_strdup(interface_opts.cfilter);
740     } else {
741 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
742       row.buffer = global_capture_opts.default_options.buffer_size;
743 #endif
744       row.pmode = global_capture_opts.default_options.promisc_mode;
745       row.has_snaplen = global_capture_opts.default_options.has_snaplen;
746       row.snaplen = global_capture_opts.default_options.snaplen;
747       row.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
748     }
749     cap_settings = capture_get_cap_settings(if_string);
750     caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, NULL);
751     gtk_list_store_append (GTK_LIST_STORE(model), &iter);
752     for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
753       if (ips != 0) {
754         g_string_append(ip_str, "\n");
755       }
756       addr = (if_addr_t *)curr_addr->data;
757
758       switch (addr->ifat_type) {
759         case IF_AT_IPv4:
760           g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
761           break;
762         case IF_AT_IPv6:
763           g_string_append(ip_str,  ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
764           break;
765         default:
766           /* In case we add non-IP addresses */
767           break;
768       }
769     } /* for curr_addr */
770     linktype_count = 0;
771     row.links = NULL;
772     if (caps != NULL) {
773 #ifdef HAVE_PCAP_CREATE
774       row.monitor_mode_enabled = cap_settings.monitor_mode;
775       row.monitor_mode_supported = caps->can_set_rfmon;
776 #endif
777       for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
778         data_link_info = lt_entry->data;
779         if (data_link_info->description != NULL) {
780           str = g_strdup_printf("%s", data_link_info->description);
781         } else {
782           str = g_strdup_printf("%s (not supported)", data_link_info->name);
783         }
784         if (linktype_count == 0) {
785           link_type_name = g_strdup(str);
786           row.active_dlt = data_link_info->dlt;
787         }
788         link = (link_row *)g_malloc(sizeof(link_row));
789         link->dlt = data_link_info->dlt;
790         link->name = g_strdup(str);
791         row.links = g_list_append(row.links, link);
792         linktype_count++;
793       } /* for link_types */
794     } else {
795       cap_settings.monitor_mode = FALSE;
796 #if defined(HAVE_PCAP_CREATE)
797       row.monitor_mode_enabled = FALSE;
798       row.monitor_mode_supported = FALSE;
799 #endif
800       row.active_dlt = -1;
801       link_type_name = g_strdup("default");
802     }
803     row.addresses = g_strdup(ip_str->str);
804     row.no_addresses = ips;
805     if (ips == 0) {
806       temp = g_strdup_printf("<b>%s</b>", row.display_name);
807     } else {
808       temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", row.display_name, row.addresses);
809     }
810 #ifdef HAVE_PCAP_REMOTE
811     row.remote_opts.src_type= global_remote_opts.src_type;
812     row.remote_opts.remote_host_opts.remote_host = g_strdup(global_remote_opts.remote_host_opts.remote_host);
813     row.remote_opts.remote_host_opts.remote_port = g_strdup(global_remote_opts.remote_host_opts.remote_port);
814     row.remote_opts.remote_host_opts.auth_type = global_remote_opts.remote_host_opts.auth_type;
815     row.remote_opts.remote_host_opts.auth_username = g_strdup(global_remote_opts.remote_host_opts.auth_username);
816     row.remote_opts.remote_host_opts.auth_password = g_strdup(global_remote_opts.remote_host_opts.auth_password);
817     row.remote_opts.remote_host_opts.datatx_udp = global_remote_opts.remote_host_opts.datatx_udp;
818     row.remote_opts.remote_host_opts.nocap_rpcap = global_remote_opts.remote_host_opts.nocap_rpcap;
819     row.remote_opts.remote_host_opts.nocap_local = global_remote_opts.remote_host_opts.nocap_local;
820 #endif
821 #ifdef HAVE_PCAP_SETSAMPLING
822     row.remote_opts.sampling_method = global_remote_opts.sampling_method;
823     row.remote_opts.sampling_param = global_remote_opts.sampling_param;
824 #endif
825     g_array_append_val(rows, row);
826     if (row.has_snaplen) {
827       snaplen_string = g_strdup_printf("%d", row.snaplen);
828     } else {
829       snaplen_string = g_strdup("default");
830     }
831
832 #if defined(HAVE_PCAP_CREATE)
833     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, MONITOR, "no",FILTER, "",-1);
834 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
835     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, BUFFER, (guint) global_capture_opts.default_options.buffer_size, FILTER, "",-1);
836  #else
837     gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, FALSE, INTERFACE, temp, LINK, link_type_name, PMODE, (row.pmode?"enabled":"disabled"), SNAPLEN, snaplen_string, -1);
838 #endif
839     count++;
840     g_string_free(ip_str, TRUE);
841 #ifdef HAVE_PCAP_REMOTE
842     add_interface_to_list(if_info->name, if_info->description, &row.remote_opts);
843 #endif
844   } /*for*/
845   gtk_tree_view_set_model(GTK_TREE_VIEW(if_cb), model);
846 }
847
848 #ifdef HAVE_PCAP_REMOTE
849 /* Retrieve the list of local or remote interfaces according to selected
850  * options and re-fill interface name combobox */
851 static void
852 update_interface_list(void)
853 {
854   GtkWidget *iftype_cbx;
855   GtkTreeView *if_cb;
856   GList     *if_list, *if_r_list;
857   int        iftype, prev_iftype, err;
858   gchar     *err_str;
859
860   if (cap_open_w == NULL)
861     return;
862   if_cb = (GtkTreeView *)g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
863   iftype_cbx = g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFTYPE_CBX_KEY);
864   iftype = CAPTURE_IFREMOTE;
865   if (iftype >= CAPTURE_IFREMOTE) {
866     if_r_list = get_remote_interface_list(global_remote_opts.remote_host_opts.remote_host,
867                                         global_remote_opts.remote_host_opts.remote_port,
868                                         global_remote_opts.remote_host_opts.auth_type,
869                                         global_remote_opts.remote_host_opts.auth_username,
870                                         global_remote_opts.remote_host_opts.auth_password,
871                                         &err, &err_str);
872
873     if_list = if_r_list;
874   } else {
875     if_list = capture_interface_list(&err, &err_str);   /* Warning: see capture_prep_cb() */
876     g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IF_LIST_KEY, NULL);
877   }
878
879   if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
880     gpointer dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
881     g_free(err_str);
882
883     if (iftype >= CAPTURE_IFREMOTE) {
884       /* Fall back to previous interface list */
885       simple_dialog_set_cb(dialog, error_list_remote_interface_cb, iftype_cbx);
886       prev_iftype = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(iftype_cbx),
887                                                       E_CAP_CBX_PREV_IFTYPE_VALUE_KEY));
888       g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_VALUE_KEY, GINT_TO_POINTER(prev_iftype));
889       return;
890     }
891   } else if (iftype == CAPTURE_IFREMOTE) {
892     /* New remote interface */
893     insert_new_rows(if_list);
894     if (interfaces_dialog_window_present()) {
895       refresh_if_window();
896     }
897   }
898 }
899
900 /* User changed an interface entry of "Remote interface" dialog */
901 static void
902 capture_remote_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
903 {
904   GtkWidget *auth_passwd_rb,
905             *username_lb, *username_te,
906             *passwd_lb, *passwd_te;
907   gboolean  state;
908
909   auth_passwd_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
910                                                   E_REMOTE_AUTH_PASSWD_KEY);
911   username_lb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
912                                                E_REMOTE_USERNAME_LB_KEY);
913   username_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w),
914                                                E_REMOTE_USERNAME_TE_KEY);
915   passwd_lb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_REMOTE_PASSWD_LB_KEY);
916   passwd_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_REMOTE_PASSWD_TE_KEY);
917
918   state =  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auth_passwd_rb));
919   gtk_widget_set_sensitive(GTK_WIDGET(username_lb), state);
920   gtk_widget_set_sensitive(GTK_WIDGET(username_te), state);
921   gtk_widget_set_sensitive(GTK_WIDGET(passwd_lb), state);
922   gtk_widget_set_sensitive(GTK_WIDGET(passwd_te), state);
923 }
924
925 /* user requested to destroy the dialog */
926 static void
927 capture_remote_destroy_cb(GtkWidget *win, gpointer user_data _U_)
928 {
929   GtkWidget *caller;
930
931   caller = g_object_get_data(G_OBJECT(win), E_CAP_REMOTE_CALLER_PTR_KEY);
932   g_object_set_data(G_OBJECT(caller), E_CAP_REMOTE_DIALOG_PTR_KEY, NULL);
933 }
934
935 /* user requested to accept remote interface options */
936 static void
937 capture_remote_ok_cb(GtkWidget *win _U_, GtkWidget *remote_w)
938 {
939   GtkWidget *host_te, *port_te, *auth_pwd_rb, *username_te, *passwd_te,
940             *auth_null_rb, *auth_passwd_rb, *iftype_cbx;
941   int prev_iftype;
942
943   if (remote_w == NULL) {
944     return;
945   }
946   host_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_HOST_TE_KEY);
947   port_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_PORT_TE_KEY);
948   auth_pwd_rb = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w),
949                                                E_REMOTE_AUTH_PASSWD_KEY);
950   username_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w),
951                                                E_REMOTE_USERNAME_TE_KEY);
952   passwd_te = (GtkWidget *)g_object_get_data(G_OBJECT(remote_w), E_REMOTE_PASSWD_TE_KEY);
953   auth_null_rb = (GtkWidget *) g_object_get_data(G_OBJECT(remote_w), E_REMOTE_AUTH_NULL_KEY);
954   auth_passwd_rb = (GtkWidget *) g_object_get_data(G_OBJECT(remote_w), E_REMOTE_AUTH_PASSWD_KEY);
955   iftype_cbx = g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFTYPE_CBX_KEY);
956   prev_iftype = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(iftype_cbx),
957                                                   E_CAP_CBX_IFTYPE_VALUE_KEY));
958   g_free(global_remote_opts.remote_host_opts.remote_host);
959   global_remote_opts.remote_host_opts.remote_host = g_strdup(gtk_entry_get_text(GTK_ENTRY(host_te)));
960   g_free(global_remote_opts.remote_host_opts.remote_port);
961   global_remote_opts.remote_host_opts.remote_port = g_strdup(gtk_entry_get_text(GTK_ENTRY(port_te)));
962   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auth_passwd_rb)))
963     global_remote_opts.remote_host_opts.auth_type = CAPTURE_AUTH_PWD;
964   else
965     global_remote_opts.remote_host_opts.auth_type = CAPTURE_AUTH_NULL;
966   g_free(global_remote_opts.remote_host_opts.auth_username);
967   global_remote_opts.remote_host_opts.auth_username =
968     g_strdup(gtk_entry_get_text(GTK_ENTRY(username_te)));
969
970   g_free(global_remote_opts.remote_host_opts.auth_password);
971   global_remote_opts.remote_host_opts.auth_password =
972     g_strdup(gtk_entry_get_text(GTK_ENTRY(passwd_te)));
973
974   g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_PREV_IFTYPE_VALUE_KEY,
975                     GINT_TO_POINTER(prev_iftype));
976   g_object_set_data(G_OBJECT(iftype_cbx), E_CAP_CBX_IFTYPE_VALUE_KEY,
977                     GINT_TO_POINTER(CAPTURE_IFREMOTE));
978
979   window_destroy(GTK_WIDGET(remote_w));
980   update_interface_list();
981 }
982
983 static void
984 capture_remote_cancel_cb(GtkWidget *win, gpointer data)
985 {
986   GtkWidget *iftype_cbx;
987   int old_iftype;
988
989   iftype_cbx = g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFTYPE_CBX_KEY);
990   old_iftype = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(iftype_cbx),
991                                                  E_CAP_CBX_PREV_IFTYPE_VALUE_KEY));
992   gtk_combo_box_set_active(GTK_COMBO_BOX(iftype_cbx), old_iftype);
993
994   window_cancel_button_cb (win, data);
995 }
996
997 /* Show remote capture interface parameters dialog */
998 static void
999 capture_remote_cb(GtkWidget *w, gboolean focus_username)
1000 {
1001   GtkWidget   *caller, *remote_w,
1002               *main_vb, *host_tb,
1003               *host_lb, *host_te, *port_lb, *port_te,
1004               *auth_fr, *auth_vb,
1005               *auth_null_rb, *auth_passwd_rb, *auth_passwd_tb,
1006               *user_lb, *user_te, *passwd_lb, *passwd_te,
1007               *bbox, *ok_bt, *cancel_bt;
1008   gchar       *title;
1009   GSList      *auth_group;
1010
1011   caller = gtk_widget_get_toplevel(w);
1012   remote_w = g_object_get_data(G_OBJECT(caller), E_CAP_REMOTE_DIALOG_PTR_KEY);
1013   if (remote_w != NULL) {
1014     reactivate_window(remote_w);
1015     return;
1016   }
1017
1018   title = create_user_window_title("Wireshark: Remote Interface");
1019   remote_w = dlg_window_new(title);
1020   g_object_set_data(G_OBJECT(remote_w), E_CAP_REMOTE_CALLER_PTR_KEY, caller);
1021   g_object_set_data(G_OBJECT(caller), E_CAP_REMOTE_DIALOG_PTR_KEY, remote_w);
1022   g_free(title);
1023
1024   main_vb = gtk_vbox_new(FALSE, 0);
1025   gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
1026   gtk_container_add(GTK_CONTAINER(remote_w), main_vb);
1027
1028   /* Host/port table */
1029   host_tb = gtk_table_new(2, 2, FALSE);
1030   gtk_table_set_row_spacings(GTK_TABLE(host_tb), 3);
1031   gtk_table_set_col_spacings(GTK_TABLE(host_tb), 3);
1032   gtk_box_pack_start(GTK_BOX(main_vb), host_tb, FALSE, FALSE, 0);
1033
1034   /* Host row */
1035   host_lb = gtk_label_new("Host:");
1036   gtk_table_attach_defaults(GTK_TABLE(host_tb), host_lb, 0, 1, 0, 1);
1037
1038   host_te = gtk_entry_new();
1039   gtk_widget_set_tooltip_text(host_te,  "Enter the hostname or host IP address to be used as a source for remote capture.");
1040   gtk_table_attach_defaults(GTK_TABLE(host_tb), host_te, 1, 2, 0, 1);
1041   if (global_remote_opts.remote_host_opts.remote_host != NULL)
1042     gtk_entry_set_text(GTK_ENTRY(host_te), global_remote_opts.remote_host_opts.remote_host);
1043
1044   /* Port row */
1045   port_lb = gtk_label_new("Port:");
1046   gtk_table_attach_defaults(GTK_TABLE(host_tb), port_lb, 0, 1, 1, 2);
1047
1048   port_te = gtk_entry_new();
1049   gtk_widget_set_tooltip_text(port_te, "Enter the TCP port number used by RPCAP server at remote host "
1050                               "(leave it empty for default port number).");
1051   gtk_table_attach_defaults(GTK_TABLE(host_tb), port_te, 1, 2, 1, 2);
1052
1053   if (global_remote_opts.remote_host_opts.remote_port != NULL)
1054     gtk_entry_set_text(GTK_ENTRY(port_te),global_remote_opts.remote_host_opts.remote_port);
1055
1056   /* Authentication options frame */
1057   auth_fr = gtk_frame_new("Authentication");
1058   gtk_container_add(GTK_CONTAINER(main_vb), auth_fr);
1059
1060   auth_vb = gtk_vbox_new(FALSE, 3);
1061   gtk_container_set_border_width(GTK_CONTAINER(auth_vb), 5);
1062   gtk_container_add(GTK_CONTAINER(auth_fr), auth_vb);
1063
1064   auth_null_rb = gtk_radio_button_new_with_label(NULL,
1065                                                  "Null authentication");
1066   gtk_box_pack_start(GTK_BOX(auth_vb), auth_null_rb, TRUE, TRUE, 0);
1067
1068   auth_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(auth_null_rb));
1069   auth_passwd_rb = gtk_radio_button_new_with_label(auth_group,
1070                                                    "Password authentication");
1071   gtk_box_pack_start(GTK_BOX(auth_vb), auth_passwd_rb, TRUE, TRUE, 0);
1072   g_signal_connect(auth_passwd_rb, "toggled",
1073                    G_CALLBACK(capture_remote_adjust_sensitivity), remote_w);
1074
1075   auth_passwd_tb = gtk_table_new(2, 2, FALSE);
1076   gtk_table_set_row_spacings(GTK_TABLE(auth_passwd_tb), 3);
1077   gtk_table_set_col_spacings(GTK_TABLE(auth_passwd_tb), 3);
1078   gtk_box_pack_start(GTK_BOX(auth_vb), auth_passwd_tb, FALSE, FALSE, 0);
1079
1080   user_lb = gtk_label_new("Username:");
1081   gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), user_lb, 0, 1, 0, 1);
1082
1083   user_te = gtk_entry_new();
1084   gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), user_te, 1, 2, 0, 1);
1085   if (global_remote_opts.remote_host_opts.auth_username != NULL)
1086     gtk_entry_set_text(GTK_ENTRY(user_te), global_remote_opts.remote_host_opts.auth_username);
1087
1088   passwd_lb = gtk_label_new("Password:");
1089   gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), passwd_lb, 0, 1, 1, 2);
1090
1091   passwd_te = gtk_entry_new();
1092   gtk_entry_set_visibility(GTK_ENTRY(passwd_te), FALSE);
1093   gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), passwd_te, 1, 2, 1, 2);
1094   if (global_remote_opts.remote_host_opts.auth_password != NULL)
1095     gtk_entry_set_text(GTK_ENTRY(passwd_te), global_remote_opts.remote_host_opts.auth_password);
1096
1097   /* Button row: "Start" and "Cancel" buttons */
1098   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
1099   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
1100
1101   ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
1102   g_signal_connect(ok_bt, "clicked", G_CALLBACK(capture_remote_ok_cb), remote_w);
1103   gtk_widget_set_tooltip_text(ok_bt,
1104                        "Accept remote host parameters and lookup "
1105                        "remote interfaces.");
1106
1107   cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
1108   gtk_widget_set_tooltip_text(cancel_bt, "Cancel and exit dialog.");
1109   window_set_cancel_button(remote_w, cancel_bt, capture_remote_cancel_cb);
1110
1111   if (focus_username) {
1112     /* Give the initial focus to the "Username" entry box. */
1113     gtk_widget_grab_focus(user_te);
1114   }
1115
1116   gtk_widget_grab_default(ok_bt);
1117
1118   /* Catch the "activate" signal on the text
1119      entries, so that if the user types Return there, we act as if the
1120      "OK" button had been selected, as happens if Return is typed if some
1121      widget that *doesn't* handle the Return key has the input focus. */
1122   dlg_set_activate(host_te, ok_bt);
1123   dlg_set_activate(port_te, ok_bt);
1124   dlg_set_activate(user_te, ok_bt);
1125   dlg_set_activate(passwd_te, ok_bt);
1126
1127   g_signal_connect(remote_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
1128   g_signal_connect(remote_w, "destroy", G_CALLBACK(capture_remote_destroy_cb), NULL);
1129
1130   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_HOST_TE_KEY, host_te);
1131   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_PORT_TE_KEY, port_te);
1132   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_AUTH_NULL_KEY, auth_null_rb);
1133   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_AUTH_PASSWD_KEY, auth_passwd_rb);
1134   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_USERNAME_LB_KEY, user_lb);
1135   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_USERNAME_TE_KEY, user_te);
1136   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_PASSWD_LB_KEY, passwd_lb);
1137   g_object_set_data(G_OBJECT(remote_w), E_REMOTE_PASSWD_TE_KEY, passwd_te);
1138
1139   if (global_remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD)
1140     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_passwd_rb), TRUE);
1141   else
1142     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_null_rb), TRUE);
1143   capture_remote_adjust_sensitivity(NULL, remote_w);
1144
1145   gtk_widget_show_all(remote_w);
1146   window_present(remote_w);
1147 }
1148
1149 /* user requested to destroy the dialog */
1150 static void
1151 options_remote_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1152 {
1153   GtkWidget *caller;
1154
1155   caller = g_object_get_data(G_OBJECT(win), E_OPT_REMOTE_CALLER_PTR_KEY);
1156   g_object_set_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY, NULL);
1157 }
1158
1159 /* user requested to accept remote interface options */
1160 static void
1161 options_remote_ok_cb(GtkWidget *win _U_, GtkWidget *parent_w)
1162 {
1163   GtkWidget *datatx_udp_cb, *nocap_rpcap_cb;
1164 #ifdef HAVE_PCAP_SETSAMPLING
1165   GtkWidget *samp_none_rb, *samp_count_rb, *samp_timer_rb,
1166             *samp_count_sb, *samp_timer_sb;
1167 #endif
1168   interface_row row;
1169
1170   if (parent_w == NULL)
1171     return;
1172
1173   row = g_array_index(rows, interface_row, marked_row);
1174   g_array_remove_index(rows, marked_row);
1175   datatx_udp_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_DATATX_UDP_CB_KEY);
1176   nocap_rpcap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_NOCAP_RPCAP_CB_KEY);
1177
1178   row.remote_opts.remote_host_opts.datatx_udp =
1179     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(datatx_udp_cb));
1180   row.remote_opts.remote_host_opts.nocap_rpcap =
1181     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb));
1182
1183 #ifdef HAVE_PCAP_SETSAMPLING
1184   samp_none_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_NONE_RB_KEY);
1185   samp_count_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_RB_KEY);
1186   samp_timer_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_RB_KEY);
1187   samp_count_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_SB_KEY);
1188   samp_timer_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_SB_KEY);
1189
1190   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_none_rb)))
1191     row.remote_opts.sampling_method = CAPTURE_SAMP_NONE;
1192   else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb))) {
1193     row.remote_opts.sampling_method = CAPTURE_SAMP_BY_COUNT;
1194     row.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_count_sb));
1195   } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb))) {
1196     row.remote_opts.sampling_method = CAPTURE_SAMP_BY_TIMER;
1197     row.remote_opts.sampling_param = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(samp_timer_sb));
1198   }
1199 #endif /* HAVE_PCAP_SETSAMPLING*/
1200   g_array_insert_val(rows, marked_row, row);
1201   window_destroy(GTK_WIDGET(parent_w));
1202 }
1203 #endif /*HAVE_PCAP_REMOTE*/
1204
1205 #ifdef HAVE_PCAP_SETSAMPLING
1206 static void
1207 options_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1208 {
1209   GtkWidget *samp_count_rb, *samp_timer_rb,
1210             *samp_count_sb, *samp_timer_sb;
1211
1212   samp_count_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_RB_KEY);
1213   samp_timer_rb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_RB_KEY);
1214   samp_count_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_COUNT_SB_KEY);
1215   samp_timer_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SAMP_TIMER_SB_KEY);
1216
1217   if (samp_count_sb && samp_count_rb)
1218    gtk_widget_set_sensitive(GTK_WIDGET(samp_count_sb),
1219       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb)));
1220
1221   if (samp_timer_sb && samp_timer_rb)
1222    gtk_widget_set_sensitive(GTK_WIDGET(samp_timer_sb),
1223       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb)));
1224 }
1225
1226 #endif /*HAVE_PCAP_SETSAMPLING*/
1227 #ifdef HAVE_PCAP_REMOTE
1228 void
1229 options_remote_cb(GtkWidget *w _U_, gpointer d _U_)
1230 {
1231   GtkWidget *opt_remote_w, *main_vb;
1232   GtkWidget   *caller, *bbox, *ok_bt, *cancel_bt;
1233   GtkWidget     *capture_fr, *capture_vb;
1234   GtkWidget     *nocap_rpcap_cb, *datatx_udp_cb;
1235 #ifdef HAVE_PCAP_SETSAMPLING
1236   GtkWidget     *sampling_fr, *sampling_vb, *sampling_tb, *sampling_lb,
1237                 *samp_none_rb, *samp_count_rb, *samp_timer_rb,
1238                 *samp_count_sb, *samp_timer_sb;
1239   GtkAdjustment *samp_count_adj, *samp_timer_adj;
1240   GSList        *samp_group;
1241 #endif
1242   interface_row row;
1243
1244   caller = gtk_widget_get_toplevel(w);
1245   opt_remote_w = g_object_get_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY);
1246   if (opt_remote_w != NULL) {
1247     reactivate_window(opt_remote_w);
1248     return;
1249   }
1250
1251   row = g_array_index(rows, interface_row, marked_row);
1252   opt_remote_w = dlg_window_new("Remote Capture Settings");
1253   g_object_set_data(G_OBJECT(opt_remote_w), E_OPT_REMOTE_CALLER_PTR_KEY, caller);
1254   g_object_set_data(G_OBJECT(caller), E_OPT_REMOTE_DIALOG_PTR_KEY, opt_remote_w);
1255
1256   main_vb = gtk_vbox_new(FALSE, 0);
1257   gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
1258   gtk_container_add(GTK_CONTAINER(opt_remote_w), main_vb);
1259
1260   /* Remote capture options */
1261   capture_fr = gtk_frame_new("Capture Options");
1262   gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
1263
1264   capture_vb = gtk_vbox_new(FALSE, 0);
1265   gtk_container_set_border_width(GTK_CONTAINER(capture_vb), 5);
1266   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
1267
1268   nocap_rpcap_cb = gtk_check_button_new_with_mnemonic("Do not capture own RPCAP traffic");
1269   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb),
1270           row.remote_opts.remote_host_opts.nocap_rpcap);
1271   gtk_container_add(GTK_CONTAINER(capture_vb), nocap_rpcap_cb);
1272
1273   datatx_udp_cb = gtk_check_button_new_with_mnemonic("Use UDP for data transfer");
1274   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(datatx_udp_cb),
1275           row.remote_opts.remote_host_opts.datatx_udp);
1276   gtk_container_add(GTK_CONTAINER(capture_vb), datatx_udp_cb);
1277
1278 #ifdef HAVE_PCAP_SETSAMPLING
1279   /* Sampling options */
1280   sampling_fr = gtk_frame_new("Sampling Options");
1281   gtk_container_add(GTK_CONTAINER(main_vb), sampling_fr);
1282
1283   sampling_vb = gtk_vbox_new(FALSE, 0);
1284   gtk_container_set_border_width(GTK_CONTAINER(sampling_vb), 5);
1285   gtk_container_add(GTK_CONTAINER(sampling_fr), sampling_vb);
1286
1287   sampling_tb = gtk_table_new(3, 3, FALSE);
1288   gtk_table_set_row_spacings(GTK_TABLE(sampling_tb), 1);
1289   gtk_table_set_col_spacings(GTK_TABLE(sampling_tb), 3);
1290   gtk_box_pack_start(GTK_BOX(sampling_vb), sampling_tb, FALSE, FALSE, 0);
1291
1292   /* "No sampling" row */
1293   samp_none_rb = gtk_radio_button_new_with_label(NULL, "None");
1294   if (row.remote_opts.sampling_method == CAPTURE_SAMP_NONE)
1295     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_none_rb), TRUE);
1296   g_signal_connect(samp_none_rb, "toggled",
1297                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
1298   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_none_rb, 0, 1, 0, 1);
1299
1300   /* "Sampling by counter" row */
1301   samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_none_rb));
1302   samp_count_rb = gtk_radio_button_new_with_label(samp_group, "1 of");
1303   if (row.remote_opts.sampling_method == CAPTURE_SAMP_BY_COUNT)
1304     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_count_rb), TRUE);
1305   g_signal_connect(samp_count_rb, "toggled",
1306                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
1307   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_count_rb, 0, 1, 1, 2);
1308
1309   samp_count_adj = (GtkAdjustment *) gtk_adjustment_new(
1310                         (gfloat)row.remote_opts.sampling_param,
1311                         1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
1312   samp_count_sb = gtk_spin_button_new(samp_count_adj, 0, 0);
1313   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_count_sb), TRUE);
1314   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_count_sb, 1, 2, 1, 2);
1315
1316   sampling_lb = gtk_label_new("packets");
1317   gtk_misc_set_alignment(GTK_MISC(sampling_lb), 0, 0.5);
1318   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), sampling_lb, 2, 3, 1, 2);
1319
1320   /* "Sampling by timer" row */
1321   samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_count_rb));
1322   samp_timer_rb = gtk_radio_button_new_with_label(samp_group, "1 every");
1323   if (row.remote_opts.sampling_method == CAPTURE_SAMP_BY_TIMER)
1324     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_timer_rb), TRUE);
1325   g_signal_connect(samp_timer_rb, "toggled",
1326                  G_CALLBACK(options_prep_adjust_sensitivity), opt_remote_w);
1327   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_timer_rb, 0, 1, 2, 3);
1328
1329   samp_timer_adj = (GtkAdjustment *) gtk_adjustment_new(
1330                         (gfloat)row.remote_opts.sampling_param,
1331                         1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
1332   samp_timer_sb = gtk_spin_button_new(samp_timer_adj, 0, 0);
1333   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_timer_sb), TRUE);
1334   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_timer_sb, 1, 2, 2, 3);
1335
1336   sampling_lb = gtk_label_new("milliseconds");
1337   gtk_misc_set_alignment(GTK_MISC(sampling_lb), 0, 0.5);
1338   gtk_table_attach_defaults(GTK_TABLE(sampling_tb), sampling_lb, 2, 3, 2, 3);
1339 #endif
1340
1341   /* Button row: "Start" and "Cancel" buttons */
1342   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
1343   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
1344
1345   ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
1346   g_signal_connect(ok_bt, "clicked", G_CALLBACK(options_remote_ok_cb), opt_remote_w);
1347   gtk_widget_set_tooltip_text(ok_bt, "Accept parameters and close dialog");
1348   cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
1349   gtk_widget_set_tooltip_text(cancel_bt, "Cancel and exit dialog.");
1350   window_set_cancel_button(opt_remote_w, cancel_bt, window_cancel_button_cb);
1351
1352   gtk_widget_grab_default(ok_bt);
1353
1354   g_signal_connect(opt_remote_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
1355   g_signal_connect(opt_remote_w, "destroy", G_CALLBACK(options_remote_destroy_cb), NULL);
1356
1357   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_NOCAP_RPCAP_CB_KEY, nocap_rpcap_cb);
1358   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_DATATX_UDP_CB_KEY, datatx_udp_cb);
1359
1360 #ifdef HAVE_PCAP_SETSAMPLING
1361   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_NONE_RB_KEY, samp_none_rb);
1362   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_COUNT_RB_KEY, samp_count_rb);
1363   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_COUNT_SB_KEY, samp_count_sb);
1364   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_TIMER_RB_KEY, samp_timer_rb);
1365   g_object_set_data(G_OBJECT(opt_remote_w), E_CAP_SAMP_TIMER_SB_KEY, samp_timer_sb);
1366 #endif
1367
1368 #ifdef HAVE_PCAP_SETSAMPLING
1369   /* Set the sensitivity of various widgets as per the settings of other
1370      widgets. */
1371   options_prep_adjust_sensitivity(NULL, opt_remote_w);
1372 #endif
1373
1374   gtk_widget_show_all(opt_remote_w);
1375   window_present(opt_remote_w);
1376 }
1377
1378 static void
1379 recent_print_remote_host (gpointer key _U_, gpointer value, gpointer user)
1380 {
1381   FILE *rf = user;
1382   struct remote_host *ri = value;
1383
1384   fprintf (rf, RECENT_KEY_REMOTE_HOST ": %s,%s,%d\n", ri->remote_host, ri->remote_port, ri->auth_type);
1385 }
1386
1387 void
1388 capture_remote_combo_recent_write_all(FILE *rf)
1389 {
1390   if (remote_host_list && g_hash_table_size (remote_host_list) > 0) {
1391     /* Write all remote interfaces to the recent file */
1392     g_hash_table_foreach (remote_host_list, recent_print_remote_host, rf);
1393   }
1394 }
1395
1396 gboolean
1397 capture_remote_combo_add_recent(gchar *s)
1398 {
1399   GList *vals = prefs_get_string_list (s);
1400   GList *valp = vals;
1401   struct remote_host *rh;
1402   gint auth_type;
1403   char *p;
1404
1405   if (valp == NULL)
1406     return FALSE;
1407
1408   if (remote_host_list == NULL) {
1409     remote_host_list = g_hash_table_new (g_str_hash, g_str_equal);
1410   }
1411
1412   rh = g_malloc (sizeof (*rh));
1413
1414   /* First value is the host */
1415   rh->remote_host = g_strdup (valp->data);
1416   if (strlen(rh->remote_host) == 0)
1417     /* Empty remote host */
1418     return FALSE;
1419   rh->auth_type = CAPTURE_AUTH_NULL;
1420   valp = valp->next;
1421
1422   if (valp) {
1423     /* Found value 2, this is the port number */
1424     rh->remote_port = g_strdup (valp->data);
1425     valp = valp->next;
1426   } else {
1427     /* Did not find a port number */
1428     rh->remote_port = g_strdup ("");
1429   }
1430
1431   if (valp) {
1432     /* Found value 3, this is the authentication type */
1433     auth_type = strtol(valp->data, &p, 0);
1434     if (p != valp->data && *p == '\0') {
1435       rh->auth_type = auth_type;
1436     }
1437   }
1438
1439   /* Do not store username and password */
1440   rh->auth_username = g_strdup ("");
1441   rh->auth_password = g_strdup ("");
1442
1443   prefs_clear_string_list(vals);
1444
1445   g_hash_table_insert (remote_host_list, g_strdup(rh->remote_host), rh);
1446
1447   return TRUE;
1448 }
1449
1450 #endif /* HAVE_PCAP_REMOTE */
1451
1452 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
1453 static void
1454 capture_filter_compile_cb(GtkWidget *w _U_, gpointer user_data _U_)
1455 {
1456   pcap_t *pd;
1457   struct bpf_program fcode;
1458
1459   GtkWidget *filter_cm;
1460   const gchar *filter_text;
1461   gpointer  ptr;
1462   int       dlt;
1463   GtkWidget *linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
1464
1465   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
1466     g_assert_not_reached();  /* Programming error: somehow nothing is active */
1467   }
1468   if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
1469     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
1470   }
1471   pd = pcap_open_dead(dlt, DUMMY_SNAPLENGTH);
1472   filter_cm = g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY);
1473   filter_text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(filter_cm));
1474   /* pcap_compile will not alter the filter string, so the (char *) cast is "safe" */
1475 #ifdef PCAP_NETMASK_UNKNOWN
1476   if (pcap_compile(pd, &fcode, (char *)filter_text, 1 /* Do optimize */, PCAP_NETMASK_UNKNOWN) < 0) {
1477 #else
1478   if (pcap_compile(pd, &fcode, (char *)filter_text, 1 /* Do optimize */, 0) < 0) {
1479 #endif
1480     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", pcap_geterr(pd));
1481   } else {
1482     GString *bpf_code_dump = g_string_new("");
1483     struct bpf_insn *insn = fcode.bf_insns;
1484     int i, n = fcode.bf_len;
1485
1486     gchar *bpf_code_str;
1487     gchar *bpf_code_markup;
1488
1489     for (i = 0; i < n; ++insn, ++i) {
1490         g_string_append(bpf_code_dump, bpf_image(insn, i));
1491         g_string_append(bpf_code_dump, "\n");
1492     }
1493
1494     bpf_code_str = g_string_free(bpf_code_dump, FALSE);
1495     bpf_code_markup = g_markup_escape_text(bpf_code_str, -1);
1496
1497     simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "<markup><tt>%s</tt></markup>", bpf_code_markup);
1498
1499     g_free(bpf_code_str);
1500     g_free(bpf_code_markup);
1501   }
1502
1503   pcap_close(pd);
1504 }
1505 #endif /* HAVE_PCAP_OPEN_DEAD && HAVE_BPF_IMAGE */
1506
1507 static void
1508 options_edit_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1509 {
1510   GtkWidget *caller;
1511
1512   caller = g_object_get_data(G_OBJECT(win), E_OPT_EDIT_CALLER_PTR_KEY);
1513   g_object_set_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY, NULL);
1514 }
1515
1516 static void
1517 update_options_table(gint index)
1518 {
1519   guint i;
1520   gboolean found = FALSE;
1521   interface_row row;
1522   interface_options interface_opts;
1523   GtkTreePath  *path;
1524   GtkTreeView  *if_cb;
1525   GtkTreeModel *model;
1526   GtkTreeIter  iter;
1527   gchar *temp, *path_str, *snaplen_string;
1528   GList *list;
1529   link_row *link = NULL;
1530   gboolean enabled;
1531
1532   row = g_array_index(rows, interface_row, index);
1533
1534   if (global_capture_opts.ifaces->len > 0) {
1535     for (i = 0; i < global_capture_opts.ifaces->len; i++) {
1536       interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
1537       if (strcmp(interface_opts.name, row.name) == 0) {
1538         found = TRUE;
1539         break;
1540       }
1541     }
1542     if (found) {
1543       global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
1544       g_free(interface_opts.cfilter);
1545       interface_opts.linktype = row.active_dlt;
1546       interface_opts.promisc_mode = row.pmode;
1547       interface_opts.has_snaplen = row.has_snaplen;
1548       interface_opts.snaplen = row.snaplen;
1549       interface_opts.cfilter = g_strdup(row.cfilter);
1550 #ifdef HAVE_PCAP_CREATE
1551       interface_opts.monitor_mode = row.monitor_mode_enabled;
1552 #else
1553       interface_opts.monitor_mode = FALSE;
1554 #endif
1555 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1556       interface_opts.buffer_size = row.buffer;
1557 #endif
1558       g_array_insert_val(global_capture_opts.ifaces, i, interface_opts);
1559     }
1560   }
1561   if (!found || global_capture_opts.ifaces->len == 0) {
1562     interface_opts.name = g_strdup(row.name);
1563     interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
1564     interface_opts.linktype = row.active_dlt;
1565     interface_opts.promisc_mode = row.pmode;
1566     interface_opts.has_snaplen = row.has_snaplen;
1567     interface_opts.snaplen = row.snaplen;
1568     interface_opts.cfilter = g_strdup(row.cfilter);
1569 #ifdef HAVE_PCAP_CREATE
1570     interface_opts.monitor_mode = row.monitor_mode_enabled;
1571 #else
1572     interface_opts.monitor_mode = FALSE;
1573 #endif
1574 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1575     interface_opts.buffer_size = row.buffer;
1576 #endif
1577 #ifdef HAVE_PCAP_REMOTE
1578     interface_opts.src_type = global_capture_opts.default_options.src_type;
1579     interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
1580     interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
1581     interface_opts.auth_type = global_capture_opts.default_options.auth_type;
1582     interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
1583     interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
1584     interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
1585     interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
1586     interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
1587 #endif
1588 #ifdef HAVE_PCAP_SETSAMPLING
1589     interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
1590     interface_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
1591 #endif
1592     g_array_append_val(global_capture_opts.ifaces, interface_opts);
1593   }
1594   path_str = g_strdup_printf("%d", index);
1595   path = gtk_tree_path_new_from_string(path_str);
1596   if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
1597   model = gtk_tree_view_get_model(if_cb);
1598   gtk_tree_model_get_iter (model, &iter, path);
1599   if (row.no_addresses == 0) {
1600     temp = g_strdup_printf("<b>%s</b>", row.display_name);
1601   } else {
1602     temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", row.display_name, row.addresses);
1603   }
1604   for (list=row.links; list!=NULL; list=g_list_next(list))
1605   {
1606     link = (link_row*)(list->data);
1607     if (link->dlt == row.active_dlt) {
1608       break;
1609     }
1610   }
1611   gtk_tree_model_get(model, &iter, CAPTURE, &enabled, -1);
1612   if (enabled == FALSE) {
1613     num_selected++;
1614   }
1615   if (row.has_snaplen) {
1616     snaplen_string = g_strdup_printf("%d", row.snaplen);
1617   } else {
1618     snaplen_string = g_strdup("default");
1619   }
1620 #if defined(HAVE_PCAP_CREATE)
1621   gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, MONITOR, row.monitor_mode_supported?(row.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, row.cfilter, -1);
1622 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
1623   gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp,LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, FILTER, row.cfilter, -1);
1624 #else
1625   gtk_list_store_set (GTK_LIST_STORE(model), &iter, CAPTURE, TRUE, INTERFACE, temp,LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, row.cfilter, -1);
1626 #endif
1627 #ifdef USE_THREADS
1628   if (num_selected > 0) {
1629 #else
1630   if (num_selected == 1) {
1631 #endif
1632     gtk_widget_set_sensitive(ok_bt, TRUE);
1633   } else {
1634     gtk_widget_set_sensitive(ok_bt, FALSE);
1635   }
1636   if (interfaces_dialog_window_present()) {
1637     update_selected_interface(g_strdup(row.name), TRUE);
1638   }
1639   if (get_welcome_window() != NULL) {
1640     change_interface_selection(g_strdup(row.name), TRUE);
1641   }
1642   gtk_tree_path_free (path);
1643 }
1644
1645 static void
1646 save_options_cb(GtkWidget *win _U_, gpointer user_data _U_)
1647 {
1648   GtkWidget *snap_cb, *snap_sb, *promisc_cb,
1649 #ifdef HAVE_PCAP_CREATE
1650             *monitor_cb,
1651 #endif
1652             *filter_cm, *linktype_combo_box;
1653 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1654   GtkWidget *buffer_size_sb;
1655 #endif
1656
1657   interface_row row;
1658   gpointer  ptr;
1659   int       dlt;
1660   const gchar *filter_text;
1661
1662   row = g_array_index(rows, interface_row, marked_row);
1663   rows = g_array_remove_index(rows, marked_row);
1664   snap_cb    = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY);
1665   snap_sb    = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY);
1666 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1667   buffer_size_sb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_BUFFER_SIZE_SB_KEY);
1668 #endif
1669   promisc_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_PROMISC_KEY);
1670 #ifdef HAVE_PCAP_CREATE
1671   monitor_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_MONITOR_KEY);
1672 #endif
1673   filter_cm  = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY);
1674
1675   linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
1676
1677   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
1678     g_assert_not_reached();  /* Programming error: somehow nothing is active */
1679   }
1680   if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
1681     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
1682   }
1683   row.active_dlt = dlt;
1684 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1685   row.buffer = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb));
1686 #endif
1687   row.pmode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
1688   row.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
1689   if (row.has_snaplen) {
1690     row.snaplen = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
1691     if (row.snaplen < 1)
1692       row.snaplen = WTAP_MAX_PACKET_SIZE;
1693     else if (row.snaplen < MIN_PACKET_SIZE)
1694       row.snaplen = MIN_PACKET_SIZE;
1695   } else {
1696     row.snaplen = WTAP_MAX_PACKET_SIZE;
1697   }
1698
1699   filter_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(filter_cm));
1700   if (row.cfilter)
1701     g_free(row.cfilter);
1702   g_assert(filter_text != NULL);
1703   row.cfilter = g_strdup(filter_text);
1704 #ifdef HAVE_PCAP_CREATE
1705   row.monitor_mode_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor_cb));
1706 #endif
1707   g_array_insert_val(rows, marked_row, row);
1708   window_destroy(opt_edit_w);
1709   update_options_table(marked_row);
1710 }
1711
1712 static void
1713 adjust_snap_sensitivity(GtkWidget *tb _U_, gpointer parent_w _U_)
1714 {
1715   GtkWidget *snap_cb, *snap_sb;
1716   interface_row row;
1717
1718   row = g_array_index(rows, interface_row, marked_row);
1719   rows = g_array_remove_index(rows, marked_row);
1720
1721   snap_cb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY);
1722   snap_sb = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY);
1723
1724   /* The snapshot length spinbox is sensitive if the "Limit each packet
1725      to" checkbox is on. */
1726   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
1727       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
1728   row.has_snaplen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
1729   g_array_insert_val(rows, marked_row, row);
1730 }
1731
1732 static void options_interface_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column _U_, gpointer userdata)
1733 {
1734   GtkWidget     *caller, *window, *swindow=NULL, *if_view,
1735                 *main_vb, *if_hb, *if_lb, *if_lb_name,
1736                 *main_hb, *left_vb,
1737 #if defined (HAVE_AIRPCAP) || defined (HAVE_PCAP_REMOTE) || defined (HAVE_PCAP_CREATE)
1738                 *right_vb,
1739 #endif
1740                 *capture_fr, *capture_vb,
1741                 *if_ip_hb, *if_ip_lb = NULL, *if_ip_name,
1742                 *if_vb_left, *if_vb_right,
1743                 *linktype_hb, *linktype_lb, *linktype_combo_box,
1744                 *snap_hb, *snap_cb, *snap_sb, *snap_lb,
1745                 *promisc_cb,
1746 #ifdef HAVE_PCAP_CREATE
1747                 *monitor_cb,
1748 #endif
1749                 *filter_hb, *filter_bt, *filter_te, *filter_cm,
1750 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
1751                 *compile_bt,
1752 #endif
1753                 *bbox, *ok_bt, *cancel_bt,
1754                 *help_bt;
1755   GList         *cf_entry, *list, *cfilter_list;
1756   GtkAdjustment *snap_adj;
1757 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1758   GtkAdjustment *buffer_size_adj;
1759   GtkWidget     *buffer_size_lb, *buffer_size_sb, *buffer_size_hb;
1760 #endif
1761 #ifdef HAVE_PCAP_REMOTE
1762   GtkWidget     *remote_bt;
1763 #endif
1764  #ifdef HAVE_AIRPCAP
1765   GtkWidget     *advanced_bt;
1766 #endif
1767   interface_row row;
1768   GtkTreeModel  *model;
1769   GtkTreeIter   iter;
1770   link_row      *temp;
1771   gboolean      found = FALSE;
1772   gint          num_supported_link_types;
1773   gchar         *tok;
1774   GtkCellRenderer *renderer;
1775   GtkListStore    *store;
1776
1777   window = (GtkWidget *)userdata;
1778   caller = gtk_widget_get_toplevel(GTK_WIDGET(window));
1779   opt_edit_w = g_object_get_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY);
1780   if (opt_edit_w != NULL) {
1781     reactivate_window(opt_edit_w);
1782     return;
1783   }
1784
1785   model = gtk_tree_view_get_model(view);
1786   gtk_tree_model_get_iter (model, &iter, path);
1787   marked_row = atoi(gtk_tree_path_to_string(path));
1788   row = g_array_index(rows, interface_row, marked_row);
1789
1790   opt_edit_w = dlg_window_new("Edit Interface Settings");
1791   g_object_set_data(G_OBJECT(opt_edit_w), E_OPT_EDIT_CALLER_PTR_KEY, caller);
1792   g_object_set_data(G_OBJECT(caller), E_OPT_EDIT_DIALOG_PTR_KEY, opt_edit_w);
1793
1794   main_vb = gtk_vbox_new(FALSE, 0);
1795   gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
1796   gtk_container_add(GTK_CONTAINER(opt_edit_w), main_vb);
1797
1798   /* Capture-related options frame */
1799   capture_fr = gtk_frame_new("Capture");
1800   gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
1801
1802   capture_vb = gtk_vbox_new(FALSE, 3);
1803   gtk_container_set_border_width(GTK_CONTAINER(capture_vb), 5);
1804   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
1805
1806   /* Interface row */
1807   if_hb = gtk_hbox_new(FALSE, 3);
1808   gtk_box_pack_start(GTK_BOX(capture_vb), if_hb, FALSE, FALSE, 3);
1809
1810   if_lb = gtk_label_new("Interface:  ");
1811   gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 3);
1812
1813   if_lb_name = gtk_label_new(row.display_name);
1814   gtk_box_pack_start(GTK_BOX(if_hb), if_lb_name, FALSE, FALSE, 3);
1815
1816   /* IP addresses row */
1817   if_ip_hb = gtk_hbox_new(FALSE, 3);
1818
1819   gtk_widget_set_tooltip_text(if_ip_hb, "Lists the IP address(es) "
1820                        "assigned to the selected interface. ");
1821   if_vb_left = gtk_vbox_new(FALSE, 3);
1822   gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_left, FALSE, FALSE, 3);
1823   if_vb_right = gtk_vbox_new(FALSE, 3);
1824
1825   if_ip_lb = gtk_label_new("IP address:");
1826   gtk_misc_set_alignment(GTK_MISC(if_ip_lb), 0, 0); /* Left justified */
1827   gtk_box_pack_start(GTK_BOX(if_vb_left), if_ip_lb, FALSE, FALSE, 0);
1828
1829   if (row.no_addresses > 0) {
1830     gtk_box_pack_start(GTK_BOX(capture_vb), if_ip_hb, TRUE, TRUE, 0);
1831     gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, TRUE, TRUE, 3);
1832     swindow = gtk_scrolled_window_new (NULL, NULL);
1833     gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN);
1834     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1835     gtk_widget_set_size_request(GTK_WIDGET(swindow),-1, 50);
1836     if_view = gtk_tree_view_new ();
1837     g_object_set(G_OBJECT(if_view), "headers-visible", FALSE, NULL);
1838     renderer = gtk_cell_renderer_text_new();
1839     column = gtk_tree_view_column_new_with_attributes ("",
1840                     GTK_CELL_RENDERER(renderer),
1841                     "text", 0,
1842                     NULL);
1843     gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
1844     store = gtk_list_store_new(1, G_TYPE_STRING);
1845     for (tok = strtok (row.addresses, "\n"); tok; tok = strtok(NULL, "\n")) {
1846       gtk_list_store_append (store, &iter);
1847       gtk_list_store_set (store, &iter, 0, tok, -1);
1848     }
1849     gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store));
1850     gtk_container_add (GTK_CONTAINER (swindow), if_view);
1851     gtk_box_pack_start(GTK_BOX(if_vb_right), swindow, TRUE, TRUE, 0);
1852   } else {
1853     gtk_box_pack_start(GTK_BOX(capture_vb), if_ip_hb, FALSE, FALSE, 0);
1854     gtk_box_pack_start(GTK_BOX(if_ip_hb), if_vb_right, FALSE, FALSE, 3);
1855     if_ip_name = gtk_label_new("none");
1856     gtk_misc_set_alignment(GTK_MISC(if_ip_name), 0, 0); /* Left justified */
1857     gtk_box_pack_start(GTK_BOX(if_vb_right), if_ip_name, FALSE, FALSE, 0);
1858   }
1859   main_hb = gtk_hbox_new(FALSE, 5);
1860   gtk_container_set_border_width(GTK_CONTAINER(main_hb), 0);
1861   gtk_box_pack_start(GTK_BOX(capture_vb), main_hb, FALSE, FALSE, 3);
1862
1863   left_vb = gtk_vbox_new(FALSE, 0);
1864   gtk_container_set_border_width(GTK_CONTAINER(left_vb), 0);
1865   gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
1866
1867 #if defined (HAVE_AIRPCAP) || defined (HAVE_PCAP_REMOTE) || defined (HAVE_PCAP_CREATE)
1868   /* Avoid adding the right vbox if not needed, because it steals 3 pixels */
1869   right_vb = gtk_vbox_new(FALSE, 3);
1870   gtk_container_set_border_width(GTK_CONTAINER(right_vb), 0);
1871   gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 3);
1872 #endif
1873
1874   /* Linktype row */
1875   linktype_hb = gtk_hbox_new(FALSE, 3);
1876   gtk_box_pack_start(GTK_BOX(left_vb), linktype_hb, FALSE, FALSE, 0);
1877
1878   linktype_lb = gtk_label_new("Link-layer header type:");
1879   gtk_box_pack_start(GTK_BOX(linktype_hb), linktype_lb, FALSE, FALSE, 3);
1880
1881   linktype_combo_box = ws_combo_box_new_text_and_pointer();
1882   g_object_set_data(G_OBJECT(linktype_combo_box), E_CAP_LT_CBX_LABEL_KEY, linktype_lb);
1883   /* Default to "use the default" */
1884   /* Datalink menu index is not reset; it will be restored with last used value */
1885
1886   g_object_set_data(G_OBJECT(linktype_combo_box), E_CAP_IFACE_IP_KEY, if_ip_lb);
1887   if (cap_settings_history == NULL) {
1888     cap_settings_history = g_hash_table_new(g_str_hash, g_str_equal);
1889   }
1890   /*
1891    * XXX - in some cases, this is "multiple link-layer header types", e.g.
1892    * some 802.11 interfaces on FreeBSD 5.2 and later, where you can request
1893    * fake Ethernet, 802.11, or 802.11-plus-radio-information headers.
1894    *
1895    * In other cases, it's "multiple link-layer types", e.g., with recent
1896    * versions of libpcap, a DAG card on an "HDLC" WAN, where you can
1897    * request Cisco HDLC or PPP depending on what type of traffic is going
1898    * over the WAN, or an Ethernet interface, where you can request Ethernet
1899    * or DOCSIS, the latter being for some Cisco cable modem equipment that
1900    * can be configured to send raw DOCSIS frames over an Ethernet inside
1901    * Ethernet low-level framing, for traffic capture purposes.
1902    *
1903    * We leave it as "multiple link-layer types" for now.
1904    */
1905   gtk_widget_set_tooltip_text(linktype_combo_box, "The selected interface supports multiple link-layer types; select the desired one.");
1906   gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_combo_box, FALSE, FALSE, 0);
1907   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY, linktype_combo_box);
1908   num_supported_link_types = 0;
1909   for (list=row.links; list!=NULL; list=g_list_next(list))
1910   {
1911     temp = (link_row*)(list->data);
1912     ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box),
1913                                                   temp->name,
1914                                                   GINT_TO_POINTER(temp->dlt)  /* Flag as "not supported" */
1915                                                   );
1916     num_supported_link_types++;
1917     if (temp->dlt == row.active_dlt) {
1918       ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box), num_supported_link_types - 1);
1919       found = TRUE;
1920     }
1921   }
1922   gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
1923   gtk_widget_set_sensitive(linktype_combo_box, num_supported_link_types >= 2);
1924   if (!found) {
1925     ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box),0);
1926   }
1927   g_signal_connect(linktype_combo_box, "changed", G_CALLBACK(select_link_type_cb), NULL);
1928
1929   /* Promiscuous mode row */
1930   promisc_cb = gtk_check_button_new_with_mnemonic(
1931       "Capture packets in _promiscuous mode");
1932   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb),
1933                                row.pmode);
1934   gtk_widget_set_tooltip_text(promisc_cb,
1935     "Usually a network adapter will only capture the traffic sent to its own network address. "
1936     "If you want to capture all traffic that the network adapter can \"see\", mark this option. "
1937     "See the FAQ for some more details of capturing packets from a switched network.");
1938   gtk_box_pack_start (GTK_BOX(left_vb), promisc_cb, FALSE, FALSE, 0);
1939   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_PROMISC_KEY, promisc_cb);
1940
1941 #ifdef HAVE_PCAP_CREATE
1942   /* Monitor mode row */
1943   monitor_cb = gtk_check_button_new_with_mnemonic( "Capture packets in monitor mode");
1944   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(monitor_cb), row.monitor_mode_enabled);
1945   gtk_widget_set_sensitive(monitor_cb, row.monitor_mode_supported);
1946   g_signal_connect(monitor_cb, "toggled", G_CALLBACK(capture_prep_monitor_changed_cb), NULL);
1947
1948   gtk_widget_set_tooltip_text(monitor_cb,
1949     "Usually a Wi-Fi adapter will, even in promiscuous mode, only capture the traffic on the BSS to which it's associated. "
1950     "If you want to capture all traffic that the Wi-Fi adapter can \"receive\", mark this option. "
1951     "In order to see IEEE 802.11 headers or to see radio information for captured packets,"
1952     "it might be necessary to turn this option on.\n\n"
1953     "Note that, in monitor mode, the adapter might disassociate from the network to which it's associated.");
1954   gtk_box_pack_start (GTK_BOX(left_vb), monitor_cb, FALSE, FALSE, 0);
1955
1956   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_MONITOR_KEY, monitor_cb);
1957 #endif
1958
1959   /*
1960    * This controls the sensitivity of both the link-type list and, if
1961    * you have it, the monitor mode checkbox.  That's why we do this
1962    * now.
1963    */
1964
1965   /* Capture length row */
1966   snap_hb = gtk_hbox_new(FALSE, 3);
1967   gtk_box_pack_start (GTK_BOX(left_vb), snap_hb, FALSE, FALSE, 0);
1968
1969   snap_cb = gtk_check_button_new_with_mnemonic("_Limit each packet to");
1970   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(snap_cb),
1971                                row.has_snaplen);
1972   g_signal_connect(snap_cb, "toggled", G_CALLBACK(adjust_snap_sensitivity), NULL);
1973   gtk_widget_set_tooltip_text(snap_cb,
1974     "Limit the maximum number of bytes to be captured from each packet. This size includes the "
1975     "link-layer header and all subsequent headers. ");
1976   gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
1977
1978   snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) row.snaplen,
1979     MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
1980   snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
1981   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
1982   gtk_widget_set_size_request(snap_sb, 80, -1);
1983   gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
1984
1985   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_CB_KEY, snap_cb);
1986   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_SNAP_SB_KEY, snap_sb);
1987   snap_lb = gtk_label_new("bytes");
1988   gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5f);
1989   gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
1990   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), row.has_snaplen);
1991
1992   /* Filter row */
1993   filter_hb = gtk_hbox_new(FALSE, 3);
1994   gtk_box_pack_start(GTK_BOX(capture_vb), filter_hb, FALSE, FALSE, 0);
1995
1996   filter_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_CAPTURE_FILTER_ENTRY);
1997   g_signal_connect(filter_bt, "clicked", G_CALLBACK(capture_filter_construct_cb), NULL);
1998   g_signal_connect(filter_bt, "destroy", G_CALLBACK(filter_button_destroy_cb), NULL);
1999   gtk_widget_set_tooltip_text(filter_bt,
2000     "Select a capture filter to reduce the amount of packets to be captured. "
2001     "See \"Capture Filters\" in the online help for further information how to use it."
2002     );
2003   gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
2004
2005   /* Create the capture filter combo box*/
2006   filter_cm = gtk_combo_box_text_new_with_entry();
2007   cfilter_list = g_object_get_data(G_OBJECT(opt_edit_w), E_CFILTER_FL_KEY);
2008   g_object_set_data(G_OBJECT(opt_edit_w), E_CFILTER_FL_KEY, cfilter_list);
2009   g_object_set_data(G_OBJECT(opt_edit_w), E_CFILTER_CM_KEY, filter_cm);
2010   filter_te = gtk_bin_get_child(GTK_BIN(filter_cm));
2011   colorize_filter_te_as_empty(filter_te);
2012   g_signal_connect(filter_te, "changed", G_CALLBACK(capture_filter_check_syntax_cb), NULL);
2013
2014   for (cf_entry = cfilter_list; cf_entry != NULL; cf_entry = g_list_next(cf_entry)) {
2015     if (cf_entry->data && (strlen(cf_entry->data) > 0)) {
2016       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(filter_cm), cf_entry->data);
2017     }
2018   }
2019   if (global_capture_opts.default_options.cfilter && (strlen(global_capture_opts.default_options.cfilter) > 0)) {
2020     gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), global_capture_opts.default_options.cfilter);
2021   }
2022   if (row.cfilter && (strlen(row.cfilter) > 0)) {
2023     gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(filter_cm), row.cfilter);
2024     gtk_combo_box_set_active(GTK_COMBO_BOX(filter_cm), 0);
2025   }
2026
2027   gtk_widget_set_tooltip_text(filter_cm,
2028     "Enter a capture filter to reduce the amount of packets to be captured. "
2029     "See \"Capture Filters\" in the online help for further information how to use it. "
2030     "Syntax checking can be disabled in Preferences -> Capture -> Syntax check capture filter."
2031     );
2032   gtk_box_pack_start(GTK_BOX(filter_hb), filter_cm, TRUE, TRUE, 3);
2033
2034   /* let an eventually capture filters dialog know the text entry to fill in */
2035   g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
2036
2037 #if defined(HAVE_PCAP_OPEN_DEAD) && defined(HAVE_BPF_IMAGE)
2038   compile_bt = gtk_button_new_with_label("Compile BPF");
2039   g_signal_connect(compile_bt, "clicked", G_CALLBACK(capture_filter_compile_cb), NULL);
2040   gtk_widget_set_tooltip_text(compile_bt,
2041    "Compile the capture filter expression and show the BPF (Berkeley Packet Filter) code.");
2042   gtk_box_pack_start(GTK_BOX(filter_hb), compile_bt, FALSE, FALSE, 3);
2043 #endif
2044
2045 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2046   buffer_size_hb = gtk_hbox_new(FALSE, 3);
2047   buffer_size_lb = gtk_label_new("Buffer size:");
2048   gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_lb, FALSE, FALSE, 0);
2049
2050   buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) row.buffer,
2051     1, 65535, 1.0, 10.0, 0.0);
2052   buffer_size_sb = gtk_spin_button_new (buffer_size_adj, 0, 0);
2053   gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) row.buffer);
2054   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (buffer_size_sb), TRUE);
2055   gtk_widget_set_size_request(buffer_size_sb, 80, -1);
2056   gtk_widget_set_tooltip_text(buffer_size_sb,
2057    "The memory buffer size used while capturing. If you notice packet drops, you can try to increase this size.");
2058   gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_sb, FALSE, FALSE, 0);
2059   g_object_set_data(G_OBJECT(opt_edit_w), E_CAP_BUFFER_SIZE_SB_KEY, buffer_size_sb);
2060   buffer_size_lb = gtk_label_new("megabyte(s)");
2061   gtk_box_pack_start (GTK_BOX(buffer_size_hb), buffer_size_lb, FALSE, FALSE, 3);
2062   gtk_misc_set_alignment(GTK_MISC(buffer_size_lb), 1, 0);
2063 #ifdef HAVE_PCAP_REMOTE
2064   gtk_box_pack_start (GTK_BOX(left_vb), buffer_size_hb, FALSE, FALSE, 0);
2065 #else
2066   gtk_box_pack_start (GTK_BOX(right_vb), buffer_size_hb, FALSE, FALSE, 0);
2067 #endif
2068 #endif
2069
2070 #ifdef HAVE_PCAP_REMOTE
2071   remote_bt = gtk_button_new_with_label("Remote Settings");
2072   gtk_widget_set_tooltip_text(remote_bt, "Various settings for remote capture.");
2073
2074   /* Both the callback and the data are global */
2075   g_signal_connect(remote_bt, "clicked", G_CALLBACK(options_remote_cb), NULL);
2076   g_object_set_data(G_OBJECT(opt_edit_w), E_OPT_REMOTE_BT_KEY, remote_bt);
2077   if (strncmp (row.name, "rpcap://", 8) == 0)  {
2078     gtk_widget_set_sensitive(remote_bt, TRUE);
2079   } else {
2080     gtk_widget_set_sensitive(remote_bt, FALSE);
2081   }
2082   gtk_box_pack_start(GTK_BOX(right_vb), remote_bt, FALSE, FALSE, 0);
2083   gtk_widget_show(remote_bt);
2084 #endif
2085   /* advanced row */
2086 #ifdef HAVE_AIRPCAP
2087   advanced_bt = gtk_button_new_with_label("Wireless Settings");
2088
2089   /* Both the callback and the data are global */
2090   g_signal_connect(advanced_bt,"clicked", G_CALLBACK(options_airpcap_advanced_cb),airpcap_tb);
2091   g_object_set_data(G_OBJECT(top_level),AIRPCAP_OPTIONS_ADVANCED_KEY,advanced_bt);
2092   if(airpcap_if_selected != NULL) {
2093     /* It is an airpcap interface */
2094     gtk_widget_set_sensitive(advanced_bt,TRUE);
2095   } else {
2096     gtk_widget_set_sensitive(advanced_bt,FALSE);
2097   }
2098
2099   gtk_box_pack_start(GTK_BOX(right_vb), advanced_bt, FALSE, FALSE, 0);
2100   gtk_widget_show(advanced_bt);
2101 #endif
2102
2103 /* Button row: "Start", "Cancel" and "Help" buttons */
2104   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
2105   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
2106
2107   ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
2108   g_signal_connect(ok_bt, "clicked", G_CALLBACK(save_options_cb), NULL);
2109   gtk_widget_set_tooltip_text(ok_bt,
2110     "Accept interface settings.");
2111   cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
2112   gtk_widget_set_tooltip_text(cancel_bt,
2113     "Cancel and exit dialog.");
2114   window_set_cancel_button(opt_edit_w, cancel_bt, window_cancel_button_cb);
2115   help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
2116   gtk_widget_set_tooltip_text(help_bt,
2117     "Show help about capturing.");
2118   g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_CAPTURE_OPTIONS_DIALOG);
2119   gtk_widget_grab_default(ok_bt);
2120   dlg_set_activate(filter_te, ok_bt);
2121   g_signal_connect(opt_edit_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
2122   g_signal_connect(opt_edit_w, "destroy", G_CALLBACK(options_edit_destroy_cb), NULL);
2123   gtk_widget_show_all(opt_edit_w);
2124   window_present(opt_edit_w);
2125 }
2126
2127 static void toggle_callback(GtkCellRendererToggle *cell _U_,
2128                gchar *path_str,
2129                gpointer data _U_)
2130 {
2131   /* get the treemodel from somewhere */
2132   GtkTreeIter  iter;
2133   GtkTreeView  *if_cb;
2134   GtkTreeModel *model;
2135   GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
2136   gboolean enabled, found = FALSE;
2137   GtkWidget *pcap_ng_cb;
2138   interface_options interface_opts;
2139   interface_row row;
2140   int index = atoi(path_str);
2141   guint i;
2142
2143   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
2144   model = gtk_tree_view_get_model(if_cb);
2145   gtk_tree_model_get_iter (model, &iter, path);
2146   gtk_tree_model_get (model, &iter, CAPTURE, &enabled, -1);
2147   row = g_array_index(rows, interface_row, index);
2148   if (enabled == FALSE)
2149     num_selected++;
2150   else
2151     num_selected--;
2152   enabled ^= 1;
2153   pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY);
2154   if (num_selected >= 2) {
2155     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE);
2156     gtk_widget_set_sensitive(pcap_ng_cb, FALSE);
2157   } else {
2158     gtk_widget_set_sensitive(pcap_ng_cb, TRUE);
2159   }
2160 #ifdef USE_THREADS
2161   if (num_selected > 0) {
2162 #else
2163   if (num_selected == 1) {
2164 #endif
2165     gtk_widget_set_sensitive(ok_bt, TRUE);
2166   } else {
2167     gtk_widget_set_sensitive(ok_bt, FALSE);
2168   }
2169   /* do something with the new enabled value, and set the new
2170      enabled value in your treemodel */
2171   gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enabled, -1);
2172
2173   if (global_capture_opts.ifaces->len > 0) {
2174     for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2175       interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
2176       if (strcmp(interface_opts.name, row.name) == 0) {
2177         found = TRUE;
2178         break;
2179       }
2180     }
2181     if (found) {
2182       global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
2183       g_free(interface_opts.cfilter);
2184       if (enabled) {
2185         interface_opts.linktype = row.active_dlt;
2186         interface_opts.promisc_mode = row.pmode;
2187         interface_opts.has_snaplen = row.has_snaplen;
2188         interface_opts.snaplen = row.snaplen;
2189         interface_opts.cfilter = g_strdup(row.cfilter);
2190 #ifdef HAVE_PCAP_CREATE
2191         interface_opts.monitor_mode = row.monitor_mode_enabled;
2192 #else
2193         interface_opts.monitor_mode = FALSE;
2194 #endif
2195 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2196         interface_opts.buffer_size = row.buffer;
2197 #endif
2198 #ifdef HAVE_PCAP_REMOTE
2199         interface_opts.src_type = row.remote_opts.src_type;
2200         if (interface_opts.src_type == CAPTURE_IFREMOTE) {
2201           interface_opts.remote_host = g_strdup(row.remote_opts.remote_host_opts.remote_host);
2202           interface_opts.remote_port = g_strdup(row.remote_opts.remote_host_opts.remote_port);
2203           interface_opts.auth_type = row.remote_opts.remote_host_opts.auth_type;
2204           interface_opts.auth_username = g_strdup(row.remote_opts.remote_host_opts.auth_username);
2205           interface_opts.auth_password = g_strdup(row.remote_opts.remote_host_opts.auth_password);
2206           interface_opts.datatx_udp = row.remote_opts.remote_host_opts.datatx_udp;
2207           interface_opts.nocap_rpcap = row.remote_opts.remote_host_opts.nocap_rpcap;
2208           interface_opts.nocap_local = row.remote_opts.remote_host_opts.nocap_local;
2209 #ifdef HAVE_PCAP_SETSAMPLING
2210           interface_opts.sampling_method = row.remote_opts.sampling_method;
2211           interface_opts.sampling_param  = row.remote_opts.sampling_param;
2212 #endif
2213         } else {
2214           interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
2215           interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
2216           interface_opts.auth_type = global_capture_opts.default_options.auth_type;
2217           interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
2218           interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
2219           interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
2220           interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
2221           interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
2222 #ifdef HAVE_PCAP_SETSAMPLING
2223           interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
2224           interface_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
2225 #endif
2226         }
2227 #endif
2228         g_array_insert_val(global_capture_opts.ifaces, i, interface_opts);
2229       } else { /* not enabled */
2230         if (interfaces_dialog_window_present()) {
2231           update_selected_interface(g_strdup(interface_opts.name), FALSE);
2232         }
2233         if (get_welcome_window() != NULL) {
2234           change_interface_selection(g_strdup(interface_opts.name), FALSE);
2235         }
2236       }
2237     }
2238   }
2239   if (!found && enabled) {
2240     interface_opts.name = g_strdup(row.name);
2241     interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
2242     interface_opts.linktype = row.active_dlt;
2243     interface_opts.promisc_mode = row.pmode;
2244     interface_opts.has_snaplen = row.has_snaplen;
2245     interface_opts.snaplen = row.snaplen;
2246     interface_opts.cfilter = g_strdup(row.cfilter);
2247 #ifdef HAVE_PCAP_CREATE
2248     interface_opts.monitor_mode = row.monitor_mode_enabled;
2249 #else
2250     interface_opts.monitor_mode = FALSE;
2251 #endif
2252 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2253     interface_opts.buffer_size = row.buffer;
2254 #endif
2255 #ifdef HAVE_PCAP_REMOTE
2256     interface_opts.src_type = row.remote_opts.src_type;
2257     if (interface_opts.src_type == CAPTURE_IFREMOTE) {
2258       interface_opts.remote_host = g_strdup(row.remote_opts.remote_host_opts.remote_host);
2259       interface_opts.remote_port = g_strdup(row.remote_opts.remote_host_opts.remote_port);
2260       interface_opts.auth_type = row.remote_opts.remote_host_opts.auth_type;
2261       interface_opts.auth_username = g_strdup(row.remote_opts.remote_host_opts.auth_username);
2262       interface_opts.auth_password = g_strdup(row.remote_opts.remote_host_opts.auth_password);
2263       interface_opts.datatx_udp = row.remote_opts.remote_host_opts.datatx_udp;
2264       interface_opts.nocap_rpcap = row.remote_opts.remote_host_opts.nocap_rpcap;
2265       interface_opts.nocap_local = row.remote_opts.remote_host_opts.nocap_local;
2266 #ifdef HAVE_PCAP_SETSAMPLING
2267       interface_opts.sampling_method = row.remote_opts.sampling_method;
2268       interface_opts.sampling_param  = row.remote_opts.sampling_param;
2269 #endif
2270     } else {
2271       interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
2272       interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
2273       interface_opts.auth_type = global_capture_opts.default_options.auth_type;
2274       interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
2275       interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
2276       interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
2277       interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
2278       interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
2279 #ifdef HAVE_PCAP_SETSAMPLING
2280       interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
2281       interface_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
2282 #endif
2283     }
2284 #endif
2285     g_array_append_val(global_capture_opts.ifaces, interface_opts);
2286     if (interfaces_dialog_window_present()) {
2287       update_selected_interface(g_strdup(interface_opts.name), TRUE);
2288     }
2289     if (get_welcome_window() != NULL) {
2290       change_interface_selection(g_strdup(interface_opts.name), TRUE);
2291     }
2292   }
2293   gtk_tree_path_free (path);
2294 }
2295
2296 void enable_selected_interface(gchar *name, gboolean enable)
2297 {
2298   guint i;
2299   interface_row row;
2300   GtkTreeIter  iter;
2301   GtkTreeView  *if_cb;
2302   GtkTreeModel *model;
2303   gchar *path_str;
2304   gboolean enabled;
2305
2306   for (i = 0; i < rows->len; i++) {
2307     row = g_array_index(rows, interface_row, i);
2308     if (strcmp(name, row.name) == 0) {
2309       if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
2310       model = gtk_tree_view_get_model(if_cb);
2311       path_str = g_strdup_printf("%d", i);
2312       gtk_tree_model_get_iter_from_string(model, &iter, path_str);
2313       gtk_tree_model_get (model, &iter, CAPTURE, &enabled, -1);
2314       if ((enabled == TRUE) && (enable == FALSE)) {
2315         num_selected--;
2316       }
2317       if ((enabled == FALSE) && (enable == TRUE)) {
2318         num_selected++;
2319       }
2320       gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enable, -1);
2321       break;
2322     }
2323   }
2324 #ifdef USE_THREADS
2325   if (num_selected > 0) {
2326 #else
2327   if (num_selected == 1) {
2328 #endif
2329     gtk_widget_set_sensitive(ok_bt, TRUE);
2330   } else {
2331     gtk_widget_set_sensitive(ok_bt, FALSE);
2332   }
2333 }
2334
2335
2336 static void capture_all_cb(GtkToggleButton *button, gpointer d _U_)
2337 {
2338   GtkTreeIter  iter;
2339   GtkTreeView  *if_cb;
2340   GtkTreeModel *model;
2341   GtkWidget *pcap_ng_cb;
2342   gboolean enabled = FALSE, capture_set = FALSE;
2343
2344   if (gtk_toggle_button_get_active(button))
2345     enabled = TRUE;
2346   if_cb = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
2347   model = gtk_tree_view_get_model(if_cb);
2348   pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY);
2349   if (gtk_tree_model_get_iter_first(model, &iter)) {
2350     do {
2351       gtk_tree_model_get (model, &iter, CAPTURE, &capture_set, -1);
2352       if (!capture_set && enabled) {
2353         num_selected++;
2354       } else if (capture_set && !enabled) {
2355         num_selected--;
2356       }
2357       gtk_list_store_set(GTK_LIST_STORE(model), &iter, CAPTURE, enabled, -1);
2358     } while (gtk_tree_model_iter_next(model, &iter));
2359   }
2360   if (num_selected >= 2) {
2361     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), TRUE);
2362     gtk_widget_set_sensitive(pcap_ng_cb, FALSE);
2363   } else if (num_selected <= 1) {
2364     gtk_widget_set_sensitive(pcap_ng_cb, TRUE);
2365   }
2366   if (interfaces_dialog_window_present()) {
2367     select_all_interfaces(enabled);
2368   }
2369   if (get_welcome_window() != NULL) {
2370     change_selection_for_all(enabled);
2371   }
2372 #ifdef USE_THREADS
2373   if (num_selected > 0) {
2374 #else
2375   if (num_selected == 1) {
2376 #endif
2377     gtk_widget_set_sensitive(ok_bt, TRUE);
2378   } else {
2379     gtk_widget_set_sensitive(ok_bt, FALSE);
2380   }
2381 }
2382
2383
2384 static void promisc_mode_callback(GtkToggleButton *button, gpointer d _U_)
2385 {
2386   GtkTreeIter  iter;
2387   GtkTreeView  *if_cb;
2388   GtkTreeModel *model;
2389   gboolean enabled = FALSE;
2390   interface_row row;
2391   interface_options interface_opts;
2392   guint i;
2393
2394   if (gtk_toggle_button_get_active(button))
2395     enabled = TRUE;
2396
2397   if_cb      = (GtkTreeView *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY);
2398   model = gtk_tree_view_get_model(if_cb);
2399   if (gtk_tree_model_get_iter_first(model, &iter)) {
2400     do {
2401       gtk_list_store_set(GTK_LIST_STORE(model), &iter, PMODE, enabled?"enabled":"disabled", -1);
2402     } while (gtk_tree_model_iter_next(model, &iter));
2403   }
2404
2405   for (i = 0; i < rows->len; i++) {
2406     row = g_array_index(rows, interface_row, i);
2407     rows = g_array_remove_index(rows, i);
2408     row.pmode = (enabled?TRUE:FALSE);
2409     g_array_insert_val(rows, i, row);
2410   }
2411
2412   for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2413     interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
2414     global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
2415     interface_opts.promisc_mode = (enabled?TRUE:FALSE);
2416     g_array_insert_val(global_capture_opts.ifaces, i, interface_opts);
2417   }
2418 }
2419
2420 #if defined (HAVE_PCAP_REMOTE)
2421 void show_remote_dialog(GtkWidget *w)
2422 {
2423
2424     g_free(global_remote_opts.remote_host_opts.remote_host);
2425     g_free(global_remote_opts.remote_host_opts.remote_port);
2426     g_free(global_remote_opts.remote_host_opts.auth_username);
2427     g_free(global_remote_opts.remote_host_opts.auth_password);
2428     global_remote_opts.src_type = CAPTURE_IFREMOTE;
2429     global_remote_opts.remote_host_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
2430     global_remote_opts.remote_host_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
2431     global_remote_opts.remote_host_opts.auth_type = global_capture_opts.default_options.auth_type;
2432     global_remote_opts.remote_host_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
2433     global_remote_opts.remote_host_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
2434     global_remote_opts.remote_host_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
2435     global_remote_opts.remote_host_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
2436     global_remote_opts.remote_host_opts.nocap_local = global_capture_opts.default_options.nocap_local;
2437 #ifdef HAVE_PCAP_SETSAMPLING
2438     global_remote_opts.sampling_method = global_capture_opts.default_options.sampling_method;
2439     global_remote_opts.sampling_param = global_capture_opts.default_options.sampling_param;
2440 #endif
2441     capture_remote_cb(GTK_WIDGET(w), FALSE);
2442 }
2443 #endif
2444
2445 /* show capture prepare (options) dialog */
2446
2447 /* XXX: Warning:
2448         Note that capture_interface_list() is called directly (or indirectly) during the
2449          creation of (and changes to) the capture options dialog window.
2450
2451         Also note that capture_interface_list() indirectly runs the gtk main loop temporarily
2452          to process queued events (which may include button-presses, key-presses, etc).
2453          (This is done while awaiting a response from dumpcap which is invoked to obtain
2454           the capture interface list).
2455         This means other Wireshark callbacks can be invoked while the capture options window
2456          is being created or updated (in effect an "interrupt" can occur).
2457
2458         Needless to say, "race conditions" may occur in "interrupt" code which depends upon the exact
2459         state of the capture options dialog window and which may be invoked during the
2460         creation of (or changes to) the capture options dialog window.
2461
2462         For example: if a user hits "Capture:Options" and then immediately hits "Capture:Start",
2463          capture_start_cb() may be invoked before capture_prep_cb() has been completed (i.e., during
2464          a call to capture_interface_list() in the code which creates the capture options window).
2465         capture_start_cb() depends upon certain properties of the capture options window having been
2466          initialized and thus fails if the properties have not (yet) been initialized.
2467
2468         An interlock has been added to handle this particular situation;
2469         Ideally a more general solution should be implemented since it's probably difficult
2470          (if not nearly impossible) to identify all the possible "race conditions".
2471
2472         ? Prevent the temporary running of the gtk main loop in cases wherein dumpcap is invoked for a
2473           simple request/reply ? (e.g., capture_interface_list()) ??
2474
2475         ? Other ??
2476 */
2477
2478 void
2479 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
2480 {
2481   GtkWidget     *main_vb,
2482                 *main_hb, *left_vb, *right_vb,
2483                 *capture_fr, *capture_vb,
2484                 *all_hb, *all_cb,
2485                 *promisc_cb, *pcap_ng_cb,
2486                 *file_fr, *file_vb,
2487                 *file_hb, *file_bt, *file_lb, *file_te,
2488                 *multi_tb, *multi_files_on_cb,
2489                 *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_cbx,
2490                 *file_duration_cb, *file_duration_sb, *file_duration_cbx,
2491                 *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
2492                 *stop_files_cb, *stop_files_sb, *stop_files_lb,
2493                 *limit_fr, *limit_vb, *limit_tb,
2494                 *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
2495                 *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_cbx,
2496                 *stop_duration_cb, *stop_duration_sb, *stop_duration_cbx,
2497                 *display_fr, *display_vb,
2498                 *sync_cb, *auto_scroll_cb, *hide_info_cb,
2499                 *resolv_fr, *resolv_vb,
2500                 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
2501                 *bbox, *close_bt,
2502                 *help_bt;
2503 #ifdef HAVE_AIRPCAP
2504   GtkWidget     *decryption_cb;
2505 #endif
2506 #ifdef HAVE_PCAP_REMOTE
2507   GtkWidget     *iftype_cbx;
2508 #endif
2509
2510   GtkAdjustment *ringbuffer_nbf_adj,
2511                 *stop_packets_adj, *stop_filesize_adj, *stop_duration_adj, *stop_files_adj,
2512                 *ring_filesize_adj, *file_duration_adj;
2513   GList           *if_list;
2514   int              row;
2515   int              err;
2516   gchar            *err_str;
2517   guint32          value;
2518   gchar            *cap_title;
2519   GtkWidget        *view;
2520   GtkWidget        *swindow;
2521   GtkCellRenderer  *renderer;
2522   GtkCellRenderer  *toggle_renderer;
2523   GtkTreeSelection  *selection;
2524   GtkTreeViewColumn *column;
2525   gboolean          if_present = TRUE;
2526
2527   if (interfaces_dialog_window_present()) {
2528     destroy_if_window();
2529   }
2530   if (cap_open_w != NULL) {
2531     /* There's already a "Capture Options" dialog box; reactivate it. */
2532     reactivate_window(cap_open_w);
2533     return;
2534   }
2535
2536 #ifdef _WIN32
2537   /* Is WPcap loaded? */
2538   if (!has_wpcap) {
2539     char *detailed_err;
2540
2541     detailed_err = cant_load_winpcap_err("Wireshark");
2542     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", detailed_err);
2543     g_free(detailed_err);
2544     return;
2545   }
2546 #endif
2547   num_selected = 0;
2548   /* use user-defined title if preference is set */
2549
2550   cap_title = create_user_window_title("Wireshark: Capture Options");
2551
2552   cap_open_complete = FALSE;
2553   cap_open_w = dlg_window_new(cap_title);
2554   g_free(cap_title);
2555
2556   if_list = capture_interface_list(&err, &err_str);
2557
2558   if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
2559     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
2560     g_free(err_str);
2561   }
2562 #ifdef HAVE_AIRPCAP
2563   /* update airpcap interface list */
2564
2565   /* load the airpcap interfaces */
2566   airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2567
2568   decryption_cb = g_object_get_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY);
2569   update_decryption_mode_list(decryption_cb);
2570
2571   if (airpcap_if_list == NULL && err == CANT_GET_AIRPCAP_INTERFACE_LIST) {
2572     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
2573     g_free(err_str);
2574   }
2575
2576   /* select the first as default (THIS SHOULD BE CHANGED) */
2577   airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2578 #endif
2579
2580   main_vb = gtk_vbox_new(FALSE, 0);
2581   gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
2582   gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
2583
2584   /* Capture-related options frame */
2585   capture_fr = gtk_frame_new("Capture");
2586   gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
2587
2588   capture_vb = gtk_vbox_new(FALSE, 3);
2589   gtk_container_set_border_width(GTK_CONTAINER(capture_vb), 5);
2590   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
2591
2592 #if defined (HAVE_PCAP_REMOTE)
2593   if (remote_host_list == NULL) {
2594     remote_host_list = g_hash_table_new (g_str_hash, g_str_equal);
2595   }
2596 #endif
2597
2598   swindow = gtk_scrolled_window_new (NULL, NULL);
2599   gtk_widget_set_size_request(swindow, FALSE, 180);
2600   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN);
2601
2602   view = gtk_tree_view_new ();
2603   gtk_tree_view_set_rules_hint(GTK_TREE_VIEW (view), TRUE);
2604   g_signal_connect(view, "row-activated", G_CALLBACK(options_interface_cb), (gpointer)cap_open_w);
2605   toggle_renderer = gtk_cell_renderer_toggle_new();
2606   column = gtk_tree_view_column_new_with_attributes("Capture", GTK_CELL_RENDERER(toggle_renderer), "active", CAPTURE, NULL);
2607   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2608   g_signal_connect (G_OBJECT(toggle_renderer), "toggled", G_CALLBACK (toggle_callback), NULL);
2609   g_object_set (GTK_TREE_VIEW(view), "has-tooltip", TRUE, NULL);
2610   g_signal_connect (GTK_TREE_VIEW(view), "query-tooltip", G_CALLBACK (query_tooltip_tree_view_cb), NULL);
2611
2612   renderer = gtk_cell_renderer_text_new ();
2613   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view), -1, "Interface", renderer, "markup", INTERFACE, NULL);
2614   column = gtk_tree_view_get_column(GTK_TREE_VIEW (view), INTERFACE);
2615   gtk_tree_view_column_set_min_width(column, 200);
2616   gtk_tree_view_column_set_resizable(column, TRUE );
2617   gtk_tree_view_column_set_alignment(column, 0.5);
2618   g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
2619
2620   renderer = gtk_cell_renderer_text_new();
2621   column = gtk_tree_view_column_new_with_attributes ("Link-layer header", renderer, "text", LINK, NULL);
2622   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2623   gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW (view),LINK), TRUE );
2624   gtk_tree_view_column_set_alignment(column, 0.5);
2625
2626   renderer = gtk_cell_renderer_text_new();
2627   column = gtk_tree_view_column_new_with_attributes("Prom. Mode", renderer, "text", PMODE, NULL);
2628   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2629   g_object_set(renderer, "xalign", 0.5, NULL);
2630   gtk_tree_view_column_set_alignment(column, 0.5);
2631
2632   renderer = gtk_cell_renderer_text_new();
2633   column = gtk_tree_view_column_new_with_attributes("Snaplen [B]", renderer, "text", SNAPLEN, NULL);
2634   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2635   g_object_set(renderer, "xalign", 0.5, NULL);
2636
2637 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2638   renderer = gtk_cell_renderer_text_new();
2639   column = gtk_tree_view_column_new_with_attributes("Buffer [MB]", renderer, "text", BUFFER, NULL);
2640   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2641   g_object_set(renderer, "xalign", 0.5, NULL);
2642 #endif
2643
2644 #if defined (HAVE_PCAP_CREATE)
2645   renderer = gtk_cell_renderer_text_new();
2646   column = gtk_tree_view_column_new_with_attributes ("Mon. Mode", renderer, "text", MONITOR, NULL);
2647   gtk_tree_view_column_set_cell_data_func(column, renderer, activate_monitor, NULL, FALSE);
2648   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2649   g_object_set(renderer, "xalign", 0.5, NULL);
2650 #endif
2651
2652   renderer = gtk_cell_renderer_text_new();
2653   column = gtk_tree_view_column_new_with_attributes("Capture Filter", renderer, "text", FILTER, NULL);
2654   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2655   gtk_tree_view_column_set_alignment(column, 0.5);
2656   create_and_fill_model(if_list, TRUE, GTK_TREE_VIEW(view));
2657   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
2658   gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2659   gtk_container_add (GTK_CONTAINER (swindow), view);
2660   gtk_box_pack_start(GTK_BOX(capture_vb), swindow, TRUE, TRUE, 0);
2661
2662   free_interface_list(if_list);
2663   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IFACE_KEY, view);
2664
2665 #ifdef HAVE_AIRPCAP
2666   /* get the airpcap interface (if it IS an airpcap interface, and update the
2667      toolbar... and of course enable the advanced button...)*/
2668  /* airpcap_if_selected = get_airpcap_if_from_name(airpcap_if_list,interface_opts.name);*/
2669 #endif
2670   main_hb = gtk_hbox_new(FALSE, 5);
2671   gtk_container_set_border_width(GTK_CONTAINER(main_hb), 3);
2672   gtk_box_pack_start(GTK_BOX(capture_vb), main_hb, FALSE, FALSE, 0);
2673   all_hb = gtk_hbox_new(FALSE, 5);
2674   gtk_container_set_border_width(GTK_CONTAINER(all_hb), 0);
2675   gtk_box_pack_start(GTK_BOX(main_hb), all_hb, TRUE, TRUE, 0);
2676
2677   left_vb = gtk_vbox_new(FALSE, 0);
2678   gtk_container_set_border_width(GTK_CONTAINER(left_vb), 0);
2679   gtk_box_pack_start(GTK_BOX(all_hb), left_vb, TRUE, TRUE, 0);
2680
2681   right_vb = gtk_vbox_new(FALSE, 3);
2682   gtk_container_set_border_width(GTK_CONTAINER(right_vb), 0);
2683   gtk_box_pack_start(GTK_BOX(all_hb), right_vb, FALSE, FALSE, 3);
2684
2685   all_cb = gtk_check_button_new_with_mnemonic( "Capture on all interfaces");
2686   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(all_cb), FALSE);
2687   g_signal_connect(all_cb, "toggled", G_CALLBACK(capture_all_cb), NULL);
2688   gtk_widget_set_tooltip_text(all_cb, "Activate the box to capture on all interfaces. "
2689     "Deactivate it to capture on none and set the interfaces individually.");
2690   gtk_box_pack_start(GTK_BOX(left_vb), all_cb, TRUE, TRUE, 0);
2691
2692   gtk_widget_set_sensitive(GTK_WIDGET(all_cb), if_present);
2693   /* Promiscuous mode row */
2694   promisc_cb = gtk_check_button_new_with_mnemonic("Capture all in _promiscuous mode");
2695   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(promisc_cb),
2696                                global_capture_opts.default_options.promisc_mode);
2697   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb)))
2698     promisc_mode_callback(GTK_TOGGLE_BUTTON(promisc_cb), NULL);
2699   g_signal_connect(promisc_cb, "toggled", G_CALLBACK(promisc_mode_callback), NULL);
2700
2701   gtk_widget_set_tooltip_text(promisc_cb,
2702     "Usually a network adapter will only capture the traffic sent to its own network address. "
2703     "If you want to capture all traffic that all network adapters can \"see\", mark this option. "
2704     "If you want to set this option on a per interface basis, unmark this button and set the "
2705     "option individually."
2706     "See the FAQ for some more details of capturing packets from a switched network.");
2707 #if defined (HAVE_PCAP_REMOTE)
2708   gtk_box_pack_start(GTK_BOX(left_vb), promisc_cb, TRUE, TRUE, 0);
2709 #else
2710   gtk_box_pack_start(GTK_BOX(right_vb), promisc_cb, TRUE, TRUE, 0);
2711 #endif
2712   gtk_widget_set_sensitive(GTK_WIDGET(promisc_cb), if_present);
2713
2714 #ifdef HAVE_PCAP_REMOTE
2715   iftype_cbx = gtk_button_new_with_label("Add Remote Interfaces");
2716   gtk_widget_set_tooltip_text(iftype_cbx, "Connect to remote host to get interfaces to capture from");
2717   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_IFTYPE_CBX_KEY, iftype_cbx);
2718
2719   gtk_box_pack_start(GTK_BOX(right_vb), iftype_cbx, FALSE, FALSE, 0);
2720   g_signal_connect(iftype_cbx, "clicked", G_CALLBACK(show_remote_dialog), iftype_cbx);
2721   gtk_widget_show(iftype_cbx);
2722 #endif
2723   main_hb = gtk_hbox_new(FALSE, 5);
2724   gtk_container_set_border_width(GTK_CONTAINER(main_hb), 0);
2725   gtk_box_pack_start(GTK_BOX(main_vb), main_hb, FALSE, FALSE, 0);
2726
2727   left_vb = gtk_vbox_new(FALSE, 0);
2728   gtk_container_set_border_width(GTK_CONTAINER(left_vb), 0);
2729   gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
2730
2731   right_vb = gtk_vbox_new(FALSE, 0);
2732   gtk_container_set_border_width(GTK_CONTAINER(right_vb), 0);
2733   gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 0);
2734
2735   /* Capture file-related options frame */
2736   file_fr = gtk_frame_new("Capture File(s)");
2737   gtk_container_add(GTK_CONTAINER(left_vb), file_fr);
2738
2739   file_vb = gtk_vbox_new(FALSE, 3);
2740   gtk_container_set_border_width(GTK_CONTAINER(file_vb), 5);
2741   gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
2742
2743   /* File row */
2744   file_hb = gtk_hbox_new(FALSE, 3);
2745   gtk_box_pack_start(GTK_BOX(file_vb), file_hb, FALSE, FALSE, 0);
2746
2747   file_lb = gtk_label_new("File:");
2748   gtk_box_pack_start(GTK_BOX(file_hb), file_lb, FALSE, FALSE, 3);
2749
2750   file_te = gtk_entry_new();
2751   gtk_widget_set_tooltip_text(file_te,
2752     "Enter the file name to which captured data will be written. "
2753     "If you don't enter something here, a temporary file will be used."
2754      );
2755   gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
2756
2757   file_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_BROWSE);
2758   gtk_widget_set_tooltip_text(file_bt,
2759     "Select a file to which captured data will be written, "
2760     "instead of entering the file name directly. "
2761     );
2762   gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 0);
2763
2764   g_signal_connect(file_bt, "clicked", G_CALLBACK(capture_prep_file_cb), file_te);
2765
2766   /* multiple files table */
2767   multi_tb = gtk_table_new(5, 3, FALSE);
2768   gtk_table_set_row_spacings(GTK_TABLE(multi_tb), 1);
2769   gtk_table_set_col_spacings(GTK_TABLE(multi_tb), 3);
2770   gtk_box_pack_start(GTK_BOX(file_vb), multi_tb, FALSE, FALSE, 0);
2771   row = 0;
2772
2773   /* multiple files row */
2774   multi_files_on_cb = gtk_check_button_new_with_mnemonic("Use _multiple files");
2775   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(multi_files_on_cb),
2776                                global_capture_opts.multi_files_on);
2777   g_signal_connect(multi_files_on_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity),
2778                  cap_open_w);
2779   gtk_widget_set_tooltip_text(multi_files_on_cb,
2780     "Instead of using a single capture file, multiple files will be created. "
2781     "The generated file names will contain an incrementing number and the start time of the capture.");
2782   gtk_table_attach_defaults(GTK_TABLE(multi_tb), multi_files_on_cb, 0, 1, row, row+1);
2783
2784   /* Pcap-NG row */
2785   pcap_ng_cb = gtk_check_button_new_with_mnemonic("Use pcap-ng format");
2786   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcap_ng_cb), global_capture_opts.use_pcapng);
2787   gtk_widget_set_tooltip_text(pcap_ng_cb, "Capture packets in the next-generation capture file format. "
2788                        "This is still experimental.");
2789   gtk_table_attach_defaults(GTK_TABLE(multi_tb), pcap_ng_cb, 2, 3, row, row+1);
2790   row++;
2791
2792   /* Ring buffer filesize row */
2793   ring_filesize_cb = gtk_check_button_new_with_label("Next file every");
2794   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb),
2795                                global_capture_opts.has_autostop_filesize || !global_capture_opts.has_file_duration);
2796   g_signal_connect(ring_filesize_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2797   gtk_widget_set_tooltip_text(ring_filesize_cb,
2798     "If the selected file size is exceeded, capturing switches to the next file.\n"
2799     "PLEASE NOTE: at least one of the \"Next file every\" options MUST be selected.");
2800   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_cb, 0, 1, row, row+1);
2801
2802   ring_filesize_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
2803     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
2804   ring_filesize_sb = gtk_spin_button_new (ring_filesize_adj, 0, 0);
2805   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_filesize_sb), TRUE);
2806   gtk_widget_set_size_request(ring_filesize_sb, 80, -1);
2807   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_sb, 1, 2, row, row+1);
2808
2809   ring_filesize_cbx = size_unit_combo_box_new(global_capture_opts.autostop_filesize);
2810   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_cbx, 2, 3, row, row+1);
2811
2812   value = size_unit_combo_box_set_value(global_capture_opts.autostop_filesize);
2813   gtk_adjustment_set_value(ring_filesize_adj, (gfloat) value);
2814
2815   row++;
2816
2817   /* Ring buffer duration row */
2818   file_duration_cb = gtk_check_button_new_with_label("Next file every");
2819   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(file_duration_cb),
2820                                global_capture_opts.has_file_duration);
2821   g_signal_connect(file_duration_cb, "toggled",
2822                    G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2823   gtk_widget_set_tooltip_text(file_duration_cb,
2824     "If the selected duration is exceeded, capturing switches to the next file.\n"
2825     "PLEASE NOTE: at least one of the \"Next file every\" options MUST be selected.");
2826   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_cb, 0, 1, row, row+1);
2827
2828   file_duration_adj = (GtkAdjustment *)gtk_adjustment_new(0.0,
2829     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
2830   file_duration_sb = gtk_spin_button_new (file_duration_adj, 0, 0);
2831   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (file_duration_sb), TRUE);
2832   gtk_widget_set_size_request(file_duration_sb, 80, -1);
2833   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_sb, 1, 2, row, row+1);
2834
2835   file_duration_cbx = time_unit_combo_box_new(global_capture_opts.file_duration);
2836   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_cbx, 2, 3, row, row+1);
2837
2838   value = time_unit_combo_box_convert_value(global_capture_opts.file_duration);
2839   gtk_adjustment_set_value(file_duration_adj, (gfloat) value);
2840   row++;
2841
2842   /* Ring buffer files row */
2843   ringbuffer_nbf_cb = gtk_check_button_new_with_label("Ring buffer with");
2844   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb),
2845                                global_capture_opts.has_ring_num_files);
2846   g_signal_connect(ringbuffer_nbf_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2847   gtk_widget_set_tooltip_text(ringbuffer_nbf_cb,
2848     "After capturing has switched to the next file and the given number of files has exceeded, "
2849     "the oldest file will be removed."
2850     );
2851   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_cb, 0, 1, row, row+1);
2852
2853   ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) global_capture_opts.ring_num_files,
2854     2/*RINGBUFFER_MIN_NUM_FILES*/, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
2855   ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
2856   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
2857   gtk_widget_set_size_request(ringbuffer_nbf_sb, 80, -1);
2858   g_signal_connect(ringbuffer_nbf_sb, "changed", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2859   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_sb, 1, 2, row, row+1);
2860
2861   ringbuffer_nbf_lb = gtk_label_new("files");
2862   gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 0, 0.5f);
2863   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_lb, 2, 3, row, row+1);
2864   row++;
2865
2866   /* Files row */
2867   stop_files_cb = gtk_check_button_new_with_label("Stop capture after");
2868   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_files_cb),
2869                                global_capture_opts.has_autostop_files);
2870   g_signal_connect(stop_files_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2871   gtk_widget_set_tooltip_text(stop_files_cb, "Stop capturing after the given number of \"file switches\" have been done.");
2872   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_cb, 0, 1, row, row+1);
2873
2874   stop_files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)global_capture_opts.autostop_files,
2875     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
2876   stop_files_sb = gtk_spin_button_new (stop_files_adj, 0, 0);
2877   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_files_sb), TRUE);
2878   gtk_widget_set_size_request(stop_files_sb, 80, -1);
2879   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_sb, 1, 2, row, row+1);
2880
2881   stop_files_lb = gtk_label_new("file(s)");
2882   gtk_misc_set_alignment(GTK_MISC(stop_files_lb), 0, 0.5f);
2883   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_lb, 2, 3, row, row+1);
2884   row++;
2885
2886   /* Capture limits frame */
2887   limit_fr = gtk_frame_new("Stop Capture ...");
2888   gtk_container_add(GTK_CONTAINER(left_vb), limit_fr);
2889
2890   limit_vb = gtk_vbox_new(FALSE, 3);
2891   gtk_container_set_border_width(GTK_CONTAINER(limit_vb), 5);
2892   gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
2893
2894   /* limits table */
2895   limit_tb = gtk_table_new(3, 3, FALSE);
2896   gtk_table_set_row_spacings(GTK_TABLE(limit_tb), 1);
2897   gtk_table_set_col_spacings(GTK_TABLE(limit_tb), 3);
2898   gtk_box_pack_start(GTK_BOX(limit_vb), limit_tb, FALSE, FALSE, 0);
2899   row = 0;
2900
2901   /* Packet count row */
2902   stop_packets_cb = gtk_check_button_new_with_label("... after");
2903   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_packets_cb),
2904                                global_capture_opts.has_autostop_packets);
2905   g_signal_connect(stop_packets_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2906   gtk_widget_set_tooltip_text(stop_packets_cb, "Stop capturing after the given number of packets have been captured.");
2907   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_cb, 0, 1, row, row+1);
2908
2909   stop_packets_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)global_capture_opts.autostop_packets,
2910     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
2911   stop_packets_sb = gtk_spin_button_new (stop_packets_adj, 0, 0);
2912   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_packets_sb), TRUE);
2913   gtk_widget_set_size_request(stop_packets_sb, 80, -1);
2914   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_sb, 1, 2, row, row+1);
2915
2916   stop_packets_lb = gtk_label_new("packet(s)");
2917   gtk_misc_set_alignment(GTK_MISC(stop_packets_lb), 0, 0.5f);
2918   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_lb, 2, 3, row, row+1);
2919   row++;
2920
2921   /* Filesize row */
2922   stop_filesize_cb = gtk_check_button_new_with_label("... after");
2923   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_filesize_cb),
2924                                global_capture_opts.has_autostop_filesize);
2925   g_signal_connect(stop_filesize_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2926   gtk_widget_set_tooltip_text(stop_filesize_cb, "Stop capturing after the given amount of capture data has been captured.");
2927   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_cb, 0, 1, row, row+1);
2928
2929   stop_filesize_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
2930     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
2931   stop_filesize_sb = gtk_spin_button_new (stop_filesize_adj, 0, 0);
2932   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_filesize_sb), TRUE);
2933   gtk_widget_set_size_request(stop_filesize_sb, 80, -1);
2934   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_sb, 1, 2, row, row+1);
2935
2936   stop_filesize_cbx = size_unit_combo_box_new(global_capture_opts.autostop_filesize);
2937   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_cbx, 2, 3, row, row+1);
2938
2939   value = size_unit_combo_box_set_value(global_capture_opts.autostop_filesize);
2940   gtk_adjustment_set_value(stop_filesize_adj, (gfloat) value);
2941
2942   row++;
2943
2944   /* Duration row */
2945   stop_duration_cb = gtk_check_button_new_with_label("... after");
2946   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_duration_cb),
2947                                global_capture_opts.has_autostop_duration);
2948   g_signal_connect(stop_duration_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2949   gtk_widget_set_tooltip_text(stop_duration_cb, "Stop capturing after the given time is exceeded.");
2950   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_cb, 0, 1, row, row+1);
2951
2952   stop_duration_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
2953     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
2954   stop_duration_sb = gtk_spin_button_new (stop_duration_adj, 0, 0);
2955   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_duration_sb), TRUE);
2956   gtk_widget_set_size_request(stop_duration_sb, 80, -1);
2957   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_sb, 1, 2, row, row+1);
2958
2959   stop_duration_cbx = time_unit_combo_box_new(global_capture_opts.autostop_duration);
2960   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_cbx, 2, 3, row, row+1);
2961
2962   value = time_unit_combo_box_convert_value(global_capture_opts.autostop_duration);
2963   gtk_adjustment_set_value(stop_duration_adj, (gfloat) value);
2964   row++;
2965
2966   /* Display-related options frame */
2967   display_fr = gtk_frame_new("Display Options");
2968   gtk_container_add(GTK_CONTAINER(right_vb), display_fr);
2969
2970   display_vb = gtk_vbox_new(FALSE, 0);
2971   gtk_container_set_border_width(GTK_CONTAINER(display_vb), 5);
2972   gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
2973
2974   /* "Update display in real time" row */
2975   sync_cb = gtk_check_button_new_with_mnemonic(
2976       "_Update list of packets in real time");
2977   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sync_cb),
2978                                global_capture_opts.real_time_mode);
2979   g_signal_connect(sync_cb, "toggled", G_CALLBACK(capture_prep_adjust_sensitivity), cap_open_w);
2980   gtk_widget_set_tooltip_text(sync_cb,
2981     "Using this option will show the captured packets immediately on the main screen. "
2982     "Please note: this will slow down capturing, so increased packet drops might appear.");
2983   gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
2984
2985   /* "Auto-scroll live update" row */
2986   auto_scroll_cb = gtk_check_button_new_with_mnemonic("_Automatic scrolling in live capture");
2987   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
2988   gtk_widget_set_tooltip_text(auto_scroll_cb,
2989     "This will scroll the \"Packet List\" automatically to the latest captured packet, "
2990     "when the \"Update List of packets in real time\" option is used.");
2991   gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
2992
2993   /* "Hide capture info" row */
2994   hide_info_cb = gtk_check_button_new_with_mnemonic("_Hide capture info dialog");
2995   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hide_info_cb), !global_capture_opts.show_info);
2996   gtk_widget_set_tooltip_text(hide_info_cb, "Hide the capture info dialog while capturing.");
2997   gtk_container_add(GTK_CONTAINER(display_vb), hide_info_cb);
2998
2999   /* Name Resolution frame */
3000   resolv_fr = gtk_frame_new("Name Resolution");
3001   gtk_container_add(GTK_CONTAINER(right_vb), resolv_fr);
3002
3003   resolv_vb = gtk_vbox_new(FALSE, 0);
3004   gtk_container_set_border_width(GTK_CONTAINER(resolv_vb), 5);
3005   gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
3006
3007   m_resolv_cb = gtk_check_button_new_with_mnemonic(
3008                 "Enable _MAC name resolution");
3009   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_resolv_cb),
3010                 gbl_resolv_flags & RESOLV_MAC);
3011   gtk_widget_set_tooltip_text(m_resolv_cb, "Perform MAC layer name resolution while capturing.");
3012   gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
3013
3014   n_resolv_cb = gtk_check_button_new_with_mnemonic(
3015                 "Enable _network name resolution");
3016   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(n_resolv_cb),
3017                 gbl_resolv_flags & RESOLV_NETWORK);
3018   gtk_widget_set_tooltip_text(n_resolv_cb, "Perform network layer name resolution while capturing.");
3019   gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
3020
3021   t_resolv_cb = gtk_check_button_new_with_mnemonic(
3022                 "Enable _transport name resolution");
3023   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_resolv_cb),
3024                 gbl_resolv_flags & RESOLV_TRANSPORT);
3025   gtk_widget_set_tooltip_text(t_resolv_cb,
3026     "Perform transport layer name resolution while capturing.");
3027   gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
3028
3029   /* Button row: "Start", "Cancel" and "Help" buttons */
3030   bbox = dlg_button_row_new(WIRESHARK_STOCK_CAPTURE_START, GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
3031   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
3032
3033   ok_bt = g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CAPTURE_START);
3034   g_signal_connect(ok_bt, "clicked", G_CALLBACK(capture_start_cb), NULL);
3035   gtk_widget_set_tooltip_text(ok_bt, "Start the capture process.");
3036 #ifdef USE_THREADS
3037   if (num_selected > 0) {
3038 #else
3039   if (num_selected == 1) {
3040 #endif
3041     gtk_widget_set_sensitive(ok_bt, TRUE);
3042   } else {
3043     gtk_widget_set_sensitive(ok_bt, FALSE);
3044   }
3045
3046   close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
3047   gtk_widget_set_tooltip_text(close_bt,
3048     "Exit dialog.");
3049   window_set_cancel_button(cap_open_w, close_bt, window_cancel_button_cb);
3050
3051   help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
3052   gtk_widget_set_tooltip_text(help_bt,
3053     "Show help about capturing.");
3054   g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_CAPTURE_OPTIONS_DIALOG);
3055   gtk_widget_grab_default(ok_bt);
3056
3057   /* Attach pointers to needed widgets to the capture prefs window/object */
3058 #ifdef HAVE_PCAP_REMOTE
3059   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_REMOTE_DIALOG_PTR_KEY, NULL);
3060 #endif
3061   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_PROMISC_KEY_ALL, promisc_cb);
3062   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_PCAP_NG_KEY, pcap_ng_cb);
3063   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_TE_KEY,  file_te);
3064   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_MULTI_FILES_ON_CB_KEY,  multi_files_on_cb);
3065   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_NBF_CB_KEY,  ringbuffer_nbf_cb);
3066   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_NBF_SB_KEY,  ringbuffer_nbf_sb);
3067   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_NBF_LB_KEY,  ringbuffer_nbf_lb);
3068   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_FILESIZE_CB_KEY,  ring_filesize_cb);
3069   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_FILESIZE_SB_KEY,  ring_filesize_sb);
3070   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_RING_FILESIZE_CBX_KEY,  ring_filesize_cbx);
3071   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_DURATION_CB_KEY,  file_duration_cb);
3072   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_DURATION_SB_KEY,  file_duration_sb);
3073   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_FILE_DURATION_CBX_KEY,  file_duration_cbx);
3074   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_SYNC_KEY,  sync_cb);
3075   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
3076   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_HIDE_INFO_KEY, hide_info_cb);
3077   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_PACKETS_CB_KEY, stop_packets_cb);
3078   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_PACKETS_SB_KEY, stop_packets_sb);
3079   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_PACKETS_LB_KEY, stop_packets_lb);
3080   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILESIZE_CB_KEY, stop_filesize_cb);
3081   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILESIZE_SB_KEY, stop_filesize_sb);
3082   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILESIZE_CBX_KEY, stop_filesize_cbx);
3083   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_DURATION_CB_KEY,  stop_duration_cb);
3084   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_DURATION_SB_KEY,  stop_duration_sb);
3085   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_DURATION_CBX_KEY,  stop_duration_cbx);
3086   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILES_CB_KEY, stop_files_cb);
3087   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILES_SB_KEY, stop_files_sb);
3088   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_STOP_FILES_LB_KEY, stop_files_lb);
3089   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
3090   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
3091   g_object_set_data(G_OBJECT(cap_open_w), E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
3092
3093   /* Set the sensitivity of various widgets as per the settings of other
3094      widgets. */
3095   capture_prep_adjust_sensitivity(NULL, cap_open_w);
3096
3097   /* Catch the "activate" signal on the text
3098      entries, so that if the user types Return there, we act as if the
3099      "OK" button had been selected, as happens if Return is typed if some
3100      widget that *doesn't* handle the Return key has the input focus. */
3101   /*dlg_set_activate(gtk_bin_get_child(GTK_BIN(if_cb)), ok_bt);*/
3102   dlg_set_activate(file_te, ok_bt);
3103
3104   g_signal_connect(cap_open_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
3105   g_signal_connect(cap_open_w, "destroy", G_CALLBACK(capture_prep_destroy_cb), NULL);
3106
3107   gtk_widget_show_all(cap_open_w);
3108   window_present(cap_open_w);
3109
3110   cap_open_complete = TRUE;   /* "Capture:Start" is now OK */
3111 }
3112
3113 /* everythings prepared, now it's really time to start the capture */
3114 void
3115 capture_start_confirmed(void)
3116 {
3117   interface_options interface_opts;
3118   guint i;
3119
3120   /* did the user ever select a capture interface before? */
3121   if(global_capture_opts.ifaces->len == 0 && prefs.capture_device == NULL) {
3122     simple_dialog(ESD_TYPE_CONFIRMATION,
3123                   ESD_BTN_OK,
3124                   "%sNo capture interface selected!%s\n\n"
3125                   "To select an interface use:\n\n"
3126                   "Capture->Options (until Wireshark is stopped)\n"
3127                   "Edit->Preferences/Capture (permanent, if saved)",
3128                   simple_dialog_primary_start(), simple_dialog_primary_end());
3129     return;
3130   }
3131
3132   /* XXX - we might need to init other pref data as well... */
3133   menu_auto_scroll_live_changed(auto_scroll_live);
3134
3135   if (capture_start(&global_capture_opts)) {
3136     /* The capture succeeded, which means the capture filter syntax is
3137        valid; add this capture filter to the recent capture filter list. */
3138     for (i = 0; i < global_capture_opts.ifaces->len; i++) {
3139       interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
3140       if (interface_opts.cfilter) {
3141         cfilter_combo_add_recent(interface_opts.cfilter);
3142       }
3143     }
3144   }
3145 }
3146
3147 /* user confirmed the "Save capture file..." dialog */
3148 static void
3149 capture_start_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
3150 {
3151   switch(btn) {
3152   case(ESD_BTN_SAVE):
3153     /* save file first */
3154     file_save_as_cmd(after_save_capture_dialog, data);
3155     break;
3156   case(ESD_BTN_DONT_SAVE):
3157     /* XXX - unlink old file? */
3158     /* start the capture */
3159     capture_start_confirmed();
3160     break;
3161   case(ESD_BTN_CANCEL):
3162     break;
3163   default:
3164     g_assert_not_reached();
3165   }
3166 }
3167
3168 /* user pressed the "Start" button (in dialog or toolbar) */
3169 void
3170 capture_start_cb(GtkWidget *w _U_, gpointer d _U_)
3171 {
3172   gpointer  dialog;
3173   gchar *if_name;
3174   cap_settings_t *cap_settings_p = NULL;
3175   interface_options interface_opts;
3176   guint i;
3177
3178 #ifdef HAVE_AIRPCAP
3179   airpcap_if_active = airpcap_if_selected;
3180   airpcap_set_toolbar_start_capture(airpcap_if_active);
3181 #endif
3182
3183 #ifdef _WIN32
3184   /* Is WPcap loaded? */
3185   if (!has_wpcap) {
3186     char * err_msg = cant_load_winpcap_err("Wireshark");
3187
3188     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, err_msg);
3189     g_free(err_msg);
3190     return;
3191   }
3192 #endif
3193
3194   if (cap_open_w) {
3195     /*
3196      * There's an options dialog; get the values from it and close it.
3197      */
3198     gboolean success;
3199
3200     /* Determine if "capture start" while building of the "capture options" window */
3201     /*  is in progress. If so, ignore the "capture start.                          */
3202     /* XXX: Would it be better/cleaner for the "capture options" window code to    */
3203     /*      disable the capture start button temporarily ?                         */
3204     if (cap_open_complete == FALSE) {
3205       return;  /* Building options window: ignore "capture start" */
3206     }
3207     success = capture_dlg_prep(cap_open_w);
3208     window_destroy(GTK_WIDGET(cap_open_w));
3209     if (!success)
3210       return;   /* error in options dialog */
3211   }
3212
3213   if (global_capture_opts.ifaces->len == 0) {
3214     if (prefs.capture_device == NULL) {
3215       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3216         "You didn't specify an interface on which to capture packets.");
3217       return;
3218     }
3219     interface_opts.name = g_strdup(get_if_name(prefs.capture_device));
3220     interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
3221 #ifdef HAVE_PCAP_CREATE
3222     interface_opts.monitor_mode = prefs_capture_device_monitor_mode(interface_opts.name);
3223 #else
3224     interface_opts.monitor_mode = FALSE;
3225 #endif
3226     interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name);
3227     interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
3228     interface_opts.snaplen = global_capture_opts.default_options.snaplen;
3229     interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen;
3230     interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode;
3231 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
3232     interface_opts.buffer_size =  global_capture_opts.default_options.buffer_size;
3233 #endif
3234 #ifdef HAVE_PCAP_REMOTE
3235     interface_opts.src_type = global_capture_opts.default_options.src_type;
3236     interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
3237     interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
3238     interface_opts.auth_type = global_capture_opts.default_options.auth_type;
3239     interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
3240     interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
3241     interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
3242     interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
3243     interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
3244  #endif
3245  #ifdef HAVE_PCAP_SETSAMPLING
3246     interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
3247     interface_opts.sampling_param  = global_capture_opts.default_options.sampling_param;
3248  #endif
3249     g_array_insert_val(global_capture_opts.ifaces, 0, interface_opts);
3250   }
3251
3252   if (cap_settings_history != NULL) {
3253     for (i = 0; i < global_capture_opts.ifaces->len; i++) {
3254       interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
3255       if_name = g_strdup(interface_opts.name);
3256       cap_settings_p = g_hash_table_lookup(cap_settings_history, if_name);
3257       if (cap_settings_p == NULL) {
3258         cap_settings_p = g_malloc(sizeof (cap_settings_t));
3259         g_hash_table_insert(cap_settings_history, if_name, cap_settings_p);
3260       } else {
3261         g_free(if_name);
3262       }
3263       cap_settings_p->monitor_mode = interface_opts.monitor_mode;
3264       cap_settings_p->linktype = interface_opts.linktype;
3265     }
3266   }
3267
3268   if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
3269     /* user didn't saved his current file, ask him */
3270     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
3271                 "%sSave capture file before starting a new capture?%s\n\n"
3272                 "If you start a new capture without saving, your current capture data will\nbe discarded.",
3273                 simple_dialog_primary_start(), simple_dialog_primary_end());
3274     simple_dialog_set_cb(dialog, capture_start_answered_cb, NULL);
3275   } else {
3276     /* unchanged file, just capture a new one */
3277     capture_start_confirmed();
3278   }
3279 }
3280
3281
3282 /* user change linktype selection;, convert to internal DLT value */
3283 static void
3284 select_link_type_cb(GtkWidget *linktype_combo_box, gpointer data _U_)
3285 {
3286   gpointer  ptr;
3287   int       dlt;
3288   interface_row row;
3289
3290   row = g_array_index(rows, interface_row, marked_row);
3291   rows = g_array_remove_index(rows, marked_row);
3292   if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(linktype_combo_box), &ptr)) {
3293     g_assert_not_reached();  /* Programming error: somehow nothing is active */
3294   }
3295   if ((dlt = GPOINTER_TO_INT(ptr)) == -1) {
3296     g_assert_not_reached();  /* Programming error: somehow managed to select an "unsupported" entry */
3297   }
3298   row.active_dlt = dlt;
3299   g_array_insert_val(rows, marked_row, row);
3300   capture_filter_check_syntax_cb(linktype_combo_box, data);
3301 }
3302
3303 /* user pressed "File" button */
3304 static void
3305 capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te)
3306 {
3307   file_selection_browse(file_bt, file_te, "Wireshark: Specify a Capture File", FILE_SELECTION_WRITE_BROWSE);
3308 }
3309
3310
3311 /* convert dialog settings into capture_opts values */
3312 static gboolean
3313 capture_dlg_prep(gpointer parent_w) {
3314   GtkWidget *pcap_ng_cb,
3315             *file_te, *multi_files_on_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_cb,
3316             *sync_cb, *auto_scroll_cb, *hide_info_cb,
3317             *stop_packets_cb, *stop_packets_sb,
3318             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_cbx,
3319             *stop_duration_cb, *stop_duration_sb, *stop_duration_cbx,
3320             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_cbx,
3321             *file_duration_cb, *file_duration_sb, *file_duration_cbx,
3322             *stop_files_cb, *stop_files_sb,
3323             *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
3324   const gchar *g_save_file;
3325   gchar *cf_name;
3326   gchar *dirname;
3327   gint32 tmp;
3328
3329   pcap_ng_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_PCAP_NG_KEY);
3330   file_te    = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_TE_KEY);
3331   multi_files_on_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_MULTI_FILES_ON_CB_KEY);
3332   ringbuffer_nbf_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_CB_KEY);
3333   ringbuffer_nbf_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
3334   ring_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CB_KEY);
3335   ring_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_SB_KEY);
3336   ring_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CBX_KEY);
3337   file_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CB_KEY);
3338   file_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_SB_KEY);
3339   file_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CBX_KEY);
3340   sync_cb   = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SYNC_KEY);
3341   auto_scroll_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
3342   hide_info_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_HIDE_INFO_KEY);
3343   stop_packets_cb   = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_CB_KEY);
3344   stop_packets_sb   = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_SB_KEY);
3345   stop_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CB_KEY);
3346   stop_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_SB_KEY);
3347   stop_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CBX_KEY);
3348   stop_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CB_KEY);
3349   stop_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_SB_KEY);
3350   stop_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CBX_KEY);
3351   stop_files_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_CB_KEY);
3352   stop_files_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_SB_KEY);
3353   m_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_M_RESOLVE_KEY);
3354   n_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY);
3355   t_resolv_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY);
3356
3357   if (global_capture_opts.ifaces->len == 0) {
3358     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3359       "You didn't specify an interface on which to capture packets.");
3360     return FALSE;
3361   }
3362   global_capture_opts.use_pcapng =
3363     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pcap_ng_cb));
3364   /* Wireshark always saves to a capture file. */
3365   global_capture_opts.saving_to_file = TRUE;
3366   g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
3367   if (g_save_file && g_save_file[0]) {
3368     /* User specified a file to which the capture should be written. */
3369     global_capture_opts.save_file = g_strdup(g_save_file);
3370     /* Save the directory name for future file dialogs. */
3371     cf_name = g_strdup(g_save_file);
3372     dirname = get_dirname(cf_name);  /* Overwrites cf_name */
3373     set_last_open_dir(dirname);
3374     g_free(cf_name);
3375   } else {
3376     /* User didn't specify a file; save to a temporary file. */
3377     global_capture_opts.save_file = NULL;
3378   }
3379
3380   global_capture_opts.has_autostop_packets =
3381     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb));
3382   if (global_capture_opts.has_autostop_packets)
3383     global_capture_opts.autostop_packets =
3384       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_packets_sb));
3385
3386   global_capture_opts.has_autostop_duration =
3387     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb));
3388   if (global_capture_opts.has_autostop_duration) {
3389     global_capture_opts.autostop_duration =
3390       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_duration_sb));
3391     global_capture_opts.autostop_duration =
3392       time_unit_combo_box_get_value(stop_duration_cbx, global_capture_opts.autostop_duration);
3393   }
3394
3395   global_capture_opts.real_time_mode =
3396     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
3397
3398   auto_scroll_live =
3399       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
3400
3401   global_capture_opts.show_info =
3402       !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hide_info_cb));
3403
3404   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
3405     gbl_resolv_flags |= RESOLV_MAC;
3406   else
3407     gbl_resolv_flags &= ~RESOLV_MAC;
3408   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
3409     gbl_resolv_flags |= RESOLV_NETWORK;
3410   else
3411     gbl_resolv_flags &= ~RESOLV_NETWORK;
3412   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
3413     gbl_resolv_flags |= RESOLV_TRANSPORT;
3414   else
3415     gbl_resolv_flags &= ~RESOLV_TRANSPORT;
3416
3417   global_capture_opts.has_ring_num_files =
3418     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb));
3419
3420   global_capture_opts.ring_num_files =
3421     gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
3422   if (global_capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES)
3423     global_capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES;
3424 #if RINGBUFFER_MIN_NUM_FILES > 0
3425   else if (global_capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES)
3426     global_capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES;
3427 #endif
3428
3429   global_capture_opts.multi_files_on =
3430     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb));
3431
3432   global_capture_opts.has_file_duration =
3433     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb));
3434   if (global_capture_opts.has_file_duration) {
3435     global_capture_opts.file_duration =
3436       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(file_duration_sb));
3437     global_capture_opts.file_duration =
3438       time_unit_combo_box_get_value(file_duration_cbx, global_capture_opts.file_duration);
3439   }
3440
3441   global_capture_opts.has_autostop_files =
3442     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb));
3443   if (global_capture_opts.has_autostop_files)
3444     global_capture_opts.autostop_files =
3445       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_files_sb));
3446
3447   if (global_capture_opts.multi_files_on) {
3448     global_capture_opts.has_autostop_filesize =
3449       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb));
3450     if (global_capture_opts.has_autostop_filesize) {
3451       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_filesize_sb));
3452       tmp = size_unit_combo_box_convert_value(ring_filesize_cbx, tmp);
3453       if(tmp != 0) {
3454         global_capture_opts.autostop_filesize = tmp;
3455       } else {
3456         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3457           "%sMultiple files: Requested filesize too large!%s\n\n"
3458           "The setting \"Next file every x byte(s)\" can't be greater than %u bytes (2GB).",
3459           simple_dialog_primary_start(), simple_dialog_primary_end(), G_MAXINT);
3460         return FALSE;
3461       }
3462     }
3463
3464     /* test if the settings are ok for a ringbuffer */
3465     if (global_capture_opts.save_file == NULL) {
3466       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3467         "%sMultiple files: No capture file name given!%s\n\n"
3468         "You must specify a filename if you want to use multiple files.",
3469         simple_dialog_primary_start(), simple_dialog_primary_end());
3470       return FALSE;
3471     } else if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
3472       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3473         "%sMultiple files: No file limit given!%s\n\n"
3474         "You must specify a file size or duration at which is switched to the next capture file\n"
3475         "if you want to use multiple files.",
3476         simple_dialog_primary_start(), simple_dialog_primary_end());
3477       g_free(global_capture_opts.save_file);
3478       global_capture_opts.save_file = NULL;
3479       return FALSE;
3480     }
3481   } else {
3482     global_capture_opts.has_autostop_filesize =
3483       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb));
3484     if (global_capture_opts.has_autostop_filesize) {
3485       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_filesize_sb));
3486       tmp = size_unit_combo_box_convert_value(stop_filesize_cbx, tmp);
3487       if(tmp != 0) {
3488         global_capture_opts.autostop_filesize = tmp;
3489       } else {
3490         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3491           "%sStop Capture: Requested filesize too large!%s\n\n"
3492           "The setting \"... after x byte(s)\" can't be greater than %u bytes (2GB).",
3493           simple_dialog_primary_start(), simple_dialog_primary_end(), G_MAXINT);
3494         return FALSE;
3495       }
3496     }
3497   } /* multi_files_on */
3498   return TRUE;
3499 }
3500
3501 GtkTreeModel *create_and_fill_model(GList *if_list, gboolean do_hide, GtkTreeView *view)
3502 {
3503   GtkListStore *store;
3504   GtkTreeIter iter;
3505   GList *if_entry, *list;
3506   if_info_t *if_info;
3507   char *if_string="", *temp="", *snaplen_string;
3508   gchar *descr;
3509   if_capabilities_t *caps=NULL;
3510   gint linktype_count;
3511   cap_settings_t cap_settings;
3512   GSList *curr_addr;
3513   int ips = 0;
3514   guint i, j;
3515   if_addr_t *addr;
3516   GList *lt_entry;
3517   link_row *link = NULL;
3518   data_link_info_t *data_link_info;
3519   gchar *str, *link_type_name = NULL;
3520   interface_row row;
3521   interface_options interface_opts;
3522   gboolean found = FALSE;
3523   GString *ip_str;
3524
3525 #if defined(HAVE_PCAP_CREATE)
3526   store = gtk_list_store_new (8, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
3527 #elif defined(_WIN32) && !defined (HAVE_PCAP_CREATE)
3528   store = gtk_list_store_new (7, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
3529 #else
3530   store = gtk_list_store_new (6, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
3531 #endif
3532
3533   if (rows && rows->len > 0) {
3534     for (i = 0; i < rows->len; i++) {
3535       row = g_array_index(rows, interface_row, i);
3536       found = FALSE;
3537       for (j = 0; j < global_capture_opts.ifaces->len; j++) {
3538         interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, j);
3539         if (!interface_opts.name || strcmp(interface_opts.name, (char*)row.name)!=0) {
3540           continue;
3541         } else {
3542           found = TRUE;
3543           num_selected++;
3544           break;
3545         }
3546       }
3547       if (row.no_addresses == 0) {
3548         temp = g_strdup_printf("<b>%s</b>", row.display_name);
3549       } else {
3550         temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", row.display_name, row.addresses);
3551       }
3552       for (list = row.links; list != NULL; list = g_list_next(list)) {
3553         link = (link_row*)(list->data);
3554         if (link->dlt == row.active_dlt) {
3555           break;
3556         }
3557       }
3558       if (row.has_snaplen) {
3559         snaplen_string = g_strdup_printf("%d", row.snaplen);
3560       } else {
3561         snaplen_string = g_strdup("default");
3562       }
3563       gtk_list_store_append (store, &iter);
3564 #if defined(HAVE_PCAP_CREATE)
3565       gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, MONITOR, row.monitor_mode_supported?(row.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, row.cfilter, -1);
3566 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
3567       gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, FILTER, row.cfilter, -1);
3568 #else
3569       gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link->name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, row.cfilter, -1);
3570 #endif
3571     }
3572   } else {
3573     rows = g_array_new(TRUE, TRUE, sizeof(interface_row));
3574     /* Scan through the list and build a list of strings to display. */
3575     for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
3576       if_info = if_entry->data;
3577       ip_str = g_string_new("");
3578       str = "";
3579       ips = 0;
3580       row.name = g_strdup(if_info->name);
3581       /* Is this interface hidden and, if so, should we include it anyway? */
3582       if (!prefs_is_capture_device_hidden(if_info->name) || !do_hide) {
3583         /* It's not hidden, or it is but we should include it in the list. */
3584         /* Do we have a user-supplied description? */
3585         descr = capture_dev_user_descr_find(if_info->name);
3586         if (descr != NULL) {
3587           /* Yes, we have a user-supplied description; use it. */
3588           if_string = g_strdup_printf("%s: %s", descr, if_info->name);
3589           g_free(descr);
3590         } else {
3591           /* No, we don't have a user-supplied description; did we get
3592              one from the OS or libpcap? */
3593           if (if_info->description != NULL) {
3594             /* Yes - use it. */
3595             if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
3596           } else {
3597             /* No. */
3598             if_string = g_strdup(if_info->name);
3599           }
3600         }
3601         if (if_info->loopback) {
3602           row.display_name = g_strdup_printf("%s (loopback)", if_string);
3603         } else {
3604           row.display_name = g_strdup(if_string);
3605         }
3606         found = FALSE;
3607         for (i = 0; i < global_capture_opts.ifaces->len; i++) {
3608           interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
3609           if (!interface_opts.name || strcmp(interface_opts.name, (char*)row.name)!=0) {
3610             continue;
3611           } else {
3612             found = TRUE;
3613             num_selected++;
3614             break;
3615           }
3616         }
3617         if (found) {
3618 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
3619           row.buffer = interface_opts.buffer_size;
3620 #endif
3621           row.pmode = interface_opts.promisc_mode;
3622           row.has_snaplen = interface_opts.has_snaplen;
3623           row.snaplen = interface_opts.snaplen;
3624           row.cfilter = g_strdup(interface_opts.cfilter);
3625         } else {
3626 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
3627           row.buffer = global_capture_opts.default_options.buffer_size;
3628 #endif
3629           row.pmode = global_capture_opts.default_options.promisc_mode;
3630           row.has_snaplen = global_capture_opts.default_options.has_snaplen;
3631           row.snaplen = global_capture_opts.default_options.snaplen;
3632           row.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
3633         }
3634         cap_settings = capture_get_cap_settings(if_info->name);
3635         gtk_list_store_append (store, &iter);
3636         caps = capture_get_if_capabilities(if_info->name, cap_settings.monitor_mode, NULL);
3637         for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
3638           if (ips != 0) {
3639             g_string_append(ip_str, "\n");
3640           }
3641           addr = (if_addr_t *)curr_addr->data;
3642           switch (addr->ifat_type) {
3643             case IF_AT_IPv4:
3644               g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
3645               break;
3646             case IF_AT_IPv6:
3647               g_string_append(ip_str,  ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
3648               break;
3649             default:
3650               /* In case we add non-IP addresses */
3651               break;
3652           }
3653         }
3654         linktype_count = 0;
3655         row.links = NULL;
3656         if (caps != NULL) {
3657 #ifdef HAVE_PCAP_CREATE
3658           row.monitor_mode_enabled = cap_settings.monitor_mode;
3659           row.monitor_mode_supported = caps->can_set_rfmon;
3660 #endif
3661           for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
3662             data_link_info = lt_entry->data;
3663             if (data_link_info->description != NULL) {
3664               str = g_strdup_printf("%s", data_link_info->description);
3665             } else {
3666               str = g_strdup_printf("%s (not supported)", data_link_info->name);
3667             }
3668             if (linktype_count == 0) {
3669               link_type_name = g_strdup(str);
3670               row.active_dlt = data_link_info->dlt;
3671             }
3672             link = (link_row *)g_malloc(sizeof(link_row));
3673             link->dlt = data_link_info->dlt;
3674             link->name = g_strdup(str);
3675             row.links = g_list_append(row.links, link);
3676             linktype_count++;
3677           }
3678         } else {
3679           cap_settings.monitor_mode = FALSE;
3680 #ifdef HAVE_PCAP_CREATE
3681           row.monitor_mode_enabled = FALSE;
3682           row.monitor_mode_supported = FALSE;
3683 #endif
3684           row.active_dlt = -1;
3685           link_type_name = g_strdup("default");
3686         }
3687         row.addresses = g_strdup(ip_str->str);
3688         row.no_addresses = ips;
3689         if (ips == 0) {
3690           temp = g_strdup_printf("<b>%s</b>", row.display_name);
3691         } else {
3692           temp = g_strdup_printf("<b>%s</b>\n<span size='small'>%s</span>", row.display_name, row.addresses);
3693         }
3694         g_array_append_val(rows, row);
3695         if (row.has_snaplen) {
3696           snaplen_string = g_strdup_printf("%d", row.snaplen);
3697         } else {
3698           snaplen_string = g_strdup("default");
3699         }
3700 #if defined(HAVE_PCAP_CREATE)
3701         gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link_type_name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, MONITOR, row.monitor_mode_supported?(row.monitor_mode_enabled?"enabled":"disabled"):"n/a", FILTER, row.cfilter, -1);
3702 #elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
3703         gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link_type_name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, BUFFER, (guint) row.buffer, FILTER, row.cfilter, -1);
3704 #else
3705         gtk_list_store_set (store, &iter, CAPTURE, found, INTERFACE, temp, LINK, link_type_name,  PMODE, row.pmode?"enabled":"disabled", SNAPLEN, snaplen_string, FILTER, row.cfilter, -1);
3706 #endif
3707         if (caps != NULL) {
3708           free_if_capabilities(caps);
3709         }
3710       }
3711       g_string_free(ip_str, TRUE);
3712     }
3713   }
3714   gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
3715   return GTK_TREE_MODEL(store);
3716 }
3717
3718 gboolean query_tooltip_tree_view_cb (GtkWidget  *widget,
3719                                      gint        x,
3720                                      gint        y,
3721                                      gboolean    keyboard_tip,
3722                                      GtkTooltip *tooltip,
3723                                      gpointer    data _U_)
3724 {
3725   GtkTreeIter iter;
3726   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
3727   GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
3728   GtkTreePath *path = NULL;
3729   gchar *tmp;
3730   gchar *pathstring;
3731   GtkTreeViewColumn *column;
3732   int col;
3733   GtkCellRenderer* renderer=NULL;
3734   GList *renderer_list;
3735
3736   char buffer[512];
3737
3738    if (!gtk_tree_view_get_tooltip_context (tree_view, &x, &y, keyboard_tip, &model, &path, &iter))
3739     return FALSE;
3740
3741   gtk_tree_model_get (model, &iter, 0, &tmp, -1);
3742   pathstring = gtk_tree_path_to_string (path);
3743
3744   if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tree_view), (gint) x, (gint) y, NULL, &column, NULL, NULL)) {
3745     for (col = 0; col < NUM_COLUMNS; col++) {
3746       if (gtk_tree_view_get_column(tree_view, col) == column)
3747         break;
3748     }
3749     switch (col)
3750     {
3751       case 0: g_snprintf (buffer, 511, "Choose which interface (network adapter) will be used to capture packets from. "
3752                 "Be sure to select the correct one, as it's a common mistake to select the wrong interface.");
3753               break;
3754       case 1: g_snprintf (buffer, 511, "Lists the interface name and the IP address(es) assigned to it. ");
3755               break;
3756       case 2: g_snprintf (buffer, 511, "Link-layer type the interface supports.");
3757               break;
3758       case 3: g_snprintf (buffer, 511, "Usually a network adapter will only capture the traffic sent to its own network address. "
3759                 "If you want to capture all traffic that the network adapter can \"see\", promiscuous mode should be configured.");
3760               break;
3761       case 4: g_snprintf(buffer, 511, "Limit the maximum number of bytes to be captured from each packet. This size includes the "
3762                 "link-layer header and all subsequent headers. ");
3763               break;
3764       case 5: g_snprintf (buffer, 511, "The memory buffer size used while capturing."
3765                 "If you notice packet drops, you can try to increase this size.");
3766               break;
3767       case 6: g_snprintf (buffer, 511, "Usually a Wi-Fi adapter will, even in promiscuous mode, only capture "
3768                 "the traffic on the BSS to which it's associated. "
3769                 "If you want to capture all traffic that the Wi-Fi adapter can \"receive\", mark this option."
3770                 "In order to see IEEE 802.11 headers or to see radio information for captured packets,"
3771                 "it might be necessary to turn this option on.\n\n"
3772                 "Note that, in monitor mode, the adapter might disassociate from the network to which it's associated. mode");
3773               break;
3774       case 7: g_snprintf(buffer, 511, "Selected capture filter to reduce the amount of packets to be captured.");
3775               break;
3776       default: g_snprintf(buffer, 511, "another option");
3777     }
3778
3779     gtk_tooltip_set_markup (tooltip, buffer);
3780     renderer_list = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
3781     /* get the first renderer */
3782     if (g_list_first(renderer_list)) {
3783       renderer = (GtkCellRenderer*)g_list_nth_data(renderer_list, 0);
3784       gtk_tree_view_set_tooltip_cell (tree_view, tooltip, path, column, renderer);
3785     }
3786   }
3787   gtk_tree_path_free (path);
3788   g_free (pathstring);
3789
3790   return TRUE;
3791 }
3792
3793 #if defined (HAVE_PCAP_CREATE)
3794 void activate_monitor (GtkTreeViewColumn *tree_column _U_, GtkCellRenderer *renderer,
3795                               GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data _U_)
3796 {
3797   interface_row row;
3798   GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter);
3799   int index = atoi(gtk_tree_path_to_string(path));
3800
3801   row = g_array_index(rows, interface_row, index);
3802
3803   if (row.monitor_mode_supported==TRUE) {
3804     g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
3805   } else {
3806     g_object_set(G_OBJECT(renderer), "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
3807   }
3808 }
3809 #endif
3810
3811 /* user requested to destroy the dialog */
3812 static void
3813 capture_prep_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
3814 {
3815   GtkWidget *fs;
3816 #ifdef HAVE_PCAP_REMOTE
3817   GList     *if_list;
3818   GtkWidget *remote_w;
3819 #endif
3820
3821   /* Is there a file selection dialog associated with this
3822      Capture Options dialog? */
3823   fs = g_object_get_data(G_OBJECT(cap_open_w), E_FILE_SEL_DIALOG_PTR_KEY);
3824
3825 #ifdef HAVE_PCAP_REMOTE
3826   if_list = (GList *) g_object_get_data(G_OBJECT(cap_open_w), E_CAP_IF_LIST_KEY);
3827   if (if_list && g_list_length(if_list)>0) {
3828       free_interface_list(if_list);
3829   }
3830 #endif
3831
3832   if (fs != NULL) {
3833     /* Yes.  Destroy it. */
3834     window_destroy(fs);
3835   }
3836
3837   /* Note that we no longer have a "Capture Options" dialog box. */
3838   cap_open_w = NULL;
3839
3840 #ifdef HAVE_AIRPCAP
3841   /* update airpcap toolbar */
3842   airpcap_set_toolbar_stop_capture(airpcap_if_active);
3843 #endif
3844
3845 #ifdef HAVE_PCAP_REMOTE
3846   remote_w = g_object_get_data(G_OBJECT(win), E_CAP_REMOTE_DIALOG_PTR_KEY);
3847   if (remote_w != NULL)
3848       window_destroy(remote_w);
3849 #endif
3850 }
3851
3852
3853 #ifdef HAVE_PCAP_CREATE
3854 /* user changed the setting of the monitor-mode checkbox */
3855 static void
3856 capture_prep_monitor_changed_cb(GtkWidget *monitor, gpointer argp _U_)
3857 {
3858   GList *lt_entry;
3859   gchar *if_string="";
3860   cap_settings_t cap_settings;
3861   if_capabilities_t *caps=NULL;
3862   gint linktype_count = 0, i;
3863   data_link_info_t *data_link_info;
3864   interface_row row;
3865   link_row *link;
3866   GtkWidget *linktype_combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(opt_edit_w), E_CAP_LT_CBX_KEY);
3867   GtkWidget *linktype_lb = g_object_get_data(G_OBJECT(linktype_combo_box), E_CAP_LT_CBX_LABEL_KEY);
3868
3869   row = g_array_index(rows, interface_row, marked_row);
3870   rows = g_array_remove_index(rows, marked_row);
3871
3872
3873   if_string = g_strdup(row.name);
3874   cap_settings = capture_get_cap_settings(if_string);
3875   cap_settings.monitor_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(monitor));
3876   caps = capture_get_if_capabilities(if_string, cap_settings.monitor_mode, NULL);
3877
3878   if (caps != NULL) {
3879     g_signal_handlers_disconnect_by_func(linktype_combo_box, G_CALLBACK(select_link_type_cb), NULL );
3880     ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box));
3881     for (i = (gint)g_list_length(row.links)-1; i >= 0; i--) {
3882       GList* rem = g_list_nth(row.links, i);
3883       row.links = g_list_remove_link(row.links, rem);
3884       g_list_free_1(rem);
3885     }
3886     row.active_dlt = -1;
3887     linktype_count = 0;
3888     row.monitor_mode_supported = caps->can_set_rfmon;
3889     row.monitor_mode_enabled = cap_settings.monitor_mode;
3890     for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
3891       link = (link_row *)g_malloc(sizeof(link_row));
3892       data_link_info = lt_entry->data;
3893       if (data_link_info->description != NULL) {
3894         ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(linktype_combo_box),
3895                                              data_link_info->description,
3896                                              GINT_TO_POINTER(data_link_info->dlt));
3897         link->dlt = data_link_info->dlt;
3898         if (linktype_count == 0) {
3899           row.active_dlt = data_link_info->dlt;
3900         }
3901         link->name = g_strdup(data_link_info->description);
3902       } else {
3903         gchar *str;
3904         /* Not supported - tell them about it but don't let them select it. */
3905         str = g_strdup_printf("%s (not supported)", data_link_info->name);
3906         ws_combo_box_append_text_and_pointer_full(GTK_COMBO_BOX(linktype_combo_box),
3907                                                   NULL,
3908                                                   str,
3909                                                   GINT_TO_POINTER(-1),  /* Flag as "not supported" */
3910                                                   FALSE);
3911         link->dlt = -1;
3912         link->name = g_strdup(str);
3913         g_free(str);
3914       }
3915       row.links = g_list_append(row.links, link);
3916       linktype_count++;
3917     }
3918     free_if_capabilities(caps);
3919   } else {
3920     /* We don't know whether this supports monitor mode or not;
3921     don't ask for monitor mode. */
3922     cap_settings.monitor_mode = FALSE;
3923     row.monitor_mode_enabled = FALSE;
3924     row.monitor_mode_supported = FALSE;
3925   }
3926   gtk_widget_set_sensitive(linktype_lb, linktype_count >= 2);
3927   gtk_widget_set_sensitive(linktype_combo_box, linktype_count >= 2);
3928   ws_combo_box_set_active(GTK_COMBO_BOX(linktype_combo_box),0);
3929   g_array_insert_val(rows, marked_row, row);
3930 }
3931 #endif
3932
3933 /*
3934  * Adjust the sensitivity of various widgets as per the current setting
3935  * of other widgets.
3936  */
3937 static void
3938 capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
3939 {
3940   GtkWidget *multi_files_on_cb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
3941             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_cbx,
3942             *file_duration_cb, *file_duration_sb, *file_duration_cbx,
3943             *sync_cb, *auto_scroll_cb,
3944             *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
3945             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_cbx,
3946             *stop_duration_cb, *stop_duration_sb, *stop_duration_cbx,
3947             *stop_files_cb, *stop_files_sb, *stop_files_lb;
3948
3949   multi_files_on_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_MULTI_FILES_ON_CB_KEY);
3950   ringbuffer_nbf_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_CB_KEY);
3951   ringbuffer_nbf_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
3952   ringbuffer_nbf_lb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_NBF_LB_KEY);
3953   ring_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CB_KEY);
3954   ring_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_SB_KEY);
3955   ring_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_RING_FILESIZE_CBX_KEY);
3956   file_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CB_KEY);
3957   file_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_SB_KEY);
3958   file_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_FILE_DURATION_CBX_KEY);
3959   sync_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_SYNC_KEY);
3960   auto_scroll_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
3961   stop_packets_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_CB_KEY);
3962   stop_packets_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_SB_KEY);
3963   stop_packets_lb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_PACKETS_LB_KEY);
3964   stop_filesize_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CB_KEY);
3965   stop_filesize_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_SB_KEY);
3966   stop_filesize_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILESIZE_CBX_KEY);
3967   stop_duration_cb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CB_KEY);
3968   stop_duration_sb  = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_SB_KEY);
3969   stop_duration_cbx = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_DURATION_CBX_KEY);
3970   stop_files_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_CB_KEY);
3971   stop_files_sb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_SB_KEY);
3972   stop_files_lb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CAP_STOP_FILES_LB_KEY);
3973
3974   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
3975     /* "Update list of packets in real time" captures enabled; we don't
3976        support ring buffer mode for those captures, so turn ring buffer
3977        mode off if it's on, and make its toggle button, and the spin
3978        button for the number of ring buffer files (and the spin button's
3979        label), insensitive. */
3980 #if 0
3981     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(multi_files_on_cb), FALSE);
3982     gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), FALSE);
3983 #endif
3984
3985     /* Auto-scroll mode is meaningful only in "Update list of packets
3986        in real time" captures, so make its toggle button sensitive. */
3987     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
3988
3989     /*gtk_widget_set_sensitive(GTK_WIDGET(hide_info_cb), TRUE);*/
3990   } else {
3991     /* "Update list of packets in real time" captures disabled; that
3992        means ring buffer mode is OK, so make its toggle button
3993        sensitive. */
3994 /*    gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), TRUE);*/
3995
3996     /* Auto-scroll mode is meaningful only in "Update list of packets
3997        in real time" captures, so make its toggle button insensitive. */
3998     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
3999
4000     /*gtk_widget_set_sensitive(GTK_WIDGET(hide_info_cb), FALSE);*/
4001   }
4002
4003   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb))) {
4004     /* Ring buffer mode enabled. */
4005
4006     /* Force at least one of the "file switch" conditions (we need at least one) */
4007     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)) == FALSE &&
4008         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)) == FALSE) {
4009       if (tb == ring_filesize_cb)
4010         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(file_duration_cb), TRUE);
4011       else
4012         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb), TRUE);
4013     }
4014
4015     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), TRUE);
4016     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb),
4017           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
4018     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb),
4019           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
4020
4021     /* The ring filesize spinbox is sensitive if the "Next capture file
4022          after N kilobytes" checkbox is on. */
4023     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), TRUE);
4024     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),
4025           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
4026     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cbx),
4027           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
4028
4029     /* The ring duration spinbox is sensitive if the "Next capture file
4030          after N seconds" checkbox is on. */
4031     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), TRUE);
4032     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),
4033           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
4034     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cbx),
4035           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
4036
4037     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), FALSE);
4038     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb), FALSE);
4039     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cbx), FALSE);
4040
4041     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), TRUE);
4042     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb),
4043           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
4044     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb),
4045           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
4046   } else {
4047     /* Ring buffer mode disabled. */
4048     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), FALSE);
4049     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
4050     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
4051
4052     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), FALSE);
4053     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),FALSE);
4054     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cbx),FALSE);
4055
4056     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), FALSE);
4057     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),FALSE);
4058     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cbx),FALSE);
4059
4060     /* The maximum file size spinbox is sensitive if the "Stop capture
4061          after N kilobytes" checkbox is on. */
4062     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), TRUE);
4063     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb),
4064           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
4065     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cbx),
4066           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
4067
4068     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), FALSE);
4069     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb), FALSE);
4070     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb), FALSE);
4071   }
4072
4073   /* The maximum packet count spinbox is sensitive if the "Stop capture
4074      after N packets" checkbox is on. */
4075   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_sb),
4076       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
4077   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_lb),
4078       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
4079
4080   /* The capture duration spinbox is sensitive if the "Stop capture
4081      after N seconds" checkbox is on. */
4082   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_sb),
4083       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
4084   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_cbx),