1c39ab5dc9c619f7fb37da412304fd790d2411e2
[obnox/wireshark/wip.git] / gtk / capture_dlg.c
1 /* capture_dlg.c
2  * Routines for packet capture windows
3  *
4  * $Id: capture_dlg.c,v 1.120 2004/03/06 11:10:14 ulfl Exp $
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/resolv.h>
39 #include "main.h"
40 #include "ui_util.h"
41 #include "capture_dlg.h"
42 #include "filter_prefs.h"
43 #include "simple_dialog.h"
44 #include "dlg_utils.h"
45 #include "pcap-util.h"
46 #include "capture_combo_utils.h"
47 #include "prefs.h"
48 #include "ringbuffer.h"
49 #include <epan/filesystem.h>
50 #include "compat_macros.h"
51 #include "file_dlg.h"
52 #include "help_dlg.h"
53
54 #ifdef _WIN32
55 #include "capture-wpcap.h"
56 #endif
57
58 /* Capture callback data keys */
59 #define E_CAP_IFACE_KEY             "cap_iface"
60 #define E_CAP_SNAP_CB_KEY           "cap_snap_cb"
61 #define E_CAP_LT_OM_KEY             "cap_lt_om"
62 #define E_CAP_LT_OM_LABEL_KEY       "cap_lt_om_label"
63 #define E_CAP_SNAP_SB_KEY           "cap_snap_sb"
64 #define E_CAP_PROMISC_KEY           "cap_promisc"
65 #define E_CAP_FILT_KEY              "cap_filter_te"
66 #define E_CAP_FILE_TE_KEY           "cap_file_te"
67 #define E_CAP_MULTI_FILES_ON_CB_KEY "cap_multi_files_on_cb"
68 #define E_CAP_RING_FILESIZE_CB_KEY  "cap_ring_filesize_cb"
69 #define E_CAP_RING_FILESIZE_SB_KEY  "cap_ring_filesize_sb"
70 #define E_CAP_RING_FILESIZE_OM_KEY  "cap_ring_filesize_om"
71 #define E_CAP_FILE_DURATION_CB_KEY  "cap_file_duration_cb"
72 #define E_CAP_FILE_DURATION_SB_KEY  "cap_file_duration_sb"
73 #define E_CAP_FILE_DURATION_OM_KEY  "cap_file_duration_om"
74 #define E_CAP_RING_NBF_CB_KEY       "cap_ring_nbf_cb"
75 #define E_CAP_RING_NBF_SB_KEY       "cap_ring_nbf_sb"
76 #define E_CAP_RING_NBF_LB_KEY       "cap_ring_nbf_lb"
77 #define E_CAP_STOP_FILES_CB_KEY     "cap_stop_files_cb"
78 #define E_CAP_STOP_FILES_SB_KEY     "cap_stop_files_sb"
79 #define E_CAP_STOP_FILES_LB_KEY     "cap_stop_files_lb"
80 #define E_CAP_SYNC_KEY              "cap_sync"
81 #define E_CAP_AUTO_SCROLL_KEY       "cap_auto_scroll"
82 #define E_CAP_STOP_PACKETS_CB_KEY   "cap_stop_packets_cb"
83 #define E_CAP_STOP_PACKETS_SB_KEY   "cap_stop_packets_sb"
84 #define E_CAP_STOP_PACKETS_LB_KEY   "cap_stop_packets_lb"
85 #define E_CAP_STOP_FILESIZE_CB_KEY  "cap_stop_filesize_cb"
86 #define E_CAP_STOP_FILESIZE_SB_KEY  "cap_stop_filesize_sb"
87 #define E_CAP_STOP_FILESIZE_OM_KEY  "cap_stop_filesize_om"
88 #define E_CAP_STOP_DURATION_CB_KEY  "cap_stop_duration_cb"
89 #define E_CAP_STOP_DURATION_SB_KEY  "cap_stop_duration_sb"
90 #define E_CAP_STOP_DURATION_OM_KEY  "cap_stop_duration_om"
91 #define E_CAP_M_RESOLVE_KEY         "cap_m_resolve"
92 #define E_CAP_N_RESOLVE_KEY         "cap_n_resolve"
93 #define E_CAP_T_RESOLVE_KEY         "cap_t_resolve"
94
95 #define E_CAP_OM_LT_VALUE_KEY       "cap_om_lt_value"
96
97 #define E_FS_CALLER_PTR_KEY         "fs_caller_ptr"
98 #define E_FILE_SEL_DIALOG_PTR_KEY   "file_sel_dialog_ptr"
99
100 static void
101 capture_prep_file_cb(GtkWidget *w, gpointer te);
102
103 static void
104 select_link_type_cb(GtkWidget *w, gpointer data);
105
106 static void
107 cap_prep_fs_ok_cb(GtkWidget *w, gpointer data);
108
109 static void
110 cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
111
112 static void
113 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
114
115 static void
116 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
117
118 static void
119 capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
120
121 static void
122 capture_prep_close_cb(GtkWidget *close_bt, 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 void
131 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
132 {
133     capture_stop();
134 }
135
136 /*
137  * Given text that contains an interface name possibly prefixed by an
138  * interface description, extract the interface name.
139  */
140 static char *
141 get_if_name(char *if_text)
142 {
143   char *if_name;
144
145 #ifdef WIN32
146   /*
147    * We cannot assume that the interface name doesn't contain a space;
148    * some names on Windows OT do.
149    *
150    * We also can't assume it begins with "\Device\", either, as, on
151    * Windows OT, WinPcap doesn't put "\Device\" in front of the name.
152    *
153    * As I remember, we can't assume that the interface description
154    * doesn't contain a colon, either; I think some do.
155    *
156    * We can probably assume that the interface *name* doesn't contain
157    * a colon, however; if any interface name does contain a colon on
158    * Windows, it'll be time to just get rid of the damn interface
159    * descriptions in the drop-down list, have just the names in the
160    * drop-down list, and have a "Browse..." button to browse for interfaces,
161    * with names, descriptions, IP addresses, blah blah blah available when
162    * possible.
163    *
164    * So we search backwards for a colon.  If we don't find it, just
165    * return the entire string; otherwise, skip the colon and any blanks
166    * after it, and return that string.
167    */
168    if_name = strrchr(if_text, ':');
169    if (if_name == NULL) {
170      if_name = if_text;
171    } else {
172      if_name++;
173      while (*if_name == ' ')
174        if_name++;
175    }
176 #else
177   /*
178    * There's a space between the interface description and name, and
179    * the interface name shouldn't have a space in it (it doesn't, on
180    * UNIX systems); look backwards in the string for a space.
181    *
182    * (An interface name might, however, contain a colon in it, which
183    * is why we don't use the colon search on UNIX.)
184    */
185   if_name = strrchr(if_text, ' ');
186   if (if_name == NULL) {
187     if_name = if_text;
188   } else {
189     if_name++;
190   }
191 #endif
192   return if_name;
193 }
194
195 /*
196  * Keep a static pointer to the current "Capture Options" window, if
197  * any, so that if somebody tries to do "Capture:Start" while there's
198  * already a "Capture Options" window up, we just pop up the existing
199  * one, rather than creating a new one.
200  */
201 static GtkWidget *cap_open_w;
202
203 static void
204 set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
205 {
206   gchar *entry_text;
207   gchar *if_text;
208   gchar *if_name;
209   GList *if_list;
210   GList *if_entry;
211   if_info_t *if_info;
212   GList *lt_list;
213   int err;
214   char err_buf[PCAP_ERRBUF_SIZE];
215   GtkWidget *lt_menu, *lt_menu_item;
216   GList *lt_entry;
217   data_link_info_t *data_link_info;
218   gchar *linktype_menu_label;
219   guint num_supported_link_types;
220   GtkWidget *linktype_lb = OBJECT_GET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY);
221
222   lt_menu = gtk_menu_new();
223   entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
224   if_text = g_strstrip(entry_text);
225   if_name = get_if_name(if_text);
226
227   /*
228    * If the interface name is in the list of known interfaces, get
229    * its list of link-layer types and set the option menu to display it.
230    *
231    * If it's not, don't bother - the user might be in the middle of
232    * editing the list, or it might be a remote device in which case
233    * getting the list could take an arbitrarily-long period of time.
234    * The list currently won't contain any remote devices (as
235    * "pcap_findalldevs()" doesn't know about remote devices, and neither
236    * does the code we use if "pcap_findalldevs()" isn't available), but
237    * should contain all the local devices on which you can capture.
238    */
239   lt_list = NULL;
240   if (*if_name != '\0') {
241     /*
242      * Try to get the list of known interfaces.
243      */
244     if_list = get_interface_list(&err, err_buf);
245     if (if_list != NULL) {
246       /*
247        * We have the list - check it.
248        */
249       for (if_entry = if_list; if_entry != NULL;
250            if_entry = g_list_next(if_entry)) {
251         if_info = if_entry->data;
252         if (strcmp(if_info->name, if_name) == 0) {
253           /*
254            * It's in the list.
255            * Get the list of link-layer types for it.
256            */
257           lt_list = get_pcap_linktype_list(if_name, err_buf);
258         }
259       }
260       free_interface_list(if_list);
261     }
262   }
263   g_free(entry_text);
264   num_supported_link_types = 0;
265   for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
266     data_link_info = lt_entry->data;
267     if (data_link_info->description != NULL) {
268       lt_menu_item = gtk_menu_item_new_with_label(data_link_info->description);
269       OBJECT_SET_DATA(lt_menu_item, E_CAP_LT_OM_KEY, linktype_om);
270       SIGNAL_CONNECT(lt_menu_item, "activate", select_link_type_cb,
271                      GINT_TO_POINTER(data_link_info->dlt));
272       num_supported_link_types++;
273     } else {
274       /* Not supported - tell them about it but don't let them select it. */
275       linktype_menu_label = g_strdup_printf("%s (not supported)",
276                                             data_link_info->name);
277       lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
278       g_free(linktype_menu_label);
279       gtk_widget_set_sensitive(lt_menu_item, FALSE);
280     }
281     gtk_menu_append(GTK_MENU(lt_menu), lt_menu_item);
282   }
283   if (lt_list != NULL)
284     free_pcap_linktype_list(lt_list);
285   gtk_option_menu_set_menu(GTK_OPTION_MENU(linktype_om), lt_menu);
286   gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
287   gtk_widget_set_sensitive(linktype_om, num_supported_link_types >= 2);
288 }
289
290
291 #define TIME_UNIT_SECOND    0
292 #define TIME_UNIT_MINUTE    1
293 #define TIME_UNIT_HOUR      2
294 #define TIME_UNIT_DAY       3
295 #define MAX_TIME_UNITS 4
296 static char *time_unit_name[MAX_TIME_UNITS] = {
297         "second(s)",
298         "minute(s)",
299         "hour(s)",
300         "day(s)",
301 };
302
303 GtkWidget *time_unit_option_menu_new(void) {
304     GtkWidget *unit_om, *menu, *menu_item;
305     int i;
306
307         unit_om=gtk_option_menu_new();
308         menu=gtk_menu_new();
309         for(i=0;i<MAX_TIME_UNITS;i++){
310                 menu_item=gtk_menu_item_new_with_label(time_unit_name[i]);
311                 OBJECT_SET_DATA(menu_item, "time_unit", GINT_TO_POINTER(i));
312                 gtk_menu_append(GTK_MENU(menu), menu_item);
313         }
314         gtk_menu_set_active(GTK_MENU(menu), TIME_UNIT_MINUTE);
315
316         gtk_option_menu_set_menu(GTK_OPTION_MENU(unit_om), menu);
317
318     return unit_om;
319 }
320
321 guint32 time_unit_option_menu_get_value(
322 GtkWidget *unit_om,
323 guint32 value)
324 {
325         GtkWidget *menu, *menu_item;
326     int unit;
327         
328     menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(unit_om));
329     menu_item = gtk_menu_get_active(GTK_MENU(menu));
330     unit = GPOINTER_TO_INT(OBJECT_GET_DATA(menu_item, "time_unit"));
331
332
333     switch(unit) {
334     case(TIME_UNIT_SECOND):
335         return value;
336         break;
337     case(TIME_UNIT_MINUTE):
338         return value * 60;
339         break;
340     case(TIME_UNIT_HOUR):
341         return value * 60 * 60;
342         break;
343     case(TIME_UNIT_DAY):
344         return value * 60 * 60 * 24;
345         break;
346     default:
347         g_assert_not_reached();
348         return 0;
349     }
350 }
351
352
353 #define SIZE_UNIT_BYTES     0
354 #define SIZE_UNIT_KILOBYTES 1
355 #define SIZE_UNIT_MEGABYTES 2
356 #define SIZE_UNIT_GIGABYTES 3
357 #define MAX_SIZE_UNITS 4
358 static char *size_unit_name[MAX_SIZE_UNITS] = {
359         "byte(s)",
360         "kilobyte(s)",
361         "megabyte(s)",
362         "gigabyte(s)",
363 };
364
365 GtkWidget *size_unit_option_menu_new(void) {
366     GtkWidget *unit_om, *menu, *menu_item;
367     int i;
368
369         unit_om=gtk_option_menu_new();
370         menu=gtk_menu_new();
371         for(i=0;i<MAX_SIZE_UNITS;i++){
372                 menu_item=gtk_menu_item_new_with_label(size_unit_name[i]);
373                 OBJECT_SET_DATA(menu_item, "size_unit", GINT_TO_POINTER(i));
374                 gtk_menu_append(GTK_MENU(menu), menu_item);
375         }
376         gtk_menu_set_active(GTK_MENU(menu), SIZE_UNIT_MEGABYTES);
377
378         gtk_option_menu_set_menu(GTK_OPTION_MENU(unit_om), menu);
379
380     return unit_om;
381 }
382
383 guint32 size_unit_option_menu_get_value(
384 GtkWidget *unit_om,
385 guint32 value)
386 {
387         GtkWidget *menu, *menu_item;
388     int unit;
389         
390     menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(unit_om));
391     menu_item = gtk_menu_get_active(GTK_MENU(menu));
392     unit = GPOINTER_TO_INT(OBJECT_GET_DATA(menu_item, "size_unit"));
393
394
395     switch(unit) {
396     case(SIZE_UNIT_BYTES):
397         return value;
398         break;
399     case(SIZE_UNIT_KILOBYTES):
400         if(value > G_MAXINT / 1024) {
401             return 0;
402         } else {
403             return value * 1024;
404         }
405         break;
406     case(SIZE_UNIT_MEGABYTES):
407         if(value > G_MAXINT / (1024 * 1024)) {
408             return 0;
409         } else {
410             return value * 1024 * 1024;
411         }
412         break;
413     case(SIZE_UNIT_GIGABYTES):
414         if(value > G_MAXINT / (1024 * 1024 * 1024)) {
415             return 0;
416         } else {
417             return value * 1024 * 1024 * 1024;
418         }
419         break;
420     default:
421         g_assert_not_reached();
422         return 0;
423     }
424 }
425
426
427 void
428 capture_prep(void)
429 {
430   GtkWidget     *main_vb,
431                 *main_hb, *left_vb, *right_vb,
432
433                 *capture_fr, *capture_vb,
434                 *if_hb, *if_cb, *if_lb,
435                 *linktype_hb, *linktype_lb, *linktype_om,
436                 *snap_hb, *snap_cb, *snap_sb, *snap_lb,
437                 *promisc_cb,
438                 *filter_hb, *filter_bt, *filter_te,
439
440                 *file_fr, *file_vb,
441                 *file_hb, *file_bt, *file_lb, *file_te,
442                 *multi_tb, *multi_files_on_cb, 
443                 *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_om,
444                 *file_duration_cb, *file_duration_sb, *file_duration_om,
445                 *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb, 
446                 *stop_files_cb, *stop_files_sb, *stop_files_lb,
447
448                 *limit_fr, *limit_vb, *limit_tb,
449                 *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
450                 *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_om,
451                 *stop_duration_cb, *stop_duration_sb, *stop_duration_om,
452
453                 *display_fr, *display_vb,
454                 *sync_cb, *auto_scroll_cb,
455
456                 *resolv_fr, *resolv_vb,
457                 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
458                 *bbox, *ok_bt, *cancel_bt,
459                 *help_bt;
460 #if GTK_MAJOR_VERSION < 2
461   GtkAccelGroup *accel_group;
462 #endif
463   GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
464                 *stop_packets_adj, *stop_filesize_adj, *stop_duration_adj, *stop_files_adj, *ring_filesize_adj, *file_duration_adj;
465   GList         *if_list, *combo_list;
466   int           err;
467   int           row;
468   char          err_str[PCAP_ERRBUF_SIZE];
469
470   if (cap_open_w != NULL) {
471     /* There's already a "Capture Options" dialog box; reactivate it. */
472     reactivate_window(cap_open_w);
473     return;
474   }
475
476 #ifdef _WIN32
477   /* Is WPcap loaded? */
478   if (!has_wpcap) {
479           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
480                   "Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n"
481                   "to capture packets.\n\n"
482                   "In order to capture packets, WinPcap must be installed; see\n"
483                   "\n"
484                   "        http://winpcap.polito.it/\n"
485                   "\n"
486                   "or the mirror at\n"
487                   "\n"
488                   "        http://winpcap.mirror.ethereal.com/\n"
489                   "\n"
490                   "or the mirror at\n"
491                   "\n"
492                   "        http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n"
493                   "\n"
494                   "for a downloadable version of WinPcap and for instructions\n"
495                   "on how to install WinPcap.");
496           return;
497   }
498 #endif
499
500   if_list = get_interface_list(&err, err_str);
501   if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
502     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "Can't get list of interfaces: %s",
503                         err_str);
504   }
505
506   cap_open_w = dlg_window_new("Ethereal: Capture Options");
507   SIGNAL_CONNECT(cap_open_w, "destroy", capture_prep_destroy_cb, NULL);
508
509 #if GTK_MAJOR_VERSION < 2
510   /* Accelerator group for the accelerators (or, as they're called in
511      Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
512      Ctrl+<key> is an accelerator). */
513   accel_group = gtk_accel_group_new();
514   gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group);
515 #endif
516
517   main_vb = gtk_vbox_new(FALSE, 0);
518   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
519   gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
520
521   /* Capture-related options frame */
522   capture_fr = gtk_frame_new("Capture");
523   gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
524
525   capture_vb = gtk_vbox_new(FALSE, 3);
526   gtk_container_border_width(GTK_CONTAINER(capture_vb), 5);
527   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
528
529   /* Interface row */
530   if_hb = gtk_hbox_new(FALSE, 3);
531   gtk_container_add(GTK_CONTAINER(capture_vb), if_hb);
532
533   if_lb = gtk_label_new("Interface:");
534   gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
535
536   if_cb = gtk_combo_new();
537   combo_list = build_capture_combo_list(if_list, TRUE);
538   if (combo_list != NULL)
539     gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
540   if (cfile.iface == NULL && prefs.capture_device != NULL) {
541     /* No interface was specified on the command line or in a previous
542        capture, but there is one specified in the preferences file;
543        make the one from the preferences file the default */
544     cfile.iface = g_strdup(prefs.capture_device);
545   }
546   if (cfile.iface != NULL)
547     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
548   else if (combo_list != NULL) {
549     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
550                        (char *)combo_list->data);
551   }
552   free_capture_combo_list(combo_list);
553   free_interface_list(if_list);
554   gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
555
556   /* Linktype row */
557   linktype_hb = gtk_hbox_new(FALSE, 3);
558   gtk_box_pack_start(GTK_BOX(capture_vb), linktype_hb, FALSE, FALSE, 0);
559
560   linktype_lb = gtk_label_new("Link-layer header type:");
561   gtk_box_pack_start(GTK_BOX(linktype_hb), linktype_lb, FALSE, FALSE, 6);
562
563   linktype_om = gtk_option_menu_new();
564   OBJECT_SET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY, linktype_lb);
565   /* Default to "use the default" */
566   OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(-1));
567   set_link_type_list(linktype_om, GTK_COMBO(if_cb)->entry);
568   gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_om, FALSE, FALSE, 0);
569   SIGNAL_CONNECT(GTK_ENTRY(GTK_COMBO(if_cb)->entry), "changed",
570                  capture_prep_interface_changed_cb, linktype_om);
571
572   /* Promiscuous mode row */
573   promisc_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
574       "Capture packets in _promiscuous mode", accel_group);
575   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb),
576                 capture_opts.promisc_mode);
577   gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
578
579   /* Capture length row */
580   snap_hb = gtk_hbox_new(FALSE, 3);
581   gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
582
583   snap_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("_Limit each packet to", accel_group);
584   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb),
585                 capture_opts.has_snaplen);
586   SIGNAL_CONNECT(snap_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
587   gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
588
589   snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.snaplen,
590     MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
591   snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
592   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
593   WIDGET_SET_SIZE(snap_sb, 80, -1);
594   gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
595
596   snap_lb = gtk_label_new("bytes");
597   gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5);
598   gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
599
600   /* Filter row */
601   filter_hb = gtk_hbox_new(FALSE, 3);
602   gtk_box_pack_start(GTK_BOX(capture_vb), filter_hb, FALSE, FALSE, 0);
603
604   filter_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_CAPTURE_FILTER_ENTRY);
605   SIGNAL_CONNECT(filter_bt, "clicked", capture_filter_construct_cb, NULL);
606   SIGNAL_CONNECT(filter_bt, "destroy", filter_button_destroy_cb, NULL);
607   gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
608
609   filter_te = gtk_entry_new();
610   if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
611   OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
612   gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3);
613
614   main_hb = gtk_hbox_new(FALSE, 5);
615   gtk_container_border_width(GTK_CONTAINER(main_hb), 0);
616   gtk_container_add(GTK_CONTAINER(main_vb), main_hb);
617
618   left_vb = gtk_vbox_new(FALSE, 0);
619   gtk_container_border_width(GTK_CONTAINER(left_vb), 0);
620   gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
621
622   right_vb = gtk_vbox_new(FALSE, 0);
623   gtk_container_border_width(GTK_CONTAINER(right_vb), 0);
624   gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 0);
625
626
627   /* Capture file-related options frame */
628   file_fr = gtk_frame_new("Capture File(s)");
629   gtk_container_add(GTK_CONTAINER(left_vb), file_fr);
630
631   file_vb = gtk_vbox_new(FALSE, 3);
632   gtk_container_border_width(GTK_CONTAINER(file_vb), 5);
633   gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
634
635   /* File row */
636   file_hb = gtk_hbox_new(FALSE, 3);
637   gtk_box_pack_start(GTK_BOX(file_vb), file_hb, FALSE, FALSE, 0);
638
639   file_lb = gtk_label_new("File:");
640   gtk_box_pack_start(GTK_BOX(file_hb), file_lb, FALSE, FALSE, 3);
641
642   file_te = gtk_entry_new();
643   gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
644
645   file_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_BROWSE);
646   gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3);
647
648   SIGNAL_CONNECT(file_bt, "clicked", capture_prep_file_cb, file_te);
649
650   /* multiple files table */
651   multi_tb = gtk_table_new(5, 3, FALSE);
652   gtk_table_set_row_spacings(GTK_TABLE(multi_tb), 1);
653   gtk_table_set_col_spacings(GTK_TABLE(multi_tb), 3);
654   gtk_box_pack_start(GTK_BOX(file_vb), multi_tb, FALSE, FALSE, 0);
655   row = 0;
656
657   /* multiple files row */
658   multi_files_on_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("Use _multiple files", accel_group);
659   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(multi_files_on_cb),
660                 capture_opts.multi_files_on);
661   SIGNAL_CONNECT(multi_files_on_cb, "toggled", capture_prep_adjust_sensitivity,
662                  cap_open_w);
663   gtk_table_attach_defaults(GTK_TABLE(multi_tb), multi_files_on_cb, 0, 1, row, row+1);
664   row++;
665
666   /* Ring buffer filesize row */
667   ring_filesize_cb = gtk_check_button_new_with_label("Next file every");
668   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_filesize_cb),
669                 capture_opts.has_autostop_filesize);
670   SIGNAL_CONNECT(ring_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
671   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_cb, 0, 1, row, row+1);
672
673   ring_filesize_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_filesize,
674     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
675   ring_filesize_sb = gtk_spin_button_new (ring_filesize_adj, 0, 0);
676   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_filesize_sb), TRUE);
677   WIDGET_SET_SIZE(ring_filesize_sb, 80, -1);
678   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_sb, 1, 2, row, row+1);
679
680   ring_filesize_om = size_unit_option_menu_new();
681   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ring_filesize_om, 2, 3, row, row+1);
682   row++;
683
684   /* Ring buffer duration row */
685   file_duration_cb = gtk_check_button_new_with_label("Next file every");
686   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(file_duration_cb),
687                               capture_opts.has_file_duration);
688   SIGNAL_CONNECT(file_duration_cb, "toggled", 
689                  capture_prep_adjust_sensitivity, cap_open_w);
690   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_cb, 0, 1, row, row+1);
691
692   file_duration_adj = (GtkAdjustment *)gtk_adjustment_new((gfloat)capture_opts.file_duration,
693     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
694   file_duration_sb = gtk_spin_button_new (file_duration_adj, 0, 0);
695   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (file_duration_sb), TRUE);
696   WIDGET_SET_SIZE(file_duration_sb, 80, -1);
697   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_sb, 1, 2, row, row+1);
698
699   file_duration_om = time_unit_option_menu_new();
700   gtk_table_attach_defaults(GTK_TABLE(multi_tb), file_duration_om, 2, 3, row, row+1);
701   row++;
702
703   /* Ring buffer files row */
704   ringbuffer_nbf_cb = gtk_check_button_new_with_label("Ring buffer with");
705   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb),
706                 capture_opts.has_ring_num_files);
707   SIGNAL_CONNECT(ringbuffer_nbf_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
708   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_cb, 0, 1, row, row+1);
709
710   ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.ring_num_files,
711     2/*RINGBUFFER_MIN_NUM_FILES*/, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
712   ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
713   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
714   WIDGET_SET_SIZE(ringbuffer_nbf_sb, 80, -1);
715   SIGNAL_CONNECT(ringbuffer_nbf_sb, "changed", capture_prep_adjust_sensitivity, cap_open_w);
716   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_sb, 1, 2, row, row+1);
717
718   ringbuffer_nbf_lb = gtk_label_new("files");
719   gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 0, 0.5);
720   gtk_table_attach_defaults(GTK_TABLE(multi_tb), ringbuffer_nbf_lb, 2, 3, row, row+1);
721   row++;
722
723   /* Files row */
724   stop_files_cb = gtk_check_button_new_with_label("Stop capture after");
725   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_files_cb),
726                 capture_opts.has_autostop_files);
727   SIGNAL_CONNECT(stop_files_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
728   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_cb, 0, 1, row, row+1);
729
730   stop_files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_files,
731     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
732   stop_files_sb = gtk_spin_button_new (stop_files_adj, 0, 0);
733   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_files_sb), TRUE);
734   WIDGET_SET_SIZE(stop_files_sb, 80, -1);
735   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_sb, 1, 2, row, row+1);
736
737   stop_files_lb = gtk_label_new("file(s)");
738   gtk_misc_set_alignment(GTK_MISC(stop_files_lb), 0, 0.5);
739   gtk_table_attach_defaults(GTK_TABLE(multi_tb), stop_files_lb, 2, 3, row, row+1);
740   row++;
741
742   /* Capture limits frame */
743   limit_fr = gtk_frame_new("Stop Capture ...");
744   gtk_container_add(GTK_CONTAINER(left_vb), limit_fr);
745
746   limit_vb = gtk_vbox_new(FALSE, 3);
747   gtk_container_border_width(GTK_CONTAINER(limit_vb), 5);
748   gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
749
750   /* limits table */
751   limit_tb = gtk_table_new(3, 3, FALSE);
752   gtk_table_set_row_spacings(GTK_TABLE(limit_tb), 1);
753   gtk_table_set_col_spacings(GTK_TABLE(limit_tb), 3);
754   gtk_box_pack_start(GTK_BOX(limit_vb), limit_tb, FALSE, FALSE, 0);
755   row = 0;
756
757   /* Packet count row */
758   stop_packets_cb = gtk_check_button_new_with_label("... after");
759   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_packets_cb),
760                 capture_opts.has_autostop_packets);
761   SIGNAL_CONNECT(stop_packets_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
762   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_cb, 0, 1, row, row+1);
763
764   stop_packets_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_packets,
765     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
766   stop_packets_sb = gtk_spin_button_new (stop_packets_adj, 0, 0);
767   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_packets_sb), TRUE);
768   WIDGET_SET_SIZE(stop_packets_sb, 80, -1);
769   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_sb, 1, 2, row, row+1);
770
771   stop_packets_lb = gtk_label_new("packet(s)");
772   gtk_misc_set_alignment(GTK_MISC(stop_packets_lb), 0, 0.5);
773   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_packets_lb, 2, 3, row, row+1);
774   row++;
775
776   /* Filesize row */
777   stop_filesize_cb = gtk_check_button_new_with_label("... after");
778   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_filesize_cb),
779                 capture_opts.has_autostop_filesize);
780   SIGNAL_CONNECT(stop_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
781   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_cb, 0, 1, row, row+1);
782
783   stop_filesize_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_filesize,
784     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
785   stop_filesize_sb = gtk_spin_button_new (stop_filesize_adj, 0, 0);
786   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_filesize_sb), TRUE);
787   WIDGET_SET_SIZE(stop_filesize_sb, 80, -1);
788   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_sb, 1, 2, row, row+1);
789
790   stop_filesize_om = size_unit_option_menu_new();
791   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_filesize_om, 2, 3, row, row+1);
792   row++;
793
794   /* Duration row */
795   stop_duration_cb = gtk_check_button_new_with_label("... after");
796   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(stop_duration_cb),
797                 capture_opts.has_autostop_duration);
798   SIGNAL_CONNECT(stop_duration_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
799   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_cb, 0, 1, row, row+1);
800
801   stop_duration_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_duration,
802     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
803   stop_duration_sb = gtk_spin_button_new (stop_duration_adj, 0, 0);
804   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_duration_sb), TRUE);
805   WIDGET_SET_SIZE(stop_duration_sb, 80, -1);
806   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_sb, 1, 2, row, row+1);
807
808   stop_duration_om = time_unit_option_menu_new();
809   gtk_table_attach_defaults(GTK_TABLE(limit_tb), stop_duration_om, 2, 3, row, row+1);
810   row++;
811
812   /* Display-related options frame */
813   display_fr = gtk_frame_new("Display Options");
814   gtk_container_add(GTK_CONTAINER(right_vb), display_fr);
815
816   display_vb = gtk_vbox_new(FALSE, 0);
817   gtk_container_border_width(GTK_CONTAINER(display_vb), 5);
818   gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
819
820   /* "Update display in real time" row */
821   sync_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
822       "_Update list of packets in real time", accel_group);
823   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb),
824                 capture_opts.sync_mode);
825   SIGNAL_CONNECT(sync_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
826   gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
827
828   /* "Auto-scroll live update" row */
829   auto_scroll_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
830                 "_Automatic scrolling in live capture", accel_group);
831   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
832   gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
833
834   /* Name Resolution frame */
835   resolv_fr = gtk_frame_new("Name Resolution");
836   gtk_container_add(GTK_CONTAINER(right_vb), resolv_fr);
837
838   resolv_vb = gtk_vbox_new(FALSE, 0);
839   gtk_container_border_width(GTK_CONTAINER(resolv_vb), 5);
840   gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
841
842   m_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
843                 "Enable _MAC name resolution", accel_group);
844   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
845                 g_resolv_flags & RESOLV_MAC);
846   gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
847
848   n_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
849                 "Enable _network name resolution", accel_group);
850   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
851                 g_resolv_flags & RESOLV_NETWORK);
852   gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
853
854   t_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
855                 "Enable _transport name resolution", accel_group);
856   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
857                 g_resolv_flags & RESOLV_TRANSPORT);
858   gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
859
860   /* Button row: OK and cancel buttons */
861   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
862   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
863
864   ok_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
865   SIGNAL_CONNECT(ok_bt, "clicked", capture_prep_ok_cb, cap_open_w);
866   gtk_widget_grab_default(ok_bt);
867
868   cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
869   SIGNAL_CONNECT(cancel_bt, "clicked", capture_prep_close_cb, cap_open_w);
870
871   help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
872   SIGNAL_CONNECT(help_bt, "clicked", help_topic_cb, "Capturing");
873
874   /* Attach pointers to needed widgets to the capture prefs window/object */
875   OBJECT_SET_DATA(cap_open_w, E_CAP_IFACE_KEY, if_cb);
876   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_CB_KEY, snap_cb);
877   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_SB_KEY, snap_sb);
878   OBJECT_SET_DATA(cap_open_w, E_CAP_LT_OM_KEY, linktype_om);
879   OBJECT_SET_DATA(cap_open_w, E_CAP_PROMISC_KEY, promisc_cb);
880   OBJECT_SET_DATA(cap_open_w, E_CAP_FILT_KEY,  filter_te);
881   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_TE_KEY,  file_te);
882   OBJECT_SET_DATA(cap_open_w, E_CAP_MULTI_FILES_ON_CB_KEY,  multi_files_on_cb);
883   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_CB_KEY,  ringbuffer_nbf_cb);
884   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_SB_KEY,  ringbuffer_nbf_sb);
885   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_LB_KEY,  ringbuffer_nbf_lb);
886   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_CB_KEY,  ring_filesize_cb);
887   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_SB_KEY,  ring_filesize_sb);
888   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_OM_KEY,  ring_filesize_om);
889   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_DURATION_CB_KEY,  file_duration_cb);
890   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_DURATION_SB_KEY,  file_duration_sb);
891   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_DURATION_OM_KEY,  file_duration_om);
892   OBJECT_SET_DATA(cap_open_w, E_CAP_SYNC_KEY,  sync_cb);
893   OBJECT_SET_DATA(cap_open_w, E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
894   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_PACKETS_CB_KEY, stop_packets_cb);
895   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_PACKETS_SB_KEY, stop_packets_sb);
896   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_PACKETS_LB_KEY, stop_packets_lb);
897   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILESIZE_CB_KEY, stop_filesize_cb);
898   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILESIZE_SB_KEY, stop_filesize_sb);
899   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILESIZE_OM_KEY, stop_filesize_om);
900   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_DURATION_CB_KEY,  stop_duration_cb);
901   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_DURATION_SB_KEY,  stop_duration_sb);
902   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_DURATION_OM_KEY,  stop_duration_om);
903   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILES_CB_KEY, stop_files_cb);
904   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILES_SB_KEY, stop_files_sb);
905   OBJECT_SET_DATA(cap_open_w, E_CAP_STOP_FILES_LB_KEY, stop_files_lb);
906   OBJECT_SET_DATA(cap_open_w, E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
907   OBJECT_SET_DATA(cap_open_w, E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
908   OBJECT_SET_DATA(cap_open_w, E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
909
910   /* Set the sensitivity of various widgets as per the settings of other
911      widgets. */
912   capture_prep_adjust_sensitivity(NULL, cap_open_w);
913
914   /* Catch the "activate" signal on the filter and file name text
915      entries, so that if the user types Return there, we act as if the
916      "OK" button had been selected, as happens if Return is typed if some
917      widget that *doesn't* handle the Return key has the input focus. */
918   dlg_set_activate(filter_te, ok_bt);
919   dlg_set_activate(file_te, ok_bt);
920
921   /* Catch the "key_press_event" signal in the window, so that we can catch
922      the ESC key being pressed and act as if the "Cancel" button had
923      been selected. */
924   dlg_set_cancel(cap_open_w, cancel_bt);
925
926   /* XXX - why does not
927
928      gtk_widget_grab_focus(if_cb);
929
930     give the initial focus to the "Interface" combo box?
931
932     Or should I phrase that as "why does GTK+ continually frustrate
933     attempts to make GUIs driveable from the keyboard?"  We have to
934     go catch the activate signal on every single GtkEntry widget
935     (rather than having widgets whose activate signal is *not*
936     caught not catch the Return keystroke, so that it passes on,
937     ultimately, to the window, which can activate the default
938     widget, i.e. the "OK" button); we have to catch the "key_press_event"
939     signal and have the handler check for ESC, so that we can have ESC
940     activate the "Cancel" button; in order to support Alt+<key> mnemonics
941     for buttons and the like, we may have to construct an accelerator
942     group by hand and set up the accelerators by hand (if that even
943     works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()"
944     to keep some container widget from getting the initial focus, so that
945     you don't have to tab into the first widget in order to start typing
946     in it; and it now appears that you simply *can't* make a combo box
947     get the initial focus, at least not in the obvious fashion. Sigh.... */
948
949   gtk_widget_show_all(cap_open_w);
950 }
951
952 static void 
953 capture_prep_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
954 {
955     switch(btn) {
956     case(ESD_BTN_YES):
957         /* save file first */
958         file_save_as_cmd(after_save_capture_dialog, data);
959         break;
960     case(ESD_BTN_NO):
961         capture_prep();
962         break;
963     case(ESD_BTN_CANCEL):
964         break;
965     default:
966         g_assert_not_reached();
967     }
968 }
969
970 void
971 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
972 {
973   gpointer  dialog;
974
975   if((cfile.state != FILE_CLOSED) && !cfile.user_saved) {
976     /* user didn't saved his current file, ask him */
977     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO_CANCEL,
978                 PRIMARY_TEXT_START "Save capture file before starting a new capture?" PRIMARY_TEXT_END "\n\n"
979                 "If you start a new capture without saving, your current capture data will be discarded.");
980     simple_dialog_set_cb(dialog, capture_prep_answered_cb, NULL);
981   } else {
982     /* unchanged file, just capture a new one */
983     capture_prep();
984   }
985 }
986
987 static void
988 select_link_type_cb(GtkWidget *w, gpointer data)
989 {
990   int new_linktype = GPOINTER_TO_INT(data);
991   GtkWidget *linktype_om = OBJECT_GET_DATA(w, E_CAP_LT_OM_KEY);
992   int old_linktype = GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
993
994   if (old_linktype != new_linktype)
995     OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(new_linktype));
996 }
997
998 static void
999 capture_prep_file_cb(GtkWidget *w, gpointer file_te)
1000 {
1001   GtkWidget *caller = gtk_widget_get_toplevel(w);
1002   GtkWidget *fs;
1003
1004   /* Has a file selection dialog box already been opened for that top-level
1005      widget? */
1006   fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY);
1007
1008   if (fs != NULL) {
1009     /* Yes.  Just re-activate that dialog box. */
1010     reactivate_window(fs);
1011     return;
1012   }
1013
1014   fs = file_selection_new ("Ethereal: Capture File");
1015
1016   /* If we've opened a file, start out by showing the files in the directory
1017      in which that file resided. */
1018   if (last_open_dir)
1019     gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
1020
1021   OBJECT_SET_DATA(fs, E_CAP_FILE_TE_KEY, file_te);
1022
1023   /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
1024   OBJECT_SET_DATA(fs, E_FS_CALLER_PTR_KEY, caller);
1025
1026   /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
1027   OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, fs);
1028
1029   /* Call a handler when the file selection box is destroyed, so we can inform
1030      our caller, if any, that it's been destroyed. */
1031   SIGNAL_CONNECT(fs, "destroy", cap_prep_fs_destroy_cb, file_te);
1032
1033   SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->ok_button, "clicked", cap_prep_fs_ok_cb, fs);
1034
1035   /* Connect the cancel_button to destroy the widget */
1036   SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->cancel_button, "clicked", cap_prep_fs_cancel_cb,
1037                  fs);
1038
1039   /* Catch the "key_press_event" signal in the window, so that we can catch
1040      the ESC key being pressed and act as if the "Cancel" button had
1041      been selected. */
1042   dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
1043
1044   gtk_widget_show_all(fs);
1045 }
1046
1047 static void
1048 cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
1049 {
1050   gchar     *cf_name;
1051
1052   cf_name = g_strdup(gtk_file_selection_get_filename(
1053     GTK_FILE_SELECTION (data)));
1054
1055   /* Perhaps the user specified a directory instead of a file.
1056      Check whether they did. */
1057   if (test_for_directory(cf_name) == EISDIR) {
1058         /* It's a directory - set the file selection box to display it. */
1059         set_last_open_dir(cf_name);
1060         g_free(cf_name);
1061         gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
1062           last_open_dir);
1063         return;
1064   }
1065
1066   gtk_entry_set_text(GTK_ENTRY(OBJECT_GET_DATA(data, E_CAP_FILE_TE_KEY)), cf_name);
1067
1068   gtk_widget_destroy(GTK_WIDGET(data));
1069   g_free(cf_name);
1070 }
1071
1072 static void
1073 cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
1074 {
1075   gtk_widget_destroy(GTK_WIDGET(data));
1076 }
1077
1078 static void
1079 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
1080 {
1081   GtkWidget *caller;
1082
1083   /* Get the widget that requested that we be popped up.
1084      (It should arrange to destroy us if it's destroyed, so
1085      that we don't get a pointer to a non-existent window here.) */
1086   caller = OBJECT_GET_DATA(win, E_FS_CALLER_PTR_KEY);
1087
1088   /* Tell it we no longer exist. */
1089   OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, NULL);
1090
1091   /* Now nuke this window. */
1092   gtk_grab_remove(GTK_WIDGET(win));
1093   gtk_widget_destroy(GTK_WIDGET(win));
1094
1095   /* Give the focus to the file text entry widget so the user can just press
1096      Return to start the capture. */
1097   gtk_widget_grab_focus(file_te);
1098 }
1099
1100 static void
1101 capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
1102   GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te,
1103             *file_te, *multi_files_on_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_cb,
1104             *linktype_om, *sync_cb, *auto_scroll_cb,
1105             *stop_packets_cb, *stop_packets_sb,
1106             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_om,
1107             *stop_duration_cb, *stop_duration_sb, *stop_duration_om,
1108             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_om,
1109             *file_duration_cb, *file_duration_sb, *file_duration_om,
1110             *stop_files_cb, *stop_files_sb,
1111             *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
1112   gchar *entry_text;
1113   gchar *if_text;
1114   gchar *if_name;
1115   const gchar *filter_text;
1116   gchar *save_file;
1117   const gchar *g_save_file;
1118   gchar *cf_name;
1119   gchar *dirname;
1120   gint32 tmp;
1121
1122   if_cb     = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
1123   snap_cb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
1124   snap_sb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
1125   linktype_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_LT_OM_KEY);
1126   promisc_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_PROMISC_KEY);
1127   filter_te = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILT_KEY);
1128   file_te   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_TE_KEY);
1129   multi_files_on_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_MULTI_FILES_ON_CB_KEY);
1130   ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
1131   ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
1132   ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
1133   ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
1134   ring_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_OM_KEY);
1135   file_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_CB_KEY);
1136   file_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_SB_KEY);
1137   file_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_OM_KEY);
1138   sync_cb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1139   auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1140   stop_packets_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_CB_KEY);
1141   stop_packets_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_SB_KEY);
1142   stop_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_CB_KEY);
1143   stop_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_SB_KEY);
1144   stop_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_OM_KEY);
1145   stop_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_CB_KEY);
1146   stop_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_SB_KEY);
1147   stop_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_OM_KEY);
1148   stop_files_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_CB_KEY);
1149   stop_files_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_SB_KEY);
1150   m_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_M_RESOLVE_KEY);
1151   n_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_N_RESOLVE_KEY);
1152   t_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_T_RESOLVE_KEY);
1153
1154   entry_text =
1155     g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
1156   if_text = g_strstrip(entry_text);
1157   if_name = get_if_name(if_text);
1158   if (*if_name == '\0') {
1159     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1160       "You didn't specify an interface on which to capture packets.");
1161     g_free(entry_text);
1162     return;
1163   }
1164   if (cfile.iface)
1165     g_free(cfile.iface);
1166   cfile.iface = g_strdup(if_name);
1167   g_free(entry_text);
1168
1169   capture_opts.linktype =
1170       GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
1171
1172   capture_opts.has_snaplen =
1173     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
1174   if (capture_opts.has_snaplen) {
1175     capture_opts.snaplen =
1176       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
1177     if (capture_opts.snaplen < 1)
1178       capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
1179     else if (capture_opts.snaplen < MIN_PACKET_SIZE)
1180       capture_opts.snaplen = MIN_PACKET_SIZE;
1181   }
1182
1183   capture_opts.promisc_mode =
1184     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
1185
1186   /* XXX - don't try to get clever and set "cfile.filter" to NULL if the
1187      filter string is empty, as an indication that we don't have a filter
1188      and thus don't have to set a filter when capturing - the version of
1189      libpcap in Red Hat Linux 6.1, and versions based on later patches
1190      in that series, don't bind the AF_PACKET socket to an interface
1191      until a filter is set, which means they aren't bound at all if
1192      no filter is set, which means no packets arrive as input on that
1193      socket, which means Ethereal never sees any packets. */
1194   filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
1195   if (cfile.cfilter)
1196     g_free(cfile.cfilter);
1197   g_assert(filter_text != NULL);
1198   cfile.cfilter = g_strdup(filter_text);
1199
1200   g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
1201   if (g_save_file && g_save_file[0]) {
1202     /* User specified a file to which the capture should be written. */
1203     save_file = g_strdup(g_save_file);
1204     /* Save the directory name for future file dialogs. */
1205     cf_name = g_strdup(g_save_file);
1206     dirname = get_dirname(cf_name);  /* Overwrites cf_name */
1207     set_last_open_dir(dirname);
1208     g_free(cf_name);
1209   } else {
1210     /* User didn't specify a file; save to a temporary file. */
1211     save_file = NULL;
1212   }
1213
1214   capture_opts.has_autostop_packets =
1215     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb));
1216   if (capture_opts.has_autostop_packets)
1217     capture_opts.autostop_packets =
1218       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_packets_sb));
1219
1220   capture_opts.has_autostop_duration =
1221     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb));
1222   if (capture_opts.has_autostop_duration) {
1223     capture_opts.autostop_duration =
1224       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_duration_sb));
1225     capture_opts.autostop_duration =
1226       time_unit_option_menu_get_value(stop_duration_om, capture_opts.autostop_duration);
1227   }
1228
1229   capture_opts.sync_mode =
1230     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
1231
1232   auto_scroll_live =
1233       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
1234
1235   g_resolv_flags |= g_resolv_flags & RESOLV_CONCURRENT;
1236   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
1237     g_resolv_flags |= RESOLV_MAC;
1238   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
1239     g_resolv_flags |= RESOLV_NETWORK;
1240   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
1241     g_resolv_flags |= RESOLV_TRANSPORT;
1242
1243   capture_opts.has_ring_num_files =
1244     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb));  
1245
1246   capture_opts.ring_num_files =
1247     gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
1248   if (capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES)
1249     capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES;
1250 #if RINGBUFFER_MIN_NUM_FILES > 0
1251   else if (capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES)
1252     capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES;
1253 #endif
1254
1255   capture_opts.multi_files_on =
1256     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb));
1257
1258   if(capture_opts.sync_mode)
1259     capture_opts.multi_files_on = FALSE;
1260
1261   if (capture_opts.multi_files_on) {
1262     capture_opts.has_autostop_filesize =
1263       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb));
1264     if (capture_opts.has_autostop_filesize) {
1265       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_filesize_sb));
1266       tmp = size_unit_option_menu_get_value(ring_filesize_om, tmp);
1267       if(tmp != 0) {
1268         capture_opts.autostop_filesize = tmp;
1269       } else {
1270         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1271           PRIMARY_TEXT_START "Multiple files: Requested filesize too large!\n\n" PRIMARY_TEXT_END
1272           "The setting \"Next file every x byte(s)\" can't be greater than %u bytes (2GB).", G_MAXINT);
1273         return;
1274       }        
1275     }
1276
1277     /* test if the settings are ok for a ringbuffer */
1278     if (save_file == NULL) {
1279       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1280         PRIMARY_TEXT_START "Multiple files: No capture file name given!\n\n" PRIMARY_TEXT_END
1281         "You must specify a filename if you want to use multiple files.");
1282       return;
1283     } else if (!capture_opts.has_autostop_filesize) {
1284       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1285         PRIMARY_TEXT_START "Multiple files: No file limit given!\n\n" PRIMARY_TEXT_END
1286         "You must specify a file size at which is switched to the next capture file\n"
1287         "if you want to use multiple files.");
1288       g_free(save_file);
1289       return;
1290     }
1291   } else {
1292     capture_opts.has_autostop_filesize =
1293       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb));
1294     if (capture_opts.has_autostop_filesize) {
1295       tmp = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_filesize_sb));
1296       tmp = size_unit_option_menu_get_value(stop_filesize_om, tmp);
1297       if(tmp != 0) {
1298         capture_opts.autostop_filesize = tmp;
1299       } else {
1300         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1301           PRIMARY_TEXT_START "Stop Capture: Requested filesize too large!\n\n" PRIMARY_TEXT_END
1302           "The setting \"... after x byte(s)\" can't be greater than %u bytes (2GB).", G_MAXINT);
1303         return;
1304       }        
1305     }
1306   }
1307
1308   capture_opts.has_file_duration =
1309     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb));
1310   if (capture_opts.has_file_duration) {
1311     capture_opts.file_duration =
1312       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(file_duration_sb));
1313     capture_opts.file_duration =
1314       time_unit_option_menu_get_value(file_duration_om, capture_opts.file_duration);
1315   }
1316
1317   capture_opts.has_autostop_files =
1318     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb));
1319   if (capture_opts.has_autostop_files)
1320     capture_opts.autostop_files =
1321       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stop_files_sb));
1322
1323   gtk_widget_destroy(GTK_WIDGET(parent_w));
1324
1325   do_capture(save_file);
1326   if (save_file != NULL)
1327     g_free(save_file);
1328 }
1329
1330 static void
1331 capture_prep_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
1332 {
1333   gtk_grab_remove(GTK_WIDGET(parent_w));
1334   gtk_widget_destroy(GTK_WIDGET(parent_w));
1335 }
1336
1337 static void
1338 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1339 {
1340   GtkWidget *fs;
1341
1342   /* Is there a file selection dialog associated with this
1343      Capture Options dialog? */
1344   fs = OBJECT_GET_DATA(win, E_FILE_SEL_DIALOG_PTR_KEY);
1345
1346   if (fs != NULL) {
1347     /* Yes.  Destroy it. */
1348     gtk_widget_destroy(fs);
1349   }
1350
1351   /* Note that we no longer have a "Capture Options" dialog box. */
1352   cap_open_w = NULL;
1353 }
1354
1355 static void
1356 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer argp)
1357 {
1358   GtkWidget *linktype_om = argp;
1359
1360   set_link_type_list(linktype_om, entry);
1361 }
1362
1363 /*
1364  * Adjust the sensitivity of various widgets as per the current setting
1365  * of other widgets.
1366  */
1367 static void
1368 capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1369 {
1370   GtkWidget *if_cb,
1371             *snap_cb, *snap_sb,
1372             *multi_files_on_cb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
1373             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_om,
1374             *file_duration_cb, *file_duration_sb, *file_duration_om,
1375             *sync_cb, *auto_scroll_cb,
1376             *stop_packets_cb, *stop_packets_sb, *stop_packets_lb,
1377             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_om,
1378             *stop_duration_cb, *stop_duration_sb, *stop_duration_om,
1379             *stop_files_cb, *stop_files_sb, *stop_files_lb;
1380
1381
1382   if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
1383   snap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
1384   snap_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
1385   multi_files_on_cb  = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_MULTI_FILES_ON_CB_KEY);
1386   ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
1387   ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
1388   ringbuffer_nbf_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_LB_KEY);
1389   ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
1390   ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
1391   ring_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_OM_KEY);
1392   file_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_CB_KEY);
1393   file_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_SB_KEY);
1394   file_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_DURATION_OM_KEY);
1395   sync_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1396   auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1397   stop_packets_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_CB_KEY);
1398   stop_packets_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_SB_KEY);
1399   stop_packets_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_PACKETS_LB_KEY);
1400   stop_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_CB_KEY);
1401   stop_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_SB_KEY);
1402   stop_filesize_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILESIZE_OM_KEY);
1403   stop_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_CB_KEY);
1404   stop_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_SB_KEY);
1405   stop_duration_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_DURATION_OM_KEY);
1406   stop_files_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_CB_KEY);
1407   stop_files_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_SB_KEY);
1408   stop_files_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_LB_KEY);
1409
1410   /* The snapshot length spinbox is sensitive if the "Limit each packet
1411      to" checkbox is on. */
1412   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
1413       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
1414
1415
1416   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
1417     /* "Update list of packets in real time" captures enabled; we don't
1418        support ring buffer mode for those captures, so turn ring buffer
1419        mode off if it's on, and make its toggle button, and the spin
1420        button for the number of ring buffer files (and the spin button's
1421        label), insensitive. */
1422     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(multi_files_on_cb), FALSE);
1423     gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), FALSE);
1424
1425     /* Auto-scroll mode is meaningful only in "Update list of packets
1426        in real time" captures, so make its toggle button sensitive. */
1427     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
1428   } else {
1429     /* "Update list of packets in real time" captures disabled; that
1430        means ring buffer mode is OK, so make its toggle button
1431        sensitive. */
1432     gtk_widget_set_sensitive(GTK_WIDGET(multi_files_on_cb), TRUE);
1433
1434     /* Auto-scroll mode is meaningful only in "Update list of packets
1435        in real time" captures, so make its toggle button insensitive. */
1436     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
1437   }
1438
1439   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(multi_files_on_cb))) {
1440     /* Ring buffer mode enabled. */
1441     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb), TRUE);
1442
1443     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), TRUE);
1444     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb),
1445           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
1446     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb),
1447           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
1448
1449     /* The ring filesize spinbox is sensitive if the "Next capture file
1450          after N kilobytes" checkbox is on. */
1451     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), TRUE);
1452     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),
1453           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
1454     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_om),
1455           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
1456
1457     /* The ring duration spinbox is sensitive if the "Next capture file
1458          after N seconds" checkbox is on. */
1459     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), TRUE);
1460     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),
1461           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
1462     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_om),
1463           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(file_duration_cb)));
1464
1465     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), FALSE);
1466     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb), FALSE);
1467     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_om), FALSE);
1468
1469     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), TRUE);
1470     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb), 
1471           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
1472     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb),
1473           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_files_cb)));
1474   } else {
1475     /* Ring buffer mode disabled. */
1476     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), FALSE);
1477     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
1478     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
1479
1480     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), FALSE);
1481     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),FALSE);
1482     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_om),FALSE);
1483
1484     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_cb), FALSE);
1485     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_sb),FALSE);
1486     gtk_widget_set_sensitive(GTK_WIDGET(file_duration_om),FALSE);
1487
1488     /* The maximum file size spinbox is sensitive if the "Stop capture
1489          after N kilobytes" checkbox is on. */
1490     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_cb), TRUE);
1491     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_sb),
1492           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
1493     gtk_widget_set_sensitive(GTK_WIDGET(stop_filesize_om),
1494           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_filesize_cb)));
1495
1496     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_cb), FALSE);
1497     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_sb), FALSE);
1498     gtk_widget_set_sensitive(GTK_WIDGET(stop_files_lb), FALSE);
1499   }
1500
1501   /* The maximum packet count spinbox is sensitive if the "Stop capture
1502      after N packets" checkbox is on. */
1503   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_sb),
1504       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
1505   gtk_widget_set_sensitive(GTK_WIDGET(stop_packets_lb),
1506       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_packets_cb)));
1507
1508   /* The capture duration spinbox is sensitive if the "Stop capture
1509      after N seconds" checkbox is on. */
1510   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_sb),
1511       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
1512   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_om),
1513       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
1514 }
1515
1516 #endif /* HAVE_LIBPCAP */