ask for unsaved file when using the new start capture feature,
[obnox/wireshark/wip.git] / gtk / capture_dlg.c
1 /* capture_dlg.c
2  * Routines for packet capture windows
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
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 #include <pcap.h>
32 #include <string.h>
33 #include <gtk/gtk.h>
34
35 #include <epan/packet.h>
36 #include "capture.h"
37 #include "globals.h"
38 #include <epan/addr_resolv.h>
39 #include "main.h"
40 #include "ui_util.h"
41 #include "capture.h"
42 #include "capture_dlg.h"
43 #include "filter_dlg.h"
44 #include "simple_dialog.h"
45 #include "dlg_utils.h"
46 #include "pcap-util.h"
47 #include "capture_ui_utils.h"
48 #include <epan/prefs.h>
49 #include "ringbuffer.h"
50 #include <epan/filesystem.h>
51 #include "compat_macros.h"
52 #include "file_dlg.h"
53 #include "help_dlg.h"
54 #include "gtkglobals.h"
55 #include "cfilter_combo_utils.h"
56
57 #ifdef _WIN32
58 #include "capture-wpcap.h"
59 #endif
60
61 /* Capture callback data keys */
62 #define E_CAP_IFACE_KEY             "cap_iface"
63 #define E_CAP_IFACE_IP_KEY          "cap_iface_ip"
64 #define E_CAP_SNAP_CB_KEY           "cap_snap_cb"
65 #define E_CAP_LT_OM_KEY             "cap_lt_om"
66 #define E_CAP_LT_OM_LABEL_KEY       "cap_lt_om_label"
67 #ifdef _WIN32
68 #define E_CAP_BUFFER_SIZE_SB_KEY    "cap_buffer_size_sb"
69 #endif
70 #define E_CAP_SNAP_SB_KEY           "cap_snap_sb"
71 #define E_CAP_PROMISC_KEY           "cap_promisc"
72 #define E_CAP_FILT_KEY              "cap_filter_te"
73 #define E_CAP_FILE_TE_KEY           "cap_file_te"
74 #define E_CAP_MULTI_FILES_ON_CB_KEY "cap_multi_files_on_cb"
75 #define E_CAP_RING_FILESIZE_CB_KEY  "cap_ring_filesize_cb"
76 #define E_CAP_RING_FILESIZE_SB_KEY  "cap_ring_filesize_sb"
77 #define E_CAP_RING_FILESIZE_OM_KEY  "cap_ring_filesize_om"
78 #define E_CAP_FILE_DURATION_CB_KEY  "cap_file_duration_cb"
79 #define E_CAP_FILE_DURATION_SB_KEY  "cap_file_duration_sb"
80 #define E_CAP_FILE_DURATION_OM_KEY  "cap_file_duration_om"
81 #define E_CAP_RING_NBF_CB_KEY       "cap_ring_nbf_cb"
82 #define E_CAP_RING_NBF_SB_KEY       "cap_ring_nbf_sb"
83 #define E_CAP_RING_NBF_LB_KEY       "cap_ring_nbf_lb"
84 #define E_CAP_STOP_FILES_CB_KEY     "cap_stop_files_cb"
85 #define E_CAP_STOP_FILES_SB_KEY     "cap_stop_files_sb"
86 #define E_CAP_STOP_FILES_LB_KEY     "cap_stop_files_lb"
87 #define E_CAP_SYNC_KEY              "cap_sync"
88 #define E_CAP_AUTO_SCROLL_KEY       "cap_auto_scroll"
89 #define E_CAP_HIDE_INFO_KEY         "cap_hide_info"
90 #define E_CAP_STOP_PACKETS_CB_KEY   "cap_stop_packets_cb"
91 #define E_CAP_STOP_PACKETS_SB_KEY   "cap_stop_packets_sb"
92 #define E_CAP_STOP_PACKETS_LB_KEY   "cap_stop_packets_lb"
93 #define E_CAP_STOP_FILESIZE_CB_KEY  "cap_stop_filesize_cb"
94 #define E_CAP_STOP_FILESIZE_SB_KEY  "cap_stop_filesize_sb"
95 #define E_CAP_STOP_FILESIZE_OM_KEY  "cap_stop_filesize_om"
96 #define E_CAP_STOP_DURATION_CB_KEY  "cap_stop_duration_cb"
97 #define E_CAP_STOP_DURATION_SB_KEY  "cap_stop_duration_sb"
98 #define E_CAP_STOP_DURATION_OM_KEY  "cap_stop_duration_om"
99 #define E_CAP_M_RESOLVE_KEY         "cap_m_resolve"
100 #define E_CAP_N_RESOLVE_KEY         "cap_n_resolve"
101 #define E_CAP_T_RESOLVE_KEY         "cap_t_resolve"
102
103 #define E_CAP_OM_LT_VALUE_KEY       "cap_om_lt_value"
104
105
106 /*
107  * Keep a static pointer to the current "Capture Options" window, if
108  * any, so that if somebody tries to do "Capture:Start" while there's
109  * already a "Capture Options" window up, we just pop up the existing
110  * one, rather than creating a new one.
111  */
112 static GtkWidget *cap_open_w;
113
114
115 static void
116 capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te);
117
118 static void
119 select_link_type_cb(GtkWidget *w, gpointer data);
120
121 static void
122 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
123
124 static void
125 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
126
127 static void
128 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer parent_w);
129
130 static void
131 capture_dlg_prep(gpointer parent_w);
132
133
134 /* stop the currently running capture */
135 void
136 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
137 {
138     capture_stop(capture_opts);
139 }
140
141 /* restart (stop - delete old file - start) running capture */
142 void
143 capture_restart_cb(GtkWidget *w _U_, gpointer d _U_)
144 {
145     capture_restart(capture_opts);
146 }
147
148 /* init the link type list */
149 /* (often this list has only one entry and will therefore be disabled) */
150 static void
151 set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
152 {
153   gchar *entry_text;
154   gchar *if_text;
155   gchar *if_name;
156   GList *if_list;
157   GList *if_entry;
158   if_info_t *if_info;
159   GList *lt_list;
160   int err;
161   char err_buf[PCAP_ERRBUF_SIZE];
162   GtkWidget *lt_menu, *lt_menu_item;
163   GList *lt_entry;
164   data_link_info_t *data_link_info;
165   gchar *linktype_menu_label;
166   guint num_supported_link_types;
167   GtkWidget *linktype_lb = OBJECT_GET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY);
168   GtkWidget *if_ip_lb;
169   GString *ip_str = g_string_new("IP address: ");
170   int ips = 0;
171   GSList *curr_ip;
172   if_addr_t *ip_addr;
173
174   lt_menu = gtk_menu_new();
175   entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
176   if_text = g_strstrip(entry_text);
177   if_name = get_if_name(if_text);
178
179   /*
180    * If the interface name is in the list of known interfaces, get
181    * its list of link-layer types and set the option menu to display it.
182    *
183    * If it's not, don't bother - the user might be in the middle of
184    * editing the list, or it might be a remote device in which case
185    * getting the list could take an arbitrarily-long period of time.
186    * The list currently won't contain any remote devices (as
187    * "pcap_findalldevs()" doesn't know about remote devices, and neither
188    * does the code we use if "pcap_findalldevs()" isn't available), but
189    * should contain all the local devices on which you can capture.
190    */
191   lt_list = NULL;
192   if (*if_name != '\0') {
193     /*
194      * Try to get the list of known interfaces.
195      */
196     if_list = get_interface_list(&err, err_buf);
197     if (if_list != NULL) {
198       /*
199        * We have the list - check it.
200        */
201       for (if_entry = if_list; if_entry != NULL;
202            if_entry = g_list_next(if_entry)) {
203         if_info = if_entry->data;
204         if (strcmp(if_info->name, if_name) == 0) {
205           /*
206            * It's in the list.
207            * Get the list of link-layer types for it.
208            */
209           lt_list = get_pcap_linktype_list(if_name, err_buf);
210
211           /* create string of list of IP addresses of this interface */
212           for (; (curr_ip = g_slist_nth(if_info->ip_addr, ips)) != NULL; ips++) {
213             if (ips != 0)
214               g_string_append(ip_str, ", ");
215
216             ip_addr = (if_addr_t *)curr_ip->data;
217             switch (ip_addr->type) {
218
219             case AT_IPv4:
220               g_string_append(ip_str,
221                 ip_to_str((guint8 *)&ip_addr->ip_addr.ip4_addr));
222               break;
223
224             case AT_IPv6:
225               g_string_append(ip_str,
226                   ip6_to_str((struct e_in6_addr *)&ip_addr->ip_addr.ip6_addr));
227               break;
228
229             default:
230               g_assert_not_reached();
231             }
232           }
233
234           if (if_info->loopback)
235             g_string_append(ip_str, " (loopback)");
236         }
237       }
238       free_interface_list(if_list);
239     }
240   }
241   g_free(entry_text);
242   num_supported_link_types = 0;
243   for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
244     data_link_info = lt_entry->data;
245     if (data_link_info->description != NULL) {
246       lt_menu_item = gtk_menu_item_new_with_label(data_link_info->description);
247       OBJECT_SET_DATA(lt_menu_item, E_CAP_LT_OM_KEY, linktype_om);
248       SIGNAL_CONNECT(lt_menu_item, "activate", select_link_type_cb,
249                      GINT_TO_POINTER(data_link_info->dlt));
250       num_supported_link_types++;
251     } else {
252       /* Not supported - tell them about it but don't let them select it. */
253       linktype_menu_label = g_strdup_printf("%s (not supported)",
254                                             data_link_info->name);
255       lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
256       g_free(linktype_menu_label);
257       gtk_widget_set_sensitive(lt_menu_item, FALSE);
258     }
259     gtk_menu_append(GTK_MENU(lt_menu), lt_menu_item);
260   }
261   if (lt_list != NULL)
262     free_pcap_linktype_list(lt_list);
263   gtk_option_menu_set_menu(GTK_OPTION_MENU(linktype_om), lt_menu);
264   gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
265   gtk_widget_set_sensitive(linktype_om, num_supported_link_types >= 2);
266
267   if_ip_lb = OBJECT_GET_DATA(linktype_om, E_CAP_IFACE_KEY);
268   if(ips == 0) {
269     g_string_append(ip_str, "unknown");
270   }
271   gtk_label_set_text(GTK_LABEL(if_ip_lb), ip_str->str);
272   g_string_free(ip_str, TRUE);
273 }
274
275
276 #define TIME_UNIT_SECOND    0
277 #define TIME_UNIT_MINUTE    1
278 #define TIME_UNIT_HOUR      2
279 #define TIME_UNIT_DAY       3
280 #define MAX_TIME_UNITS 4
281 static char *time_unit_name[MAX_TIME_UNITS] = {
282         "second(s)",
283         "minute(s)",
284         "hour(s)",
285         "day(s)",
286 };
287
288 /* create one of the duration options */
289 /* (and select the matching unit depending on the given value) */
290 static GtkWidget *time_unit_option_menu_new(guint32 value) {
291     GtkWidget *unit_om, *menu, *menu_item;
292     int i;
293
294         unit_om=gtk_option_menu_new();
295         menu=gtk_menu_new();
296         for(i=0;i<MAX_TIME_UNITS;i++){
297                 menu_item=gtk_menu_item_new_with_label(time_unit_name[i]);
298                 OBJECT_SET_DATA(menu_item, "time_unit", GINT_TO_POINTER(i));
299                 gtk_menu_append(GTK_MENU(menu), menu_item);
300         }
301
302     /* the selected menu item can't be changed, once the option_menu
303        is created, so set the matching menu item now */
304     /* days */
305     if(value >= 60 * 60 * 24) {
306             gtk_menu_set_active(GTK_MENU(menu), TIME_UNIT_DAY);
307     } else {
308         /* hours */
309         if(value >= 60 * 60) {
310                 gtk_menu_set_active(GTK_MENU(menu), TIME_UNIT_HOUR);
311         } else {
312             /* minutes */
313             if(value >= 60) {
314                     gtk_menu_set_active(GTK_MENU(menu), TIME_UNIT_MINUTE);
315             } else {
316                 /* seconds */
317                     gtk_menu_set_active(GTK_MENU(menu), TIME_UNIT_SECOND);
318             }
319         }
320     }
321
322         gtk_option_menu_set_menu(GTK_OPTION_MENU(unit_om), menu);
323
324     return unit_om;
325 }
326
327 /* convert time value from raw to displayed (e.g. 60s -> 1min) */
328 static guint32 time_unit_option_menu_convert_value(
329 guint32 value)
330 {
331     /* days */
332     if(value >= 60 * 60 * 24) {
333         return value / (60 * 60 * 24);
334     }
335
336     /* hours */
337     if(value >= 60 * 60) {
338         return value / (60 * 60);
339     }
340
341     /* minutes */
342     if(value >= 60) {
343         return value / 60;
344     }
345
346     /* seconds */
347     return value;
348 }
349
350 /* get raw value from unit and value fields */
351 static guint32 time_unit_option_menu_get_value(
352 GtkWidget *unit_om,
353 guint32 value)
354 {
355         GtkWidget *menu, *menu_item;
356     int unit;
357
358     menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(unit_om));
359     menu_item = gtk_menu_get_active(GTK_MENU(menu));
360     unit = GPOINTER_TO_INT(OBJECT_GET_DATA(menu_item, "time_unit"));
361
362
363     switch(unit) {
364     case(TIME_UNIT_SECOND):
365         return value;
366         break;
367     case(TIME_UNIT_MINUTE):
368         return value * 60;
369         break;
370     case(TIME_UNIT_HOUR):
371         return value * 60 * 60;
372         break;
373     case(TIME_UNIT_DAY):
374         return value * 60 * 60 * 24;
375         break;
376     default:
377         g_assert_not_reached();
378         return 0;
379     }
380 }
381
382
383 #define SIZE_UNIT_BYTES     0
384 #define SIZE_UNIT_KILOBYTES 1
385 #define SIZE_UNIT_MEGABYTES 2
386 #define SIZE_UNIT_GIGABYTES 3
387 #define MAX_SIZE_UNITS 4
388 static char *size_unit_name[MAX_SIZE_UNITS] = {
389         "byte(s)",
390         "kilobyte(s)",
391         "megabyte(s)",
392         "gigabyte(s)",
393 };
394
395 /* create one of the size options */
396 /* (and select the matching unit depending on the given value) */
397 static GtkWidget *size_unit_option_menu_new(guint32 value) {
398     GtkWidget *unit_om, *menu, *menu_item;
399     int i;
400
401         unit_om=gtk_option_menu_new();
402         menu=gtk_menu_new();
403         for(i=0;i<MAX_SIZE_UNITS;i++){
404                 menu_item=gtk_menu_item_new_with_label(size_unit_name[i]);
405                 OBJECT_SET_DATA(menu_item, "size_unit", GINT_TO_POINTER(i));
406                 gtk_menu_append(GTK_MENU(menu), menu_item);
407         }
408
409     /* the selected menu item can't be changed, once the option_menu
410        is created, so set the matching menu item now */
411     /* gigabytes */
412     if(value >= 1024 * 1024 * 1024) {
413             gtk_menu_set_active(GTK_MENU(menu), SIZE_UNIT_GIGABYTES);
414     } else {
415         /* megabytes */
416         if(value >= 1024 * 1024) {
417                 gtk_menu_set_active(GTK_MENU(menu), SIZE_UNIT_MEGABYTES);
418         } else {
419             /* kilobytes */
420             if(value >= 1024) {
421                     gtk_menu_set_active(GTK_MENU(menu), SIZE_UNIT_KILOBYTES);
422             } else {
423                 /* bytes */
424                     gtk_menu_set_active(GTK_MENU(menu), SIZE_UNIT_BYTES);
425             }
426         }
427     }
428
429         gtk_option_menu_set_menu(GTK_OPTION_MENU(unit_om), menu);
430
431     return unit_om;
432 }
433
434 /* convert size value from raw to displayed (e.g. 1024 Bytes -> 1 KB) */
435 static guint32 size_unit_option_menu_set_value(
436 guint32 value)
437 {
438     /* gigabytes */
439     if(value >= 1024 * 1024 * 1024) {
440         return value / (1024 * 1024 * 1024);
441     }
442
443     /* megabytes */
444     if(value >= 1024 * 1024) {
445         return value / (1024 * 1024);
446     }
447
448     /* kilobytes */
449     if(value >= 1024) {
450         return value / 1024;
451     }
452
453     /* bytes */
454     return value;
455 }
456
457 /* get raw value from unit and value fields */
458 static guint32 size_unit_option_menu_convert_value(
459 GtkWidget *unit_om,
460 guint32 value)
461 {
462         GtkWidget *menu, *menu_item;
463     int unit;
464
465     menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(unit_om));
466     menu_item = gtk_menu_get_active(GTK_MENU(menu));
467     unit = GPOINTER_TO_INT(OBJECT_GET_DATA(menu_item, "size_unit"));
468
469
470     switch(unit) {
471     case(SIZE_UNIT_BYTES):
472         return value;
473         break;
474     case(SIZE_UNIT_KILOBYTES):
475         if(value > G_MAXINT / 1024) {
476             return 0;
477         } else {
478             return value * 1024;
479         }
480         break;
481     case(SIZE_UNIT_MEGABYTES):
482         if(value > G_MAXINT / (1024 * 1024)) {
483             return 0;
484         } else {
485             return value * 1024 * 1024;
486         }
487         break;
488     case(SIZE_UNIT_GIGABYTES):
489         if(value > G_MAXINT / (1024 * 1024 * 1024)) {
490             return 0;
491         } else {
492             return value * 1024 * 1024 * 1024;
493         }
494         break;
495     default:
496         g_assert_not_reached();
497         return 0;
498     }
499 }
500
501
502 /* show capture prepare (options) dialog */
503 void
504 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
505 {
506   GtkWidget     *main_vb,
507                 *main_hb, *left_vb, *right_vb,
508
509                 *capture_fr, *capture_vb,
510                 *if_hb, *if_cb, *if_lb,
511                 *if_ip_hb, *if_ip_lb,
512                 *linktype_hb, *linktype_lb, *linktype_om,
513                 *snap_hb, *snap_cb, *snap_sb, *snap_lb,
514                 *promisc_cb,
515                 *filter_hb, *filter_bt, *filter_te, *filter_cm,
516
517                 *file_fr, *file_vb,
518                 *file_hb, *file_bt, *file_lb, *file_te,
519                 *multi_tb, *multi_files_on_cb,
520                 *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_om,
521                 *file_duration_cb, *file_duration_sb, *file_duration_om,
522                 *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
523                 *stop_files_cb, *stop_files_sb, *stop_files_lb,
524
525                 *limit_fr, *limit_vb, *limit_tb,
526                 *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
527                 *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_om,
528                 *stop_duration_cb, *stop_duration_sb, *stop_duration_om,
529
530                 *display_fr, *display_vb,
531                 *sync_cb, *auto_scroll_cb, *hide_info_cb,
532
533                 *resolv_fr, *resolv_vb,
534                 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
535                 *bbox, *ok_bt, *cancel_bt,
536                 *help_bt;
537 #if GTK_MAJOR_VERSION < 2
538   GtkAccelGroup *accel_group;
539 #endif
540   GtkTooltips   *tooltips;
541   GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
542                 *stop_packets_adj, *stop_filesize_adj, *stop_duration_adj, *stop_files_adj, *ring_filesize_adj, *file_duration_adj;
543   GList         *if_list, *combo_list, *cfilter_list;
544   int           err;
545   int           row;
546   char          err_str[PCAP_ERRBUF_SIZE];
547   gchar         *cant_get_if_list_errstr;
548 #ifdef _WIN32
549   GtkAdjustment *buffer_size_adj;
550   GtkWidget     *buffer_size_lb, *buffer_size_sb;
551 #endif
552   guint32       value;
553   gchar         *cap_title;
554
555   if (cap_open_w != NULL) {
556     /* There's already a "Capture Options" dialog box; reactivate it. */
557     reactivate_window(cap_open_w);
558     return;
559   }
560
561 #ifdef _WIN32
562   /* Is WPcap loaded? */
563   if (!has_wpcap) {
564           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
565                   "Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n"
566                   "to capture packets.\n\n"
567                   "In order to capture packets, WinPcap must be installed; see\n"
568                   "\n"
569                   "        http://winpcap.polito.it/\n"
570                   "\n"
571                   "or the mirror at\n"
572                   "\n"
573                   "        http://winpcap.mirror.ethereal.com/\n"
574                   "\n"
575                   "or the mirror at\n"
576                   "\n"
577                   "        http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n"
578                   "\n"
579                   "for a downloadable version of WinPcap and for instructions\n"
580                   "on how to install WinPcap.");
581           return;
582   }
583 #endif
584
585   if_list = get_interface_list(&err, err_str);
586   if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
587     cant_get_if_list_errstr = cant_get_if_list_error_message(err_str);
588     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
589                   cant_get_if_list_errstr);
590     g_free(cant_get_if_list_errstr);
591   }
592
593   /* use user-defined title if preference is set */
594   cap_title = create_user_window_title("Ethereal: Capture Options");
595
596   cap_open_w = dlg_window_new(cap_title);
597   g_free(cap_title);
598
599   tooltips = gtk_tooltips_new();
600
601 #if GTK_MAJOR_VERSION < 2
602   /* Accelerator group for the accelerators (or, as they're called in
603      Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
604      Ctrl+<key> is an accelerator). */
605   accel_group = gtk_accel_group_new();
606   gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group);
607 #endif
608
609   main_vb = gtk_vbox_new(FALSE, 0);
610   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
611   gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
612
613   /* Capture-related options frame */
614   capture_fr = gtk_frame_new("Capture");
615   gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
616
617   capture_vb = gtk_vbox_new(FALSE, 3);
618   gtk_container_border_width(GTK_CONTAINER(capture_vb), 5);
619   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
620
621   /* Interface row */
622   if_hb = gtk_hbox_new(FALSE, 3);
623   gtk_container_add(GTK_CONTAINER(capture_vb), if_hb);
624
625   if_lb = gtk_label_new("Interface:");
626   gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
627
628   if_cb = gtk_combo_new();
629   combo_list = build_capture_combo_list(if_list, TRUE);
630   if (combo_list != NULL)
631     gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
632   if (capture_opts->iface == NULL && prefs.capture_device != NULL) {
633     /* No interface was specified on the command line or in a previous
634        capture, but there is one specified in the preferences file;
635        make the one from the preferences file the default */
636     capture_opts->iface = g_strdup(prefs.capture_device);
637   }
638   if (capture_opts->iface != NULL)
639     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), capture_opts->iface);
640   else if (combo_list != NULL) {
641     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
642                        (char *)combo_list->data);
643   }
644   free_capture_combo_list(combo_list);
645   free_interface_list(if_list);
646   gtk_tooltips_set_tip(tooltips, GTK_COMBO(if_cb)->entry,
647     "Choose which interface (network card) will be used to capture packets from. "
648     "Be sure to select the correct one, as it's a common mistake to select the wrong interface.", NULL);
649   gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
650
651   if_ip_hb = gtk_hbox_new(FALSE, 3);
652   gtk_box_pack_start(GTK_BOX(capture_vb), if_ip_hb, FALSE, FALSE, 0);
653
654   if_ip_lb = gtk_label_new("");
655   gtk_box_pack_start(GTK_BOX(if_ip_hb), if_ip_lb, FALSE, FALSE, 6);
656
657   /* Linktype row */
658   linktype_hb = gtk_hbox_new(FALSE, 3);
659   gtk_box_pack_start(GTK_BOX(capture_vb), linktype_hb, FALSE, FALSE, 0);
660
661   linktype_lb = gtk_label_new("Link-layer header type:");
662   gtk_box_pack_start(GTK_BOX(linktype_hb), linktype_lb, FALSE, FALSE, 6);
663
664   linktype_om = gtk_option_menu_new();
665   OBJECT_SET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY, linktype_lb);
666   /* Default to "use the default" */
667   OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(-1));
668   OBJECT_SET_DATA(linktype_om, E_CAP_IFACE_KEY, if_ip_lb);
669   set_link_type_list(linktype_om, GTK_COMBO(if_cb)->entry);
670   /*
671    * XXX - in some cases, this is "multiple link-layer header types", e.g.
672    * some 802.11 interfaces on FreeBSD 5.2 and later, where you can request
673    * fake Ethernet, 802.11, or 802.11-plus-radio-information headers.
674    *
675    * In other cases, it's "multiple link-layer types", e.g., with recent
676    * versions of libpcap, a DAG card on an "HDLC" WAN, where you can
677    * request Cisco HDLC or PPP depending on what type of traffic is going
678    * over the WAN, or an Ethernet interface, where you can request Ethernet
679    * or DOCSIS, the latter being for some Cisco cable modem equipment that
680    * can be configured to send raw DOCSIS frames over an Ethernet inside
681    * Ethernet low-level framing, for traffic capture purposes.
682    *
683    * We leave it as "multiple link-layer types" for now.
684    */
685   gtk_tooltips_set_tip(tooltips, linktype_om,
686     "The selected interface supports multiple link-layer types; select the desired one.", NULL);
687   gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_om, FALSE, FALSE, 0);
688   SIGNAL_CONNECT(GTK_ENTRY(GTK_COMBO(if_cb)->entry), "changed",
689                  capture_prep_interface_changed_cb, linktype_om);
690
691 #ifdef _WIN32
692   buffer_size_lb = gtk_label_new("Buffer size:");
693   gtk_box_pack_start (GTK_BOX(linktype_hb), buffer_size_lb, FALSE, FALSE, 0);
694
695   buffer_size_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts->buffer_size,
696     1, 65535, 1.0, 10.0, 0.0);
697   buffer_size_sb = gtk_spin_button_new (buffer_size_adj, 0, 0);
698   gtk_spin_button_set_value(GTK_SPIN_BUTTON (buffer_size_sb), (gfloat) capture_opts->buffer_size);
699   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (buffer_size_sb), TRUE);
700   WIDGET_SET_SIZE(buffer_size_sb, 80, -1);
701   gtk_tooltips_set_tip(tooltips, buffer_size_sb,
702     "The memory buffer size used while capturing. If you notice packet drops, you can try to increase this size.", NULL);
703   gtk_box_pack_start (GTK_BOX(linktype_hb), buffer_size_sb, FALSE, FALSE, 0);
704
705   buffer_size_lb = gtk_label_new("megabyte(s)");
706   gtk_box_pack_start (GTK_BOX(linktype_hb), buffer_size_lb, FALSE, FALSE, 0);
707 #endif
708
709   /* Promiscuous mode row */
710   promisc_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
711       "Capture packets in _promiscuous mode", accel_group);
712   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb),
713                 capture_opts->promisc_mode);
714   gtk_tooltips_set_tip(tooltips, promisc_cb,
715     "Usually a network card will only capture the traffic sent to its own network address. "
716     "If you want to capture all traffic that the network card can \"see\", mark this option. "
717     "See the FAQ for some more details of capturing packets from a switched network.", NULL);
718   gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
719
720   /* Capture length row */
721   snap_hb = gtk_hbox_new(FALSE, 3);
722   gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
723
724   snap_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("_Limit each packet to", accel_group);
725   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb),
726                 capture_opts->has_snaplen);
727   SIGNAL_CONNECT(snap_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
728   gtk_tooltips_set_tip(tooltips, snap_cb,
729     "Limit the maximum number of bytes to be captured from each packet. This size includes the "
730     "link-layer header and all subsequent headers. ", NULL);
731   gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
732
733   snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts->snaplen,
734     MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
735   snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
736   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
737   WIDGET_SET_SIZE(snap_sb, 80, -1);
738   gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
739
740   snap_lb = gtk_label_new("bytes");
741   gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5);
742   gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
743
744   /* Filter row */
745   filter_hb = gtk_hbox_new(FALSE, 3);
746   gtk_box_pack_start(GTK_BOX(capture_vb), filter_hb, FALSE, FALSE, 0);
747
748   filter_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_CAPTURE_FILTER_ENTRY);
749   SIGNAL_CONNECT(filter_bt, "clicked", capture_filter_construct_cb, NULL);
750   SIGNAL_CONNECT(filter_bt, "destroy", filter_button_destroy_cb, NULL);
751   gtk_tooltips_set_tip(tooltips, filter_bt,
752     "Select a capture filter to reduce the amount of packets to be captured. "
753     "See \"Capture Filters\" in the online help for further information how to use it.",
754     NULL);
755   gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
756
757   /* Create the capture filter combo */
758   filter_cm = gtk_combo_new();
759
760   cfilter_list = OBJECT_GET_DATA(top_level, E_CFILTER_FL_KEY);
761   gtk_combo_disable_activate(GTK_COMBO(filter_cm));
762   gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
763   OBJECT_SET_DATA(top_level, E_CFILTER_FL_KEY, cfilter_list);
764   OBJECT_SET_DATA(top_level, E_CFILTER_CM_KEY, filter_cm);
765   filter_te = GTK_COMBO(filter_cm)->entry;
766
767   if (cfilter_list != NULL)
768     gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), cfilter_list);
769   if (capture_opts->cfilter)
770     gtk_entry_set_text(GTK_ENTRY(filter_te), capture_opts->cfilter);
771   gtk_tooltips_set_tip(tooltips, filter_te,
772     "Enter a capture filter to reduce the amount of packets to be captured. "
773     "See \"Capture Filters\" in the online help for further information how to use it.",
774     NULL);
775   WIDGET_SET_SIZE(filter_cm, 400, -1);
776   gtk_box_pack_start(GTK_BOX(filter_hb), filter_cm, FALSE, FALSE, 3);
777   main_hb = gtk_hbox_new(FALSE, 5);
778   gtk_container_border_width(GTK_CONTAINER(main_hb), 0);
779   gtk_container_add(GTK_CONTAINER(main_vb), main_hb);
780
781   left_vb = gtk_vbox_new(FALSE, 0);
782   gtk_container_border_width(GTK_CONTAINER(left_vb), 0);
783   gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
784
785   right_vb = gtk_vbox_new(FALSE, 0);
786   gtk_container_border_width(GTK_CONTAINER(right_vb), 0);
787   gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 0);
788
789   /* let an eventually capture filters dialog know the text entry to fill in */
790   OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
791
792   /* Capture file-related options frame */
793   file_fr = gtk_frame_new("Capture File(s)");
794   gtk_container_add(GTK_CONTAINER(left_vb), file_fr);
795
796   file_vb = gtk_vbox_new(FALSE, 3);
797   gtk_container_border_width(GTK_CONTAINER(file_vb), 5);
798   gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
799
800   /* File row */
801   file_hb = gtk_hbox_new(FALSE, 3);
802   gtk_box_pack_start(GTK_BOX(file_vb), file_hb, FALSE, FALSE, 0);
803
804   file_lb = gtk_label_new("File:");
805   gtk_box_pack_start(GTK_BOX(file_hb), file_lb, FALSE, FALSE, 3);
806
807   file_te = gtk_entry_new();
808   gtk_tooltips_set_tip(tooltips, file_te,
809     "Enter the file name to which captured data will be written. "
810     "If you don't enter something here, a temporary file will be used.",
811     NULL);
812   gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
813
814   file_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_BROWSE);
815   gtk_tooltips_set_tip(tooltips, file_bt,
816     "Select a file to which captured data will be written, "
817     "instead of entering the file name directly. ",
818     NULL);
819   gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3);
820
821   SIGNAL_CONNECT(file_bt, "clicked", capture_prep_file_cb, file_te);
822
823   /* multiple files table */
824   multi_tb = gtk_table_new(5, 3, FALSE);
825   gtk_table_set_row_spacings(GTK_TABLE(multi_tb), 1);
826   gtk_table_set_col_spacings(GTK_TABLE(multi_tb), 3);
827   gtk_box_pack_start(GTK_BOX(file_vb), multi_tb, FALSE, FALSE, 0);
828   row = 0;
829
830   /* multiple files row */
831   multi_files_on_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("Use _multiple files", accel_group);
832   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(multi_files_on_cb),
833                 capture_opts->multi_files_on);
834   SIGNAL_CONNECT(multi_files_on_cb, "toggled", capture_prep_adjust_sensitivity,
835                  cap_open_w);
836   gtk_tooltips_set_tip(tooltips, multi_files_on_cb,
837     "Instead of using a single capture file, multiple files will be created. "
838     "The generated file names will contain an incrementing number and the start time of the capture.", NULL);
839   gtk_table_attach_defaults(GTK_TABLE(multi_tb), multi_files_on_cb, 0, 1, row, row+1);
840   row++;
841
842   /* Ring buffer filesize row */
843   ring_filesize_cb = gtk_check_button_new_with_label("Next file every");
844   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_filesize_cb),
845                 capture_opts->has_autostop_filesize);
846   SIGNAL_CONNECT(ring_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
847   gtk_tooltips_set_tip(tooltips, ring_filesize_cb,
848     "If the selected file size is exceeded, capturing switches to the next file.\n"
849     "PLEASE NOTE: at least one of the \"Next file every\" options MUST be selected.",
850     NULL);
851   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_cb, 0, 1, row, row+1);
852
853   ring_filesize_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
854     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
855   ring_filesize_sb = gtk_spin_button_new (ring_filesize_adj, 0, 0);
856   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_filesize_sb), TRUE);
857   WIDGET_SET_SIZE(ring_filesize_sb, 80, -1);
858   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_sb, 1, 2, row, row+1);
859
860   ring_filesize_om = size_unit_option_menu_new(capture_opts->autostop_filesize);
861   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_om, 2, 3, row, row+1);
862
863   value = size_unit_option_menu_set_value(capture_opts->autostop_filesize);
864   gtk_adjustment_set_value(ring_filesize_adj, (gfloat) value);
865
866   row++;
867
868   /* Ring buffer duration row */
869   file_duration_cb = gtk_check_button_new_with_label("Next file every");
870   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(file_duration_cb),
871                               capture_opts->has_file_duration);
872   SIGNAL_CONNECT(file_duration_cb, "toggled",
873                  capture_prep_adjust_sensitivity, cap_open_w);
874   gtk_tooltips_set_tip(tooltips, file_duration_cb,
875     "If the selected duration is exceeded, capturing switches to the next file.\n"
876     "PLEASE NOTE: at least one of the \"Next file every\" options MUST be selected.",
877     NULL);
878   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_cb, 0, 1, row, row+1);
879
880   file_duration_adj = (GtkAdjustment *)gtk_adjustment_new(0.0,
881     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
882   file_duration_sb = gtk_spin_button_new (file_duration_adj, 0, 0);
883   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (file_duration_sb), TRUE);
884   WIDGET_SET_SIZE(file_duration_sb, 80, -1);
885   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_sb, 1, 2, row, row+1);
886
887   file_duration_om = time_unit_option_menu_new(capture_opts->file_duration);
888   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_om, 2, 3, row, row+1);
889
890   value = time_unit_option_menu_convert_value(capture_opts->file_duration);
891   gtk_adjustment_set_value(file_duration_adj, (gfloat) value);
892   row++;
893
894   /* Ring buffer files row */
895   ringbuffer_nbf_cb = gtk_check_button_new_with_label("Ring buffer with");
896   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb),
897                 capture_opts->has_ring_num_files);
898   SIGNAL_CONNECT(ringbuffer_nbf_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
899   gtk_tooltips_set_tip(tooltips, ringbuffer_nbf_cb,
900     "After capturing has switched to the next file and the given number of files has exceeded, "
901     "the oldest file will be removed.",
902     NULL);
903   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_cb, 0, 1, row, row+1);
904
905   ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts->ring_num_files,
906     2/*RINGBUFFER_MIN_NUM_FILES*/, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
907   ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
908   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
909   WIDGET_SET_SIZE(ringbuffer_nbf_sb, 80, -1);
910   SIGNAL_CONNECT(ringbuffer_nbf_sb, "changed", capture_prep_adjust_sensitivity, cap_open_w);
911   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_sb, 1, 2, row, row+1);
912
913   ringbuffer_nbf_lb = gtk_label_new("files");
914   gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 0, 0.5);
915   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_lb, 2, 3, row, row+1);
916   row++;
917
918   /* Files row */
919   stop_files_cb = gtk_check_button_new_with_label("Stop capture after");
920   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_files_cb),
921                 capture_opts->has_autostop_files);
922   SIGNAL_CONNECT(stop_files_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
923   gtk_tooltips_set_tip(tooltips, stop_files_cb,
924     "Stop capturing after the given number of \"file switches\" have been done.", NULL);
925   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_cb, 0, 1, row, row+1);
926
927   stop_files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts->autostop_files,
928     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
929   stop_files_sb = gtk_spin_button_new (stop_files_adj, 0, 0);
930   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_files_sb), TRUE);
931   WIDGET_SET_SIZE(stop_files_sb, 80, -1);
932   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_sb, 1, 2, row, row+1);
933
934   stop_files_lb = gtk_label_new("file(s)");
935   gtk_misc_set_alignment(GTK_MISC(stop_files_lb), 0, 0.5);
936   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_lb, 2, 3, row, row+1);
937   row++;
938
939   /* Capture limits frame */
940   limit_fr = gtk_frame_new("Stop Capture ...");
941   gtk_container_add(GTK_CONTAINER(left_vb), limit_fr);
942
943   limit_vb = gtk_vbox_new(FALSE, 3);
944   gtk_container_border_width(GTK_CONTAINER(limit_vb), 5);
945   gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
946
947   /* limits table */
948   limit_tb = gtk_table_new(3, 3, FALSE);
949   gtk_table_set_row_spacings(GTK_TABLE(limit_tb), 1);
950   gtk_table_set_col_spacings(GTK_TABLE(limit_tb), 3);
951   gtk_box_pack_start(GTK_BOX(limit_vb), limit_tb, FALSE, FALSE, 0);
952   row = 0;
953
954   /* Packet count row */
955   stop_packets_cb = gtk_check_button_new_with_label("... after");
956   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_packets_cb),
957                 capture_opts->has_autostop_packets);
958   SIGNAL_CONNECT(stop_packets_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
959   gtk_tooltips_set_tip(tooltips, stop_packets_cb,
960     "Stop capturing after the given number of packets have been captured.", NULL);
961   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_cb, 0, 1, row, row+1);
962
963   stop_packets_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts->autostop_packets,
964     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
965   stop_packets_sb = gtk_spin_button_new (stop_packets_adj, 0, 0);
966   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_packets_sb), TRUE);
967   WIDGET_SET_SIZE(stop_packets_sb, 80, -1);
968   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_sb, 1, 2, row, row+1);
969
970   stop_packets_lb = gtk_label_new("packet(s)");
971   gtk_misc_set_alignment(GTK_MISC(stop_packets_lb), 0, 0.5);
972   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_lb, 2, 3, row, row+1);
973   row++;
974
975   /* Filesize row */
976   stop_filesize_cb = gtk_check_button_new_with_label("... after");
977   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_filesize_cb),
978                 capture_opts->has_autostop_filesize);
979   SIGNAL_CONNECT(stop_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
980   gtk_tooltips_set_tip(tooltips, stop_filesize_cb,
981     "Stop capturing after the given amount of capture data has been captured.", NULL);
982   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_cb, 0, 1, row, row+1);
983
984   stop_filesize_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
985     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
986   stop_filesize_sb = gtk_spin_button_new (stop_filesize_adj, 0, 0);
987   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_filesize_sb), TRUE);
988   WIDGET_SET_SIZE(stop_filesize_sb, 80, -1);
989   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_sb, 1, 2, row, row+1);
990
991   stop_filesize_om = size_unit_option_menu_new(capture_opts->autostop_filesize);
992   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_om, 2, 3, row, row+1);
993
994   value = size_unit_option_menu_set_value(capture_opts->autostop_filesize);
995   gtk_adjustment_set_value(stop_filesize_adj, (gfloat) value);
996
997   row++;
998
999   /* Duration row */
1000   stop_duration_cb = gtk_check_button_new_with_label("... after");
1001   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_duration_cb),
1002                 capture_opts->has_autostop_duration);
1003   SIGNAL_CONNECT(stop_duration_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
1004   gtk_tooltips_set_tip(tooltips, stop_duration_cb,
1005     "Stop capturing after the given time is exceeded.", NULL);
1006   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_cb, 0, 1, row, row+1);
1007
1008   stop_duration_adj = (GtkAdjustment *) gtk_adjustment_new(0.0,
1009     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
1010   stop_duration_sb = gtk_spin_button_new (stop_duration_adj, 0, 0);
1011   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_duration_sb), TRUE);
1012   WIDGET_SET_SIZE(stop_duration_sb, 80, -1);
1013   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_sb, 1, 2, row, row+1);
1014
1015   stop_duration_om = time_unit_option_menu_new(capture_opts->autostop_duration);
1016   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_om, 2, 3, row, row+1);
1017
1018   value = time_unit_option_menu_convert_value(capture_opts->autostop_duration);
1019   gtk_adjustment_set_value(stop_duration_adj, (gfloat) value);
1020   row++;
1021
1022   /* Display-related options frame */
1023   display_fr = gtk_frame_new("Display Options");
1024   gtk_container_add(GTK_CONTAINER(right_vb), display_fr);
1025
1026   display_vb = gtk_vbox_new(FALSE, 0);
1027   gtk_container_border_width(GTK_CONTAINER(display_vb), 5);
1028   gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
1029
1030   /* "Update display in real time" row */
1031   sync_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
1032       "_Update list of packets in real time", accel_group);
1033   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb),
1034                 capture_opts->real_time_mode);
1035   SIGNAL_CONNECT(sync_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
1036   gtk_tooltips_set_tip(tooltips, sync_cb,
1037     "Using this option will show the captured packets immediately on the main screen. "
1038     "Please note: this will slow down capturing, so increased packet drops might appear.", NULL);
1039   gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
1040
1041   /* "Auto-scroll live update" row */
1042   auto_scroll_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
1043                 "_Automatic scrolling in live capture", accel_group);
1044   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
1045   gtk_tooltips_set_tip(tooltips, auto_scroll_cb,
1046     "This will scroll the \"Packet List\" automatically to the latest captured packet, "
1047     "when the \"Update List of packets in real time\" option is used.", NULL);
1048   gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
1049
1050   /* "Hide capture info" row */
1051   hide_info_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
1052                 "_Hide capture info dialog", accel_group);
1053   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(hide_info_cb), !capture_opts->show_info);
1054   gtk_tooltips_set_tip(tooltips, hide_info_cb,
1055     "Hide the capture info dialog while capturing.", NULL);
1056   gtk_container_add(GTK_CONTAINER(display_vb), hide_info_cb);
1057
1058   /* Name Resolution frame */
1059   resolv_fr = gtk_frame_new("Name Resolution");
1060   gtk_container_add(GTK_CONTAINER(right_vb), resolv_fr);
1061
1062   resolv_vb = gtk_vbox_new(FALSE, 0);
1063   gtk_container_border_width(GTK_CONTAINER(resolv_vb), 5);
1064   gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
1065
1066   m_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
1067                 "Enable _MAC name resolution", accel_group);
1068   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
1069                 g_resolv_flags & RESOLV_MAC);
1070   gtk_tooltips_set_tip(tooltips, m_resolv_cb,
1071     "Perform MAC layer name resolution while capturing.", NULL);
1072   gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
1073
1074   n_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
1075                 "Enable _network name resolution", accel_group);
1076   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
1077                 g_resolv_flags & RESOLV_NETWORK);
1078   gtk_tooltips_set_tip(tooltips, n_resolv_cb,
1079     "Perform network layer name resolution while capturing.", NULL);
1080   gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
1081
1082   t_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
1083                 "Enable _transport name resolution", accel_group);
1084   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
1085                 g_resolv_flags & RESOLV_TRANSPORT);
1086   gtk_tooltips_set_tip(tooltips, t_resolv_cb,
1087     "Perform transport layer name resolution while capturing.", NULL);
1088   gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
1089
1090   /* Button row: "Start" and "Cancel" buttons */
1091   bbox = dlg_button_row_new(ETHEREAL_STOCK_CAPTURE_START, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
1092   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
1093
1094   ok_bt = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CAPTURE_START);
1095   SIGNAL_CONNECT(ok_bt, "clicked", capture_start_cb, cap_open_w);
1096   gtk_tooltips_set_tip(tooltips, ok_bt,
1097     "Start the capture process.", NULL);
1098
1099   cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
1100   gtk_tooltips_set_tip(tooltips, cancel_bt,
1101     "Cancel and exit dialog.", NULL);
1102   window_set_cancel_button(cap_open_w, cancel_bt, window_cancel_button_cb);
1103
1104   help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
1105   gtk_tooltips_set_tip(tooltips, help_bt,
1106     "Show help about capturing.", NULL);
1107   SIGNAL_CONNECT(help_bt, "clicked", topic_cb, HELP_CAPTURE_OPTIONS_DIALOG);
1108
1109   gtk_widget_grab_default(ok_bt);
1110
1111   /* Attach pointers to needed widgets to the capture prefs window/object */
1112   OBJECT_SET_DATA(cap_open_w, E_CAP_IFACE_KEY, if_cb);
1113   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_CB_KEY, snap_cb);
1114   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_SB_KEY, snap_sb);
1115   OBJECT_SET_DATA(cap_open_w, E_CAP_LT_OM_KEY, linktype_om);
1116 #ifdef _WIN32
1117   OBJECT_SET_DATA(cap_open_w, E_CAP_BUFFER_SIZE_SB_KEY, buffer_size_sb);
1118 #endif
1119   OBJECT_SET_DATA(cap_open_w, E_CAP_PROMISC_KEY, promisc_cb);
1120   OBJECT_SET_DATA(cap_open_w, E_CAP_FILT_KEY,  filter_te);
1121   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_TE_KEY,  file_te);
1122   OBJECT_SET_DATA(cap_open_w, E_CAP_MULTI_FILES_ON_CB_KEY,  multi_files_on_cb);
1123   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_CB_KEY,  ringbuffer_nbf_cb);
1124   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_SB_KEY,  ringbuffer_nbf_sb);
1125   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_LB_KEY,  ringbuffer_nbf_lb);
1126   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_CB_KEY,  ring_filesize_cb);
1127   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_SB_KEY,  ring_filesize_sb);
1128   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_OM_KEY,  ring_filesize_om);
1129   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_DURATION_CB_KEY,  file_duration_cb);
1130   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_DURATION_SB_KEY,  file_duration_sb);
1131   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_DURATION_OM_KEY,  file_duration_om);
1132   OBJECT_SET_DATA(cap_open_w, E_CAP_SYNC_KEY,  sync_cb);
1133   OBJECT_SET_DATA(cap_open_w, E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
1134   OBJECT_SET_DATA(cap_open_w, E_CAP_HIDE_INFO_KEY, hide_info_cb);
1135   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_PACKETS_CB_KEY, stop_packets_cb);
1136   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_PACKETS_SB_KEY, stop_packets_sb);
1137   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_PACKETS_LB_KEY, stop_packets_lb);
1138   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILESIZE_CB_KEY, stop_filesize_cb);
1139   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILESIZE_SB_KEY, stop_filesize_sb);
1140   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILESIZE_OM_KEY, stop_filesize_om);
1141   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_DURATION_CB_KEY,  stop_duration_cb);
1142   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_DURATION_SB_KEY,  stop_duration_sb);
1143   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_DURATION_OM_KEY,  stop_duration_om);
1144   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILES_CB_KEY, stop_files_cb);
1145   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILES_SB_KEY, stop_files_sb);
1146   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILES_LB_KEY, stop_files_lb);
1147   OBJECT_SET_DATA(cap_open_w, E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
1148   OBJECT_SET_DATA(cap_open_w, E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
1149   OBJECT_SET_DATA(cap_open_w, E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
1150
1151   /* Set the sensitivity of various widgets as per the settings of other
1152      widgets. */
1153   capture_prep_adjust_sensitivity(NULL, cap_open_w);
1154
1155   /* Catch the "activate" signal on the text
1156      entries, so that if the user types Return there, we act as if the
1157      "OK" button had been selected, as happens if Return is typed if some
1158      widget that *doesn't* handle the Return key has the input focus. */
1159   dlg_set_activate(GTK_COMBO(if_cb)->entry, ok_bt);
1160   dlg_set_activate(filter_te, ok_bt);
1161   dlg_set_activate(file_te, ok_bt);
1162
1163   /* XXX - why does not
1164
1165      gtk_widget_grab_focus(if_cb);
1166
1167     give the initial focus to the "Interface" combo box?
1168
1169     Or should I phrase that as "why does GTK+ continually frustrate
1170     attempts to make GUIs driveable from the keyboard?"  We have to
1171     go catch the activate signal on every single GtkEntry widget
1172     (rather than having widgets whose activate signal is *not*
1173     caught not catch the Return keystroke, so that it passes on,
1174     ultimately, to the window, which can activate the default
1175     widget, i.e. the "OK" button); we have to catch the "key_press_event"
1176     signal and have the handler check for ESC, so that we can have ESC
1177     activate the "Cancel" button; in order to support Alt+<key> mnemonics
1178     for buttons and the like, we may have to construct an accelerator
1179     group by hand and set up the accelerators by hand (if that even
1180     works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()"
1181     to keep some container widget from getting the initial focus, so that
1182     you don't have to tab into the first widget in order to start typing
1183     in it; and it now appears that you simply *can't* make a combo box
1184     get the initial focus, at least not in the obvious fashion. Sigh.... */
1185
1186   SIGNAL_CONNECT(cap_open_w, "delete_event", window_delete_event_cb, NULL);
1187   SIGNAL_CONNECT(cap_open_w, "destroy", capture_prep_destroy_cb, NULL);
1188
1189   /* Give the initial focus to the "Filter" entry box. */
1190   gtk_widget_grab_focus(filter_te);
1191
1192   gtk_widget_show_all(cap_open_w);
1193   window_present(cap_open_w);
1194 }
1195
1196 /* everythings prepared, now it's really time to start the capture */
1197 void
1198 capture_start_confirmed(void) {
1199
1200
1201     /* init iface, if never used before */
1202     /* XXX - would better be doing this in main.c */
1203     if(capture_opts->iface == NULL) {
1204         gchar *if_device;
1205         gchar *if_name;
1206
1207         if_device = g_strdup(prefs.capture_device);
1208         if_name = get_if_name(if_device);
1209         capture_opts->iface = g_strdup(if_name);
1210
1211         g_free(if_device);
1212     }
1213
1214     /* XXX - we might need to init other pref data as well... */
1215
1216     if (capture_start(capture_opts)) {
1217         /* The capture succeeded, which means the capture filter syntax is
1218         valid; add this capture filter to the recent capture filter list. */
1219         cfilter_combo_add_recent(capture_opts->cfilter);
1220     }
1221 }
1222
1223 /* user confirmed the "Save capture file..." dialog */
1224 static void
1225 capture_start_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
1226 {
1227     switch(btn) {
1228     case(ESD_BTN_SAVE):
1229         /* save file first */
1230         file_save_as_cmd(after_save_capture_dialog, data);
1231         break;
1232     case(ESD_BTN_DONT_SAVE):
1233         /* XXX - unlink old file? */
1234         /* start the capture */
1235         capture_start_confirmed();
1236         break;
1237     case(ESD_BTN_CANCEL):
1238         break;
1239     default:
1240         g_assert_not_reached();
1241     }
1242 }
1243
1244 /* user pressed the "Start" button (in dialog or toolbar) */
1245 void
1246 capture_start_cb(GtkWidget *w _U_, gpointer d _U_)
1247 {
1248   gpointer  dialog;
1249
1250
1251   /* get the values and close the options dialog */
1252   if(cap_open_w) {
1253     capture_dlg_prep(cap_open_w);
1254     window_destroy(GTK_WIDGET(cap_open_w));
1255   }
1256
1257   if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1258     /* user didn't saved his current file, ask him */
1259     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1260                 PRIMARY_TEXT_START "Save capture file before starting a new capture?" PRIMARY_TEXT_END "\n\n"
1261                 "If you start a new capture without saving, your current capture data will\nbe discarded.");
1262     simple_dialog_set_cb(dialog, capture_start_answered_cb, NULL);
1263   } else {
1264     /* unchanged file, just capture a new one */
1265     capture_start_confirmed();
1266   }
1267 }
1268
1269 /* user selected a link type, convert to internal value */
1270 static void
1271 select_link_type_cb(GtkWidget *w, gpointer data)
1272 {
1273   int new_linktype = GPOINTER_TO_INT(data);
1274   GtkWidget *linktype_om = OBJECT_GET_DATA(w, E_CAP_LT_OM_KEY);
1275   int old_linktype = GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
1276
1277   if (old_linktype != new_linktype)
1278     OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(new_linktype));
1279 }
1280
1281 /* user pressed "File" button */
1282 static void
1283 capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te)
1284 {
1285     file_selection_browse(file_bt, file_te, "Ethereal: Specify a Capture File", FILE_SELECTION_WRITE_BROWSE);
1286 }
1287
1288
1289 /* convert dialog settings into capture_opts values */
1290 static void
1291 capture_dlg_prep(gpointer parent_w) {
1292   GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te, *filter_cm,
1293             *file_te, *multi_files_on_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_cb,
1294             *linktype_om, *sync_cb, *auto_scroll_cb, *hide_info_cb,
1295             *stop_packets_cb, *stop_packets_sb,
1296             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_om,
1297             *stop_duration_cb, *stop_duration_sb, *stop_duration_om,
1298             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_om,
1299             *file_duration_cb, *file_duration_sb, *file_duration_om,
1300             *stop_files_cb, *stop_files_sb,
1301             *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
1302 #ifdef _WIN32
1303   GtkWidget *buffer_size_sb;
1304 #endif
1305   gchar *entry_text;
1306   gchar *if_text;
1307   gchar *if_name;
1308   const gchar *filter_text;
1309   const gchar *g_save_file;
1310   gchar *cf_name;
1311   gchar *dirname;
1312   gint32 tmp;
1313
1314   if_cb     = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
1315   snap_cb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
1316   snap_sb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
1317   linktype_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_LT_OM_KEY);
1318 #ifdef _WIN32
1319   buffer_size_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_BUFFER_SIZE_SB_KEY);
1320 #endif
1321   promisc_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_PROMISC_KEY);
1322   filter_cm = OBJECT_GET_DATA(top_level, E_CFILTER_CM_KEY);
1323   filter_te = GTK_COMBO(filter_cm)->entry;
1324   file_te   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_TE_KEY);
1325   multi_files_on_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_MULTI_FILES_ON_CB_KEY);
1326   ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
1327   ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
1328   ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
1329   ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
1330   ring_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_OM_KEY);
1331   file_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_CB_KEY);
1332   file_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_SB_KEY);
1333   file_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_OM_KEY);
1334   sync_cb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1335   auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1336   hide_info_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_HIDE_INFO_KEY);
1337   stop_packets_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_CB_KEY);
1338   stop_packets_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_SB_KEY);
1339   stop_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_CB_KEY);
1340   stop_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_SB_KEY);
1341   stop_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_OM_KEY);
1342   stop_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_CB_KEY);
1343   stop_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_SB_KEY);
1344   stop_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_OM_KEY);
1345   stop_files_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_CB_KEY);
1346   stop_files_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_SB_KEY);
1347   m_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_M_RESOLVE_KEY);
1348   n_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_N_RESOLVE_KEY);
1349   t_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_T_RESOLVE_KEY);
1350
1351   entry_text =
1352     g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
1353   if_text = g_strstrip(entry_text);
1354   if_name = get_if_name(if_text);
1355   if (*if_name == '\0') {
1356     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1357       "You didn't specify an interface on which to capture packets.");
1358     g_free(entry_text);
1359     return;
1360   }
1361   if (capture_opts->iface)
1362     g_free(capture_opts->iface);
1363   capture_opts->iface = g_strdup(if_name);
1364   g_free(entry_text);
1365
1366   capture_opts->linktype =
1367       GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
1368
1369 #ifdef _WIN32
1370   capture_opts->buffer_size =
1371     gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb));
1372 #endif
1373
1374   capture_opts->has_snaplen =
1375     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
1376   if (capture_opts->has_snaplen) {
1377     capture_opts->snaplen =
1378       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
1379     if (capture_opts->snaplen < 1)
1380       capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
1381     else if (capture_opts->snaplen < MIN_PACKET_SIZE)
1382       capture_opts->snaplen = MIN_PACKET_SIZE;
1383   }
1384
1385   capture_opts->promisc_mode =
1386     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
1387
1388   /* XXX - don't try to get clever and set "cfile.filter" to NULL if the
1389      filter string is empty, as an indication that we don't have a filter
1390      and thus don't have to set a filter when capturing - the version of
1391      libpcap in Red Hat Linux 6.1, and versions based on later patches
1392      in that series, don't bind the AF_PACKET socket to an interface
1393      until a filter is set, which means they aren't bound at all if
1394      no filter is set, which means no packets arrive as input on that
1395      socket, which means Ethereal never sees any packets. */
1396   filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
1397   if (capture_opts->cfilter)
1398     g_free(capture_opts->cfilter);
1399   g_assert(filter_text != NULL);
1400   capture_opts->cfilter = g_strdup(filter_text);
1401
1402   g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
1403   if (g_save_file && g_save_file[0]) {
1404     /* User specified a file to which the capture should be written. */
1405     capture_opts->save_file = g_strdup(g_save_file);
1406     /* Save the directory name for future file dialogs. */
1407     cf_name = g_strdup(g_save_file);
1408     dirname = get_dirname(cf_name);  /* Overwrites cf_name */
1409     set_last_open_dir(dirname);
1410     g_free(cf_name);
1411   } else {
1412     /* User didn't specify a file; save to a temporary file. */
1413     capture_opts->save_file = NULL;
1414   }
1415
1416   capture_opts->has_autostop_packets =
1417     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb));
1418   if (capture_opts->has_autostop_packets)
1419     capture_opts->autostop_packets =
1420       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_packets_sb));
1421
1422   capture_opts->has_autostop_duration =
1423     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb));
1424   if (capture_opts->has_autostop_duration) {
1425     capture_opts->autostop_duration =
1426       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_duration_sb));
1427     capture_opts->autostop_duration =
1428       time_unit_option_menu_get_value(stop_duration_om, capture_opts->autostop_duration);
1429   }
1430
1431   capture_opts->real_time_mode =
1432     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
1433
1434   auto_scroll_live =
1435       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
1436
1437   capture_opts->show_info =
1438       !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hide_info_cb));
1439
1440   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
1441     g_resolv_flags |= RESOLV_MAC;
1442   else
1443     g_resolv_flags &= ~RESOLV_MAC;
1444   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
1445     g_resolv_flags |= RESOLV_NETWORK;
1446   else
1447     g_resolv_flags &= ~RESOLV_NETWORK;
1448   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
1449     g_resolv_flags |= RESOLV_TRANSPORT;
1450   else
1451     g_resolv_flags &= ~RESOLV_TRANSPORT;
1452
1453   capture_opts->has_ring_num_files =
1454     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb));
1455
1456   capture_opts->ring_num_files =
1457     gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
1458   if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES)
1459     capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES;
1460 #if RINGBUFFER_MIN_NUM_FILES > 0
1461   else if (capture_opts->ring_num_files < RINGBUFFER_MIN_NUM_FILES)
1462     capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
1463 #endif
1464
1465   capture_opts->multi_files_on =
1466     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb));
1467
1468   capture_opts->has_file_duration =
1469     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb));
1470   if (capture_opts->has_file_duration) {
1471     capture_opts->file_duration =
1472       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(file_duration_sb));
1473     capture_opts->file_duration =
1474       time_unit_option_menu_get_value(file_duration_om, capture_opts->file_duration);
1475   }
1476
1477   capture_opts->has_autostop_files =
1478     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb));
1479   if (capture_opts->has_autostop_files)
1480     capture_opts->autostop_files =
1481       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_files_sb));
1482
1483   if (capture_opts->multi_files_on) {
1484     capture_opts->has_autostop_filesize =
1485       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb));
1486     if (capture_opts->has_autostop_filesize) {
1487       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_filesize_sb));
1488       tmp = size_unit_option_menu_convert_value(ring_filesize_om, tmp);
1489       if(tmp != 0) {
1490         capture_opts->autostop_filesize = tmp;
1491       } else {
1492         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1493           PRIMARY_TEXT_START "Multiple files: Requested filesize too large!\n\n" PRIMARY_TEXT_END
1494           "The setting \"Next file every x byte(s)\" can't be greater than %u bytes (2GB).", G_MAXINT);
1495         return;
1496       }
1497     }
1498
1499     /* test if the settings are ok for a ringbuffer */
1500     if (capture_opts->save_file == NULL) {
1501       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1502         PRIMARY_TEXT_START "Multiple files: No capture file name given!\n\n" PRIMARY_TEXT_END
1503         "You must specify a filename if you want to use multiple files.");
1504       return;
1505     } else if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
1506       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1507         PRIMARY_TEXT_START "Multiple files: No file limit given!\n\n" PRIMARY_TEXT_END
1508         "You must specify a file size or duration at which is switched to the next capture file\n"
1509         "if you want to use multiple files.");
1510       g_free(capture_opts->save_file);
1511       capture_opts->save_file = NULL;
1512       return;
1513     }
1514   } else {
1515     capture_opts->has_autostop_filesize =
1516       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb));
1517     if (capture_opts->has_autostop_filesize) {
1518       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_filesize_sb));
1519       tmp = size_unit_option_menu_convert_value(stop_filesize_om, tmp);
1520       if(tmp != 0) {
1521         capture_opts->autostop_filesize = tmp;
1522       } else {
1523         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1524           PRIMARY_TEXT_START "Stop Capture: Requested filesize too large!\n\n" PRIMARY_TEXT_END
1525           "The setting \"... after x byte(s)\" can't be greater than %u bytes (2GB).", G_MAXINT);
1526         return;
1527       }
1528     }
1529   } /* multi_files_on */
1530 }
1531
1532 /* user requested to destroy the dialog */
1533 static void
1534 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1535 {
1536   GtkWidget *fs;
1537
1538   /* Is there a file selection dialog associated with this
1539      Capture Options dialog? */
1540   fs = OBJECT_GET_DATA(win, E_FILE_SEL_DIALOG_PTR_KEY);
1541
1542   if (fs != NULL) {
1543     /* Yes.  Destroy it. */
1544     window_destroy(fs);
1545   }
1546
1547   /* Note that we no longer have a "Capture Options" dialog box. */
1548   cap_open_w = NULL;
1549 }
1550
1551 /* user changed the interface entry */
1552 static void
1553 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer argp)
1554 {
1555   GtkWidget *linktype_om = argp;
1556
1557   set_link_type_list(linktype_om, entry);
1558 }
1559
1560 /*
1561  * Adjust the sensitivity of various widgets as per the current setting
1562  * of other widgets.
1563  */
1564 static void
1565 capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1566 {
1567   GtkWidget *if_cb,
1568             *snap_cb, *snap_sb,
1569             *multi_files_on_cb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
1570             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_om,
1571             *file_duration_cb, *file_duration_sb, *file_duration_om,
1572             *sync_cb, *auto_scroll_cb, *hide_info_cb,
1573             *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
1574             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_om,
1575             *stop_duration_cb, *stop_duration_sb, *stop_duration_om,
1576             *stop_files_cb, *stop_files_sb, *stop_files_lb;
1577
1578
1579   if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
1580   snap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
1581   snap_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
1582   multi_files_on_cb  = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_MULTI_FILES_ON_CB_KEY);
1583   ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
1584   ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
1585   ringbuffer_nbf_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_LB_KEY);
1586   ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
1587   ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
1588   ring_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_OM_KEY);
1589   file_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_CB_KEY);
1590   file_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_SB_KEY);
1591   file_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_OM_KEY);
1592   sync_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1593   auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1594   hide_info_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_HIDE_INFO_KEY);
1595   stop_packets_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_CB_KEY);
1596   stop_packets_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_SB_KEY);
1597   stop_packets_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_LB_KEY);
1598   stop_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_CB_KEY);
1599   stop_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_SB_KEY);
1600   stop_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_OM_KEY);
1601   stop_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_CB_KEY);
1602   stop_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_SB_KEY);
1603   stop_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_OM_KEY);
1604   stop_files_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_CB_KEY);
1605   stop_files_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_SB_KEY);
1606   stop_files_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_LB_KEY);
1607
1608   /* The snapshot length spinbox is sensitive if the "Limit each packet
1609      to" checkbox is on. */
1610   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
1611       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
1612
1613
1614   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
1615     /* "Update list of packets in real time" captures enabled; we don't
1616        support ring buffer mode for those captures, so turn ring buffer
1617        mode off if it's on, and make its toggle button, and the spin
1618        button for the number of ring buffer files (and the spin button's
1619        label), insensitive. */
1620 /*    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(multi_files_on_cb), FALSE);
1621     gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), FALSE);*/
1622
1623     /* Auto-scroll mode is meaningful only in "Update list of packets
1624        in real time" captures, so make its toggle button sensitive. */
1625     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
1626
1627     /*gtk_widget_set_sensitive(GTK_WIDGET(hide_info_cb), TRUE);*/
1628   } else {
1629     /* "Update list of packets in real time" captures disabled; that
1630        means ring buffer mode is OK, so make its toggle button
1631        sensitive. */
1632 /*    gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), TRUE);*/
1633
1634     /* Auto-scroll mode is meaningful only in "Update list of packets
1635        in real time" captures, so make its toggle button insensitive. */
1636     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
1637
1638     /*gtk_widget_set_sensitive(GTK_WIDGET(hide_info_cb), FALSE);*/
1639   }
1640
1641   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb))) {
1642     /* Ring buffer mode enabled. */
1643
1644     /* Force at least one of the "file switch" conditions (we need at least one) */
1645     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)) == FALSE &&
1646         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)) == FALSE) {
1647       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb), TRUE);
1648     }
1649
1650     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), TRUE);
1651     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb),
1652           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
1653     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb),
1654           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
1655
1656     /* The ring filesize spinbox is sensitive if the "Next capture file
1657          after N kilobytes" checkbox is on. */
1658     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), TRUE);
1659     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),
1660           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
1661     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_om),
1662           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
1663
1664     /* The ring duration spinbox is sensitive if the "Next capture file
1665          after N seconds" checkbox is on. */
1666     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), TRUE);
1667     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),
1668           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
1669     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_om),
1670           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
1671
1672     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), FALSE);
1673     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb), FALSE);
1674     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_om), FALSE);
1675
1676     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), TRUE);
1677     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb),
1678           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
1679     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb),
1680           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
1681   } else {
1682     /* Ring buffer mode disabled. */
1683     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), FALSE);
1684     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
1685     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
1686
1687     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), FALSE);
1688     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),FALSE);
1689     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_om),FALSE);
1690
1691     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), FALSE);
1692     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),FALSE);
1693     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_om),FALSE);
1694
1695     /* The maximum file size spinbox is sensitive if the "Stop capture
1696          after N kilobytes" checkbox is on. */
1697     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), TRUE);
1698     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb),
1699           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
1700     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_om),
1701           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
1702
1703     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), FALSE);
1704     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb), FALSE);
1705     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb), FALSE);
1706   }
1707
1708   /* The maximum packet count spinbox is sensitive if the "Stop capture
1709      after N packets" checkbox is on. */
1710   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_sb),
1711       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
1712   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_lb),
1713       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
1714
1715   /* The capture duration spinbox is sensitive if the "Stop capture
1716      after N seconds" checkbox is on. */
1717   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_sb),
1718       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
1719   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_om),
1720       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
1721 }
1722
1723 #endif /* HAVE_LIBPCAP */