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