2 * Routines for packet capture windows
4 * $Id: capture_dlg.c,v 1.90 2003/12/21 12:17:58 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"
53 #include "capture-wpcap.h"
56 /* Capture callback data keys */
57 #define E_CAP_IFACE_KEY "cap_iface"
58 #define E_CAP_SNAP_CB_KEY "cap_snap_cb"
59 #define E_CAP_LT_OM_KEY "cap_lt_om"
60 #define E_CAP_LT_OM_LABEL_KEY "cap_lt_om_label"
61 #define E_CAP_SNAP_SB_KEY "cap_snap_sb"
62 #define E_CAP_PROMISC_KEY "cap_promisc"
63 #define E_CAP_FILT_KEY "cap_filter_te"
64 #define E_CAP_FILE_TE_KEY "cap_file_te"
65 #define E_CAP_RING_ON_TB_KEY "cap_ringbuffer_on_tb"
66 #define E_CAP_RING_NBF_LB_KEY "cap_ringbuffer_nbf_lb"
67 #define E_CAP_RING_NBF_SB_KEY "cap_ringbuffer_nbf_sb"
68 #define E_CAP_RING_DURATION_CB_KEY "cap_ringbuffer_duration_cb"
69 #define E_CAP_RING_DURATION_SB_KEY "cap_ringbuffer_duration_sb"
70 #define E_CAP_SYNC_KEY "cap_sync"
71 #define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll"
72 #define E_CAP_COUNT_CB_KEY "cap_count_cb"
73 #define E_CAP_COUNT_SB_KEY "cap_count_sb"
74 #define E_CAP_FILESIZE_CB_KEY "cap_filesize_cb"
75 #define E_CAP_FILESIZE_SB_KEY "cap_filesize_sb"
76 #define E_CAP_FILESIZE_LB_KEY "cap_filesize_lb"
77 #define E_CAP_DURATION_CB_KEY "cap_duration_cb"
78 #define E_CAP_DURATION_SB_KEY "cap_duration_sb"
79 #define E_CAP_M_RESOLVE_KEY "cap_m_resolve"
80 #define E_CAP_N_RESOLVE_KEY "cap_n_resolve"
81 #define E_CAP_T_RESOLVE_KEY "cap_t_resolve"
83 #define E_CAP_OM_LT_VALUE_KEY "cap_om_lt_value"
85 #define E_FS_CALLER_PTR_KEY "fs_caller_ptr"
86 #define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
89 capture_prep_file_cb(GtkWidget *w, gpointer te);
92 select_link_type_cb(GtkWidget *w, gpointer data);
95 cap_prep_fs_ok_cb(GtkWidget *w, gpointer data);
98 cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
101 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
104 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
107 capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
110 capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w);
113 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
116 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer parent_w);
119 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
125 * Keep a static pointer to the current "Capture Options" window, if
126 * any, so that if somebody tries to do "Capture:Start" while there's
127 * already a "Capture Options" window up, we just pop up the existing
128 * one, rather than creating a new one.
130 static GtkWidget *cap_open_w;
133 set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
143 char err_buf[PCAP_ERRBUF_SIZE];
144 GtkWidget *lt_menu, *lt_menu_item;
146 data_link_info_t *data_link_info;
147 gchar *linktype_menu_label;
148 guint num_supported_link_types;
149 GtkWidget *linktype_lb = OBJECT_GET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY);
151 lt_menu = gtk_menu_new();
152 entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
153 if_text = g_strstrip(entry_text);
154 if_name = strrchr(if_text, ' ');
155 if (if_name == NULL) {
162 * If the interface name is in the list of known interfaces, get
163 * its list of link-layer types and set the option menu to display it.
165 * If it's not, don't bother - the user might be in the middle of
166 * editing the list, or it might be a remote device in which case
167 * getting the list could take an arbitrarily-long period of time.
168 * The list currently won't contain any remote devices (as
169 * "pcap_findalldevs()" doesn't know about remote devices, and neither
170 * does the code we use if "pcap_findalldevs()" isn't available), but
171 * should contain all the local devices on which you can capture.
174 if (*if_name != '\0') {
176 * Try to get the list of known interfaces.
178 if_list = get_interface_list(&err, err_buf);
179 if (if_list != NULL) {
181 * We have the list - check it.
183 for (if_entry = if_list; if_entry != NULL;
184 if_entry = g_list_next(if_entry)) {
185 if_info = if_entry->data;
186 if (strcmp(if_info->name, if_name) == 0) {
189 * Get the list of link-layer types for it.
191 lt_list = get_pcap_linktype_list(if_name, err_buf);
194 free_interface_list(if_list);
198 num_supported_link_types = 0;
199 for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
200 data_link_info = lt_entry->data;
201 if (data_link_info->description != NULL) {
202 lt_menu_item = gtk_menu_item_new_with_label(data_link_info->description);
203 OBJECT_SET_DATA(lt_menu_item, E_CAP_LT_OM_KEY, linktype_om);
204 SIGNAL_CONNECT(lt_menu_item, "activate", select_link_type_cb,
205 GINT_TO_POINTER(data_link_info->dlt));
206 num_supported_link_types++;
208 /* Not supported - tell them about it but don't let them select it. */
209 linktype_menu_label = g_strdup_printf("%s (not supported)",
210 data_link_info->name);
211 lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
212 g_free(linktype_menu_label);
213 gtk_widget_set_sensitive(lt_menu_item, FALSE);
215 gtk_menu_append(GTK_MENU(lt_menu), lt_menu_item);
216 gtk_widget_show(lt_menu_item);
219 free_pcap_linktype_list(lt_list);
220 gtk_option_menu_set_menu(GTK_OPTION_MENU(linktype_om), lt_menu);
221 gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
222 gtk_widget_set_sensitive(linktype_om, num_supported_link_types >= 2);
226 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
229 *capture_fr, *capture_vb,
230 *if_hb, *if_cb, *if_lb,
231 *linktype_hb, *linktype_lb, *linktype_om,
232 *snap_hb, *snap_cb, *snap_sb, *snap_lb,
234 *filter_hb, *filter_bt, *filter_te,
236 *file_hb, *file_bt, *file_te,
237 *ringbuffer_hb, *ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb,
238 *display_fr, *display_vb,
239 *sync_cb, *auto_scroll_cb,
240 *limit_fr, *limit_vb,
241 *count_hb, *count_cb, *count_sb, *count_lb,
242 *filesize_hb, *filesize_cb, *filesize_sb, *filesize_lb,
243 *duration_hb, *duration_cb, *duration_sb, *duration_lb,
244 *ring_duration_hb, *ring_duration_cb, *ring_duration_sb,
246 *resolv_fr, *resolv_vb,
247 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
248 *bbox, *ok_bt, *cancel_bt;
249 #if GTK_MAJOR_VERSION < 2
250 GtkAccelGroup *accel_group;
252 GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
253 *count_adj, *filesize_adj, *duration_adj, *ring_duration_adj;
254 GList *if_list, *combo_list;
256 char err_str[PCAP_ERRBUF_SIZE];
258 if (cap_open_w != NULL) {
259 /* There's already a "Capture Options" dialog box; reactivate it. */
260 reactivate_window(cap_open_w);
265 /* Is WPcap loaded? */
267 simple_dialog(ESD_TYPE_CRIT, NULL,
268 "Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n"
269 "to capture packets.\n\n"
270 "In order to capture packets, WinPcap must be installed; see\n"
272 " http://winpcap.polito.it/\n"
276 " http://winpcap.mirror.ethereal.com/\n"
280 " http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n"
282 "for a downloadable version of WinPcap and for instructions\n"
283 "on how to install WinPcap.");
288 if_list = get_interface_list(&err, err_str);
289 if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
290 simple_dialog(ESD_TYPE_WARN, NULL, "Can't get list of interfaces: %s",
294 cap_open_w = dlg_window_new("Ethereal: Capture Options");
295 SIGNAL_CONNECT(cap_open_w, "destroy", capture_prep_destroy_cb, NULL);
297 #if GTK_MAJOR_VERSION < 2
298 /* Accelerator group for the accelerators (or, as they're called in
299 Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
300 Ctrl+<key> is an accelerator). */
301 accel_group = gtk_accel_group_new();
302 gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group);
305 main_vb = gtk_vbox_new(FALSE, 0);
306 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
307 gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
308 gtk_widget_show(main_vb);
310 /* Capture-related options frame */
311 capture_fr = gtk_frame_new("Capture");
312 gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
313 gtk_widget_show(capture_fr);
315 capture_vb = gtk_vbox_new(FALSE, 0);
316 gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
317 gtk_widget_show(capture_vb);
320 if_hb = gtk_hbox_new(FALSE, 3);
321 gtk_container_add(GTK_CONTAINER(capture_vb), if_hb);
322 gtk_widget_show(if_hb);
324 if_lb = gtk_label_new("Interface:");
325 gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
326 gtk_widget_show(if_lb);
328 if_cb = gtk_combo_new();
329 combo_list = build_capture_combo_list(if_list, TRUE);
330 if (combo_list != NULL)
331 gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
332 if (cfile.iface == NULL && prefs.capture_device != NULL) {
333 /* No interface was specified on the command line or in a previous
334 capture, but there is one specified in the preferences file;
335 make the one from the preferences file the default */
336 cfile.iface = g_strdup(prefs.capture_device);
338 if (cfile.iface != NULL)
339 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
340 else if (combo_list != NULL) {
341 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
342 (char *)combo_list->data);
344 free_capture_combo_list(combo_list);
345 free_interface_list(if_list);
346 gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
347 gtk_widget_show(if_cb);
350 linktype_hb = gtk_hbox_new(FALSE, 3);
351 gtk_container_add(GTK_CONTAINER(capture_vb), linktype_hb);
352 gtk_widget_show(linktype_hb);
354 linktype_lb = gtk_label_new("Link-layer header type:");
355 gtk_box_pack_start(GTK_BOX(linktype_hb), linktype_lb, FALSE, FALSE, 6);
356 gtk_widget_show(linktype_lb);
358 linktype_om = gtk_option_menu_new();
359 OBJECT_SET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY, linktype_lb);
360 /* Default to "use the default" */
361 OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(-1));
362 set_link_type_list(linktype_om, GTK_COMBO(if_cb)->entry);
363 gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_om, FALSE, FALSE, 0);
364 gtk_widget_show(linktype_om);
365 SIGNAL_CONNECT(GTK_ENTRY(GTK_COMBO(if_cb)->entry), "changed",
366 capture_prep_interface_changed_cb, linktype_om);
368 /* Capture length row */
369 snap_hb = gtk_hbox_new(FALSE, 3);
370 gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
371 gtk_widget_show(snap_hb);
373 #if GTK_MAJOR_VERSION < 2
374 snap_cb = dlg_check_button_new_with_label_with_mnemonic(
375 "_Limit each packet to", accel_group);
377 snap_cb = gtk_check_button_new_with_mnemonic("_Limit each packet to");
379 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb),
380 capture_opts.has_snaplen);
381 SIGNAL_CONNECT(snap_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
382 gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
383 gtk_widget_show(snap_cb);
385 snap_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.snaplen,
386 MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
387 snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
388 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
389 WIDGET_SET_SIZE(snap_sb, 80, -1);
390 gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
391 gtk_widget_show(snap_sb);
393 snap_lb = gtk_label_new("bytes");
394 gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5);
395 gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
396 gtk_widget_show(snap_lb);
398 /* Promiscuous mode row */
399 #if GTK_MAJOR_VERSION < 2
400 promisc_cb = dlg_check_button_new_with_label_with_mnemonic(
401 "Capture packets in _promiscuous mode", accel_group);
403 promisc_cb = gtk_check_button_new_with_mnemonic(
404 "Capture packets in _promiscuous mode");
406 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb),
407 capture_opts.promisc_mode);
408 gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
409 gtk_widget_show(promisc_cb);
412 filter_hb = gtk_hbox_new(FALSE, 3);
413 gtk_container_add(GTK_CONTAINER(capture_vb), filter_hb);
414 gtk_widget_show(filter_hb);
416 filter_bt = gtk_button_new_with_label("Filter:");
417 SIGNAL_CONNECT(filter_bt, "clicked", capture_filter_construct_cb, NULL);
418 SIGNAL_CONNECT(filter_bt, "destroy", filter_button_destroy_cb, NULL);
419 gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
420 gtk_widget_show(filter_bt);
422 filter_te = gtk_entry_new();
423 if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
424 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
425 gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3);
426 gtk_widget_show(filter_te);
428 /* Capture file-related options frame */
429 file_fr = gtk_frame_new("Capture file(s)");
430 gtk_container_add(GTK_CONTAINER(main_vb), file_fr);
431 gtk_widget_show(file_fr);
433 file_vb = gtk_vbox_new(FALSE, 3);
434 gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
435 gtk_widget_show(file_vb);
438 file_hb = gtk_hbox_new(FALSE, 3);
439 gtk_container_add(GTK_CONTAINER(file_vb), file_hb);
440 gtk_widget_show(file_hb);
442 file_bt = gtk_button_new_with_label("File:");
443 gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3);
444 gtk_widget_show(file_bt);
446 file_te = gtk_entry_new();
447 gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
448 gtk_widget_show(file_te);
450 SIGNAL_CONNECT(file_bt, "clicked", capture_prep_file_cb, file_te);
452 /* Ring buffer row */
453 ringbuffer_hb = gtk_hbox_new(FALSE, 3);
454 gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_hb);
455 gtk_widget_show(ringbuffer_hb);
457 #if GTK_MAJOR_VERSION < 2
458 ringbuffer_on_tb = dlg_check_button_new_with_label_with_mnemonic(
459 "Use _ring buffer", accel_group);
461 ringbuffer_on_tb = gtk_check_button_new_with_mnemonic("Use _ring buffer");
463 /* Ring buffer mode is allowed only if we're not doing an "Update list of
464 packets in real time" capture, so force it off if we're doing such
466 if (capture_opts.sync_mode)
467 capture_opts.ringbuffer_on = FALSE;
468 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_on_tb),
469 capture_opts.ringbuffer_on);
470 SIGNAL_CONNECT(ringbuffer_on_tb, "toggled", capture_prep_adjust_sensitivity,
472 gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_on_tb, FALSE, FALSE, 0);
473 gtk_widget_show(ringbuffer_on_tb);
475 ringbuffer_nbf_lb = gtk_label_new("Number of files");
476 gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 1, 0.5);
477 gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_nbf_lb, FALSE, FALSE, 6);
478 gtk_widget_show(ringbuffer_nbf_lb);
480 ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.ringbuffer_num_files,
481 RINGBUFFER_MIN_NUM_FILES, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
482 ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
483 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
484 WIDGET_SET_SIZE(ringbuffer_nbf_sb, 40, -1);
485 gtk_box_pack_start (GTK_BOX(ringbuffer_hb), ringbuffer_nbf_sb, TRUE, TRUE, 0);
486 gtk_widget_show(ringbuffer_nbf_sb);
488 /* Ring buffer duration row */
489 ring_duration_hb = gtk_hbox_new(FALSE, 3);
490 gtk_container_add(GTK_CONTAINER(file_vb), ring_duration_hb);
491 gtk_widget_show(ring_duration_hb);
493 ring_duration_cb = gtk_check_button_new_with_label("Rotate capture file every");
494 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_duration_cb),
495 capture_opts.has_ring_duration);
496 SIGNAL_CONNECT(ring_duration_cb, "toggled",
497 capture_prep_adjust_sensitivity, cap_open_w);
498 gtk_box_pack_start(GTK_BOX(ring_duration_hb), ring_duration_cb,
500 gtk_widget_show(ring_duration_cb);
502 ring_duration_adj = (GtkAdjustment *)gtk_adjustment_new(capture_opts.ringbuffer_duration,
503 1, INT_MAX, 1.0, 10.0, 0.0);
504 ring_duration_sb = gtk_spin_button_new (ring_duration_adj, 0, 0);
505 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_duration_sb), TRUE);
506 WIDGET_SET_SIZE(ring_duration_sb, 80, -1);
507 gtk_box_pack_start (GTK_BOX(ring_duration_hb), ring_duration_sb,
509 gtk_widget_show(ring_duration_sb);
511 ring_duration_lb = gtk_label_new("second(s)");
512 gtk_misc_set_alignment(GTK_MISC(ring_duration_lb), 0, 0.5);
513 gtk_box_pack_start(GTK_BOX(ring_duration_hb), ring_duration_lb,
515 gtk_widget_show(ring_duration_lb);
517 /* Display-related options frame */
518 display_fr = gtk_frame_new("Display options");
519 gtk_container_add(GTK_CONTAINER(main_vb), display_fr);
520 gtk_widget_show(display_fr);
522 display_vb = gtk_vbox_new(FALSE, 0);
523 gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
524 gtk_widget_show(display_vb);
526 /* "Update display in real time" row */
527 #if GTK_MAJOR_VERSION < 2
528 sync_cb = dlg_check_button_new_with_label_with_mnemonic(
529 "_Update list of packets in real time", accel_group);
531 sync_cb = gtk_check_button_new_with_mnemonic(
532 "_Update list of packets in real time");
534 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb),
535 capture_opts.sync_mode);
536 SIGNAL_CONNECT(sync_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
537 gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
538 gtk_widget_show(sync_cb);
540 /* "Auto-scroll live update" row */
541 #if GTK_MAJOR_VERSION < 2
542 auto_scroll_cb = dlg_check_button_new_with_label_with_mnemonic(
543 "_Automatic scrolling in live capture", accel_group);
545 auto_scroll_cb = gtk_check_button_new_with_mnemonic(
546 "_Automatic scrolling in live capture");
548 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
549 gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
550 gtk_widget_show(auto_scroll_cb);
552 /* Capture limits frame */
553 limit_fr = gtk_frame_new("Capture limits");
554 gtk_container_add(GTK_CONTAINER(main_vb), limit_fr);
555 gtk_widget_show(limit_fr);
557 limit_vb = gtk_vbox_new(FALSE, 0);
558 gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
559 gtk_widget_show(limit_vb);
562 count_hb = gtk_hbox_new(FALSE, 3);
563 gtk_container_add(GTK_CONTAINER(limit_vb), count_hb);
564 gtk_widget_show(count_hb);
566 count_cb = gtk_check_button_new_with_label("Stop capture after");
567 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(count_cb),
568 capture_opts.has_autostop_count);
569 SIGNAL_CONNECT(count_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
570 gtk_box_pack_start(GTK_BOX(count_hb), count_cb, FALSE, FALSE, 0);
571 gtk_widget_show(count_cb);
573 count_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_count,
574 1, INT_MAX, 1.0, 10.0, 0.0);
575 count_sb = gtk_spin_button_new (count_adj, 0, 0);
576 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (count_sb), TRUE);
577 WIDGET_SET_SIZE(count_sb, 80, -1);
578 gtk_box_pack_start (GTK_BOX(count_hb), count_sb, FALSE, FALSE, 0);
579 gtk_widget_show(count_sb);
581 count_lb = gtk_label_new("packet(s) captured");
582 gtk_misc_set_alignment(GTK_MISC(count_lb), 0, 0.5);
583 gtk_box_pack_start(GTK_BOX(count_hb), count_lb, FALSE, FALSE, 0);
584 gtk_widget_show(count_lb);
587 filesize_hb = gtk_hbox_new(FALSE, 3);
588 gtk_container_add(GTK_CONTAINER(limit_vb), filesize_hb);
589 gtk_widget_show(filesize_hb);
591 filesize_cb = gtk_check_button_new_with_label("");
592 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb),
593 capture_opts.has_autostop_filesize);
594 SIGNAL_CONNECT(filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
595 gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_cb, FALSE, FALSE, 0);
596 gtk_widget_show(filesize_cb);
598 filesize_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_filesize,
599 1, INT_MAX, 1.0, 10.0, 0.0);
600 filesize_sb = gtk_spin_button_new (filesize_adj, 0, 0);
601 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (filesize_sb), TRUE);
602 WIDGET_SET_SIZE(filesize_sb, 80, -1);
603 gtk_box_pack_start (GTK_BOX(filesize_hb), filesize_sb, FALSE, FALSE, 0);
604 gtk_widget_show(filesize_sb);
606 filesize_lb = gtk_label_new("");
607 gtk_misc_set_alignment(GTK_MISC(filesize_lb), 0, 0.5);
608 gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_lb, FALSE, FALSE, 0);
609 gtk_widget_show(filesize_lb);
612 duration_hb = gtk_hbox_new(FALSE, 3);
613 gtk_container_add(GTK_CONTAINER(limit_vb), duration_hb);
614 gtk_widget_show(duration_hb);
616 duration_cb = gtk_check_button_new_with_label("Stop capture after");
617 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(duration_cb),
618 capture_opts.has_autostop_duration);
619 SIGNAL_CONNECT(duration_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
620 gtk_box_pack_start(GTK_BOX(duration_hb), duration_cb, FALSE, FALSE, 0);
621 gtk_widget_show(duration_cb);
623 duration_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_duration,
624 1, INT_MAX, 1.0, 10.0, 0.0);
625 duration_sb = gtk_spin_button_new (duration_adj, 0, 0);
626 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (duration_sb), TRUE);
627 WIDGET_SET_SIZE(duration_sb, 80, -1);
628 gtk_box_pack_start (GTK_BOX(duration_hb), duration_sb, FALSE, FALSE, 0);
629 gtk_widget_show(duration_sb);
631 duration_lb = gtk_label_new("second(s)");
632 gtk_misc_set_alignment(GTK_MISC(duration_lb), 0, 0.5);
633 gtk_box_pack_start(GTK_BOX(duration_hb), duration_lb, FALSE, FALSE, 0);
634 gtk_widget_show(duration_lb);
636 /* Resolution options frame */
637 resolv_fr = gtk_frame_new("Name resolution");
638 gtk_container_add(GTK_CONTAINER(main_vb), resolv_fr);
639 gtk_widget_show(resolv_fr);
641 resolv_vb = gtk_vbox_new(FALSE, 0);
642 gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
643 gtk_widget_show(resolv_vb);
645 #if GTK_MAJOR_VERSION < 2
646 m_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
647 "Enable _MAC name resolution", accel_group);
649 m_resolv_cb = gtk_check_button_new_with_mnemonic(
650 "Enable _MAC name resolution");
652 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
653 g_resolv_flags & RESOLV_MAC);
654 gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
655 gtk_widget_show(m_resolv_cb);
657 #if GTK_MAJOR_VERSION < 2
658 n_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
659 "Enable _network name resolution", accel_group);
661 n_resolv_cb = gtk_check_button_new_with_mnemonic(
662 "Enable _network name resolution");
664 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
665 g_resolv_flags & RESOLV_NETWORK);
666 gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
667 gtk_widget_show(n_resolv_cb);
669 #if GTK_MAJOR_VERSION < 2
670 t_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
671 "Enable _transport name resolution", accel_group);
673 t_resolv_cb = gtk_check_button_new_with_mnemonic(
674 "Enable _transport name resolution");
676 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
677 g_resolv_flags & RESOLV_TRANSPORT);
678 gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
679 gtk_widget_show(t_resolv_cb);
681 /* Button row: OK and cancel buttons */
682 bbox = gtk_hbutton_box_new();
683 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
684 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
685 gtk_container_add(GTK_CONTAINER(main_vb), bbox);
686 gtk_widget_show(bbox);
688 #if GTK_MAJOR_VERSION < 2
689 ok_bt = gtk_button_new_with_label ("OK");
691 ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
693 SIGNAL_CONNECT(ok_bt, "clicked", capture_prep_ok_cb, cap_open_w);
694 GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
695 gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
696 gtk_widget_grab_default(ok_bt);
697 gtk_widget_show(ok_bt);
699 #if GTK_MAJOR_VERSION < 2
700 cancel_bt = gtk_button_new_with_label ("Cancel");
702 cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
704 SIGNAL_CONNECT(cancel_bt, "clicked", capture_prep_close_cb, cap_open_w);
705 GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
706 gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
707 gtk_widget_show(cancel_bt);
709 /* Attach pointers to needed widgets to the capture prefs window/object */
710 OBJECT_SET_DATA(cap_open_w, E_CAP_IFACE_KEY, if_cb);
711 OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_CB_KEY, snap_cb);
712 OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_SB_KEY, snap_sb);
713 OBJECT_SET_DATA(cap_open_w, E_CAP_LT_OM_KEY, linktype_om);
714 OBJECT_SET_DATA(cap_open_w, E_CAP_PROMISC_KEY, promisc_cb);
715 OBJECT_SET_DATA(cap_open_w, E_CAP_FILT_KEY, filter_te);
716 OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_TE_KEY, file_te);
717 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_ON_TB_KEY, ringbuffer_on_tb);
718 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_LB_KEY, ringbuffer_nbf_lb);
719 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_SB_KEY, ringbuffer_nbf_sb);
720 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_CB_KEY, ring_duration_cb);
721 OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_SB_KEY, ring_duration_sb);
722 OBJECT_SET_DATA(cap_open_w, E_CAP_SYNC_KEY, sync_cb);
723 OBJECT_SET_DATA(cap_open_w, E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
724 OBJECT_SET_DATA(cap_open_w, E_CAP_COUNT_CB_KEY, count_cb);
725 OBJECT_SET_DATA(cap_open_w, E_CAP_COUNT_SB_KEY, count_sb);
726 OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_CB_KEY, filesize_cb);
727 OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_SB_KEY, filesize_sb);
728 OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_LB_KEY, filesize_lb);
729 OBJECT_SET_DATA(cap_open_w, E_CAP_DURATION_CB_KEY, duration_cb);
730 OBJECT_SET_DATA(cap_open_w, E_CAP_DURATION_SB_KEY, duration_sb);
731 OBJECT_SET_DATA(cap_open_w, E_CAP_M_RESOLVE_KEY, m_resolv_cb);
732 OBJECT_SET_DATA(cap_open_w, E_CAP_N_RESOLVE_KEY, n_resolv_cb);
733 OBJECT_SET_DATA(cap_open_w, E_CAP_T_RESOLVE_KEY, t_resolv_cb);
735 /* Set the sensitivity of various widgets as per the settings of other
737 capture_prep_adjust_sensitivity(NULL, cap_open_w);
739 /* Catch the "activate" signal on the filter and file name text
740 entries, so that if the user types Return there, we act as if the
741 "OK" button had been selected, as happens if Return is typed if some
742 widget that *doesn't* handle the Return key has the input focus. */
743 dlg_set_activate(filter_te, ok_bt);
744 dlg_set_activate(file_te, ok_bt);
746 /* Catch the "key_press_event" signal in the window, so that we can catch
747 the ESC key being pressed and act as if the "Cancel" button had
749 dlg_set_cancel(cap_open_w, cancel_bt);
751 /* XXX - why does not
753 gtk_widget_grab_focus(if_cb);
755 give the initial focus to the "Interface" combo box?
757 Or should I phrase that as "why does GTK+ continually frustrate
758 attempts to make GUIs driveable from the keyboard?" We have to
759 go catch the activate signal on every single GtkEntry widget
760 (rather than having widgets whose activate signal is *not*
761 caught not catch the Return keystroke, so that it passes on,
762 ultimately, to the window, which can activate the default
763 widget, i.e. the "OK" button); we have to catch the "key_press_event"
764 signal and have the handler check for ESC, so that we can have ESC
765 activate the "Cancel" button; in order to support Alt+<key> mnemonics
766 for buttons and the like, we may have to construct an accelerator
767 group by hand and set up the accelerators by hand (if that even
768 works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()"
769 to keep some container widget from getting the initial focus, so that
770 you don't have to tab into the first widget in order to start typing
771 in it; and it now appears that you simply *can't* make a combo box
772 get the initial focus, at least not in the obvious fashion. Sigh.... */
774 gtk_widget_show(cap_open_w);
778 select_link_type_cb(GtkWidget *w, gpointer data)
780 int new_linktype = GPOINTER_TO_INT(data);
781 GtkWidget *linktype_om = OBJECT_GET_DATA(w, E_CAP_LT_OM_KEY);
782 int old_linktype = GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
784 if (old_linktype != new_linktype)
785 OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(new_linktype));
789 capture_prep_file_cb(GtkWidget *w, gpointer file_te)
791 GtkWidget *caller = gtk_widget_get_toplevel(w);
794 /* Has a file selection dialog box already been opened for that top-level
796 fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY);
799 /* Yes. Just re-activate that dialog box. */
800 reactivate_window(fs);
804 fs = file_selection_new ("Ethereal: Capture File");
806 /* If we've opened a file, start out by showing the files in the directory
807 in which that file resided. */
809 gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
811 OBJECT_SET_DATA(fs, E_CAP_FILE_TE_KEY, file_te);
813 /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
814 OBJECT_SET_DATA(fs, E_FS_CALLER_PTR_KEY, caller);
816 /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
817 OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, fs);
819 /* Call a handler when the file selection box is destroyed, so we can inform
820 our caller, if any, that it's been destroyed. */
821 SIGNAL_CONNECT(fs, "destroy", cap_prep_fs_destroy_cb, file_te);
823 SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->ok_button, "clicked", cap_prep_fs_ok_cb, fs);
825 /* Connect the cancel_button to destroy the widget */
826 SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->cancel_button, "clicked", cap_prep_fs_cancel_cb,
829 /* Catch the "key_press_event" signal in the window, so that we can catch
830 the ESC key being pressed and act as if the "Cancel" button had
832 dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
838 cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
842 cf_name = g_strdup(gtk_file_selection_get_filename(
843 GTK_FILE_SELECTION (data)));
845 /* Perhaps the user specified a directory instead of a file.
846 Check whether they did. */
847 if (test_for_directory(cf_name) == EISDIR) {
848 /* It's a directory - set the file selection box to display it. */
849 set_last_open_dir(cf_name);
851 gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
856 gtk_entry_set_text(GTK_ENTRY(OBJECT_GET_DATA(data, E_CAP_FILE_TE_KEY)), cf_name);
858 gtk_widget_destroy(GTK_WIDGET(data));
863 cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
865 gtk_widget_destroy(GTK_WIDGET(data));
869 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
873 /* Get the widget that requested that we be popped up.
874 (It should arrange to destroy us if it's destroyed, so
875 that we don't get a pointer to a non-existent window here.) */
876 caller = OBJECT_GET_DATA(win, E_FS_CALLER_PTR_KEY);
878 /* Tell it we no longer exist. */
879 OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, NULL);
881 /* Now nuke this window. */
882 gtk_grab_remove(GTK_WIDGET(win));
883 gtk_widget_destroy(GTK_WIDGET(win));
885 /* Give the focus to the file text entry widget so the user can just press
886 Return to start the capture. */
887 gtk_widget_grab_focus(file_te);
891 capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
892 GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te,
893 *file_te, *ringbuffer_on_tb, *ringbuffer_nbf_sb,
894 *linktype_om, *sync_cb, *auto_scroll_cb,
895 *count_cb, *count_sb,
896 *filesize_cb, *filesize_sb,
897 *duration_cb, *duration_sb,
898 *ring_duration_cb, *ring_duration_sb,
899 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
903 const gchar *filter_text;
905 const gchar *g_save_file;
909 if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
910 snap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
911 snap_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
912 linktype_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_LT_OM_KEY);
913 promisc_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_PROMISC_KEY);
914 filter_te = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILT_KEY);
915 file_te = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_TE_KEY);
916 ringbuffer_on_tb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_ON_TB_KEY);
917 ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
918 ring_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_CB_KEY);
919 ring_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_SB_KEY);
920 sync_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
921 auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
922 count_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_CB_KEY);
923 count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_SB_KEY);
924 filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_CB_KEY);
925 filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_SB_KEY);
926 duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_CB_KEY);
927 duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_SB_KEY);
928 m_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_M_RESOLVE_KEY);
929 n_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_N_RESOLVE_KEY);
930 t_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_T_RESOLVE_KEY);
933 g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
934 if_text = g_strstrip(entry_text);
935 /* Remove interface description; if it's present, it comes before
936 the interface name, and there's a space between them, and the
937 interface name is assumed to contain no space, so we look backwards
938 in the string for a space. */
939 if_name = strrchr(if_text, ' ');
940 if (if_name == NULL) {
945 if (*if_name == '\0') {
946 simple_dialog(ESD_TYPE_CRIT, NULL,
947 "You didn't specify an interface on which to capture packets.");
953 cfile.iface = g_strdup(if_name);
956 capture_opts.linktype =
957 GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
959 capture_opts.has_snaplen =
960 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
961 if (capture_opts.has_snaplen) {
962 capture_opts.snaplen =
963 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
964 if (capture_opts.snaplen < 1)
965 capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
966 else if (capture_opts.snaplen < MIN_PACKET_SIZE)
967 capture_opts.snaplen = MIN_PACKET_SIZE;
970 capture_opts.promisc_mode =
971 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
973 /* XXX - don't try to get clever and set "cfile.filter" to NULL if the
974 filter string is empty, as an indication that we don't have a filter
975 and thus don't have to set a filter when capturing - the version of
976 libpcap in Red Hat Linux 6.1, and versions based on later patches
977 in that series, don't bind the AF_PACKET socket to an interface
978 until a filter is set, which means they aren't bound at all if
979 no filter is set, which means no packets arrive as input on that
980 socket, which means Ethereal never sees any packets. */
981 filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
983 g_free(cfile.cfilter);
984 g_assert(filter_text != NULL);
985 cfile.cfilter = g_strdup(filter_text);
987 g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
988 if (g_save_file && g_save_file[0]) {
989 /* User specified a file to which the capture should be written. */
990 save_file = g_strdup(g_save_file);
991 /* Save the directory name for future file dialogs. */
992 cf_name = g_strdup(g_save_file);
993 dirname = get_dirname(cf_name); /* Overwrites cf_name */
994 set_last_open_dir(dirname);
997 /* User didn't specify a file; save to a temporary file. */
1001 capture_opts.has_autostop_count =
1002 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb));
1003 if (capture_opts.has_autostop_count)
1004 capture_opts.autostop_count =
1005 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(count_sb));
1007 capture_opts.has_autostop_filesize =
1008 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb));
1009 if (capture_opts.has_autostop_filesize)
1010 capture_opts.autostop_filesize =
1011 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filesize_sb));
1013 capture_opts.has_autostop_duration =
1014 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb));
1015 if (capture_opts.has_autostop_duration)
1016 capture_opts.autostop_duration =
1017 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_sb));
1019 capture_opts.sync_mode =
1020 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
1023 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
1025 g_resolv_flags = RESOLV_NONE;
1026 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
1027 g_resolv_flags |= RESOLV_MAC;
1028 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
1029 g_resolv_flags |= RESOLV_NETWORK;
1030 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
1031 g_resolv_flags |= RESOLV_TRANSPORT;
1033 capture_opts.ringbuffer_on =
1034 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb)) &&
1035 !(capture_opts.sync_mode);
1036 if (capture_opts.ringbuffer_on) {
1037 if (save_file == NULL) {
1038 simple_dialog(ESD_TYPE_CRIT, NULL,
1039 "You must specify a save file if you want to use the ring buffer.");
1041 } else if (!capture_opts.has_autostop_filesize) {
1042 simple_dialog(ESD_TYPE_CRIT, NULL,
1043 "You must specify a file size at which to rotate the capture files\n"
1044 "if you want to use the ring buffer.");
1050 capture_opts.ringbuffer_num_files =
1051 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
1052 if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
1053 capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
1054 #if RINGBUFFER_MIN_NUM_FILES > 0
1055 else if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
1056 capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
1059 capture_opts.has_ring_duration =
1060 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb));
1061 if (capture_opts.has_ring_duration)
1062 capture_opts.ringbuffer_duration =
1063 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_duration_sb));
1065 gtk_widget_destroy(GTK_WIDGET(parent_w));
1067 do_capture(save_file);
1068 if (save_file != NULL)
1073 capture_prep_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
1075 gtk_grab_remove(GTK_WIDGET(parent_w));
1076 gtk_widget_destroy(GTK_WIDGET(parent_w));
1080 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1084 /* Is there a file selection dialog associated with this
1085 Capture Options dialog? */
1086 fs = OBJECT_GET_DATA(win, E_FILE_SEL_DIALOG_PTR_KEY);
1089 /* Yes. Destroy it. */
1090 gtk_widget_destroy(fs);
1093 /* Note that we no longer have a "Capture Options" dialog box. */
1098 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer argp)
1100 GtkWidget *linktype_om = argp;
1102 set_link_type_list(linktype_om, entry);
1106 * Adjust the sensitivity of various widgets as per the current setting
1110 capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1114 *ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb,
1115 *sync_cb, *auto_scroll_cb,
1116 *count_cb, *count_sb,
1117 *filesize_cb, *filesize_sb, *filesize_lb,
1118 *duration_cb, *duration_sb,
1119 *ring_duration_cb, *ring_duration_sb;
1121 if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
1122 snap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
1123 snap_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
1124 ringbuffer_on_tb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_ON_TB_KEY);
1125 ringbuffer_nbf_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_LB_KEY);
1126 ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
1127 ring_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_CB_KEY);
1128 ring_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_SB_KEY);
1129 sync_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1130 auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1131 count_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_CB_KEY);
1132 count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_SB_KEY);
1133 filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_CB_KEY);
1134 filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_SB_KEY);
1135 filesize_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_LB_KEY);
1136 duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_CB_KEY);
1137 duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_SB_KEY);
1139 /* The snapshot length spinbox is sensitive iff the "Limit each packet
1140 to" checkbox is on. */
1141 gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
1142 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
1144 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
1145 /* "Update list of packets in real time" captures enabled; we don't
1146 support ring buffer mode for those captures, so turn ring buffer
1147 mode off if it's on, and make its toggle button, and the spin
1148 button for the number of ring buffer files (and the spin button's
1149 label), insensitive. */
1150 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
1151 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb), FALSE);
1153 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), FALSE);
1155 /* Auto-scroll mode is meaningful only in "Update list of packets
1156 in real time" captures, so make its toggle button sensitive. */
1157 gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
1159 /* "Update list of packets in real time" captures disabled; that
1160 means ring buffer mode is OK, so make its toggle button
1162 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), TRUE);
1164 /* Auto-scroll mode is meaningful only in "Update list of packets
1165 in real time" captures, so make its toggle button insensitive. */
1166 gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
1169 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
1170 /* Ring buffer mode enabled. Make the spin button for the number
1171 of ring buffer files, and its label, sensitive. */
1172 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), TRUE);
1173 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), TRUE);
1174 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_cb), TRUE);
1176 /* Also, indicate that the file size is a size at which to switch
1177 ring buffer files, not a size at which to stop the capture,
1178 turn its button on. */
1179 gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child),
1180 "Rotate capture file every");
1181 gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s)");
1182 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb), TRUE);
1184 /* Ring buffer mode disabled. Make the spin button for the number
1185 of ring buffer files, and its label insensitive. */
1186 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
1187 gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
1188 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_cb), FALSE);
1190 /* Also, indicate that the file size is a size at which to stop the
1191 capture, not a size at which to switch ring buffer files. */
1192 gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child),
1193 "Stop capture after");
1194 gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s) captured");
1197 /* The maximum packet count spinbox is sensitive iff the "Stop capture
1198 after N packets captured" checkbox is on. */
1199 gtk_widget_set_sensitive(GTK_WIDGET(count_sb),
1200 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb)));
1202 /* The maximum file size spinbox is sensitive iff the "Stop capture
1203 after N kilobytes captured" checkbox is on. */
1204 gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb),
1205 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb)));
1207 /* The capture duration spinbox is sensitive iff the "Stop capture
1208 after N seconds" checkbox is on. */
1209 gtk_widget_set_sensitive(GTK_WIDGET(duration_sb),
1210 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb)));
1212 /* The ring duration spinbox is sensitive if the "Rotate capture file
1213 after N seconds" checkbox is on. */
1214 gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_sb),
1215 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb)));
1218 #endif /* HAVE_LIBPCAP */