2 * Routines for packet capture windows
4 * $Id: capture_dlg.c,v 1.115 2004/03/02 22:07:23 ulfl Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
35 #include <epan/packet.h>
38 #include <epan/resolv.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"
48 #include "ringbuffer.h"
49 #include <epan/filesystem.h>
50 #include "compat_macros.h"
55 #include "capture-wpcap.h"
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_RING_ON_TB_KEY "cap_ringbuffer_on_tb"
68 #define E_CAP_RING_NBF_CB_KEY "cap_ringbuffer_nbf_cb"
69 #define E_CAP_RING_NBF_SB_KEY "cap_ringbuffer_nbf_sb"
70 #define E_CAP_RING_NBF_LB_KEY "cap_ringbuffer_nbf_lb"
71 #define E_CAP_RING_FILESIZE_CB_KEY "cap_ringbuffer_filesize_cb"
72 #define E_CAP_RING_FILESIZE_SB_KEY "cap_ringbuffer_filesize_sb"
73 #define E_CAP_RING_FILESIZE_LB_KEY "cap_ringbuffer_filesize_lb"
74 #define E_CAP_RING_DURATION_CB_KEY "cap_ringbuffer_duration_cb"
75 #define E_CAP_RING_DURATION_SB_KEY "cap_ringbuffer_duration_sb"
76 #define E_CAP_RING_DURATION_LB_KEY "cap_ringbuffer_duration_lb"
77 #define E_CAP_SYNC_KEY "cap_sync"
78 #define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll"
79 #define E_CAP_COUNT_CB_KEY "cap_count_cb"
80 #define E_CAP_COUNT_SB_KEY "cap_count_sb"
81 #define E_CAP_FILESIZE_CB_KEY "cap_filesize_cb"
82 #define E_CAP_FILESIZE_SB_KEY "cap_filesize_sb"
83 #define E_CAP_FILESIZE_LB_KEY "cap_filesize_lb"
84 #define E_CAP_DURATION_CB_KEY "cap_duration_cb"
85 #define E_CAP_DURATION_SB_KEY "cap_duration_sb"
86 #define E_CAP_FILES_CB_KEY "cap_files_cb"
87 #define E_CAP_FILES_SB_KEY "cap_files_sb"
88 #define E_CAP_FILES_LB_KEY "cap_files_lb"
89 #define E_CAP_M_RESOLVE_KEY "cap_m_resolve"
90 #define E_CAP_N_RESOLVE_KEY "cap_n_resolve"
91 #define E_CAP_T_RESOLVE_KEY "cap_t_resolve"
93 #define E_CAP_OM_LT_VALUE_KEY "cap_om_lt_value"
95 #define E_FS_CALLER_PTR_KEY "fs_caller_ptr"
96 #define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
99 capture_prep_file_cb(GtkWidget *w, gpointer te);
102 select_link_type_cb(GtkWidget *w, gpointer data);
105 cap_prep_fs_ok_cb(GtkWidget *w, gpointer data);
108 cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
111 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
114 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
117 capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
120 capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w);
123 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
126 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer parent_w);
129 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
135 * Given text that contains an interface name possibly prefixed by an
136 * interface description, extract the interface name.
139 get_if_name(char *if_text)
145 * We cannot assume that the interface name doesn't contain a space;
146 * some names on Windows OT do.
148 * We also can't assume it begins with "\Device\", either, as, on
149 * Windows OT, WinPcap doesn't put "\Device\" in front of the name.
151 * As I remember, we can't assume that the interface description
152 * doesn't contain a colon, either; I think some do.
154 * We can probably assume that the interface *name* doesn't contain
155 * a colon, however; if any interface name does contain a colon on
156 * Windows, it'll be time to just get rid of the damn interface
157 * descriptions in the drop-down list, have just the names in the
158 * drop-down list, and have a "Browse..." button to browse for interfaces,
159 * with names, descriptions, IP addresses, blah blah blah available when
162 * So we search backwards for a colon. If we don't find it, just
163 * return the entire string; otherwise, skip the colon and any blanks
164 * after it, and return that string.
166 if_name = strrchr(if_text, ':');
167 if (if_name == NULL) {
171 while (*if_name == ' ')
176 * There's a space between the interface description and name, and
177 * the interface name shouldn't have a space in it (it doesn't, on
178 * UNIX systems); look backwards in the string for a space.
180 * (An interface name might, however, contain a colon in it, which
181 * is why we don't use the colon search on UNIX.)
183 if_name = strrchr(if_text, ' ');
184 if (if_name == NULL) {
194 * Keep a static pointer to the current "Capture Options" window, if
195 * any, so that if somebody tries to do "Capture:Start" while there's
196 * already a "Capture Options" window up, we just pop up the existing
197 * one, rather than creating a new one.
199 static GtkWidget *cap_open_w;
202 set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
212 char err_buf[PCAP_ERRBUF_SIZE];
213 GtkWidget *lt_menu, *lt_menu_item;
215 data_link_info_t *data_link_info;
216 gchar *linktype_menu_label;
217 guint num_supported_link_types;
218 GtkWidget *linktype_lb = OBJECT_GET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY);
220 lt_menu = gtk_menu_new();
221 entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
222 if_text = g_strstrip(entry_text);
223 if_name = get_if_name(if_text);
226 * If the interface name is in the list of known interfaces, get
227 * its list of link-layer types and set the option menu to display it.
229 * If it's not, don't bother - the user might be in the middle of
230 * editing the list, or it might be a remote device in which case
231 * getting the list could take an arbitrarily-long period of time.
232 * The list currently won't contain any remote devices (as
233 * "pcap_findalldevs()" doesn't know about remote devices, and neither
234 * does the code we use if "pcap_findalldevs()" isn't available), but
235 * should contain all the local devices on which you can capture.
238 if (*if_name != '\0') {
240 * Try to get the list of known interfaces.
242 if_list = get_interface_list(&err, err_buf);
243 if (if_list != NULL) {
245 * We have the list - check it.
247 for (if_entry = if_list; if_entry != NULL;
248 if_entry = g_list_next(if_entry)) {
249 if_info = if_entry->data;
250 if (strcmp(if_info->name, if_name) == 0) {
253 * Get the list of link-layer types for it.
255 lt_list = get_pcap_linktype_list(if_name, err_buf);
258 free_interface_list(if_list);
262 num_supported_link_types = 0;
263 for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
264 data_link_info = lt_entry->data;
265 if (data_link_info->description != NULL) {
266 lt_menu_item = gtk_menu_item_new_with_label(data_link_info->description);
267 OBJECT_SET_DATA(lt_menu_item, E_CAP_LT_OM_KEY, linktype_om);
268 SIGNAL_CONNECT(lt_menu_item, "activate", select_link_type_cb,
269 GINT_TO_POINTER(data_link_info->dlt));
270 num_supported_link_types++;
272 /* Not supported - tell them about it but don't let them select it. */
273 linktype_menu_label = g_strdup_printf("%s (not supported)",
274 data_link_info->name);
275 lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
276 g_free(linktype_menu_label);
277 gtk_widget_set_sensitive(lt_menu_item, FALSE);
279 gtk_menu_append(GTK_MENU(lt_menu), lt_menu_item);
282 free_pcap_linktype_list(lt_list);
283 gtk_option_menu_set_menu(GTK_OPTION_MENU(linktype_om), lt_menu);
284 gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
285 gtk_widget_set_sensitive(linktype_om, num_supported_link_types >= 2);
292 *main_hb, *left_vb, *right_vb,
294 *capture_fr, *capture_vb,
295 *if_hb, *if_cb, *if_lb,
296 *linktype_hb, *linktype_lb, *linktype_om,
297 *snap_hb, *snap_cb, *snap_sb, *snap_lb,
299 *filter_hb, *filter_bt, *filter_te,
302 *file_hb, *file_bt, *file_lb, *file_te,
303 *ringbuffer_hb, *ringbuffer_on_tb,
304 *ring_filesize_hb, *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_lb,
305 *ring_duration_hb, *ring_duration_cb, *ring_duration_sb, *ring_duration_lb,
306 *ringbuffer_nbf_hb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
308 *limit_fr, *limit_vb,
309 *count_hb, *count_cb, *count_sb, *count_lb,
310 *filesize_hb, *filesize_cb, *filesize_sb, *filesize_lb,
311 *duration_hb, *duration_cb, *duration_sb, *duration_lb,
312 *files_hb, *files_cb, *files_sb, *files_lb,
314 *display_fr, *display_vb,
315 *sync_cb, *auto_scroll_cb,
317 *resolv_fr, *resolv_vb,
318 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
319 *bbox, *ok_bt, *cancel_bt,
321 #if GTK_MAJOR_VERSION < 2
322 GtkAccelGroup *accel_group;
324 GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
325 *count_adj, *filesize_adj, *duration_adj, *files_adj, *ring_filesize_adj, *ring_duration_adj;
326 GList *if_list, *combo_list;
328 char err_str[PCAP_ERRBUF_SIZE];
330 if (cap_open_w != NULL) {
331 /* There's already a "Capture Options" dialog box; reactivate it. */
332 reactivate_window(cap_open_w);
337 /* Is WPcap loaded? */
339 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
340 "Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n"
341 "to capture packets.\n\n"
342 "In order to capture packets, WinPcap must be installed; see\n"
344 " http://winpcap.polito.it/\n"
348 " http://winpcap.mirror.ethereal.com/\n"
352 " http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n"
354 "for a downloadable version of WinPcap and for instructions\n"
355 "on how to install WinPcap.");
360 if_list = get_interface_list(&err, err_str);
361 if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
362 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "Can't get list of interfaces: %s",
366 cap_open_w = dlg_window_new("Ethereal: Capture Options");
367 SIGNAL_CONNECT(cap_open_w, "destroy", capture_prep_destroy_cb, NULL);
369 #if GTK_MAJOR_VERSION < 2
370 /* Accelerator group for the accelerators (or, as they're called in
371 Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
372 Ctrl+<key> is an accelerator). */
373 accel_group = gtk_accel_group_new();
374 gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group);
377 main_vb = gtk_vbox_new(FALSE, 0);
378 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
379 gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
381 /* Capture-related options frame */
382 capture_fr = gtk_frame_new("Capture");
383 gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
385 capture_vb = gtk_vbox_new(FALSE, 3);
386 gtk_container_border_width(GTK_CONTAINER(capture_vb), 5);
387 gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
390 if_hb = gtk_hbox_new(FALSE, 3);
391 gtk_container_add(GTK_CONTAINER(capture_vb), if_hb);
393 if_lb = gtk_label_new("Interface:");
394 gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
396 if_cb = gtk_combo_new();
397 combo_list = build_capture_combo_list(if_list, TRUE);
398 if (combo_list != NULL)
399 gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
400 if (cfile.iface == NULL && prefs.capture_device != NULL) {
401 /* No interface was specified on the command line or in a previous
402 capture, but there is one specified in the preferences file;
403 make the one from the preferences file the default */
404 cfile.iface = g_strdup(prefs.capture_device);
406 if (cfile.iface != NULL)
407 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
408 else if (combo_list != NULL) {
409 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
410 (char *)combo_list->data);
412 free_capture_combo_list(combo_list);
413 free_interface_list(if_list);
414 gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
417 linktype_hb = gtk_hbox_new(FALSE, 3);
418 gtk_box_pack_start(GTK_BOX(capture_vb), linktype_hb, FALSE, FALSE, 0);
420 linktype_lb = gtk_label_new("Link-layer header type:");
421 gtk_box_pack_start(GTK_BOX(linktype_hb), linktype_lb, FALSE, FALSE, 6);
423 linktype_om = gtk_option_menu_new();
424 OBJECT_SET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY, linktype_lb);
425 /* Default to "use the default" */
426 OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(-1));
427 set_link_type_list(linktype_om, GTK_COMBO(if_cb)->entry);
428 gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_om, FALSE, FALSE, 0);
429 SIGNAL_CONNECT(GTK_ENTRY(GTK_COMBO(if_cb)->entry), "changed",
430 capture_prep_interface_changed_cb, linktype_om);
432 /* Promiscuous mode row */
433 promisc_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
434 "Capture packets in _promiscuous mode", accel_group);
435 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb),
436 capture_opts.promisc_mode);
437 gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
439 /* Capture length row */
440 snap_hb = gtk_hbox_new(FALSE, 3);
441 gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
443 snap_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("_Limit each packet to", accel_group);
444 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb),
445 capture_opts.has_snaplen);
446 SIGNAL_CONNECT(snap_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
447 gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
449 snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.snaplen,
450 MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
451 snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
452 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
453 WIDGET_SET_SIZE(snap_sb, 80, -1);
454 gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
456 snap_lb = gtk_label_new("bytes");
457 gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5);
458 gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
461 filter_hb = gtk_hbox_new(FALSE, 3);
462 gtk_box_pack_start(GTK_BOX(capture_vb), filter_hb, FALSE, FALSE, 0);
464 filter_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_CAPTURE_FILTER_ENTRY);
465 SIGNAL_CONNECT(filter_bt, "clicked", capture_filter_construct_cb, NULL);
466 SIGNAL_CONNECT(filter_bt, "destroy", filter_button_destroy_cb, NULL);
467 gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
469 filter_te = gtk_entry_new();
470 if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
471 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
472 gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3);
474 main_hb = gtk_hbox_new(FALSE, 5);
475 gtk_container_border_width(GTK_CONTAINER(main_hb), 0);
476 gtk_container_add(GTK_CONTAINER(main_vb), main_hb);
478 left_vb = gtk_vbox_new(FALSE, 0);
479 gtk_container_border_width(GTK_CONTAINER(left_vb), 0);
480 gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
482 right_vb = gtk_vbox_new(FALSE, 0);
483 gtk_container_border_width(GTK_CONTAINER(right_vb), 0);
484 gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 0);
487 /* Capture file-related options frame */
488 file_fr = gtk_frame_new("Capture File(s)");
489 gtk_container_add(GTK_CONTAINER(left_vb), file_fr);
491 file_vb = gtk_vbox_new(FALSE, 3);
492 gtk_container_border_width(GTK_CONTAINER(file_vb), 5);
493 gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
496 file_hb = gtk_hbox_new(FALSE, 3);
497 gtk_box_pack_start(GTK_BOX(file_vb), file_hb, FALSE, FALSE, 0);
499 file_lb = gtk_label_new("File:");
500 gtk_box_pack_start(GTK_BOX(file_hb), file_lb, FALSE, FALSE, 3);
502 file_te = gtk_entry_new();
503 gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
505 file_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_BROWSE);
506 gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3);
508 SIGNAL_CONNECT(file_bt, "clicked", capture_prep_file_cb, file_te);
510 /* Ring buffer row */
511 ringbuffer_hb = gtk_hbox_new(FALSE, 3);
512 gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_hb);
514 ringbuffer_on_tb = CHECK_BUTTON_NEW_WITH_MNEMONIC("Use _multiple files", accel_group);
515 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_on_tb),
516 capture_opts.multi_files_on);
517 SIGNAL_CONNECT(ringbuffer_on_tb, "toggled", capture_prep_adjust_sensitivity,
519 gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_on_tb, FALSE, FALSE, 0);
521 /* Ring buffer filesize row */
522 ring_filesize_hb = gtk_hbox_new(FALSE, 3);
523 gtk_container_add(GTK_CONTAINER(file_vb), ring_filesize_hb);
525 ring_filesize_cb = gtk_check_button_new_with_label("Next file every");
526 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_filesize_cb),
527 capture_opts.has_autostop_filesize);
528 SIGNAL_CONNECT(ring_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
529 gtk_box_pack_start(GTK_BOX(ring_filesize_hb), ring_filesize_cb, FALSE, FALSE, 0);
531 ring_filesize_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_filesize,
532 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
533 ring_filesize_sb = gtk_spin_button_new (ring_filesize_adj, 0, 0);
534 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_filesize_sb), TRUE);
535 WIDGET_SET_SIZE(ring_filesize_sb, 80, -1);
536 gtk_box_pack_start (GTK_BOX(ring_filesize_hb), ring_filesize_sb, FALSE, FALSE, 0);
538 ring_filesize_lb = gtk_label_new("kilobyte(s)");
539 gtk_misc_set_alignment(GTK_MISC(ring_filesize_lb), 0, 0.5);
540 gtk_box_pack_start(GTK_BOX(ring_filesize_hb), ring_filesize_lb, FALSE, FALSE, 0);
542 /* Ring buffer duration row */
543 ring_duration_hb = gtk_hbox_new(FALSE, 3);
544 gtk_container_add(GTK_CONTAINER(file_vb), ring_duration_hb);
546 ring_duration_cb = gtk_check_button_new_with_label("Next file every");
547 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_duration_cb),
548 capture_opts.has_ring_duration);
549 SIGNAL_CONNECT(ring_duration_cb, "toggled",
550 capture_prep_adjust_sensitivity, cap_open_w);
551 gtk_box_pack_start(GTK_BOX(ring_duration_hb), ring_duration_cb, FALSE, FALSE, 0);
553 ring_duration_adj = (GtkAdjustment *)gtk_adjustment_new((gfloat)capture_opts.ringbuffer_duration,
554 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
555 ring_duration_sb = gtk_spin_button_new (ring_duration_adj, 0, 0);
556 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_duration_sb), TRUE);
557 WIDGET_SET_SIZE(ring_duration_sb, 80, -1);
558 gtk_box_pack_start (GTK_BOX(ring_duration_hb), ring_duration_sb, FALSE, FALSE, 0);
560 ring_duration_lb = gtk_label_new("second(s)");
561 gtk_misc_set_alignment(GTK_MISC(ring_duration_lb), 0, 0.5);
562 gtk_box_pack_start(GTK_BOX(ring_duration_hb), ring_duration_lb,
565 /* Ring buffer files row */
566 ringbuffer_nbf_hb = gtk_hbox_new(FALSE, 3);
567 gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_nbf_hb);
569 ringbuffer_nbf_cb = gtk_check_button_new_with_label("Ring buffer with");
570 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb),
571 capture_opts.has_ring_num_files);
572 SIGNAL_CONNECT(ringbuffer_nbf_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
573 gtk_box_pack_start(GTK_BOX(ringbuffer_nbf_hb), ringbuffer_nbf_cb, FALSE, FALSE, 0);
575 ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.num_files,
576 2/*RINGBUFFER_MIN_NUM_FILES*/, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
577 ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
578 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
579 WIDGET_SET_SIZE(ringbuffer_nbf_sb, 80, -1);
580 SIGNAL_CONNECT(ringbuffer_nbf_sb, "changed", capture_prep_adjust_sensitivity, cap_open_w);
581 gtk_box_pack_start (GTK_BOX(ringbuffer_nbf_hb), ringbuffer_nbf_sb, FALSE, FALSE, 0);
583 ringbuffer_nbf_lb = gtk_label_new("files");
584 gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 1, 0.5);
585 gtk_box_pack_start(GTK_BOX(ringbuffer_nbf_hb), ringbuffer_nbf_lb, FALSE, FALSE, 3);
588 files_hb = gtk_hbox_new(FALSE, 3);
589 gtk_container_add(GTK_CONTAINER(file_vb), files_hb);
591 files_cb = gtk_check_button_new_with_label("Stop capture after");
592 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(files_cb),
593 capture_opts.has_autostop_files);
594 SIGNAL_CONNECT(files_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
595 gtk_box_pack_start(GTK_BOX(files_hb), files_cb, FALSE, FALSE, 0);
597 files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_files,
598 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
599 files_sb = gtk_spin_button_new (files_adj, 0, 0);
600 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (files_sb), TRUE);
601 WIDGET_SET_SIZE(files_sb, 80, -1);
602 gtk_box_pack_start (GTK_BOX(files_hb), files_sb, FALSE, FALSE, 0);
604 files_lb = gtk_label_new("file(s)");
605 gtk_misc_set_alignment(GTK_MISC(files_lb), 0, 0.5);
606 gtk_box_pack_start(GTK_BOX(files_hb), files_lb, FALSE, FALSE, 0);
608 /* Capture limits frame */
609 limit_fr = gtk_frame_new("Stop Capture ...");
610 gtk_container_add(GTK_CONTAINER(left_vb), limit_fr);
612 limit_vb = gtk_vbox_new(FALSE, 3);
613 gtk_container_border_width(GTK_CONTAINER(limit_vb), 5);
614 gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
616 /* Packet count row */
617 count_hb = gtk_hbox_new(FALSE, 3);
618 gtk_container_add(GTK_CONTAINER(limit_vb), count_hb);
620 count_cb = gtk_check_button_new_with_label("... after");
621 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(count_cb),
622 capture_opts.has_autostop_count);
623 SIGNAL_CONNECT(count_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
624 gtk_box_pack_start(GTK_BOX(count_hb), count_cb, FALSE, FALSE, 0);
626 count_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_count,
627 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
628 count_sb = gtk_spin_button_new (count_adj, 0, 0);
629 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (count_sb), TRUE);
630 WIDGET_SET_SIZE(count_sb, 80, -1);
631 gtk_box_pack_start (GTK_BOX(count_hb), count_sb, FALSE, FALSE, 0);
633 count_lb = gtk_label_new("packet(s)");
634 gtk_misc_set_alignment(GTK_MISC(count_lb), 0, 0.5);
635 gtk_box_pack_start(GTK_BOX(count_hb), count_lb, FALSE, FALSE, 0);
638 filesize_hb = gtk_hbox_new(FALSE, 3);
639 gtk_container_add(GTK_CONTAINER(limit_vb), filesize_hb);
641 filesize_cb = gtk_check_button_new_with_label("... after");
642 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb),
643 capture_opts.has_autostop_filesize);
644 SIGNAL_CONNECT(filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
645 gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_cb, FALSE, FALSE, 0);
647 filesize_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_filesize,
648 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
649 filesize_sb = gtk_spin_button_new (filesize_adj, 0, 0);
650 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (filesize_sb), TRUE);
651 WIDGET_SET_SIZE(filesize_sb, 80, -1);
652 gtk_box_pack_start (GTK_BOX(filesize_hb), filesize_sb, FALSE, FALSE, 0);
654 filesize_lb = gtk_label_new("kilobyte(s)");
655 gtk_misc_set_alignment(GTK_MISC(filesize_lb), 0, 0.5);
656 gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_lb, FALSE, FALSE, 0);
659 duration_hb = gtk_hbox_new(FALSE, 3);
660 gtk_container_add(GTK_CONTAINER(limit_vb), duration_hb);
662 duration_cb = gtk_check_button_new_with_label("... after");
663 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(duration_cb),
664 capture_opts.has_autostop_duration);
665 SIGNAL_CONNECT(duration_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
666 gtk_box_pack_start(GTK_BOX(duration_hb), duration_cb, FALSE, FALSE, 0);
668 duration_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_duration,
669 1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
670 duration_sb = gtk_spin_button_new (duration_adj, 0, 0);
671 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (duration_sb), TRUE);
672 WIDGET_SET_SIZE(duration_sb, 80, -1);
673 gtk_box_pack_start (GTK_BOX(duration_hb), duration_sb, FALSE, FALSE, 0);
675 duration_lb = gtk_label_new("second(s)");
676 gtk_misc_set_alignment(GTK_MISC(duration_lb), 0, 0.5);
677 gtk_box_pack_start(GTK_BOX(duration_hb), duration_lb, FALSE, FALSE, 0);
679 /* Display-related options frame */
680 display_fr = gtk_frame_new("Display Options");
681 gtk_container_add(GTK_CONTAINER(right_vb), display_fr);
683 display_vb = gtk_vbox_new(FALSE, 0);
684 gtk_container_border_width(GTK_CONTAINER(display_vb), 5);
685 gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
687 /* "Update display in real time" row */
688 sync_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
689 "_Update list of packets in real time", accel_group);
690 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb),
691 capture_opts.sync_mode);
692 SIGNAL_CONNECT(sync_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
693 gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
695 /* "Auto-scroll live update" row */
696 auto_scroll_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
697 "_Automatic scrolling in live capture", accel_group);
698 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
699 gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
701 /* Name Resolution frame */
702 resolv_fr = gtk_frame_new("Name Resolution");
703 gtk_container_add(GTK_CONTAINER(right_vb), resolv_fr);
705 resolv_vb = gtk_vbox_new(FALSE, 0);
706 gtk_container_border_width(GTK_CONTAINER(resolv_vb), 5);
707 gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
709 m_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
710 "Enable _MAC name resolution", accel_group);
711 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
712 g_resolv_flags & RESOLV_MAC);
713 gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
715 n_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
716 "Enable _network name resolution", accel_group);
717 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
718 g_resolv_flags & RESOLV_NETWORK);
719 gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
721 t_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
722 "Enable _transport name resolution", accel_group);
723 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
724 g_resolv_flags & RESOLV_TRANSPORT);
725 gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
727 /* Button row: OK and cancel buttons */
728 bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
729 gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
731 ok_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
732 SIGNAL_CONNECT(ok_bt, "clicked", capture_prep_ok_cb, cap_open_w);
733 gtk_widget_grab_default(ok_bt);
735 cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
736 SIGNAL_CONNECT(cancel_bt, "clicked", capture_prep_close_cb, cap_open_w);
738 help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
739 SIGNAL_CONNECT(help_bt, "clicked", help_topic_cb, "Capturing");
741 /* Attach pointers to needed widgets to the capture prefs window/object */
742 OBJECT_SET_DATA(cap_open_w, E_CAP_IFACE_KEY, if_cb);
743 OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_CB_KEY, snap_cb);
744 OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_SB_KEY, snap_sb);
745 OBJECT_SET_DATA(cap_open_w, E_CAP_LT_OM_KEY, linktype_om);
746 OBJECT_SET_DATA(cap_open_w, E_CAP_PROMISC_KEY, promisc_cb);
747 OBJECT_SET_DATA(cap_open_w, E_CAP_FILT_KEY, filter_te);
748 OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_TE_KEY, file_te);
749 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_ON_TB_KEY, ringbuffer_on_tb);
750 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_CB_KEY, ringbuffer_nbf_cb);
751 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_SB_KEY, ringbuffer_nbf_sb);
752 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_LB_KEY, ringbuffer_nbf_lb);
753 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_CB_KEY, ring_filesize_cb);
754 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_SB_KEY, ring_filesize_sb);
755 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_LB_KEY, ring_filesize_lb);
756 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_CB_KEY, ring_duration_cb);
757 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_SB_KEY, ring_duration_sb);
758 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_LB_KEY, ring_duration_lb);
759 OBJECT_SET_DATA(cap_open_w, E_CAP_SYNC_KEY, sync_cb);
760 OBJECT_SET_DATA(cap_open_w, E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
761 OBJECT_SET_DATA(cap_open_w, E_CAP_COUNT_CB_KEY, count_cb);
762 OBJECT_SET_DATA(cap_open_w, E_CAP_COUNT_SB_KEY, count_sb);
763 OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_CB_KEY, filesize_cb);
764 OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_SB_KEY, filesize_sb);
765 OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_LB_KEY, filesize_lb);
766 OBJECT_SET_DATA(cap_open_w, E_CAP_DURATION_CB_KEY, duration_cb);
767 OBJECT_SET_DATA(cap_open_w, E_CAP_DURATION_SB_KEY, duration_sb);
768 OBJECT_SET_DATA(cap_open_w, E_CAP_FILES_CB_KEY, files_cb);
769 OBJECT_SET_DATA(cap_open_w, E_CAP_FILES_SB_KEY, files_sb);
770 OBJECT_SET_DATA(cap_open_w, E_CAP_FILES_LB_KEY, files_lb);
771 OBJECT_SET_DATA(cap_open_w, E_CAP_M_RESOLVE_KEY, m_resolv_cb);
772 OBJECT_SET_DATA(cap_open_w, E_CAP_N_RESOLVE_KEY, n_resolv_cb);
773 OBJECT_SET_DATA(cap_open_w, E_CAP_T_RESOLVE_KEY, t_resolv_cb);
775 /* Set the sensitivity of various widgets as per the settings of other
777 capture_prep_adjust_sensitivity(NULL, cap_open_w);
779 /* Catch the "activate" signal on the filter and file name text
780 entries, so that if the user types Return there, we act as if the
781 "OK" button had been selected, as happens if Return is typed if some
782 widget that *doesn't* handle the Return key has the input focus. */
783 dlg_set_activate(filter_te, ok_bt);
784 dlg_set_activate(file_te, ok_bt);
786 /* Catch the "key_press_event" signal in the window, so that we can catch
787 the ESC key being pressed and act as if the "Cancel" button had
789 dlg_set_cancel(cap_open_w, cancel_bt);
791 /* XXX - why does not
793 gtk_widget_grab_focus(if_cb);
795 give the initial focus to the "Interface" combo box?
797 Or should I phrase that as "why does GTK+ continually frustrate
798 attempts to make GUIs driveable from the keyboard?" We have to
799 go catch the activate signal on every single GtkEntry widget
800 (rather than having widgets whose activate signal is *not*
801 caught not catch the Return keystroke, so that it passes on,
802 ultimately, to the window, which can activate the default
803 widget, i.e. the "OK" button); we have to catch the "key_press_event"
804 signal and have the handler check for ESC, so that we can have ESC
805 activate the "Cancel" button; in order to support Alt+<key> mnemonics
806 for buttons and the like, we may have to construct an accelerator
807 group by hand and set up the accelerators by hand (if that even
808 works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()"
809 to keep some container widget from getting the initial focus, so that
810 you don't have to tab into the first widget in order to start typing
811 in it; and it now appears that you simply *can't* make a combo box
812 get the initial focus, at least not in the obvious fashion. Sigh.... */
814 gtk_widget_show_all(cap_open_w);
818 capture_prep_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
822 /* save file first */
823 file_save_as_cmd(after_save_capture_dialog, data);
828 case(ESD_BTN_CANCEL):
831 g_assert_not_reached();
836 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
840 if((cfile.state != FILE_CLOSED) && !cfile.user_saved) {
841 /* user didn't saved his current file, ask him */
842 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO_CANCEL,
843 PRIMARY_TEXT_START "Save capture file before starting a new capture?" PRIMARY_TEXT_END "\n\n"
844 "If you start a new capture without saving, your current capture data will be discarded.");
845 simple_dialog_set_cb(dialog, capture_prep_answered_cb, NULL);
847 /* unchanged file, just capture a new one */
853 select_link_type_cb(GtkWidget *w, gpointer data)
855 int new_linktype = GPOINTER_TO_INT(data);
856 GtkWidget *linktype_om = OBJECT_GET_DATA(w, E_CAP_LT_OM_KEY);
857 int old_linktype = GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
859 if (old_linktype != new_linktype)
860 OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(new_linktype));
864 capture_prep_file_cb(GtkWidget *w, gpointer file_te)
866 GtkWidget *caller = gtk_widget_get_toplevel(w);
869 /* Has a file selection dialog box already been opened for that top-level
871 fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY);
874 /* Yes. Just re-activate that dialog box. */
875 reactivate_window(fs);
879 fs = file_selection_new ("Ethereal: Capture File");
881 /* If we've opened a file, start out by showing the files in the directory
882 in which that file resided. */
884 gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
886 OBJECT_SET_DATA(fs, E_CAP_FILE_TE_KEY, file_te);
888 /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
889 OBJECT_SET_DATA(fs, E_FS_CALLER_PTR_KEY, caller);
891 /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
892 OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, fs);
894 /* Call a handler when the file selection box is destroyed, so we can inform
895 our caller, if any, that it's been destroyed. */
896 SIGNAL_CONNECT(fs, "destroy", cap_prep_fs_destroy_cb, file_te);
898 SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->ok_button, "clicked", cap_prep_fs_ok_cb, fs);
900 /* Connect the cancel_button to destroy the widget */
901 SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->cancel_button, "clicked", cap_prep_fs_cancel_cb,
904 /* Catch the "key_press_event" signal in the window, so that we can catch
905 the ESC key being pressed and act as if the "Cancel" button had
907 dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
909 gtk_widget_show_all(fs);
913 cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
917 cf_name = g_strdup(gtk_file_selection_get_filename(
918 GTK_FILE_SELECTION (data)));
920 /* Perhaps the user specified a directory instead of a file.
921 Check whether they did. */
922 if (test_for_directory(cf_name) == EISDIR) {
923 /* It's a directory - set the file selection box to display it. */
924 set_last_open_dir(cf_name);
926 gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
931 gtk_entry_set_text(GTK_ENTRY(OBJECT_GET_DATA(data, E_CAP_FILE_TE_KEY)), cf_name);
933 gtk_widget_destroy(GTK_WIDGET(data));
938 cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
940 gtk_widget_destroy(GTK_WIDGET(data));
944 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
948 /* Get the widget that requested that we be popped up.
949 (It should arrange to destroy us if it's destroyed, so
950 that we don't get a pointer to a non-existent window here.) */
951 caller = OBJECT_GET_DATA(win, E_FS_CALLER_PTR_KEY);
953 /* Tell it we no longer exist. */
954 OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, NULL);
956 /* Now nuke this window. */
957 gtk_grab_remove(GTK_WIDGET(win));
958 gtk_widget_destroy(GTK_WIDGET(win));
960 /* Give the focus to the file text entry widget so the user can just press
961 Return to start the capture. */
962 gtk_widget_grab_focus(file_te);
966 capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
967 GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te,
968 *file_te, *ringbuffer_on_tb, *ringbuffer_nbf_sb, *ringbuffer_nbf_cb,
969 *linktype_om, *sync_cb, *auto_scroll_cb,
970 *count_cb, *count_sb,
971 *filesize_cb, *filesize_sb,
972 *duration_cb, *duration_sb,
973 *ring_filesize_cb, *ring_filesize_sb,
974 *ring_duration_cb, *ring_duration_sb,
975 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
979 const gchar *filter_text;
981 const gchar *g_save_file;
985 if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
986 snap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
987 snap_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
988 linktype_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_LT_OM_KEY);
989 promisc_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_PROMISC_KEY);
990 filter_te = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILT_KEY);
991 file_te = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_TE_KEY);
992 ringbuffer_on_tb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_ON_TB_KEY);
993 ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
994 ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
995 ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
996 ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
997 ring_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_CB_KEY);
998 ring_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_SB_KEY);
999 sync_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1000 auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1001 count_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_CB_KEY);
1002 count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_SB_KEY);
1003 filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_CB_KEY);
1004 filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_SB_KEY);
1005 duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_CB_KEY);
1006 duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_SB_KEY);
1007 m_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_M_RESOLVE_KEY);
1008 n_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_N_RESOLVE_KEY);
1009 t_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_T_RESOLVE_KEY);
1012 g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
1013 if_text = g_strstrip(entry_text);
1014 if_name = get_if_name(if_text);
1015 if (*if_name == '\0') {
1016 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1017 "You didn't specify an interface on which to capture packets.");
1022 g_free(cfile.iface);
1023 cfile.iface = g_strdup(if_name);
1026 capture_opts.linktype =
1027 GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
1029 capture_opts.has_snaplen =
1030 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
1031 if (capture_opts.has_snaplen) {
1032 capture_opts.snaplen =
1033 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
1034 if (capture_opts.snaplen < 1)
1035 capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
1036 else if (capture_opts.snaplen < MIN_PACKET_SIZE)
1037 capture_opts.snaplen = MIN_PACKET_SIZE;
1040 capture_opts.promisc_mode =
1041 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
1043 /* XXX - don't try to get clever and set "cfile.filter" to NULL if the
1044 filter string is empty, as an indication that we don't have a filter
1045 and thus don't have to set a filter when capturing - the version of
1046 libpcap in Red Hat Linux 6.1, and versions based on later patches
1047 in that series, don't bind the AF_PACKET socket to an interface
1048 until a filter is set, which means they aren't bound at all if
1049 no filter is set, which means no packets arrive as input on that
1050 socket, which means Ethereal never sees any packets. */
1051 filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
1053 g_free(cfile.cfilter);
1054 g_assert(filter_text != NULL);
1055 cfile.cfilter = g_strdup(filter_text);
1057 g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
1058 if (g_save_file && g_save_file[0]) {
1059 /* User specified a file to which the capture should be written. */
1060 save_file = g_strdup(g_save_file);
1061 /* Save the directory name for future file dialogs. */
1062 cf_name = g_strdup(g_save_file);
1063 dirname = get_dirname(cf_name); /* Overwrites cf_name */
1064 set_last_open_dir(dirname);
1067 /* User didn't specify a file; save to a temporary file. */
1071 capture_opts.has_autostop_count =
1072 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb));
1073 if (capture_opts.has_autostop_count)
1074 capture_opts.autostop_count =
1075 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(count_sb));
1077 capture_opts.has_autostop_duration =
1078 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb));
1079 if (capture_opts.has_autostop_duration)
1080 capture_opts.autostop_duration =
1081 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_sb));
1083 capture_opts.sync_mode =
1084 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
1087 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
1089 g_resolv_flags |= g_resolv_flags & RESOLV_CONCURRENT;
1090 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
1091 g_resolv_flags |= RESOLV_MAC;
1092 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
1093 g_resolv_flags |= RESOLV_NETWORK;
1094 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
1095 g_resolv_flags |= RESOLV_TRANSPORT;
1097 capture_opts.has_ring_num_files =
1098 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb));
1100 capture_opts.num_files =
1101 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
1102 if (capture_opts.num_files > RINGBUFFER_MAX_NUM_FILES)
1103 capture_opts.num_files = RINGBUFFER_MAX_NUM_FILES;
1104 #if RINGBUFFER_MIN_NUM_FILES > 0
1105 else if (capture_opts.num_files < RINGBUFFER_MIN_NUM_FILES)
1106 capture_opts.num_files = RINGBUFFER_MIN_NUM_FILES;
1109 capture_opts.multi_files_on =
1110 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb));
1112 if(capture_opts.sync_mode)
1113 capture_opts.multi_files_on = FALSE;
1115 if (capture_opts.multi_files_on) {
1116 capture_opts.has_autostop_filesize =
1117 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb));
1118 if (capture_opts.has_autostop_filesize)
1119 capture_opts.autostop_filesize =
1120 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_filesize_sb));
1122 /* test if the settings are ok for a ringbuffer */
1123 if (save_file == NULL) {
1124 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1125 PRIMARY_TEXT_START "Multiple files: No capture file name given!\n\n" PRIMARY_TEXT_END
1126 "You must specify a filename if you want to use multiple files.");
1128 } else if (!capture_opts.has_autostop_filesize) {
1129 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1130 PRIMARY_TEXT_START "Multiple files: No file limit given!\n\n" PRIMARY_TEXT_END
1131 "You must specify a file size at which is switched to the next capture file\n"
1132 "if you want to use multiple files.");
1137 capture_opts.has_autostop_filesize =
1138 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb));
1139 if (capture_opts.has_autostop_filesize)
1140 capture_opts.autostop_filesize =
1141 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filesize_sb));
1144 capture_opts.has_ring_duration =
1145 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb));
1146 if (capture_opts.has_ring_duration)
1147 capture_opts.ringbuffer_duration =
1148 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_duration_sb));
1150 gtk_widget_destroy(GTK_WIDGET(parent_w));
1152 do_capture(save_file);
1153 if (save_file != NULL)
1158 capture_prep_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
1160 gtk_grab_remove(GTK_WIDGET(parent_w));
1161 gtk_widget_destroy(GTK_WIDGET(parent_w));
1165 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1169 /* Is there a file selection dialog associated with this
1170 Capture Options dialog? */
1171 fs = OBJECT_GET_DATA(win, E_FILE_SEL_DIALOG_PTR_KEY);
1174 /* Yes. Destroy it. */
1175 gtk_widget_destroy(fs);
1178 /* Note that we no longer have a "Capture Options" dialog box. */
1183 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer argp)
1185 GtkWidget *linktype_om = argp;
1187 set_link_type_list(linktype_om, entry);
1191 * Adjust the sensitivity of various widgets as per the current setting
1195 capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1199 *ringbuffer_on_tb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
1200 *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_lb,
1201 *sync_cb, *auto_scroll_cb,
1202 *count_cb, *count_sb,
1203 *filesize_cb, *filesize_sb, *filesize_lb,
1204 *duration_cb, *duration_sb,
1205 *files_cb, *files_sb, *files_lb,
1206 *ring_duration_cb, *ring_duration_sb, *ring_duration_lb;
1209 if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
1210 snap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
1211 snap_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
1212 ringbuffer_on_tb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_ON_TB_KEY);
1213 ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
1214 ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
1215 ringbuffer_nbf_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_LB_KEY);
1216 ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
1217 ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
1218 ring_filesize_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_LB_KEY);
1219 ring_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_CB_KEY);
1220 ring_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_SB_KEY);
1221 ring_duration_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_LB_KEY);
1222 sync_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1223 auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1224 count_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_CB_KEY);
1225 count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_SB_KEY);
1226 filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_CB_KEY);
1227 filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_SB_KEY);
1228 filesize_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_LB_KEY);
1229 duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_CB_KEY);
1230 duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_SB_KEY);
1231 files_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILES_CB_KEY);
1232 files_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILES_SB_KEY);
1233 files_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILES_LB_KEY);
1235 /* The snapshot length spinbox is sensitive if the "Limit each packet
1236 to" checkbox is on. */
1237 gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
1238 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
1241 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
1242 /* "Update list of packets in real time" captures enabled; we don't
1243 support ring buffer mode for those captures, so turn ring buffer
1244 mode off if it's on, and make its toggle button, and the spin
1245 button for the number of ring buffer files (and the spin button's
1246 label), insensitive. */
1247 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb), FALSE);
1248 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), FALSE);
1250 /* Auto-scroll mode is meaningful only in "Update list of packets
1251 in real time" captures, so make its toggle button sensitive. */
1252 gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
1254 /* "Update list of packets in real time" captures disabled; that
1255 means ring buffer mode is OK, so make its toggle button
1257 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), TRUE);
1259 /* Auto-scroll mode is meaningful only in "Update list of packets
1260 in real time" captures, so make its toggle button insensitive. */
1261 gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
1264 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
1265 /* Ring buffer mode enabled. */
1266 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb), TRUE);
1268 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), TRUE);
1269 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb),
1270 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
1271 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), TRUE);
1273 /* The ring filesize spinbox is sensitive if the "Next capture file
1274 after N kilobytes" checkbox is on. */
1275 gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), TRUE);
1276 gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),
1277 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
1278 gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_lb), TRUE);
1280 /* The ring duration spinbox is sensitive if the "Next capture file
1281 after N seconds" checkbox is on. */
1282 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_cb), TRUE);
1283 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_sb),
1284 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb)));
1285 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_lb), TRUE);
1287 gtk_widget_set_sensitive(GTK_WIDGET(filesize_cb), FALSE);
1288 gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb), FALSE);
1289 gtk_widget_set_sensitive(GTK_WIDGET(filesize_lb), FALSE);
1291 gtk_widget_set_sensitive(GTK_WIDGET(files_cb), TRUE);
1292 gtk_widget_set_sensitive(GTK_WIDGET(files_sb),
1293 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(files_cb)));
1294 gtk_widget_set_sensitive(GTK_WIDGET(files_lb), TRUE);
1296 /* Ring buffer mode disabled. */
1297 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), FALSE);
1298 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
1299 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
1301 gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), FALSE);
1302 gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),FALSE);
1303 gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_lb),FALSE);
1305 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_cb), FALSE);
1306 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_sb),FALSE);
1307 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_lb),FALSE);
1309 /* The maximum file size spinbox is sensitive if the "Stop capture
1310 after N kilobytes" checkbox is on. */
1311 gtk_widget_set_sensitive(GTK_WIDGET(filesize_cb), TRUE);
1312 gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb),
1313 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb)));
1314 gtk_widget_set_sensitive(GTK_WIDGET(filesize_lb), TRUE);
1316 gtk_widget_set_sensitive(GTK_WIDGET(files_cb), FALSE);
1317 gtk_widget_set_sensitive(GTK_WIDGET(files_sb), FALSE);
1318 gtk_widget_set_sensitive(GTK_WIDGET(files_lb), FALSE);
1321 /* The maximum packet count spinbox is sensitive if the "Stop capture
1322 after N packets" checkbox is on. */
1323 gtk_widget_set_sensitive(GTK_WIDGET(count_sb),
1324 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb)));
1326 /* The capture duration spinbox is sensitive if the "Stop capture
1327 after N seconds" checkbox is on. */
1328 gtk_widget_set_sensitive(GTK_WIDGET(duration_sb),
1329 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb)));
1332 #endif /* HAVE_LIBPCAP */