Ethereal-dev: Re: [Ethereal-dev] Unhandled exception...
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: "Gautham Thavva" <gautham.thavva@xxxxxxxxx>
Date: Sat, 12 Oct 2002 10:15:58 -0400
Hi Ashok, I have used diff version for windows and have enclosed the diffs as html. Please tell me if you need any other information. Thanks, Gautham On Fri, 11 Oct 2002 16:15:34 Ashok Narayanan wrote: > >You probably need to send out more information: > >1) A diff of your changes > >2) If you got a core dump, the backtrace of that core dump > >-Ashok > >> >> Please can someone who knows about the GUI help me. I had to include a text field for entering an IP address which would call a routine >> for bringing HDLC traffic from a remote terminal. >> >> These were the changes I made. >> >> I modified the capture file structure in file.h to add >> the IP address field. (gchar *ipaddr) >> I initialized the capture file variable in main.c >> (cfile.ipaddr = NULL) >> I added the GUI text entry construct in the capture_dlg.c >> When an IP address is entered, I trigger the remote >> capture by calling a routine. >> >> What happened was that initially, ethereal just quit. >> Then I commented out the portion of calling of the routine and recompiled. I then encountered Unhandled exception:0xC0000005:Access Violation. It was at the instruction do_capture(save_file) in capture_dlg.c >> >> I then commented out all the extra additions and having brought >> to the original state, no longer faced the unhandled exception. >> That however doesn't solve my problem. I don't understand why the >> GUI additions caused the error. >> >> Did I miss updating somewhere else? >> Please can someone help in resolving this issue. >> >> with regards, >> Gautham Thavva >> >> >> ____________________________________________________________ >> Watch a championship game with Elway or McGwire. >> Enter Now at http://champions.lycos.com >> _______________________________________________ >> Ethereal-dev mailing list >> Ethereal-dev@xxxxxxxxxxxx >> http://www.ethereal.com/mailman/listinfo/ethereal-dev > > > >--- Asok the Intern ---------------------------------------- >Ashok Narayanan >IOS Network Protocols, Cisco Systems >250 Apollo Drive, Chelmsford, MA 01824 >Ph: 978-497-8387. Fax: 978-497-8513 (Attn: Ashok Narayanan) > > ____________________________________________________________ Watch a championship game with Elway or McGwire. Enter Now at http://champions.lycos.comTitle: Differences Analysis
Base file: C:\ws\ethereal-0.9.5\gtk\capture_dlg.cCompared file: C:\ethereal-0.9.5\gtk\capture_dlg.cDifference Analysis Generated by HtmlDiff on 10/11/2002 5:51 PM 1: /* capture_dlg.c 2: * Routines for packet capture windows 3: * 4: * $Id: capture_dlg.c,v 1.69 2002/06/24 20:56:15 guy Exp $ 5: * 6: * Ethereal - Network traffic analyzer 7: * By Gerald Combs <gerald@xxxxxxxxxxxx> 8: * Copyright 1998 Gerald Combs 9: * 10: * This program is free software; you can redistribute it and/or 11: * modify it under the terms of the GNU General Public License 12: * as published by the Free Software Foundation; either version 2 13: * of the License, or (at your option) any later version. 14: * 15: * This program is distributed in the hope that it will be useful, 16: * but WITHOUT ANY WARRANTY; without even the implied warranty of 17: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: * GNU General Public License for more details. 19: * 20: * You should have received a copy of the GNU General Public License 21: * along with this program; if not, write to the Free Software 22: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23: */ 24: 25: #ifdef HAVE_CONFIG_H 26: # include "config.h" 27: #endif 28: 29: #ifdef HAVE_LIBPCAP 30: 31: #include <stdlib.h> 32: #include <stdio.h> 33: #include <string.h> 34: #include <gtk/gtk.h> 35: 36: #ifdef HAVE_UNISTD_H 37: #include <unistd.h> 38: #endif 39: 40: #include <time.h> 41: 42: #include <pcap.h> 43: 44: #ifdef NEED_SNPRINTF_H 45: # include "snprintf.h" 46: #endif 47: 48: #include "capture.h" 49: #include "capture_remote.h" 49: #include "globals.h" 50: #include <epan/resolv.h> 51: #include "main.h" 52: #include "ui_util.h" 53: #include "capture_dlg.h" 54: #include "filter_prefs.h" 55: #include "simple_dialog.h" 56: #include "dlg_utils.h" 57: #include "pcap-util.h" 58: #include "prefs.h" 59: #include "ringbuffer.h" 60: 61: #ifdef _WIN32 62: #include "capture-wpcap.h" 63: #endif 64: 65: /* Capture callback data keys */ 66: #define E_CAP_IFACE_KEY "cap_iface" 67: #define E_CAP_SNAP_CB_KEY "cap_snap_cb" 68: #define E_CAP_SNAP_SB_KEY "cap_snap_sb" 69: #define E_CAP_PROMISC_KEY "cap_promisc" 70: #define E_CAP_FILT_KEY "cap_filter_te" 72: #define E_CAP_IPADDR_TE_KEY "cap_ipaddr_te" 73: #define E_CAP_V5_IF_TE_KEY "cap_v5_if_te" 71: #define E_CAP_FILE_TE_KEY "cap_file_te" 72: #define E_CAP_RING_ON_TB_KEY "cap_ringbuffer_on_tb" 73: #define E_CAP_RING_NBF_LB_KEY "cap_ringbuffer_nbf_lb" 74: #define E_CAP_RING_NBF_SB_KEY "cap_ringbuffer_nbf_sb" 75: #define E_CAP_SYNC_KEY "cap_sync" 76: #define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll" 77: #define E_CAP_COUNT_CB_KEY "cap_count_cb" 78: #define E_CAP_COUNT_SB_KEY "cap_count_sb" 79: #define E_CAP_FILESIZE_CB_KEY "cap_filesize_cb" 80: #define E_CAP_FILESIZE_SB_KEY "cap_filesize_sb" 81: #define E_CAP_FILESIZE_LB_KEY "cap_filesize_lb" 82: #define E_CAP_DURATION_CB_KEY "cap_duration_cb" 83: #define E_CAP_DURATION_SB_KEY "cap_duration_sb" 84: #define E_CAP_M_RESOLVE_KEY "cap_m_resolve" 85: #define E_CAP_N_RESOLVE_KEY "cap_n_resolve" 86: #define E_CAP_T_RESOLVE_KEY "cap_t_resolve" 87: 88: #define E_FS_CALLER_PTR_KEY "fs_caller_ptr" 89: #define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr" 90: 91: static void 92: capture_prep_file_cb(GtkWidget *w, gpointer te); 93: 94: static void 95: cap_prep_fs_ok_cb(GtkWidget *w, gpointer data); 96: 97: static void 98: cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data); 99: 100: static void 101: cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data); 102: 103: static void 104: capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w); 105: 106: static void 107: capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w); 108: 109: static void 110: capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w); 111: 112: static void 113: capture_prep_destroy_cb(GtkWidget *win, gpointer user_data); 114: 115: void 116: capture_stop_cb(GtkWidget *w _U_, gpointer d _U_) 117: { 118: capture_stop(); 119: } 120: 121: /* 122: * Keep a static pointer to the current "Capture Options" window, if 123: * any, so that if somebody tries to do "Capture:Start" while there's 124: * already a "Capture Options" window up, we just pop up the existing 125: * one, rather than creating a new one. 126: */ 127: static GtkWidget *cap_open_w; 128: 129: void 130: capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) 131: { 132: GtkWidget *main_vb, 133: *capture_fr, *capture_vb, 134: *if_hb, *if_cb, *if_lb, 135: *snap_hb, *snap_cb, *snap_sb, *snap_lb, 136: *promisc_cb, 137: *filter_hb, *filter_bt, *filter_te, 141: *remote_snoop_fr, *remote_snoop_vb, 142: *ipaddr_hb, *ipaddr_lb, *ipaddr_te, 143: *v5_if_hb, *v5_if_lb, *v5_if_te, 138: *file_fr, *file_vb, 139: *file_hb, *file_bt, *file_te, 140: *ringbuffer_hb, *ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb, 141: *display_fr, *display_vb, 142: *sync_cb, *auto_scroll_cb, 143: *limit_fr, *limit_vb, 144: *count_hb, *count_cb, *count_sb, *count_lb, 145: *filesize_hb, *filesize_cb, *filesize_sb, *filesize_lb, 146: *duration_hb, *duration_cb, *duration_sb, *duration_lb, 147: *resolv_fr, *resolv_vb, 148: *m_resolv_cb, *n_resolv_cb, *t_resolv_cb, 149: *bbox, *ok_bt, *cancel_bt; 150: GtkAccelGroup *accel_group; 151: GtkAdjustment *snap_adj, *ringbuffer_nbf_adj, 152: *count_adj, *filesize_adj, *duration_adj; 153: GList *if_list; 154: int err; 155: char err_str[PCAP_ERRBUF_SIZE]; 156: 157: if (cap_open_w != NULL) { 158: /* There's already a "Capture Options" dialog box; reactivate it. */ 159: reactivate_window(cap_open_w); 160: return; 161: } 162: 163: #ifdef _WIN32 164: /* Is WPcap loaded? */ 165: if (!has_wpcap) { 166: simple_dialog(ESD_TYPE_CRIT, NULL, 167: "Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n" 168: "to capture packets.\n\n" 169: "In order to capture packets, WinPcap must be installed; see\n" 170: "\n" 171: " http://winpcap.polito.it/\n" 172: "\n" 173: "or the mirror at\n" 174: "\n" 175: " http://winpcap.mirror.ethereal.com/\n" 176: "\n" 177: "or the mirror at\n" 178: "\n" 179: " http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n" 180: "\n" 181: "for a downloadable version of WinPcap and for instructions\n" 182: "on how to install WinPcap."); 183: return; 184: } 185: #endif 186: 187: if_list = get_interface_list(&err, err_str); 188: if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) { 189: simple_dialog(ESD_TYPE_WARN, NULL, "Can't get list of interfaces: %s", 190: err_str); 191: } 192: 193: cap_open_w = dlg_window_new("Ethereal: Capture Options"); 194: gtk_signal_connect(GTK_OBJECT(cap_open_w), "destroy", 195: GTK_SIGNAL_FUNC(capture_prep_destroy_cb), NULL); 196: 197: /* Accelerator group for the accelerators (or, as they're called in 198: Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic, 199: Ctrl+<key> is an accelerator). */ 200: accel_group = gtk_accel_group_new(); 201: gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group); 202: 203: main_vb = gtk_vbox_new(FALSE, 0); 204: gtk_container_border_width(GTK_CONTAINER(main_vb), 5); 205: gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb); 206: gtk_widget_show(main_vb); 207: 208: /* Capture-related options frame */ 209: capture_fr = gtk_frame_new("Capture"); 210: gtk_container_add(GTK_CONTAINER(main_vb), capture_fr); 211: gtk_widget_show(capture_fr); 212: 213: capture_vb = gtk_vbox_new(FALSE, 0); 214: gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb); 215: gtk_widget_show(capture_vb); 216: 217: /* Interface row */ 218: if_hb = gtk_hbox_new(FALSE, 3); 219: gtk_container_add(GTK_CONTAINER(capture_vb), if_hb); 220: gtk_widget_show(if_hb); 221: 222: if_lb = gtk_label_new("Interface:"); 223: gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6); 224: gtk_widget_show(if_lb); 225: 226: if_cb = gtk_combo_new(); 227: if (if_list != NULL) 228: gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), if_list); 229: if (cfile.iface == NULL && prefs.capture_device != NULL) { 230: /* No interface was specified on the command line or in a previous 231: capture, but there is one specified in the preferences file; 232: make the one from the preferences file the default */ 233: cfile.iface = g_strdup(prefs.capture_device); 234: } 235: if (cfile.iface != NULL) 236: gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface); 237: else if (if_list != NULL) 238: gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), if_list->data); 239: gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6); 240: gtk_widget_show(if_cb); 241: 242: free_interface_list(if_list); 243: 244: /* Capture length row */ 245: snap_hb = gtk_hbox_new(FALSE, 3); 246: gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb); 247: gtk_widget_show(snap_hb); 248: 249: snap_cb = dlg_check_button_new_with_label_with_mnemonic( 250: "_Limit each packet to", accel_group); 251: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb), 252: capture_opts.has_snaplen); 253: gtk_signal_connect(GTK_OBJECT(snap_cb), "toggled", 254: GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w)); 255: gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0); 256: gtk_widget_show(snap_cb); 257: 258: snap_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.snaplen, 259: MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0); 260: snap_sb = gtk_spin_button_new (snap_adj, 0, 0); 261: gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE); 262: gtk_widget_set_usize (snap_sb, 80, 0); 263: gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0); 264: gtk_widget_show(snap_sb); 265: 266: snap_lb = gtk_label_new("bytes"); 267: gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5); 268: gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0); 269: gtk_widget_show(snap_lb); 270: 271: /* Promiscuous mode row */ 272: promisc_cb = dlg_check_button_new_with_label_with_mnemonic( 273: "Capture packets in _promiscuous mode", accel_group); 274: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb), 275: capture_opts.promisc_mode); 276: gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb); 277: gtk_widget_show(promisc_cb); 278: 279: /* Filter row */ 280: filter_hb = gtk_hbox_new(FALSE, 3); 281: gtk_container_add(GTK_CONTAINER(capture_vb), filter_hb); 282: gtk_widget_show(filter_hb); 283: 284: filter_bt = gtk_button_new_with_label("Filter:"); 285: gtk_signal_connect(GTK_OBJECT(filter_bt), "clicked", 286: GTK_SIGNAL_FUNC(capture_filter_construct_cb), NULL); 287: gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3); 288: gtk_widget_show(filter_bt); 289: 290: filter_te = gtk_entry_new(); 291: if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter); 292: gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te); 293: gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3); 294: gtk_widget_show(filter_te); 295: 302: /* Remote Snoop frame */ 303: 304: remote_snoop_fr = gtk_frame_new("Remote Snoop"); 305: gtk_container_add(GTK_CONTAINER(main_vb), remote_snoop_fr); 306: gtk_widget_show(remote_snoop_fr); 307: 308: remote_snoop_vb = gtk_vbox_new(FALSE, 0); 309: gtk_container_add(GTK_CONTAINER(remote_snoop_fr), remote_snoop_vb); 310: gtk_widget_show(remote_snoop_vb); 311: 312: /* IP address row */ 313: 314: ipaddr_hb = gtk_hbox_new(FALSE, 3); 315: gtk_container_add(GTK_CONTAINER(remote_snoop_vb), ipaddr_hb); 316: gtk_widget_show(ipaddr_hb); 317: 318: ipaddr_lb = gtk_label_new("IP address:"); 319: gtk_box_pack_start(GTK_BOX(ipaddr_hb), ipaddr_lb, FALSE, FALSE, 6); 320: gtk_widget_show(ipaddr_lb); 321: 322: ipaddr_te = gtk_entry_new(); 323: gtk_box_pack_start(GTK_BOX(ipaddr_hb), ipaddr_te, TRUE, TRUE, 3); 324: gtk_widget_show(ipaddr_te); 325: 326: /* V5 Interface row*/ 327: 328: v5_if_hb = gtk_hbox_new(FALSE, 3); 329: gtk_container_add(GTK_CONTAINER(remote_snoop_vb), v5_if_hb); 330: gtk_widget_show(v5_if_hb); 331: 332: v5_if_lb = gtk_label_new("V5 Interface:"); 333: gtk_box_pack_start(GTK_BOX(v5_if_hb), v5_if_lb, FALSE, FALSE, 6); 334: gtk_widget_show(v5_if_lb); 335: 336: v5_if_te = gtk_entry_new(); 337: gtk_box_pack_start(GTK_BOX(v5_if_hb), v5_if_te, TRUE, TRUE, 3); 338: gtk_widget_show(v5_if_te); 339: 340: 296: /* Capture file-related options frame */ 297: file_fr = gtk_frame_new("Capture file(s)"); 298: gtk_container_add(GTK_CONTAINER(main_vb), file_fr); 299: gtk_widget_show(file_fr); 300: 301: file_vb = gtk_vbox_new(FALSE, 3); 302: gtk_container_add(GTK_CONTAINER(file_fr), file_vb); 303: gtk_widget_show(file_vb); 304: 305: /* File row */ 306: file_hb = gtk_hbox_new(FALSE, 3); 307: gtk_container_add(GTK_CONTAINER(file_vb), file_hb); 308: gtk_widget_show(file_hb); 309: 310: file_bt = gtk_button_new_with_label("File:"); 311: gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3); 312: gtk_widget_show(file_bt); 313: 314: file_te = gtk_entry_new(); 315: gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3); 316: gtk_widget_show(file_te); 317: 318: gtk_signal_connect(GTK_OBJECT(file_bt), "clicked", 319: GTK_SIGNAL_FUNC(capture_prep_file_cb), GTK_OBJECT(file_te)); 320: 321: /* Ring buffer row */ 322: ringbuffer_hb = gtk_hbox_new(FALSE, 3); 323: gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_hb); 324: gtk_widget_show(ringbuffer_hb); 325: 326: ringbuffer_on_tb = dlg_check_button_new_with_label_with_mnemonic( 327: "Use _ring buffer", accel_group); 328: /* Ring buffer mode is allowed only if we're not doing an "Update list of 329: packets in real time" capture, so force it off if we're doing such 330: a capture. */ 331: if (capture_opts.sync_mode) 332: capture_opts.ringbuffer_on = FALSE; 333: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_on_tb), 334: capture_opts.ringbuffer_on); 335: gtk_signal_connect(GTK_OBJECT(ringbuffer_on_tb), "toggled", 336: GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w)); 337: gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_on_tb, FALSE, FALSE, 0); 338: gtk_widget_show(ringbuffer_on_tb); 339: 340: ringbuffer_nbf_lb = gtk_label_new("Number of files"); 341: gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 1, 0.5); 342: gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_nbf_lb, FALSE, FALSE, 6); 343: gtk_widget_show(ringbuffer_nbf_lb); 344: 345: ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.ringbuffer_num_files, 346: RINGBUFFER_MIN_NUM_FILES, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0); 347: ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0); 348: gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE); 349: gtk_widget_set_usize (ringbuffer_nbf_sb, 40, 0); 350: gtk_box_pack_start (GTK_BOX(ringbuffer_hb), ringbuffer_nbf_sb, TRUE, TRUE, 0); 351: gtk_widget_show(ringbuffer_nbf_sb); 352: 353: /* Display-related options frame */ 354: display_fr = gtk_frame_new("Display options"); 355: gtk_container_add(GTK_CONTAINER(main_vb), display_fr); 356: gtk_widget_show(display_fr); 357: 358: display_vb = gtk_vbox_new(FALSE, 0); 359: gtk_container_add(GTK_CONTAINER(display_fr), display_vb); 360: gtk_widget_show(display_vb); 361: 362: /* "Update display in real time" row */ 363: sync_cb = dlg_check_button_new_with_label_with_mnemonic( 364: "_Update list of packets in real time", accel_group); 365: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb), 366: capture_opts.sync_mode); 367: gtk_signal_connect(GTK_OBJECT(sync_cb), "toggled", 368: GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w)); 369: gtk_container_add(GTK_CONTAINER(display_vb), sync_cb); 370: gtk_widget_show(sync_cb); 371: 372: /* "Auto-scroll live update" row */ 373: auto_scroll_cb = dlg_check_button_new_with_label_with_mnemonic( 374: "_Automatic scrolling in live capture", accel_group); 375: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live); 376: gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb); 377: gtk_widget_show(auto_scroll_cb); 378: 379: /* Capture limits frame */ 380: limit_fr = gtk_frame_new("Capture limits"); 381: gtk_container_add(GTK_CONTAINER(main_vb), limit_fr); 382: gtk_widget_show(limit_fr); 383: 384: limit_vb = gtk_vbox_new(FALSE, 0); 385: gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb); 386: gtk_widget_show(limit_vb); 387: 388: /* Count row */ 389: count_hb = gtk_hbox_new(FALSE, 3); 390: gtk_container_add(GTK_CONTAINER(limit_vb), count_hb); 391: gtk_widget_show(count_hb); 392: 393: count_cb = gtk_check_button_new_with_label("Stop capture after"); 394: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(count_cb), 395: capture_opts.has_autostop_count); 396: gtk_signal_connect(GTK_OBJECT(count_cb), "toggled", 397: GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w)); 398: gtk_box_pack_start(GTK_BOX(count_hb), count_cb, FALSE, FALSE, 0); 399: gtk_widget_show(count_cb); 400: 401: count_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_count, 402: 1, INT_MAX, 1.0, 10.0, 0.0); 403: count_sb = gtk_spin_button_new (count_adj, 0, 0); 404: gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (count_sb), TRUE); 405: gtk_widget_set_usize (count_sb, 80, 0); 406: gtk_box_pack_start (GTK_BOX(count_hb), count_sb, FALSE, FALSE, 0); 407: gtk_widget_show(count_sb); 408: 409: count_lb = gtk_label_new("packet(s) captured"); 410: gtk_misc_set_alignment(GTK_MISC(count_lb), 0, 0.5); 411: gtk_box_pack_start(GTK_BOX(count_hb), count_lb, FALSE, FALSE, 0); 412: gtk_widget_show(count_lb); 413: 414: /* Filesize row */ 415: filesize_hb = gtk_hbox_new(FALSE, 3); 416: gtk_container_add(GTK_CONTAINER(limit_vb), filesize_hb); 417: gtk_widget_show(filesize_hb); 418: 419: filesize_cb = gtk_check_button_new_with_label(""); 420: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb), 421: capture_opts.has_autostop_filesize); 422: gtk_signal_connect(GTK_OBJECT(filesize_cb), "toggled", 423: GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w)); 424: gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_cb, FALSE, FALSE, 0); 425: gtk_widget_show(filesize_cb); 426: 427: filesize_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_filesize, 428: 1, INT_MAX, 1.0, 10.0, 0.0); 429: filesize_sb = gtk_spin_button_new (filesize_adj, 0, 0); 430: gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (filesize_sb), TRUE); 431: gtk_widget_set_usize (filesize_sb, 80, 0); 432: gtk_box_pack_start (GTK_BOX(filesize_hb), filesize_sb, FALSE, FALSE, 0); 433: gtk_widget_show(filesize_sb); 434: 435: filesize_lb = gtk_label_new(""); 436: gtk_misc_set_alignment(GTK_MISC(filesize_lb), 0, 0.5); 437: gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_lb, FALSE, FALSE, 0); 438: gtk_widget_show(filesize_lb); 439: 440: /* Duration row */ 441: duration_hb = gtk_hbox_new(FALSE, 3); 442: gtk_container_add(GTK_CONTAINER(limit_vb), duration_hb); 443: gtk_widget_show(duration_hb); 444: 445: duration_cb = gtk_check_button_new_with_label("Stop capture after"); 446: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(duration_cb), 447: capture_opts.has_autostop_duration); 448: gtk_signal_connect(GTK_OBJECT(duration_cb), "toggled", 449: GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w)); 450: gtk_box_pack_start(GTK_BOX(duration_hb), duration_cb, FALSE, FALSE, 0); 451: gtk_widget_show(duration_cb); 452: 453: duration_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_duration, 454: 1, INT_MAX, 1.0, 10.0, 0.0); 455: duration_sb = gtk_spin_button_new (duration_adj, 0, 0); 456: gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (duration_sb), TRUE); 457: gtk_widget_set_usize (duration_sb, 80, 0); 458: gtk_box_pack_start (GTK_BOX(duration_hb), duration_sb, FALSE, FALSE, 0); 459: gtk_widget_show(duration_sb); 460: 461: duration_lb = gtk_label_new("second(s)"); 462: gtk_misc_set_alignment(GTK_MISC(duration_lb), 0, 0.5); 463: gtk_box_pack_start(GTK_BOX(duration_hb), duration_lb, FALSE, FALSE, 0); 464: gtk_widget_show(duration_lb); 465: 466: /* Resolution options frame */ 467: resolv_fr = gtk_frame_new("Name resolution"); 468: gtk_container_add(GTK_CONTAINER(main_vb), resolv_fr); 469: gtk_widget_show(resolv_fr); 470: 471: resolv_vb = gtk_vbox_new(FALSE, 0); 472: gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb); 473: gtk_widget_show(resolv_vb); 474: 475: m_resolv_cb = dlg_check_button_new_with_label_with_mnemonic( 476: "Enable _MAC name resolution", accel_group); 477: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb), 478: g_resolv_flags & RESOLV_MAC); 479: gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb); 480: gtk_widget_show(m_resolv_cb); 481: 482: n_resolv_cb = dlg_check_button_new_with_label_with_mnemonic( 483: "Enable _network name resolution", accel_group); 484: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb), 485: g_resolv_flags & RESOLV_NETWORK); 486: gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb); 487: gtk_widget_show(n_resolv_cb); 488: 489: t_resolv_cb = dlg_check_button_new_with_label_with_mnemonic( 490: "Enable _transport name resolution", accel_group); 491: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb), 492: g_resolv_flags & RESOLV_TRANSPORT); 493: gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb); 494: gtk_widget_show(t_resolv_cb); 495: 496: /* Button row: OK and cancel buttons */ 497: bbox = gtk_hbutton_box_new(); 498: gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END); 499: gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); 500: gtk_container_add(GTK_CONTAINER(main_vb), bbox); 501: gtk_widget_show(bbox); 502: 503: ok_bt = gtk_button_new_with_label ("OK"); 504: gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked", 505: GTK_SIGNAL_FUNC(capture_prep_ok_cb), GTK_OBJECT(cap_open_w)); 506: GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT); 507: gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0); 508: gtk_widget_grab_default(ok_bt); 509: gtk_widget_show(ok_bt); 510: 511: cancel_bt = gtk_button_new_with_label ("Cancel"); 512: gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked", 513: GTK_SIGNAL_FUNC(capture_prep_close_cb), GTK_OBJECT(cap_open_w)); 514: GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT); 515: gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0); 516: gtk_widget_show(cancel_bt); 517: 518: /* Attach pointers to needed widgets to the capture prefs window/object */ 519: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_IFACE_KEY, if_cb); 520: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_CB_KEY, snap_cb); 521: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_SB_KEY, snap_sb); 522: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_PROMISC_KEY, promisc_cb); 523: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILT_KEY, filter_te); 569: 570: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_IPADDR_TE_KEY, ipaddr_te); 571: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_V5_IF_TE_KEY, v5_if_te); 572: 524: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILE_TE_KEY, file_te); 525: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_ON_TB_KEY, ringbuffer_on_tb); 526: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_NBF_LB_KEY, ringbuffer_nbf_lb); 527: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_NBF_SB_KEY, ringbuffer_nbf_sb); 528: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SYNC_KEY, sync_cb); 529: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb); 530: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_CB_KEY, count_cb); 531: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_SB_KEY, count_sb); 532: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_CB_KEY, filesize_cb); 533: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_SB_KEY, filesize_sb); 534: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_LB_KEY, filesize_lb); 535: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_DURATION_CB_KEY, duration_cb); 536: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_DURATION_SB_KEY, duration_sb); 537: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_M_RESOLVE_KEY, m_resolv_cb); 538: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_N_RESOLVE_KEY, n_resolv_cb); 539: gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_T_RESOLVE_KEY, t_resolv_cb); 540: 541: /* Set the sensitivity of various widgets as per the settings of other 542: widgets. */ 543: capture_prep_adjust_sensitivity(NULL, cap_open_w); 544: 545: /* Catch the "activate" signal on the frame number and file name text 546: entries, so that if the user types Return there, we act as if the 547: "OK" button had been selected, as happens if Return is typed if some 548: widget that *doesn't* handle the Return key has the input focus. */ 549: dlg_set_activate(filter_te, ok_bt); 550: dlg_set_activate(file_te, ok_bt); 551: 601: dlg_set_activate(ipaddr_te, ok_bt); 602: dlg_set_activate(v5_if_te, ok_bt); 603: 604: 552: /* Catch the "key_press_event" signal in the window, so that we can catch 553: the ESC key being pressed and act as if the "Cancel" button had 554: been selected. */ 555: dlg_set_cancel(cap_open_w, cancel_bt); 556: 557: /* XXX - why does not 558: 559: gtk_widget_grab_focus(if_cb); 560: 561: give the initial focus to the "Interface" combo box? 562: 563: Or should I phrase that as "why does GTK+ continually frustrate 564: attempts to make GUIs driveable from the keyboard?" We have to 565: go catch the activate signal on every single GtkEntry widget 566: (rather than having widgets whose activate signal is *not* 567: caught not catch the Return keystroke, so that it passes on, 568: ultimately, to the window, which can activate the default 569: widget, i.e. the "OK" button); we have to catch the "key_press_event" 570: signal and have the handler check for ESC, so that we can have ESC 571: activate the "Cancel" button; in order to support Alt+<key> mnemonics 572: for buttons and the like, we may have to construct an accelerator 573: group by hand and set up the accelerators by hand (if that even 574: works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()" 575: to keep some container widget from getting the initial focus, so that 576: you don't have to tab into the first widget in order to start typing 577: in it; and it now appears that you simply *can't* make a combo box 578: get the initial focus, at least not in the obvious fashion. Sigh.... */ 579: 580: gtk_widget_show(cap_open_w); 581: } 582: 583: static void 584: capture_prep_file_cb(GtkWidget *w, gpointer file_te) 585: { 586: GtkWidget *caller = gtk_widget_get_toplevel(w); 587: GtkWidget *fs; 588: 589: /* Has a file selection dialog box already been opened for that top-level 590: widget? */ 591: fs = gtk_object_get_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY); 592: 593: if (fs != NULL) { 594: /* Yes. Just re-activate that dialog box. */ 595: reactivate_window(fs); 596: return; 597: } 598: 599: fs = gtk_file_selection_new ("Ethereal: Capture File"); 600: 601: gtk_object_set_data(GTK_OBJECT(fs), E_CAP_FILE_TE_KEY, file_te); 602: 603: /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */ 604: gtk_object_set_data(GTK_OBJECT(fs), E_FS_CALLER_PTR_KEY, caller); 605: 606: /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */ 607: gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, fs); 608: 609: /* Call a handler when the file selection box is destroyed, so we can inform 610: our caller, if any, that it's been destroyed. */ 611: gtk_signal_connect(GTK_OBJECT(fs), "destroy", 612: GTK_SIGNAL_FUNC(cap_prep_fs_destroy_cb), NULL); 613: 614: gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button), 615: "clicked", (GtkSignalFunc) cap_prep_fs_ok_cb, fs); 616: 617: /* Connect the cancel_button to destroy the widget */ 618: gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->cancel_button), 619: "clicked", (GtkSignalFunc) cap_prep_fs_cancel_cb, fs); 620: 621: /* Catch the "key_press_event" signal in the window, so that we can catch 622: the ESC key being pressed and act as if the "Cancel" button had 623: been selected. */ 624: dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button); 625: 626: gtk_widget_show(fs); 627: } 628: 629: static void 630: cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data) 631: { 632: gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data), 633: E_CAP_FILE_TE_KEY)), 634: gtk_file_selection_get_filename (GTK_FILE_SELECTION(data))); 635: gtk_widget_destroy(GTK_WIDGET(data)); 636: } 637: 638: static void 639: cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data) 640: { 641: gtk_widget_destroy(GTK_WIDGET(data)); 642: } 643: 644: static void 645: cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data _U_) 646: { 647: GtkWidget *caller; 648: 649: /* Get the widget that requested that we be popped up. 650: (It should arrange to destroy us if it's destroyed, so 651: that we don't get a pointer to a non-existent window here.) */ 652: caller = gtk_object_get_data(GTK_OBJECT(win), E_FS_CALLER_PTR_KEY); 653: 654: /* Tell it we no longer exist. */ 655: gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, NULL); 656: 657: /* Now nuke this window. */ 658: gtk_grab_remove(GTK_WIDGET(win)); 659: gtk_widget_destroy(GTK_WIDGET(win)); 660: } 661: 662: static void 663: capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { 664: GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te, 665: *file_te, *ringbuffer_on_tb, *ringbuffer_nbf_sb, 719: *ipaddr_te, *v5_if_te, *file_te, *ringbuffer_on_tb, 720: *ringbuffer_nbf_sb, 666: *sync_cb, *auto_scroll_cb, 667: *count_cb, *count_sb, 668: *filesize_cb, *filesize_sb, 669: *duration_cb, *duration_sb, 670: *m_resolv_cb, *n_resolv_cb, *t_resolv_cb; 671: gchar *if_text; 672: gchar *if_name; 673: gchar *filter_text; 729: gchar *ipaddr_text; 730: gchar *v5_if_text; 674: gchar *save_file; 675: 676: if_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IFACE_KEY); 677: snap_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_CB_KEY); 678: snap_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_SB_KEY); 679: promisc_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_PROMISC_KEY); 680: filter_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILT_KEY); 739: 740: ipaddr_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IPADDR_TE_KEY); 741: v5_if_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_V5_IF_TE_KEY); 742: 681: file_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILE_TE_KEY); 682: ringbuffer_on_tb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_ON_TB_KEY); 683: ringbuffer_nbf_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY); 684: sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY); 685: auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY); 686: count_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_CB_KEY); 687: count_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_SB_KEY); 688: filesize_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_CB_KEY); 689: filesize_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_SB_KEY); 690: duration_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_CB_KEY); 691: duration_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_SB_KEY); 692: m_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_M_RESOLVE_KEY); 693: n_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY); 694: t_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY); 695: 696: if_text = 697: g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry))); 698: /* Windows combo entries have a description followed by the interface name */ 699: if_name = strrchr(if_text, ' '); 700: if (if_name == NULL) { 701: if_name = if_text; 702: } else { 703: if_name++; 704: } 705: if (if_name == NULL) { 706: simple_dialog(ESD_TYPE_CRIT, NULL, 707: "You didn't specify an interface on which to capture packets."); 708: g_free(if_text); 709: return; 710: } 711: if (cfile.iface) 712: g_free(cfile.iface); 713: cfile.iface = g_strdup(if_name); 714: g_free(if_text); 715: 716: capture_opts.has_snaplen = 717: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)); 718: if (capture_opts.has_snaplen) { 719: capture_opts.snaplen = 720: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb)); 721: if (capture_opts.snaplen < 1) 722: capture_opts.snaplen = WTAP_MAX_PACKET_SIZE; 723: else if (capture_opts.snaplen < MIN_PACKET_SIZE) 724: capture_opts.snaplen = MIN_PACKET_SIZE; 725: } 726: 727: capture_opts.promisc_mode = 728: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb)); 729: 730: /* XXX - don't try to get clever and set "cfile.filter" to NULL if the 731: filter string is empty, as an indication that we don't have a filter 732: and thus don't have to set a filter when capturing - the version of 733: libpcap in Red Hat Linux 6.1, and versions based on later patches 734: in that series, don't bind the AF_PACKET socket to an interface 735: until a filter is set, which means they aren't bound at all if 736: no filter is set, which means no packets arrive as input on that 737: socket, which means Ethereal never sees any packets. */ 738: filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te)); 739: if (cfile.cfilter) 740: g_free(cfile.cfilter); 741: g_assert(filter_text != NULL); 742: cfile.cfilter = g_strdup(filter_text); 743: 806: /* IP Address and V5 Interface */ 807: 808: ipaddr_text = gtk_entry_get_text(GTK_ENTRY(ipaddr_te)); 809: if (cfile.ipaddr) 810: g_free(cfile.ipaddr); 811: g_assert(ipaddr_text != NULL); 812: cfile.ipaddr = g_strdup(ipaddr_text); 813: cfile.has_ipaddr = TRUE; 814: 815: v5_if_text = gtk_entry_get_text(GTK_ENTRY(v5_if_te)); 816: if (cfile.v5iface) 817: g_free(cfile.v5iface); 818: g_assert(v5_if_text != NULL); 819: cfile.v5iface = g_strdup(v5_if_text); 820: cfile.has_v5iface = TRUE; 821: 744: save_file = gtk_entry_get_text(GTK_ENTRY(file_te)); 745: if (save_file && save_file[0]) { 746: /* User specified a file to which the capture should be written. */ 747: save_file = g_strdup(save_file); 748: } else { 749: /* User didn't specify a file; save to a temporary file. */ 750: save_file = NULL; 751: } 752: 753: capture_opts.has_autostop_count = 754: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb)); 755: if (capture_opts.has_autostop_count) 756: capture_opts.autostop_count = 757: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(count_sb)); 758: 759: capture_opts.has_autostop_filesize = 760: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb)); 761: if (capture_opts.has_autostop_filesize) 762: capture_opts.autostop_filesize = 763: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filesize_sb)); 764: 765: capture_opts.has_autostop_duration = 766: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb)); 767: if (capture_opts.has_autostop_duration) 768: capture_opts.autostop_duration = 769: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_sb)); 770: 771: capture_opts.sync_mode = 772: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb)); 773: 774: auto_scroll_live = 775: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb)); 776: 777: g_resolv_flags = RESOLV_NONE; 778: if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb))) 779: g_resolv_flags |= RESOLV_MAC; 780: if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb))) 781: g_resolv_flags |= RESOLV_NETWORK; 782: if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb))) 783: g_resolv_flags |= RESOLV_TRANSPORT; 784: 785: capture_opts.ringbuffer_on = 786: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb)) && 787: !(capture_opts.sync_mode); 788: if (capture_opts.ringbuffer_on) { 789: if (save_file == NULL) { 790: simple_dialog(ESD_TYPE_CRIT, NULL, 791: "You must specify a save file if you want to use the ring buffer."); 792: return; 793: } else if (!capture_opts.has_autostop_filesize) { 794: simple_dialog(ESD_TYPE_CRIT, NULL, 795: "You must specify a file size at which to rotate the capture files\n" 796: "if you want to use the ring buffer."); 797: return; 798: } 799: } 800: 801: capture_opts.ringbuffer_num_files = 802: gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb)); 803: if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES) 804: capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES; 805: else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES) 806: capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES; 807: 808: gtk_widget_destroy(GTK_WIDGET(parent_w)); 809: 887: /* 888: if(cfile.has_ipaddr) 889: do_snooping(); 890: */ 810: do_capture(save_file); 811: } 812: 813: static void 814: capture_prep_close_cb(GtkWidget *close_bt _U_, gpointer parent_w) 815: { 816: gtk_grab_remove(GTK_WIDGET(parent_w)); 817: gtk_widget_destroy(GTK_WIDGET(parent_w)); 818: } 819: 820: static void 821: capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_) 822: { 823: GtkWidget *capture_prep_filter_w; 824: GtkWidget *fs; 825: 826: /* Is there a filter edit/selection dialog associated with this 827: Capture Options dialog? */ 828: capture_prep_filter_w = gtk_object_get_data(GTK_OBJECT(win), E_FILT_DIALOG_PTR_KEY); 829: 830: if (capture_prep_filter_w != NULL) { 831: /* Yes. Destroy it. */ 832: gtk_widget_destroy(capture_prep_filter_w); 833: } 834: 835: /* Is there a file selection dialog associated with this 836: Print File dialog? */ 837: fs = gtk_object_get_data(GTK_OBJECT(win), E_FILE_SEL_DIALOG_PTR_KEY); 838: 839: if (fs != NULL) { 840: /* Yes. Destroy it. */ 841: gtk_widget_destroy(fs); 842: } 843: 844: /* Note that we no longer have a "Capture Options" dialog box. */ 845: cap_open_w = NULL; 846: } 847: 848: /* 849: * Adjust the sensitivity of various widgets as per the current setting 850: * of other widgets. 851: */ 852: static void 853: capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w) 854: { 855: GtkWidget *snap_cb, *snap_sb, 856: *ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb, 857: *sync_cb, *auto_scroll_cb, 858: *count_cb, *count_sb, 859: *filesize_cb, *filesize_sb, *filesize_lb, 860: *duration_cb, *duration_sb; 861: 862: snap_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_CB_KEY); 863: snap_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_SB_KEY); 864: ringbuffer_on_tb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_ON_TB_KEY); 865: ringbuffer_nbf_lb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_LB_KEY); 866: ringbuffer_nbf_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY); 867: sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY); 868: auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY); 869: count_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_CB_KEY); 870: count_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_SB_KEY); 871: filesize_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_CB_KEY); 872: filesize_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_SB_KEY); 873: filesize_lb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_LB_KEY); 874: duration_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_CB_KEY); 875: duration_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_SB_KEY); 876: 877: /* The snapshot length spinbox is sensitive iff the "Limit each packet 878: to" checkbox is on. */ 879: gtk_widget_set_sensitive(GTK_WIDGET(snap_sb), 880: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb))); 881: 882: if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) { 883: /* "Update list of packets in real time" captures enabled; we don't 884: support ring buffer mode for those captures, so turn ring buffer 885: mode off if it's on, and make its toggle button, and the spin 886: button for the number of ring buffer files (and the spin button's 887: label), insensitive. */ 888: if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) { 889: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb), FALSE); 890: } 891: gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), FALSE); 892: 893: /* Auto-scroll mode is meaningful only in "Update list of packets 894: in real time" captures, so make its toggle button sensitive. */ 895: gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE); 896: } else { 897: /* "Update list of packets in real time" captures disabled; that 898: means ring buffer mode is OK, so make its toggle button 899: sensitive. */ 900: gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), TRUE); 901: 902: /* Auto-scroll mode is meaningful only in "Update list of packets 903: in real time" captures, so make its toggle button insensitive. */ 904: gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE); 905: } 906: 907: if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) { 908: /* Ring buffer mode enabled. Make the spin button for the number 909: of ring buffer files, and its label, sensitive. */ 910: gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), TRUE); 911: gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), TRUE); 912: 913: /* Also, indicate that the file size is a size at which to switch 914: ring buffer files, not a size at which to stop the capture, 915: turn its button on. */ 916: gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child), 917: "Rotate capture file every"); 918: gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s)"); 919: gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb), TRUE); 920: } else { 921: /* Ring buffer mode disabled. Make the spin button for the number 922: of ring buffer files, and its label insensitive. */ 923: gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE); 924: gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE); 925: 926: /* Also, indicate that the file size is a size at which to stop the 927: capture, not a size at which to switch ring buffer files. */ 928: gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child), 929: "Stop capture after"); 930: gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s) captured"); 931: } 932: 933: /* The maximum packet count spinbox is sensitive iff the "Stop capture 934: after N packets captured" checkbox is on. */ 935: gtk_widget_set_sensitive(GTK_WIDGET(count_sb), 936: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb))); 937: 938: /* The maximum file size spinbox is sensitive iff the "Stop capture 939: after N kilobytes captured" checkbox is on. */ 940: gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb), 941: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb))); 942: 943: /* The capture duration spinbox is sensitive iff the "Stop capture 944: after N seconds" checkbox is on. */ 945: gtk_widget_set_sensitive(GTK_WIDGET(duration_sb), 946: gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb))); 947: } 948: 949: #endif /* HAVE_LIBPCAP */ 950: |
Base file: C:\ws\ethereal-0.9.5\file.hCompared file: C:\ethereal-0.9.5\file.hDifference Analysis Generated by HtmlDiff on 10/11/2002 5:53 PM 1: /* file.h 2: * Definitions for file structures and routines 3: * 4: * $Id: file.h,v 1.94 2002/05/27 22:00:35 guy Exp $ 5: * 6: * Ethereal - Network traffic analyzer 7: * By Gerald Combs <gerald@xxxxxxxxxxxx> 8: * Copyright 1998 Gerald Combs 9: * 10: * This program is free software; you can redistribute it and/or 11: * modify it under the terms of the GNU General Public License 12: * as published by the Free Software Foundation; either version 2 13: * of the License, or (at your option) any later version. 14: * 15: * This program is distributed in the hope that it will be useful, 16: * but WITHOUT ANY WARRANTY; without even the implied warranty of 17: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: * GNU General Public License for more details. 19: * 20: * You should have received a copy of the GNU General Public License 21: * along with this program; if not, write to the Free Software 22: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23: */ 24: 25: #ifndef __FILE_H__ 26: #define __FILE_H__ 27: 28: #ifdef HAVE_SYS_TYPES_H 29: #include <sys/types.h> 30: #endif 31: 32: #include "wiretap/wtap.h" 33: #include <epan/dfilter/dfilter.h> 34: #include "print.h" 35: #include <errno.h> 36: #include <epan/epan.h> 37: 38: /* Current state of file. */ 39: typedef enum { 40: FILE_CLOSED, /* No file open */ 41: FILE_READ_IN_PROGRESS, /* Reading a file we've opened */ 42: FILE_READ_ABORTED, /* Read aborted by user */ 43: FILE_READ_DONE /* Read completed */ 44: } file_state; 45: 46: typedef struct _capture_file { 47: file_state state; /* Current state of capture file */ 48: int filed; /* File descriptor of capture file */ 49: gchar *filename; /* Name of capture file */ 50: gboolean is_tempfile; /* Is capture file a temporary file? */ 51: gboolean user_saved;/* If capture file is temporary, has it been saved by user yet? */ 52: long f_len; /* Length of capture file */ 53: guint16 cd_t; /* File type of capture file */ 54: int lnk_t; /* Link-layer type with which to save capture */ 55: guint32 vers; /* Version. For tcpdump minor is appended to major */ 56: int count; /* Total number of frames */ 57: int marked_count; /* Number of marked frames */ 58: gboolean drops_known; /* TRUE if we know how many packets were dropped */ 59: guint32 drops; /* Dropped packets */ 60: guint32 esec; /* Elapsed seconds */ 61: guint32 eusec; /* Elapsed microseconds */ 62: gboolean has_snap; /* TRUE if maximum capture packet length is known */ 63: int snap; /* Maximum captured packet length */ 64: long progbar_quantum; /* Number of bytes read per progress bar update */ 65: long progbar_nextstep; /* Next point at which to update progress bar */ 66: gchar *iface; /* Interface */ 67: gchar *save_file; /* File that user saved capture to */ 68: int save_file_fd; /* File descriptor for saved file */ 69: wtap *wth; /* Wiretap session */ 70: dfilter_t *rfcode; /* Compiled read filter program */ 71: gchar *dfilter; /* Display filter string */ 72: dfilter_t *dfcode; /* Compiled display filter program */ 73: gchar *ipaddr; /* IP address */ 74: gboolean has_ipaddr; /* TRUE if IP address has been entered */ 75: gchar *v5iface; /* V5 Interface */ 76: gboolean has_v5iface; /* TRUE if V5 interface has been entered */ 73: #ifdef HAVE_LIBPCAP 74: gchar *cfilter; /* Capture filter string */ 75: #endif 76: gchar *sfilter; /* Search filter string */ 77: gboolean sbackward; /* TRUE if search is backward, FALSE if forward */ 78: union wtap_pseudo_header pseudo_header; /* Packet pseudo_header */ 79: guint8 pd[WTAP_MAX_PACKET_SIZE]; /* Packet data */ 80: GMemChunk *plist_chunk; /* Memory chunk for frame_data structures */ 81: frame_data *plist; /* Packet list */ 82: frame_data *plist_end; /* Last packet in list */ 83: frame_data *first_displayed; /* First frame displayed */ 84: frame_data *last_displayed; /* Last frame displayed */ 85: column_info cinfo; /* Column formatting information */ 86: frame_data *current_frame; /* Frame data for current frame */ 87: epan_dissect_t *edt; /* Protocol dissection fo rcurrently selected packet */ 88: FILE *print_fh; /* File we're printing to */ 89: } capture_file; 90: 91: /* Return values from "read_cap_file()", "continue_tail_cap_file()", 92: and "finish_tail_cap_file()". */ 93: typedef enum { 94: READ_SUCCESS, /* read succeeded */ 95: READ_ERROR, /* read got an error */ 96: READ_ABORTED /* read aborted by user */ 97: } read_status_t; 98: 99: int open_cap_file(char *, gboolean, capture_file *); 100: void close_cap_file(capture_file *); 101: read_status_t read_cap_file(capture_file *, int *); 102: int start_tail_cap_file(char *, gboolean, capture_file *); 103: read_status_t continue_tail_cap_file(capture_file *, int, int *); 104: read_status_t finish_tail_cap_file(capture_file *, int *); 105: /* size_t read_frame_header(capture_file *); */ 106: gboolean save_cap_file(char *, capture_file *, gboolean, gboolean, guint); 107: 108: int filter_packets(capture_file *cf, gchar *dfilter); 109: void colorize_packets(capture_file *); 110: void redissect_packets(capture_file *cf); 111: int print_packets(capture_file *cf, print_args_t *print_args); 112: void change_time_formats(capture_file *); 113: gboolean find_packet(capture_file *cf, dfilter_t *sfcode); 114: 115: typedef enum { 116: FOUND_FRAME, /* found the frame */ 117: NO_SUCH_FRAME, /* no frame with that number */ 118: FRAME_NOT_DISPLAYED /* frame with that number isn't displayed */ 119: } goto_result_t; 120: goto_result_t goto_frame(capture_file *cf, guint fnumber); 121: 122: void select_packet(capture_file *, int); 123: void unselect_packet(capture_file *); 124: 125: void unselect_field(void); 126: 127: /* 128: * Mark a particular frame in a particular capture. 129: */ 130: void mark_frame(capture_file *, frame_data *); 131: 132: /* 133: * Unmark a particular frame in a particular capture. 134: */ 135: void unmark_frame(capture_file *, frame_data *); 136: 137: /* Moves or copies a file. Returns 0 on failure, 1 on success */ 138: int file_mv(char *from, char *to); 139: 140: /* Copies a file. Returns 0 on failure, 1 on success */ 141: int file_cp(char *from, char *to); 142: 143: char *file_open_error_message(int, gboolean); 144: char *file_read_error_message(int); 145: char *file_write_error_message(int); 146: 147: #endif /* file.h */ 148: |
Base file: C:\ws\ethereal-0.9.5\gtk\main.cCompared file: C:\ethereal-0.9.5\gtk\main.cDifference Analysis Generated by HtmlDiff on 10/11/2002 5:52 PM 1: /* main.c 2: * 3: * $Id: main.c,v 1.252 2002/05/30 00:44:50 guy Exp $ 4: * 5: * Ethereal - Network traffic analyzer 6: * By Gerald Combs <gerald@xxxxxxxxxxxx> 7: * Copyright 1998 Gerald Combs 8: * 9: * Richard Sharpe, 13-Feb-1999, added support for initializing structures 10: * needed by dissect routines 11: * Jeff Foster, 2001/03/12, added support tabbed hex display windowss 12: * 13: * 14: * This program is free software; you can redistribute it and/or 15: * modify it under the terms of the GNU General Public License 16: * as published by the Free Software Foundation; either version 2 17: * of the License, or (at your option) any later version. 18: * 19: * This program is distributed in the hope that it will be useful, 20: * but WITHOUT ANY WARRANTY; without even the implied warranty of 21: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22: * GNU General Public License for more details. 23: * 24: * You should have received a copy of the GNU General Public License 25: * along with this program; if not, write to the Free Software 26: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27: * 28: * 29: * To do: 30: * - Graphs 31: * - Playback window 32: * - Multiple window support 33: * - Add cut/copy/paste 34: * - Create header parsing routines 35: * - Make byte view selections more fancy? 36: */ 37: 38: #ifdef HAVE_CONFIG_H 39: # include "config.h" 40: #endif 41: 42: #include <gtk/gtk.h> 43: 44: #include <stdlib.h> 45: #include <stdio.h> 46: #include <string.h> 47: #include <ctype.h> 48: 49: #ifdef HAVE_UNISTD_H 50: #include <unistd.h> 51: #endif 52: 53: #include <errno.h> 54: 55: #ifdef HAVE_SYS_TYPES_H 56: #include <sys/types.h> 57: #endif 58: 59: #ifdef HAVE_SYS_STAT_H 60: #include <sys/stat.h> 61: #endif 62: 63: #ifdef HAVE_IO_H 64: #include <io.h> /* open/close on win32 */ 65: #endif 66: 67: #ifdef HAVE_DIRECT_H 68: #include <direct.h> 69: #endif 70: 71: #ifdef HAVE_NETINET_IN_H 72: #include <netinet/in.h> 73: #endif 74: 75: #include <signal.h> 76: 77: #ifdef HAVE_LIBPCAP 78: #include <pcap.h> 79: #endif 80: 81: #ifdef HAVE_LIBZ 82: #include <zlib.h> /* to get the libz version number */ 83: #endif 84: 85: #ifdef NEED_SNPRINTF_H 86: # include "snprintf.h" 87: #endif 88: 89: #ifdef HAVE_UCD_SNMP_VERSION_H 90: #include <ucd-snmp/version.h> 91: #endif /* HAVE_UCD_SNMP_VERSION_H */ 92: 93: #ifdef NEED_STRERROR_H 94: #include "strerror.h" 95: #endif 96: 97: #ifdef NEED_GETOPT_H 98: #include "getopt.h" 99: #endif 100: 101: #ifdef WIN32 /* Needed for console I/O */ 102: #include <fcntl.h> 103: #include <conio.h> 104: #endif 105: 106: #include <epan/epan.h> 107: #include <epan/filesystem.h> 108: #include <epan/epan_dissect.h> 109: 110: #include "main.h" 111: #include <epan/timestamp.h> 112: #include <epan/packet.h> 113: #include "capture.h" 114: #include "summary.h" 115: #include "file.h" 116: #include "filters.h" 117: #include "prefs.h" 118: #include "menu.h" 119: #include "../menu.h" 120: #include "color.h" 121: #include "color_utils.h" 122: #include "filter_prefs.h" 123: #include "file_dlg.h" 124: #include "column.h" 125: #include "print.h" 126: #include <epan/resolv.h> 127: #ifdef HAVE_LIBPCAP 128: #include "pcap-util.h" 129: #endif 130: #include "statusbar.h" 131: #include "simple_dialog.h" 132: #include "proto_draw.h" 133: #include <epan/dfilter/dfilter.h> 134: #include "keys.h" 135: #include "packet_win.h" 136: #include "gtkglobals.h" 137: #include <epan/plugins.h> 138: #include "colors.h" 139: #include <epan/strutil.h> 140: #include "register.h" 141: #include "ringbuffer.h" 142: #include "ui_util.h" 143: #include "image/clist_ascend.xpm" 144: #include "image/clist_descend.xpm" 145: 146: #ifdef WIN32 147: #include "capture-wpcap.h" 148: #endif 149: 150: typedef struct column_arrows { 151: GtkWidget *table; 152: GtkWidget *ascend_pm; 153: GtkWidget *descend_pm; 154: } column_arrows; 155: 156: capture_file cfile; 157: GtkWidget *top_level, *packet_list, *tree_view, *byte_nb_ptr, 158: *tv_scrollw, *pkt_scrollw; 159: static GtkWidget *info_bar; 160: GdkFont *m_r_font, *m_b_font; 161: guint m_font_height, m_font_width; 162: static guint main_ctx, file_ctx, help_ctx; 163: static GString *comp_info_str; 164: gchar *ethereal_path = NULL; 165: gchar *last_open_dir = NULL; 166: gint root_x = G_MAXINT, root_y = G_MAXINT, top_width, top_height; 167: 168: ts_type timestamp_type = RELATIVE; 169: 170: GtkStyle *item_style; 171: 172: /* Specifies the field currently selected in the GUI protocol tree */ 173: field_info *finfo_selected = NULL; 174: 175: #ifdef WIN32 176: static gboolean has_no_console; /* TRUE if app has no console */ 177: static gboolean console_was_created; /* TRUE if console was created */ 178: static void create_console(void); 179: static void destroy_console(void); 180: static void console_log_handler(const char *log_domain, 181: GLogLevelFlags log_level, const char *message, gpointer user_data); 182: #endif 183: 184: static void create_main_window(gint, gint, gint, e_prefs*); 185: 186: #define E_DFILTER_CM_KEY "display_filter_combo" 187: #define E_DFILTER_FL_KEY "display_filter_list" 188: 189: /* About Ethereal window */ 190: void 191: about_ethereal( GtkWidget *w _U_, gpointer data _U_ ) { 192: simple_dialog(ESD_TYPE_INFO, NULL, 193: "Ethereal - Network Protocol Analyzer\n" 194: "Version " VERSION " (C) 1998-2000 Gerald Combs <gerald@xxxxxxxxxxxx>\n" 195: "Compiled %s\n\n" 196: 197: "Check the man page for complete documentation and\n" 198: "for the list of contributors.\n" 199: 200: "\nSee http://www.ethereal.com/ for more information.", 201: comp_info_str->str); 202: } 203: 204: void 205: set_fonts(GdkFont *regular, GdkFont *bold) 206: { 207: /* Yes, assert. The code that loads the font should check 208: * for NULL and provide its own error message. */ 209: g_assert(m_r_font && m_b_font); 210: m_r_font = regular; 211: m_b_font = bold; 212: 213: m_font_height = m_r_font->ascent + m_r_font->descent; 214: m_font_width = gdk_string_width(m_r_font, "0"); 215: } 216: 217: 218: /* Match selected byte pattern */ 219: static void 220: match_selected_cb_do(gpointer data, int action, gchar *text) 221: { 222: GtkWidget *filter_te; 223: char *cur_filter, *new_filter; 224: 225: if (!text) 226: return; 227: g_assert(data); 228: filter_te = gtk_object_get_data(GTK_OBJECT(data), E_DFILTER_TE_KEY); 229: g_assert(filter_te); 230: 231: cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1); 232: 233: switch (action&MATCH_SELECTED_MASK) { 234: 235: case MATCH_SELECTED_REPLACE: 236: new_filter = g_strdup(text); 237: break; 238: 239: case MATCH_SELECTED_AND: 240: if ((!cur_filter) || (0 == strlen(cur_filter))) 241: new_filter = g_strdup(text); 242: else 243: new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL); 244: break; 245: 246: case MATCH_SELECTED_OR: 247: if ((!cur_filter) || (0 == strlen(cur_filter))) 248: new_filter = g_strdup(text); 249: else 250: new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL); 251: break; 252: 253: case MATCH_SELECTED_NOT: 254: new_filter = g_strconcat("!(", text, ")", NULL); 255: break; 256: 257: case MATCH_SELECTED_AND_NOT: 258: if ((!cur_filter) || (0 == strlen(cur_filter))) 259: new_filter = g_strconcat("!(", text, ")", NULL); 260: else 261: new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL); 262: break; 263: 264: case MATCH_SELECTED_OR_NOT: 265: if ((!cur_filter) || (0 == strlen(cur_filter))) 266: new_filter = g_strconcat("!(", text, ")", NULL); 267: else 268: new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL); 269: break; 270: 271: default: 272: g_assert_not_reached(); 273: new_filter = NULL; 274: break; 275: } 276: 277: /* Free up the copy we got of the old filter text. */ 278: g_free(cur_filter); 279: 280: /* create a new one and set the display filter entry accordingly */ 281: gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter); 282: 283: /* Run the display filter so it goes in effect. */ 284: if (action&MATCH_SELECTED_APPLY_NOW) 285: filter_packets(&cfile, new_filter); 286: 287: /* Free up the new filter text. */ 288: g_free(new_filter); 289: 290: /* Free up the generated text we were handed. */ 291: g_free(text); 292: } 293: 294: void 295: match_selected_cb_replace(GtkWidget *w, gpointer data) 296: { 297: if (finfo_selected) 298: match_selected_cb_do((data ? data : w), 299: MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, 300: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 301: } 302: 303: void 304: match_selected_cb_and(GtkWidget *w, gpointer data) 305: { 306: if (finfo_selected) 307: match_selected_cb_do((data ? data : w), 308: MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, 309: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 310: } 311: 312: void 313: match_selected_cb_or(GtkWidget *w, gpointer data) 314: { 315: if (finfo_selected) 316: match_selected_cb_do((data ? data : w), 317: MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, 318: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 319: } 320: 321: void 322: match_selected_cb_not(GtkWidget *w, gpointer data) 323: { 324: if (finfo_selected) 325: match_selected_cb_do((data ? data : w), 326: MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, 327: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 328: } 329: 330: void 331: match_selected_cb_and_not(GtkWidget *w, gpointer data) 332: { 333: if (finfo_selected) 334: match_selected_cb_do((data ? data : w), 335: MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, 336: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 337: } 338: 339: void 340: match_selected_cb_or_not(GtkWidget *w, gpointer data) 341: { 342: if (finfo_selected) 343: match_selected_cb_do((data ? data : w), 344: MATCH_SELECTED_OR_NOT, 345: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 346: } 347: 348: void 349: prepare_selected_cb_replace(GtkWidget *w, gpointer data) 350: { 351: if (finfo_selected) 352: match_selected_cb_do((data ? data : w), 353: MATCH_SELECTED_REPLACE, 354: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 355: } 356: 357: void 358: prepare_selected_cb_and(GtkWidget *w, gpointer data) 359: { 360: if (finfo_selected) 361: match_selected_cb_do((data ? data : w), 362: MATCH_SELECTED_AND, 363: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 364: } 365: 366: void 367: prepare_selected_cb_or(GtkWidget *w, gpointer data) 368: { 369: if (finfo_selected) 370: match_selected_cb_do((data ? data : w), 371: MATCH_SELECTED_OR, 372: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 373: } 374: 375: void 376: prepare_selected_cb_not(GtkWidget *w, gpointer data) 377: { 378: if (finfo_selected) 379: match_selected_cb_do((data ? data : w), 380: MATCH_SELECTED_NOT, 381: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 382: } 383: 384: void 385: prepare_selected_cb_and_not(GtkWidget *w, gpointer data) 386: { 387: if (finfo_selected) 388: match_selected_cb_do((data ? data : w), 389: MATCH_SELECTED_AND_NOT, 390: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 391: } 392: 393: void 394: prepare_selected_cb_or_not(GtkWidget *w, gpointer data) 395: { 396: if (finfo_selected) 397: match_selected_cb_do((data ? data : w), 398: MATCH_SELECTED_OR_NOT, 399: proto_alloc_dfilter_string(finfo_selected, cfile.pd)); 400: } 401: 402: static gchar * 403: get_text_from_packet_list(gpointer data) 404: { 405: gint row = (gint)gtk_object_get_data(GTK_OBJECT(data), E_MPACKET_LIST_ROW_KEY); 406: gint column = (gint)gtk_object_get_data(GTK_OBJECT(data), E_MPACKET_LIST_COL_KEY); 407: frame_data *fdata = (frame_data *)gtk_clist_get_row_data(GTK_CLIST(packet_list), row); 408: epan_dissect_t *edt; 409: gchar *buf=NULL; 410: int len; 411: int err; 412: 413: if (fdata != NULL) { 414: /* XXX - do something with "err" */ 415: wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header, 416: cfile.pd, fdata->cap_len, &err); 417: 418: edt = epan_dissect_new(FALSE, FALSE); 419: epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata, 420: &cfile.cinfo); 421: epan_dissect_fill_in_columns(edt); 422: 423: if (strlen(cfile.cinfo.col_expr[column]) != 0 && 424: strlen(cfile.cinfo.col_expr_val[column]) != 0) { 425: len = strlen(cfile.cinfo.col_expr[column]) + 426: strlen(cfile.cinfo.col_expr_val[column]) + 5; 427: buf = g_malloc0(len); 428: snprintf(buf, len, "%s == %s", cfile.cinfo.col_expr[column], 429: cfile.cinfo.col_expr_val[column]); 430: } 431: 432: epan_dissect_free(edt); 433: } 434: 435: return buf; 436: } 437: 438: void 439: match_selected_cb_replace2(GtkWidget *w _U_, gpointer data) 440: { 441: match_selected_cb_do(data, 442: MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, 443: get_text_from_packet_list(data)); 444: } 445: 446: void 447: match_selected_cb_and2(GtkWidget *w _U_, gpointer data) 448: { 449: match_selected_cb_do(data, 450: MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, 451: get_text_from_packet_list(data)); 452: } 453: 454: void 455: match_selected_cb_or2(GtkWidget *w _U_, gpointer data) 456: { 457: match_selected_cb_do(data, 458: MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, 459: get_text_from_packet_list(data)); 460: } 461: 462: void 463: match_selected_cb_not2(GtkWidget *w _U_, gpointer data) 464: { 465: match_selected_cb_do(data, 466: MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, 467: get_text_from_packet_list(data)); 468: } 469: 470: void 471: match_selected_cb_and_not2(GtkWidget *w _U_, gpointer data) 472: { 473: match_selected_cb_do(data, 474: MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, 475: get_text_from_packet_list(data)); 476: } 477: 478: void 479: match_selected_cb_or_not2(GtkWidget *w _U_, gpointer data) 480: { 481: match_selected_cb_do(data, 482: MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, 483: get_text_from_packet_list(data)); 484: } 485: 486: void 487: prepare_selected_cb_replace2(GtkWidget *w _U_, gpointer data) 488: { 489: match_selected_cb_do(data, 490: MATCH_SELECTED_REPLACE, 491: get_text_from_packet_list(data)); 492: } 493: 494: void 495: prepare_selected_cb_and2(GtkWidget *w _U_, gpointer data) 496: { 497: match_selected_cb_do(data, 498: MATCH_SELECTED_AND, 499: get_text_from_packet_list(data)); 500: } 501: 502: void 503: prepare_selected_cb_or2(GtkWidget *w _U_, gpointer data) 504: { 505: match_selected_cb_do(data, 506: MATCH_SELECTED_OR, 507: get_text_from_packet_list(data)); 508: } 509: 510: void 511: prepare_selected_cb_not2(GtkWidget *w _U_, gpointer data) 512: { 513: match_selected_cb_do(data, 514: MATCH_SELECTED_NOT, 515: get_text_from_packet_list(data)); 516: } 517: 518: void 519: prepare_selected_cb_and_not2(GtkWidget *w _U_, gpointer data) 520: { 521: match_selected_cb_do(data, 522: MATCH_SELECTED_AND_NOT, 523: get_text_from_packet_list(data)); 524: } 525: 526: void 527: prepare_selected_cb_or_not2(GtkWidget *w _U_, gpointer data) 528: { 529: match_selected_cb_do(data, 530: MATCH_SELECTED_OR_NOT, 531: get_text_from_packet_list(data)); 532: } 533: 534: /* Run the current display filter on the current packet set, and 535: redisplay. */ 536: static void 537: filter_activate_cb(GtkWidget *w, gpointer data) 538: { 539: GtkCombo *filter_cm = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_CM_KEY); 540: GList *filter_list = gtk_object_get_data(GTK_OBJECT(filter_cm), E_DFILTER_FL_KEY); 541: GList *li; 542: gboolean add_filter = TRUE; 543: gboolean free_filter = TRUE; 544: char *s; 545: 546: g_assert(data); 547: s = g_strdup(gtk_entry_get_text(GTK_ENTRY(data))); 548: 549: /* GtkCombos don't let us get at their list contents easily, so we maintain 550: our own filter list, and feed it to gtk_combo_set_popdown_strings when 551: a new filter is added. */ 552: if (filter_packets(&cfile, s)) { 553: li = g_list_first(filter_list); 554: while (li) { 555: if (li->data && strcmp(s, li->data) == 0) 556: add_filter = FALSE; 557: li = li->next; 558: } 559: 560: if (add_filter) { 561: free_filter = FALSE; 562: filter_list = g_list_append(filter_list, s); 563: gtk_object_set_data(GTK_OBJECT(filter_cm), E_DFILTER_FL_KEY, filter_list); 564: gtk_combo_set_popdown_strings(filter_cm, filter_list); 565: gtk_entry_set_text(GTK_ENTRY(filter_cm->entry), g_list_last(filter_list)->data); 566: } 567: } 568: if (free_filter) 569: g_free(s); 570: } 571: 572: /* redisplay with no display filter */ 573: static void 574: filter_reset_cb(GtkWidget *w, gpointer data _U_) 575: { 576: GtkWidget *filter_te = NULL; 577: 578: if ((filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY))) { 579: gtk_entry_set_text(GTK_ENTRY(filter_te), ""); 580: } 581: filter_packets(&cfile, NULL); 582: } 583: 584: /* GTKClist compare routine, overrides default to allow numeric comparison */ 585: static gint 586: packet_list_compare(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2) 587: { 588: /* Get row text strings */ 589: char *text1 = GTK_CELL_TEXT (((GtkCListRow *)ptr1)->cell[clist->sort_column])->text; 590: char *text2 = GTK_CELL_TEXT (((GtkCListRow *)ptr2)->cell[clist->sort_column])->text; 591: 592: /* Attempt to convert to numbers */ 593: double num1 = atof(text1); 594: double num2 = atof(text2); 595: 596: gint col_fmt = cfile.cinfo.col_fmt[clist->sort_column]; 597: 598: if ((col_fmt == COL_NUMBER) || (col_fmt == COL_REL_TIME) || (col_fmt == COL_DELTA_TIME) || 599: ((col_fmt == COL_CLS_TIME) && (timestamp_type == RELATIVE)) || 600: ((col_fmt == COL_CLS_TIME) && (timestamp_type == DELTA)) || 601: (col_fmt == COL_UNRES_SRC_PORT) || (col_fmt == COL_UNRES_DST_PORT) || 602: ((num1 != 0) && (num2 != 0) && ((col_fmt == COL_DEF_SRC_PORT) || (col_fmt == COL_RES_SRC_PORT) || 603: (col_fmt == COL_DEF_DST_PORT) || (col_fmt == COL_RES_DST_PORT))) || 604: (col_fmt == COL_PACKET_LENGTH)) { 605: 606: /* Compare numeric column */ 607: 608: if (num1 < num2) 609: return -1; 610: else if (num1 > num2) 611: return 1; 612: else 613: return 0; 614: } 615: 616: else { 617: 618: /* Compare text column */ 619: if (!text2) 620: return (text1 != NULL); 621: 622: if (!text1) 623: return -1; 624: 625: return strcmp(text1, text2); 626: } 627: } 628: 629: /* What to do when a column is clicked */ 630: static void 631: packet_list_click_column_cb(GtkCList *clist, gint column, gpointer data) 632: { 633: column_arrows *col_arrows = (column_arrows *) data; 634: int i; 635: 636: gtk_clist_freeze(clist); 637: 638: for (i = 0; i < cfile.cinfo.num_cols; i++) { 639: gtk_widget_hide(col_arrows[i].ascend_pm); 640: gtk_widget_hide(col_arrows[i].descend_pm); 641: } 642: 643: if (column == clist->sort_column) { 644: if (clist->sort_type == GTK_SORT_ASCENDING) { 645: clist->sort_type = GTK_SORT_DESCENDING; 646: gtk_widget_show(col_arrows[column].descend_pm); 647: } else { 648: clist->sort_type = GTK_SORT_ASCENDING; 649: gtk_widget_show(col_arrows[column].ascend_pm); 650: } 651: } 652: else { 653: clist->sort_type = GTK_SORT_ASCENDING; 654: gtk_widget_show(col_arrows[column].ascend_pm); 655: gtk_clist_set_sort_column(clist, column); 656: } 657: gtk_clist_thaw(clist); 658: 659: gtk_clist_sort(clist); 660: } 661: 662: /* mark packets */ 663: static void 664: set_frame_mark(gboolean set, frame_data *frame, gint row) { 665: GdkColor fg, bg; 666: 667: if (row == -1) 668: return; 669: if (set) { 670: mark_frame(&cfile, frame); 671: color_t_to_gdkcolor(&fg, &prefs.gui_marked_fg); 672: color_t_to_gdkcolor(&bg, &prefs.gui_marked_bg); 673: } else { 674: unmark_frame(&cfile, frame); 675: fg = BLACK; 676: bg = WHITE; 677: } 678: file_set_save_marked_sensitive(); 679: gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg); 680: gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg); 681: } 682: 683: static void 684: packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_) { 685: 686: GdkEventButton *event_button = (GdkEventButton *)event; 687: gint row, column; 688: 689: if (w == NULL || event == NULL) 690: return; 691: 692: if (event->type == GDK_BUTTON_PRESS && event_button->button == 2 && 693: gtk_clist_get_selection_info(GTK_CLIST(w), event_button->x, event_button->y, 694: &row, &column)) { 695: frame_data *fdata = (frame_data *) gtk_clist_get_row_data(GTK_CLIST(w), row); 696: set_frame_mark(!fdata->flags.marked, fdata, row); 697: } 698: } 699: 700: void mark_frame_cb(GtkWidget *w _U_, gpointer data _U_) { 701: if (cfile.current_frame) { 702: /* XXX hum, should better have a "cfile->current_row" here ... */ 703: set_frame_mark(!cfile.current_frame->flags.marked, 704: cfile.current_frame, 705: gtk_clist_find_row_from_data(GTK_CLIST(packet_list), 706: cfile.current_frame)); 707: } 708: } 709: 710: static void mark_all_frames(gboolean set) { 711: frame_data *fdata; 712: for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) { 713: set_frame_mark(set, 714: fdata, 715: gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata)); 716: } 717: } 718: 719: void update_marked_frames(void) { 720: frame_data *fdata; 721: if (cfile.plist == NULL) return; 722: for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) { 723: if (fdata->flags.marked) 724: set_frame_mark(TRUE, 725: fdata, 726: gtk_clist_find_row_from_data(GTK_CLIST(packet_list), 727: fdata)); 728: } 729: } 730: 731: void mark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_) { 732: mark_all_frames(TRUE); 733: } 734: 735: void unmark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_) { 736: mark_all_frames(FALSE); 737: } 738: 739: /* What to do when a list item is selected/unselected */ 740: static void 741: packet_list_select_cb(GtkWidget *w _U_, gint row, gint col _U_, gpointer evt _U_) { 742: 743: /* Remove the hex display tabbed pages */ 744: while( (gtk_notebook_get_nth_page( GTK_NOTEBOOK(byte_nb_ptr), 0))) 745: gtk_notebook_remove_page( GTK_NOTEBOOK(byte_nb_ptr), 0); 746: 747: select_packet(&cfile, row); 748: } 749: 750: 751: static void 752: packet_list_unselect_cb(GtkWidget *w _U_, gint row _U_, gint col _U_, gpointer evt _U_) { 753: 754: unselect_packet(&cfile); 755: } 756: 757: 758: static void 759: tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_, gpointer user_data _U_) 760: { 761: field_info *finfo; 762: gchar *help_str = NULL; 763: gboolean has_blurb = FALSE; 764: guint length = 0, byte_len; 765: GtkWidget *byte_view; 766: const guint8 *byte_data; 767: 768: g_assert(node); 769: finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) ); 770: if (!finfo) return; 771: 772: set_notebook_page(byte_nb_ptr, finfo->ds_tvb); 773: 774: byte_view = get_notebook_bv_ptr(byte_nb_ptr); 775: byte_data = get_byte_view_data_and_length(byte_view, &byte_len); 776: g_assert(byte_data != NULL); 777: 778: finfo_selected = finfo; 779: set_menus_for_selected_tree_row(TRUE); 780: 781: if (finfo->hfinfo) { 782: if (finfo->hfinfo->blurb != NULL && 783: finfo->hfinfo->blurb[0] != '\0') { 784: has_blurb = TRUE; 785: length = strlen(finfo->hfinfo->blurb); 786: } else { 787: length = strlen(finfo->hfinfo->name); 788: } 789: statusbar_pop_field_msg(); /* get rid of current help msg */ 790: if (length) { 791: length += strlen(finfo->hfinfo->abbrev) + 10; 792: help_str = g_malloc(sizeof(gchar) * length); 793: sprintf(help_str, "%s (%s)", 794: (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name, 795: finfo->hfinfo->abbrev); 796: statusbar_push_field_msg(help_str); 797: g_free(help_str); 798: } else { 799: /* 800: * Don't show anything if the field name is zero-length; 801: * the pseudo-field for "proto_tree_add_text()" is such 802: * a field, and we don't want "Text (text)" showing up 803: * on the status line if you've selected such a field. 804: * 805: * XXX - there are zero-length fields for which we *do* 806: * want to show the field name. 807: * 808: * XXX - perhaps the name and abbrev field should be null 809: * pointers rather than null strings for that pseudo-field, 810: * but we'd have to add checks for null pointers in some 811: * places if we did that. 812: * 813: * Or perhaps protocol tree items added with 814: * "proto_tree_add_text()" should have -1 as the field index, 815: * with no pseudo-field being used, but that might also 816: * require special checks for -1 to be added. 817: */ 818: statusbar_push_field_msg(""); 819: } 820: } 821: 822: packet_hex_print(GTK_TEXT(byte_view), byte_data, cfile.current_frame, 823: finfo, byte_len); 824: } 825: 826: static void 827: tree_view_unselect_row_cb(GtkCTree *ctree _U_, GList *node _U_, gint column _U_, gpointer user_data _U_) 828: { 829: GtkWidget *byte_view; 830: const guint8 *data; 831: guint len; 832: 833: /* 834: * Which byte view is displaying the current protocol tree 835: * row's data? 836: */ 837: byte_view = get_notebook_bv_ptr(byte_nb_ptr); 838: if (byte_view == NULL) 839: return; /* none */ 840: 841: data = "" &len); 842: if (data == NULL) 843: return; /* none */ 844: 845: unselect_field(); 846: packet_hex_print(GTK_TEXT(byte_view), data, cfile.current_frame, 847: NULL, len); 848: } 849: 850: void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) { 851: if (cfile.edt->tree) 852: collapse_all_tree(cfile.edt->tree, tree_view); 853: } 854: 855: void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) { 856: if (cfile.edt->tree) 857: expand_all_tree(cfile.edt->tree, tree_view); 858: } 859: 860: void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) { 861: if (cfile.edt->tree) { 862: guint32 tmp = g_resolv_flags; 863: g_resolv_flags = RESOLV_ALL; 864: proto_tree_draw(cfile.edt->tree, tree_view); 865: g_resolv_flags = tmp; 866: } 867: } 868: 869: /* Set the selection mode of the packet list window. */ 870: void 871: set_plist_sel_browse(gboolean val) 872: { 873: gboolean old_val; 874: 875: old_val = 876: (GTK_CLIST(packet_list)->selection_mode == GTK_SELECTION_SINGLE); 877: 878: if (val == old_val) { 879: /* 880: * The mode isn't changing, so don't do anything. 881: * In particular, don't gratuitiously unselect the 882: * current packet. 883: * 884: * XXX - why do we have to unselect the current packet 885: * ourselves? The documentation for the GtkCList at 886: * 887: * http://developer.gnome.org/doc/API/gtk/gtkclist.html 888: * 889: * says "Note that setting the widget's selection mode to 890: * one of GTK_SELECTION_BROWSE or GTK_SELECTION_SINGLE will 891: * cause all the items in the GtkCList to become deselected." 892: */ 893: return; 894: } 895: 896: if (finfo_selected) 897: unselect_packet(&cfile); 898: 899: /* Yeah, GTK uses "browse" in the case where we do not, but oh well. I think 900: * "browse" in Ethereal makes more sense than "SINGLE" in GTK+ */ 901: if (val) { 902: gtk_clist_set_selection_mode(GTK_CLIST(packet_list), GTK_SELECTION_SINGLE); 903: } 904: else { 905: gtk_clist_set_selection_mode(GTK_CLIST(packet_list), GTK_SELECTION_BROWSE); 906: } 907: } 908: 909: /* Set the font of the packet list window. */ 910: void 911: set_plist_font(GdkFont *font) 912: { 913: GtkStyle *style; 914: int i; 915: 916: style = gtk_style_new(); 917: gdk_font_unref(style->font); 918: style->font = font; 919: gdk_font_ref(font); 920: 921: gtk_widget_set_style(packet_list, style); 922: 923: /* Compute static column sizes to use during a "-S" capture, so that 924: the columns don't resize during a live capture. */ 925: for (i = 0; i < cfile.cinfo.num_cols; i++) { 926: cfile.cinfo.col_width[i] = gdk_string_width(font, 927: get_column_longest_string(get_column_format(i))); 928: } 929: } 930: 931: /* 932: * Push a message referring to file access onto the statusbar. 933: */ 934: void 935: statusbar_push_file_msg(gchar *msg) 936: { 937: gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg); 938: } 939: 940: /* 941: * Pop a message referring to file access off the statusbar. 942: */ 943: void 944: statusbar_pop_file_msg(void) 945: { 946: gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx); 947: } 948: 949: /* 950: * XXX - do we need multiple statusbar contexts? 951: */ 952: 953: /* 954: * Push a message referring to the currently-selected field onto the statusbar. 955: */ 956: void 957: statusbar_push_field_msg(gchar *msg) 958: { 959: gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg); 960: } 961: 962: /* 963: * Pop a message referring to the currently-selected field off the statusbar. 964: */ 965: void 966: statusbar_pop_field_msg(void) 967: { 968: gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx); 969: } 970: 971: static gboolean 972: do_quit(void) 973: { 974: /* XXX - should we check whether the capture file is an 975: unsaved temporary file for a live capture and, if so, 976: pop up a "do you want to exit without saving the capture 977: file?" dialog, and then just return, leaving said dialog 978: box to forcibly quit if the user clicks "OK"? 979: 980: If so, note that this should be done in a subroutine that 981: returns TRUE if we do so, and FALSE otherwise, and if it 982: returns TRUE we should return TRUE without nuking anything. 983: 984: Note that, if we do that, we might also want to check if 985: an "Update list of packets in real time" capture is in 986: progress and, if so, ask whether they want to terminate 987: the capture and discard it, and return TRUE, before nuking 988: any child capture, if they say they don't want to do so. */ 989: 990: #ifdef HAVE_LIBPCAP 991: /* Nuke any child capture in progress. */ 992: kill_capture_child(); 993: #endif 994: 995: /* Are we in the middle of reading a capture? */ 996: if (cfile.state == FILE_READ_IN_PROGRESS) { 997: /* Yes, so we can't just close the file and quit, as 998: that may yank the rug out from under the read in 999: progress; instead, just set the state to 1000: "FILE_READ_ABORTED" and return - the code doing the read 1001: will check for that and, if it sees that, will clean 1002: up and quit. */ 1003: cfile.state = FILE_READ_ABORTED; 1004: 1005: /* Say that the window should *not* be deleted; 1006: that'll be done by the code that cleans up. */ 1007: return TRUE; 1008: } else { 1009: /* Close any capture file we have open; on some OSes, you 1010: can't unlink a temporary capture file if you have it 1011: open. 1012: "close_cap_file()" will unlink it after closing it if 1013: it's a temporary file. 1014: 1015: We do this here, rather than after the main loop returns, 1016: as, after the main loop returns, the main window may have 1017: been destroyed (if this is called due to a "destroy" 1018: even on the main window rather than due to the user 1019: selecting a menu item), and there may be a crash 1020: or other problem when "close_cap_file()" tries to 1021: clean up stuff in the main window. 1022: 1023: XXX - is there a better place to put this? 1024: Or should we have a routine that *just* closes the 1025: capture file, and doesn't do anything with the UI, 1026: which we'd call here, and another routine that 1027: calls that routine and also cleans up the UI, which 1028: we'd call elsewhere? */ 1029: close_cap_file(&cfile); 1030: 1031: /* Exit by leaving the main loop, so that any quit functions 1032: we registered get called. */ 1033: gtk_main_quit(); 1034: 1035: /* Say that the window should be deleted. */ 1036: return FALSE; 1037: } 1038: } 1039: 1040: static gboolean 1041: main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_) 1042: { 1043: gint desk_x, desk_y; 1044: 1045: /* Try to grab our geometry */ 1046: gdk_window_get_root_origin(top_level->window, &root_x, &root_y); 1047: if (gdk_window_get_deskrelative_origin(top_level->window, 1048: &desk_x, &desk_y)) { 1049: if (desk_x <= root_x && desk_y <= root_y) { 1050: root_x = desk_x; 1051: root_y = desk_y; 1052: } 1053: } 1054: 1055: /* XXX - Is this the "approved" method? */ 1056: gdk_window_get_size(top_level->window, &top_width, &top_height); 1057: 1058: /* "do_quit()" indicates whether the main window should be deleted. */ 1059: return do_quit(); 1060: } 1061: 1062: void 1063: file_quit_cmd_cb (GtkWidget *widget _U_, gpointer data _U_) 1064: { 1065: do_quit(); 1066: } 1067: 1068: static void 1069: print_usage(gboolean print_ver) { 1070: 1071: if (print_ver) { 1072: fprintf(stderr, "This is GNU " PACKAGE " " VERSION ", compiled %s\n", 1073: comp_info_str->str); 1074: } 1075: #ifdef HAVE_LIBPCAP 1076: fprintf(stderr, "\n%s [ -vh ] [ -klpQS ] [ -a <capture autostop condition> ] ...\n", 1077: PACKAGE); 1078: fprintf(stderr, "\t[ -b <number of ringbuffer files> ] [ -B <byte view height> ]\n"); 1079: fprintf(stderr, "\t[ -c <count> ] [ -f <capture filter> ] [ -i <interface> ]\n"); 1080: fprintf(stderr, "\t[ -m <medium font> ] [ -n ] [ -N <resolving> ]\n"); 1081: fprintf(stderr, "\t[ -o <preference setting> ] ... [ -P <packet list height> ]\n"); 1082: fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -s <snaplen> ] \n"); 1083: fprintf(stderr, "\t[ -t <time stamp format> ] [ -T <tree view height> ]\n"); 1084: fprintf(stderr, "\t[ -w <savefile> ] [ <infile> ]\n"); 1085: #else 1086: fprintf(stderr, "\n%s [ -vh ] [ -B <byte view height> ] [ -m <medium font> ]\n", 1087: PACKAGE); 1088: fprintf(stderr, "\t[ -n ] [ -N <resolving> ]\n"); 1089: fprintf(stderr, "\t[ -o <preference setting> ... [ -P <packet list height> ]\n"); 1090: fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -t <time stamp format> ]\n"); 1091: fprintf(stderr, "\t[ -T <tree view height> ] [ <infile> ]\n"); 1092: #endif 1093: } 1094: 1095: static void 1096: show_version(void) 1097: { 1098: #ifdef WIN32 1099: create_console(); 1100: #endif 1101: 1102: printf("%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str); 1103: } 1104: 1105: static int 1106: get_positive_int(const char *string, const char *name) 1107: { 1108: long number; 1109: char *p; 1110: 1111: number = strtol(string, &p, 10); 1112: if (p == string || *p != '\0') { 1113: fprintf(stderr, "ethereal: The specified %s \"%s\" is not a decimal number\n", 1114: name, string); 1115: exit(1); 1116: } 1117: if (number < 0) { 1118: fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n", 1119: name, string); 1120: exit(1); 1121: } 1122: if (number == 0) { 1123: fprintf(stderr, "ethereal: The specified %s \"%s\" is zero\n", 1124: name, string); 1125: exit(1); 1126: } 1127: if (number > INT_MAX) { 1128: fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n", 1129: name, string, INT_MAX); 1130: exit(1); 1131: } 1132: return number; 1133: } 1134: 1135: #ifdef HAVE_LIBPCAP 1136: /* 1137: * Given a string of the form "<autostop criterion>:<value>", as might appear 1138: * as an argument to a "-a" option, parse it and set the criterion in 1139: * question. Return an indication of whether it succeeded or failed 1140: * in some fashion. 1141: */ 1142: static gboolean 1143: set_autostop_criterion(const char *autostoparg) 1144: { 1145: u_char *p, *colonp; 1146: 1147: colonp = strchr(autostoparg, ':'); 1148: if (colonp == NULL) 1149: return FALSE; 1150: 1151: p = colonp; 1152: *p++ = '\0'; 1153: 1154: /* 1155: * Skip over any white space (there probably won't be any, but 1156: * as we allow it in the preferences file, we might as well 1157: * allow it here). 1158: */ 1159: while (isspace(*p)) 1160: p++; 1161: if (*p == '\0') { 1162: /* 1163: * Put the colon back, so if our caller uses, in an 1164: * error message, the string they passed us, the message 1165: * looks correct. 1166: */ 1167: *colonp = ':'; 1168: return FALSE; 1169: } 1170: if (strcmp(autostoparg,"duration") == 0) { 1171: capture_opts.has_autostop_duration = TRUE; 1172: capture_opts.autostop_duration = get_positive_int(p,"autostop duration"); 1173: } else if (strcmp(autostoparg,"filesize") == 0) { 1174: capture_opts.has_autostop_filesize = TRUE; 1175: capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize"); 1176: } else { 1177: return FALSE; 1178: } 1179: *colonp = ':'; /* put the colon back */ 1180: return TRUE; 1181: } 1182: #endif 1183: 1184: /* And now our feature presentation... [ fade to music ] */ 1185: int 1186: main(int argc, char *argv[]) 1187: { 1188: #ifdef HAVE_LIBPCAP 1189: char *command_name; 1190: #endif 1191: char *s; 1192: int i; 1193: int opt; 1194: extern char *optarg; 1195: gboolean arg_error = FALSE; 1196: #ifdef HAVE_LIBPCAP 1197: #ifdef HAVE_PCAP_VERSION 1198: extern char pcap_version[]; 1199: #endif /* HAVE_PCAP_VERSION */ 1200: #endif /* HAVE_LIBPCAP */ 1201: 1202: #ifdef WIN32 1203: WSADATA wsaData; 1204: #endif 1205: 1206: char *gpf_path, *cf_path, *df_path; 1207: const char *pf_path; 1208: int gpf_open_errno, pf_open_errno, cf_open_errno, df_open_errno; 1209: int err; 1210: #ifdef HAVE_LIBPCAP 1211: gboolean start_capture = FALSE; 1212: gchar *save_file = NULL; 1213: GList *if_list; 1214: gchar err_str[PCAP_ERRBUF_SIZE]; 1215: gboolean stats_known; 1216: struct pcap_stat stats; 1217: #else 1218: gboolean capture_option_specified = FALSE; 1219: #endif 1220: gint pl_size = 280, tv_size = 95, bv_size = 75; 1221: gchar *rc_file, *cf_name = NULL, *rfilter = NULL; 1222: dfilter_t *rfcode = NULL; 1223: gboolean rfilter_parse_failed = FALSE; 1224: e_prefs *prefs; 1225: char badopt; 1226: char *bold_font_name; 1227: gint desk_x, desk_y; 1228: gboolean prefs_write_needed = FALSE; 1229: 1230: #define OPTSTRING_INIT "a:b:B:c:f:hi:klm:nN:o:pP:Qr:R:Ss:t:T:w:v" 1231: 1232: #ifdef HAVE_LIBPCAP 1233: #ifdef WIN32 1234: #define OPTSTRING_CHILD "W:Z:" 1235: #else 1236: #define OPTSTRING_CHILD "W:" 1237: #endif /* WIN32 */ 1238: #else 1239: #define OPTSTRING_CHILD "" 1240: #endif /* HAVE_LIBPCAP */ 1241: 1242: char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_CHILD) - 1] = 1243: OPTSTRING_INIT; 1244: 1245: ethereal_path = argv[0]; 1246: 1247: #ifdef WIN32 1248: /* Arrange that if we have no console window, and a GLib message logging 1249: routine is called to log a message, we pop up a console window. 1250: 1251: We do that by inserting our own handler for all messages logged 1252: to the default domain; that handler pops up a console if necessary, 1253: and then calls the default handler. */ 1254: g_log_set_handler(NULL, 1255: G_LOG_LEVEL_ERROR| 1256: G_LOG_LEVEL_CRITICAL| 1257: G_LOG_LEVEL_WARNING| 1258: G_LOG_LEVEL_MESSAGE| 1259: G_LOG_LEVEL_INFO| 1260: G_LOG_LEVEL_DEBUG| 1261: G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION, 1262: console_log_handler, NULL); 1263: #endif 1264: 1265: #ifdef HAVE_LIBPCAP 1266: command_name = get_basename(ethereal_path); 1267: /* Set "capture_child" to indicate whether this is going to be a child 1268: process for a "-S" capture. */ 1269: capture_child = (strcmp(command_name, CHILD_NAME) == 0); 1270: if (capture_child) 1271: strcat(optstring, OPTSTRING_CHILD); 1272: #endif 1273: 1274: /* Register all dissectors; we must do this before checking for the 1275: "-G" flag, as the "-G" flag dumps information registered by the 1276: dissectors, and we must do it before we read the preferences, in 1277: case any dissectors register preferences. */ 1278: epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs); 1279: 1280: /* Now register the preferences for any non-dissector modules. 1281: We must do that before we read the preferences as well. */ 1282: prefs_register_modules(); 1283: 1284: /* If invoked with the "-G" flag, we dump out information based on 1285: the argument to the "-G" flag; if no argument is specified, 1286: for backwards compatibility we dump out a glossary of display 1287: filter symbols. 1288: 1289: We must do this before calling "gtk_init()", because "gtk_init()" 1290: tries to open an X display, and we don't want to have to do any X 1291: stuff just to do a build. 1292: 1293: Given that we call "gtk_init()" before doing the regular argument 1294: list processing, so that it can handle X and GTK+ arguments and 1295: remove them from the list at which we look, this means we must do 1296: this before doing the regular argument list processing, as well. 1297: 1298: This means that: 1299: 1300: you must give the "-G" flag as the first flag on the command line; 1301: 1302: you must give it as "-G", nothing more, nothing less; 1303: 1304: the first argument after the "-G" flag, if present, will be used 1305: to specify the information to dump; 1306: 1307: arguments after that will not be used. */ 1308: if (argc >= 2 && strcmp(argv[1], "-G") == 0) { 1309: if (argc == 2) 1310: proto_registrar_dump_fields(); 1311: else { 1312: if (strcmp(argv[2], "fields") == 0) 1313: proto_registrar_dump_fields(); 1314: else if (strcmp(argv[2], "protocols") == 0) 1315: proto_registrar_dump_protocols(); 1316: else { 1317: fprintf(stderr, "tethereal: Invalid \"%s\" option for -G flag\n", 1318: argv[2]); 1319: exit(1); 1320: } 1321: } 1322: exit(0); 1323: } 1324: 1325: /* Set the current locale according to the program environment. 1326: * We haven't localized anything, but some GTK widgets are localized 1327: * (the file selection dialogue, for example). 1328: * This also sets the C-language locale to the native environment. */ 1329: gtk_set_locale(); 1330: 1331: /* Let GTK get its args */ 1332: gtk_init (&argc, &argv); 1333: 1334: /* Read the preference files. */ 1335: prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path); 1336: 1337: #ifdef HAVE_LIBPCAP 1338: capture_opts.has_snaplen = FALSE; 1339: capture_opts.snaplen = MIN_PACKET_SIZE; 1340: capture_opts.has_autostop_count = FALSE; 1341: capture_opts.autostop_count = 1; 1342: capture_opts.has_autostop_duration = FALSE; 1343: capture_opts.autostop_duration = 1; 1344: capture_opts.has_autostop_filesize = FALSE; 1345: capture_opts.autostop_filesize = 1; 1346: capture_opts.ringbuffer_on = FALSE; 1347: capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES; 1348: 1349: /* If this is a capture child process, it should pay no attention 1350: to the "prefs.capture_prom_mode" setting in the preferences file; 1351: it should do what the parent process tells it to do, and if 1352: the parent process wants it not to run in promiscuous mode, it'll 1353: tell it so with a "-p" flag. 1354: 1355: Otherwise, set promiscuous mode from the preferences setting. */ 1356: if (capture_child) 1357: capture_opts.promisc_mode = TRUE; 1358: else 1359: capture_opts.promisc_mode = prefs->capture_prom_mode; 1360: 1361: /* Set "Update list of packets in real time" mode from the preferences 1362: setting. */ 1363: capture_opts.sync_mode = prefs->capture_real_time; 1364: 1365: /* And do the same for "Automatic scrolling in live capture" mode. */ 1366: auto_scroll_live = prefs->capture_auto_scroll; 1367: #endif 1368: 1369: /* Set the name resolution code's flags from the preferences. */ 1370: g_resolv_flags = prefs->name_resolve; 1371: 1372: /* Read the capture filter file. */ 1373: read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno); 1374: 1375: /* Read the display filter file. */ 1376: read_filter_list(DFILTER_LIST, &df_path, &df_open_errno); 1377: 1378: /* Initialize the capture file struct */ 1379: cfile.plist = NULL; 1380: cfile.plist_end = NULL; 1381: cfile.wth = NULL; 1382: cfile.filename = NULL; 1383: cfile.user_saved = FALSE; 1384: cfile.is_tempfile = FALSE; 1385: cfile.rfcode = NULL; 1386: cfile.dfilter = NULL; 1387: cfile.dfcode = NULL; 1388: #ifdef HAVE_LIBPCAP 1389: cfile.cfilter = g_strdup(EMPTY_FILTER); 1390: #endif 1391: cfile.iface = NULL; 1392: cfile.save_file = NULL; 1393: cfile.save_file_fd = -1; 1394: 1395: cfile.ipaddr = NULL; 1396: cfile.has_ipaddr = FALSE; 1397: cfile.v5iface = NULL; 1398: cfile.has_v5iface = FALSE; 1399: 1394: cfile.has_snap = FALSE; 1395: cfile.snap = WTAP_MAX_PACKET_SIZE; 1396: cfile.count = 0; 1397: col_init(&cfile.cinfo, prefs->num_cols); 1398: 1399: /* Assemble the compile-time options */ 1400: comp_info_str = g_string_new(""); 1401: 1402: g_string_append(comp_info_str, "with "); 1403: g_string_sprintfa(comp_info_str, 1404: #ifdef GTK_MAJOR_VERSION 1405: "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, 1406: GTK_MICRO_VERSION); 1407: #else 1408: "GTK+ (version unknown)"); 1409: #endif 1410: 1411: g_string_append(comp_info_str, ", with "); 1412: g_string_sprintfa(comp_info_str, 1413: #ifdef GLIB_MAJOR_VERSION 1414: "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, 1415: GLIB_MICRO_VERSION); 1416: #else 1417: "GLib (version unknown)"); 1418: #endif 1419: 1420: #ifdef HAVE_LIBPCAP 1421: g_string_append(comp_info_str, ", with libpcap "); 1422: #ifdef HAVE_PCAP_VERSION 1423: g_string_append(comp_info_str, pcap_version); 1424: #else /* HAVE_PCAP_VERSION */ 1425: g_string_append(comp_info_str, "(version unknown)"); 1426: #endif /* HAVE_PCAP_VERSION */ 1427: #else /* HAVE_LIBPCAP */ 1428: g_string_append(comp_info_str, ", without libpcap"); 1429: #endif /* HAVE_LIBPCAP */ 1430: 1431: #ifdef HAVE_LIBZ 1432: g_string_append(comp_info_str, ", with libz "); 1433: #ifdef ZLIB_VERSION 1434: g_string_append(comp_info_str, ZLIB_VERSION); 1435: #else /* ZLIB_VERSION */ 1436: g_string_append(comp_info_str, "(version unknown)"); 1437: #endif /* ZLIB_VERSION */ 1438: #else /* HAVE_LIBZ */ 1439: g_string_append(comp_info_str, ", without libz"); 1440: #endif /* HAVE_LIBZ */ 1441: 1442: /* Oh, this is pretty */ 1443: #ifdef HAVE_UCD_SNMP 1444: g_string_append(comp_info_str, ", with UCD SNMP "); 1445: #ifdef HAVE_UCD_SNMP_VERSION_H 1446: g_string_append(comp_info_str, VersionInfo); 1447: #else /* HAVE_UCD_SNMP_VERSION_H */ 1448: g_string_append(comp_info_str, "(version unknown)"); 1449: #endif /* HAVE_UCD_SNMP_VERSION_H */ 1450: #else /* no SNMP library */ 1451: g_string_append(comp_info_str, ", without UCD SNMP"); 1452: #endif 1453: 1454: /* Now get our args */ 1455: while ((opt = getopt(argc, argv, optstring)) != -1) { 1456: switch (opt) { 1457: case 'a': /* autostop criteria */ 1458: #ifdef HAVE_LIBPCAP 1459: if (set_autostop_criterion(optarg) == FALSE) { 1460: fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg); 1461: exit(1); 1462: } 1463: #else 1464: capture_option_specified = TRUE; 1465: arg_error = TRUE; 1466: #endif 1467: break; 1468: case 'b': /* Ringbuffer option */ 1469: #ifdef HAVE_LIBPCAP 1470: capture_opts.ringbuffer_on = TRUE; 1471: capture_opts.ringbuffer_num_files = 1472: get_positive_int(optarg, "number of ring buffer files"); 1473: #else 1474: capture_option_specified = TRUE; 1475: arg_error = TRUE; 1476: #endif 1477: break; 1478: case 'B': /* Byte view pane height */ 1479: bv_size = get_positive_int(optarg, "byte view pane height"); 1480: break; 1481: case 'c': /* Capture xxx packets */ 1482: #ifdef HAVE_LIBPCAP 1483: capture_opts.has_autostop_count = TRUE; 1484: capture_opts.autostop_count = get_positive_int(optarg, "packet count"); 1485: #else 1486: capture_option_specified = TRUE; 1487: arg_error = TRUE; 1488: #endif 1489: break; 1490: case 'f': 1491: #ifdef HAVE_LIBPCAP 1492: if (cfile.cfilter) 1493: g_free(cfile.cfilter); 1494: cfile.cfilter = g_strdup(optarg); 1495: #else 1496: capture_option_specified = TRUE; 1497: arg_error = TRUE; 1498: #endif 1499: break; 1500: case 'h': /* Print help and exit */ 1501: print_usage(TRUE); 1502: exit(0); 1503: break; 1504: case 'i': /* Use interface xxx */ 1505: #ifdef HAVE_LIBPCAP 1506: cfile.iface = g_strdup(optarg); 1507: #else 1508: capture_option_specified = TRUE; 1509: arg_error = TRUE; 1510: #endif 1511: break; 1512: case 'k': /* Start capture immediately */ 1513: #ifdef HAVE_LIBPCAP 1514: start_capture = TRUE; 1515: #else 1516: capture_option_specified = TRUE; 1517: arg_error = TRUE; 1518: #endif 1519: break; 1520: case 'l': /* Automatic scrolling in live capture mode */ 1521: #ifdef HAVE_LIBPCAP 1522: auto_scroll_live = TRUE; 1523: #else 1524: capture_option_specified = TRUE; 1525: arg_error = TRUE; 1526: #endif 1527: break; 1528: case 'm': /* Fixed-width font for the display */ 1529: if (prefs->gui_font_name != NULL) 1530: g_free(prefs->gui_font_name); 1531: prefs->gui_font_name = g_strdup(optarg); 1532: break; 1533: case 'n': /* No name resolution */ 1534: g_resolv_flags = RESOLV_NONE; 1535: break; 1536: case 'N': /* Select what types of addresses/port #s to resolve */ 1537: if (g_resolv_flags == RESOLV_ALL) 1538: g_resolv_flags = RESOLV_NONE; 1539: badopt = string_to_name_resolve(optarg, &g_resolv_flags); 1540: if (badopt != '\0') { 1541: fprintf(stderr, "ethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n", 1542: badopt); 1543: exit(1); 1544: } 1545: break; 1546: case 'o': /* Override preference from command line */ 1547: switch (prefs_set_pref(optarg)) { 1548: 1549: case PREFS_SET_SYNTAX_ERR: 1550: fprintf(stderr, "ethereal: Invalid -o flag \"%s\"\n", optarg); 1551: exit(1); 1552: break; 1553: 1554: case PREFS_SET_NO_SUCH_PREF: 1555: case PREFS_SET_OBSOLETE: 1556: fprintf(stderr, "ethereal: -o flag \"%s\" specifies unknown preference\n", 1557: optarg); 1558: exit(1); 1559: break; 1560: } 1561: break; 1562: case 'p': /* Don't capture in promiscuous mode */ 1563: #ifdef HAVE_LIBPCAP 1564: capture_opts.promisc_mode = FALSE; 1565: #else 1566: capture_option_specified = TRUE; 1567: arg_error = TRUE; 1568: #endif 1569: break; 1570: case 'P': /* Packet list pane height */ 1571: pl_size = get_positive_int(optarg, "packet list pane height"); 1572: break; 1573: case 'Q': /* Quit after capture (just capture to file) */ 1574: #ifdef HAVE_LIBPCAP 1575: quit_after_cap = 1; 1576: start_capture = TRUE; /*** -Q implies -k !! ***/ 1577: #else 1578: capture_option_specified = TRUE; 1579: arg_error = TRUE; 1580: #endif 1581: break; 1582: case 'r': /* Read capture file xxx */ 1583: /* We may set "last_open_dir" to "cf_name", and if we change 1584: "last_open_dir" later, we free the old value, so we have to 1585: set "cf_name" to something that's been allocated. */ 1586: cf_name = g_strdup(optarg); 1587: break; 1588: case 'R': /* Read file filter */ 1589: rfilter = optarg; 1590: break; 1591: case 's': /* Set the snapshot (capture) length */ 1592: #ifdef HAVE_LIBPCAP 1593: capture_opts.has_snaplen = TRUE; 1594: capture_opts.snaplen = get_positive_int(optarg, "snapshot length"); 1595: #else 1596: capture_option_specified = TRUE; 1597: arg_error = TRUE; 1598: #endif 1599: break; 1600: case 'S': /* "Sync" mode: used for following file ala tail -f */ 1601: #ifdef HAVE_LIBPCAP 1602: capture_opts.sync_mode = TRUE; 1603: #else 1604: capture_option_specified = TRUE; 1605: arg_error = TRUE; 1606: #endif 1607: break; 1608: case 't': /* Time stamp type */ 1609: if (strcmp(optarg, "r") == 0) 1610: timestamp_type = RELATIVE; 1611: else if (strcmp(optarg, "a") == 0) 1612: timestamp_type = ABSOLUTE; 1613: else if (strcmp(optarg, "ad") == 0) 1614: timestamp_type = ABSOLUTE_WITH_DATE; 1615: else if (strcmp(optarg, "d") == 0) 1616: timestamp_type = DELTA; 1617: else { 1618: fprintf(stderr, "ethereal: Invalid time stamp type \"%s\"\n", 1619: optarg); 1620: fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n"); 1621: fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n"); 1622: exit(1); 1623: } 1624: break; 1625: case 'T': /* Tree view pane height */ 1626: tv_size = get_positive_int(optarg, "tree view pane height"); 1627: break; 1628: case 'v': /* Show version and exit */ 1629: show_version(); 1630: #ifdef WIN32 1631: if (console_was_created) 1632: destroy_console(); 1633: #endif 1634: exit(0); 1635: break; 1636: case 'w': /* Write to capture file xxx */ 1637: #ifdef HAVE_LIBPCAP 1638: save_file = g_strdup(optarg); 1639: #else 1640: capture_option_specified = TRUE; 1641: arg_error = TRUE; 1642: #endif 1643: break; 1644: #ifdef HAVE_LIBPCAP 1645: /* This is a hidden option supporting Sync mode, so we don't set 1646: * the error flags for the user in the non-libpcap case. 1647: */ 1648: case 'W': /* Write to capture file FD xxx */ 1649: cfile.save_file_fd = atoi(optarg); 1650: break; 1651: #endif 1652: 1653: #ifdef _WIN32 1654: #ifdef HAVE_LIBPCAP 1655: /* Hidden option supporting Sync mode */ 1656: case 'Z': /* Write to pipe FD XXX */ 1657: /* associate stdout with pipe */ 1658: i = atoi(optarg); 1659: if (dup2(i, 1) < 0) { 1660: fprintf(stderr, "Unable to dup pipe handle\n"); 1661: exit(1); 1662: } 1663: break; 1664: #endif /* HAVE_LIBPCAP */ 1665: #endif /* _WIN32 */ 1666: 1667: default: 1668: case '?': /* Bad flag - print usage message */ 1669: arg_error = TRUE; 1670: break; 1671: } 1672: } 1673: argc -= optind; 1674: argv += optind; 1675: if (argc >= 1) { 1676: if (cf_name != NULL) { 1677: /* 1678: * Input file name specified with "-r" *and* specified as a regular 1679: * command-line argument. 1680: */ 1681: arg_error = TRUE; 1682: } else { 1683: /* 1684: * Input file name not specified with "-r", and a command-line argument 1685: * was specified; treat it as the input file name. 1686: * 1687: * Yes, this is different from tethereal, where non-flag command-line 1688: * arguments are a filter, but this works better on GUI desktops 1689: * where a command can be specified to be run to open a particular 1690: * file - yes, you could have "-r" as the last part of the command, 1691: * but that's a bit ugly. 1692: */ 1693: cf_name = g_strdup(argv[0]); 1694: } 1695: argc--; 1696: argv++; 1697: } 1698: 1699: if (argc != 0) { 1700: /* 1701: * Extra command line arguments were specified; complain. 1702: */ 1703: fprintf(stderr, "Invalid argument: %s\n", argv[0]); 1704: arg_error = TRUE; 1705: } 1706: if (arg_error) { 1707: print_usage(FALSE); 1708: exit(1); 1709: } 1710: 1711: #ifdef HAVE_LIBPCAP 1712: if (capture_opts.ringbuffer_on) { 1713: /* Ring buffer works only under certain conditions: 1714: a) ring buffer does not work with temporary files; 1715: b) sync_mode and capture_opts.ringbuffer_on are mutually exclusive - 1716: sync_mode takes precedence; 1717: c) it makes no sense to enable the ring buffer if the maximum 1718: file size is set to "infinite". */ 1719: if (cfile.save_file == NULL) { 1720: fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n"); 1721: capture_opts.ringbuffer_on = FALSE; 1722: } 1723: if (capture_opts.sync_mode) { 1724: fprintf(stderr, "ethereal: Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.\n"); 1725: capture_opts.ringbuffer_on = FALSE; 1726: } 1727: if (!capture_opts.has_autostop_filesize) { 1728: fprintf(stderr, "ethereal: Ring buffer requested, but no maximum capture file size was specified.\n"); 1729: capture_opts.ringbuffer_on = FALSE; 1730: } 1731: } 1732: #endif 1733: 1734: #ifdef WIN32 1735: /* Load wpcap if possible */ 1736: load_wpcap(); 1737: 1738: /* Start windows sockets */ 1739: WSAStartup( MAKEWORD( 1, 1 ), &wsaData ); 1740: #endif 1741: 1742: /* Notify all registered modules that have had any of their preferences 1743: changed either from one of the preferences file or from the command 1744: line that its preferences have changed. */ 1745: prefs_apply_all(); 1746: 1747: #ifndef HAVE_LIBPCAP 1748: if (capture_option_specified) 1749: fprintf(stderr, "This version of Ethereal was not built with support for capturing packets.\n"); 1750: #endif 1751: #ifdef HAVE_LIBPCAP 1752: if (start_capture) { 1753: /* We're supposed to do a live capture; did the user specify an interface 1754: to use? */ 1755: if (cfile.iface == NULL) { 1756: /* No - is a default specified in the preferences file? */ 1757: if (prefs->capture_device != NULL) { 1758: /* Yes - use it. */ 1759: cfile.iface = g_strdup(prefs->capture_device); 1760: } else { 1761: /* No - pick the first one from the list of interfaces. */ 1762: if_list = get_interface_list(&err, err_str); 1763: if (if_list == NULL) { 1764: switch (err) { 1765: 1766: case CANT_GET_INTERFACE_LIST: 1767: fprintf(stderr, "ethereal: Can't get list of interfaces: %s\n", 1768: err_str); 1769: break; 1770: 1771: case NO_INTERFACES_FOUND: 1772: fprintf(stderr, "ethereal: There are no interfaces on which a capture can be done\n"); 1773: break; 1774: } 1775: exit(2); 1776: } 1777: cfile.iface = g_strdup(if_list->data); /* first interface */ 1778: free_interface_list(if_list); 1779: } 1780: } 1781: } 1782: if (capture_child) { 1783: if (cfile.save_file_fd == -1) { 1784: /* XXX - send this to the standard output as something our parent 1785: should put in an error message box? */ 1786: fprintf(stderr, "%s: \"-W\" flag not specified\n", CHILD_NAME); 1787: exit(1); 1788: } 1789: } 1790: #endif 1791: 1792: /* Build the column format array */ 1793: for (i = 0; i < cfile.cinfo.num_cols; i++) { 1794: cfile.cinfo.col_fmt[i] = get_column_format(i); 1795: cfile.cinfo.col_title[i] = g_strdup(get_column_title(i)); 1796: cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) * 1797: NUM_COL_FMTS); 1798: get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]); 1799: cfile.cinfo.col_data[i] = NULL; 1800: if (cfile.cinfo.col_fmt[i] == COL_INFO) 1801: cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN); 1802: else 1803: cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN); 1804: cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN); 1805: cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN); 1806: } 1807: 1808: #ifdef HAVE_LIBPCAP 1809: if (capture_opts.has_snaplen) { 1810: if (capture_opts.snaplen < 1) 1811: capture_opts.snaplen = WTAP_MAX_PACKET_SIZE; 1812: else if (capture_opts.snaplen < MIN_PACKET_SIZE) 1813: capture_opts.snaplen = MIN_PACKET_SIZE; 1814: } 1815: 1816: /* Check the value range of the ringbuffer_num_files parameter */ 1817: if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES) 1818: capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES; 1819: else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES) 1820: capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES; 1821: #endif 1822: 1823: rc_file = get_persconffile_path(RC_FILE, FALSE); 1824: gtk_rc_parse(rc_file); 1825: 1826: /* Try to load the regular and boldface fixed-width fonts */ 1827: bold_font_name = boldify(prefs->gui_font_name); 1828: m_r_font = gdk_font_load(prefs->gui_font_name); 1829: m_b_font = gdk_font_load(bold_font_name); 1830: if (m_r_font == NULL || m_b_font == NULL) { 1831: /* XXX - pop this up as a dialog box? no */ 1832: if (m_r_font == NULL) { 1833: #ifdef HAVE_LIBPCAP 1834: if (!capture_child) 1835: #endif 1836: fprintf(stderr, "ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n", 1837: prefs->gui_font_name); 1838: } else { 1839: gdk_font_unref(m_r_font); 1840: } 1841: if (m_b_font == NULL) { 1842: #ifdef HAVE_LIBPCAP 1843: if (!capture_child) 1844: #endif 1845: fprintf(stderr, "ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n", 1846: bold_font_name); 1847: } else { 1848: gdk_font_unref(m_b_font); 1849: } 1850: g_free(bold_font_name); 1851: if ((m_r_font = gdk_font_load("6x13")) == NULL) { 1852: fprintf(stderr, "ethereal: Error: font 6x13 not found\n"); 1853: exit(1); 1854: } 1855: if ((m_b_font = gdk_font_load("6x13bold")) == NULL) { 1856: fprintf(stderr, "ethereal: Error: font 6x13bold not found\n"); 1857: exit(1); 1858: } 1859: g_free(prefs->gui_font_name); 1860: prefs->gui_font_name = g_strdup("6x13"); 1861: } 1862: 1863: /* Call this for the side-effects that set_fonts() produces */ 1864: set_fonts(m_r_font, m_b_font); 1865: 1866: 1867: #ifdef HAVE_LIBPCAP 1868: /* Is this a "child" ethereal, which is only supposed to pop up a 1869: capture box to let us stop the capture, and run a capture 1870: to a file that our parent will read? */ 1871: if (!capture_child) { 1872: #endif 1873: /* No. Pop up the main window, and read in a capture file if 1874: we were told to. */ 1875: 1876: create_main_window(pl_size, tv_size, bv_size, prefs); 1877: set_menus_for_capture_file(FALSE); 1878: 1879: colfilter_init(); 1880: 1881: /* If we were given the name of a capture file, read it in now; 1882: we defer it until now, so that, if we can't open it, and pop 1883: up an alert box, the alert box is more likely to come up on 1884: top of the main window - but before the preference-file-error 1885: alert box, so, if we get one of those, it's more likely to come 1886: up on top of us. */ 1887: if (cf_name) { 1888: if (rfilter != NULL) { 1889: if (!dfilter_compile(rfilter, &rfcode)) { 1890: simple_dialog(ESD_TYPE_CRIT, NULL, dfilter_error_msg); 1891: rfilter_parse_failed = TRUE; 1892: } 1893: } 1894: if (!rfilter_parse_failed) { 1895: if ((err = open_cap_file(cf_name, FALSE, &cfile)) == 0) { 1896: /* "open_cap_file()" succeeded, so it closed the previous 1897: capture file, and thus destroyed any previous read filter 1898: attached to "cf". */ 1899: cfile.rfcode = rfcode; 1900: switch (read_cap_file(&cfile, &err)) { 1901: 1902: case READ_SUCCESS: 1903: case READ_ERROR: 1904: /* Just because we got an error, that doesn't mean we were unable 1905: to read any of the file; we handle what we could get from the 1906: file. */ 1907: break; 1908: 1909: case READ_ABORTED: 1910: /* Exit now. */ 1911: gtk_exit(0); 1912: break; 1913: } 1914: /* Save the name of the containing directory specified in the 1915: path name, if any; we can write over cf_name, which is a 1916: good thing, given that "get_dirname()" does write over its 1917: argument. */ 1918: s = get_dirname(cf_name); 1919: set_last_open_dir(s); 1920: } else { 1921: if (rfcode != NULL) 1922: dfilter_free(rfcode); 1923: cfile.rfcode = NULL; 1924: } 1925: } 1926: } 1927: #ifdef HAVE_LIBPCAP 1928: } 1929: #endif 1930: 1931: /* If the global preferences file exists but we failed to open it, 1932: pop up an alert box; we defer that until now, so that the alert 1933: box is more likely to come up on top of the main window. */ 1934: if (gpf_path != NULL) { 1935: simple_dialog(ESD_TYPE_WARN, NULL, 1936: "Could not open global preferences file\n\"%s\": %s.", gpf_path, 1937: strerror(gpf_open_errno)); 1938: } 1939: 1940: /* If the user's preferences file exists but we failed to open it, 1941: pop up an alert box; we defer that until now, so that the alert 1942: box is more likely to come up on top of the main window. */ 1943: if (pf_path != NULL) { 1944: simple_dialog(ESD_TYPE_WARN, NULL, 1945: "Could not open your preferences file\n\"%s\": %s.", pf_path, 1946: strerror(pf_open_errno)); 1947: } 1948: 1949: /* If the user's capture filter file exists but we failed to open it, 1950: pop up an alert box; we defer that until now, so that the alert 1951: box is more likely to come up on top of the main window. */ 1952: if (cf_path != NULL) { 1953: simple_dialog(ESD_TYPE_WARN, NULL, 1954: "Could not open your capture filter file\n\"%s\": %s.", cf_path, 1955: strerror(cf_open_errno)); 1956: g_free(cf_path); 1957: } 1958: 1959: /* If the user's display filter file exists but we failed to open it, 1960: pop up an alert box; we defer that until now, so that the alert 1961: box is more likely to come up on top of the main window. */ 1962: if (df_path != NULL) { 1963: simple_dialog(ESD_TYPE_WARN, NULL, 1964: "Could not open your display filter file\n\"%s\": %s.", df_path, 1965: strerror(df_open_errno)); 1966: g_free(df_path); 1967: } 1968: 1969: #ifdef HAVE_LIBPCAP 1970: if (capture_child) { 1971: /* This is the child process for a sync mode or fork mode capture, 1972: so just do the low-level work of a capture - don't create 1973: a temporary file and fork off *another* child process (so don't 1974: call "do_capture()"). */ 1975: 1976: /* XXX - hand these stats to the parent process */ 1977: capture(&stats_known, &stats); 1978: 1979: /* The capture is done; there's nothing more for us to do. */ 1980: gtk_exit(0); 1981: } else { 1982: if (start_capture) { 1983: /* "-k" was specified; start a capture. */ 1984: do_capture(save_file); 1985: } 1986: else { 1987: set_menus_for_capture_in_progress(FALSE); 1988: } 1989: } 1990: #else 1991: set_menus_for_capture_in_progress(FALSE); 1992: #endif 1993: 1994: gtk_main(); 1995: 1996: /* Try to save our geometry. GTK+ provides two routines to get a 1997: window's position relative to the X root window. If I understand the 1998: documentation correctly, gdk_window_get_deskrelative_origin applies 1999: mainly to Enlightenment and gdk_window_get_root_origin applies for 2000: all other WMs. 2001: 2002: The code below tries both routines, and picks the one that returns 2003: the upper-left-most coordinates. 2004: 2005: More info at: 2006: 2007: http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html 2008: http://www.gtk.org/faq/#AEN600 */ 2009: 2010: /* Re-read our saved preferences. */ 2011: /* XXX - Move all of this into a separate function? */ 2012: prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path); 2013: 2014: if (pf_path == NULL) { 2015: if (prefs->gui_geometry_save_position) { 2016: if (top_level->window != NULL) { 2017: gdk_window_get_root_origin(top_level->window, &root_x, &root_y); 2018: if (gdk_window_get_deskrelative_origin(top_level->window, 2019: &desk_x, &desk_y)) { 2020: if (desk_x <= root_x && desk_y <= root_y) { 2021: root_x = desk_x; 2022: root_y = desk_y; 2023: } 2024: } 2025: } 2026: if (prefs->gui_geometry_main_x != root_x) { 2027: prefs->gui_geometry_main_x = root_x; 2028: prefs_write_needed = TRUE; 2029: } 2030: if (prefs->gui_geometry_main_y != root_y) { 2031: prefs->gui_geometry_main_y = root_y; 2032: prefs_write_needed = TRUE; 2033: } 2034: } 2035: 2036: if (prefs->gui_geometry_save_size) { 2037: if (top_level->window != NULL) { 2038: /* XXX - Is this the "approved" method? */ 2039: gdk_window_get_size(top_level->window, &top_width, &top_height); 2040: } 2041: if (prefs->gui_geometry_main_width != top_width) { 2042: prefs->gui_geometry_main_width = top_width; 2043: prefs_write_needed = TRUE; 2044: } 2045: if (prefs->gui_geometry_main_height != top_height) { 2046: prefs->gui_geometry_main_height = top_height; 2047: prefs_write_needed = TRUE; 2048: } 2049: } 2050: 2051: if (prefs_write_needed) { 2052: write_prefs(&pf_path); 2053: } 2054: } 2055: 2056: epan_cleanup(); 2057: g_free(rc_file); 2058: 2059: #ifdef WIN32 2060: /* Shutdown windows sockets */ 2061: WSACleanup(); 2062: 2063: /* For some unknown reason, the "atexit()" call in "create_console()" 2064: doesn't arrange that "destroy_console()" be called when we exit, 2065: so we call it here if a console was created. */ 2066: if (console_was_created) 2067: destroy_console(); 2068: #endif 2069: 2070: gtk_exit(0); 2071: 2072: /* This isn't reached, but we need it to keep GCC from complaining 2073: that "main()" returns without returning a value - it knows that 2074: "exit()" never returns, but it doesn't know that "gtk_exit()" 2075: doesn't, as GTK+ doesn't declare it with the attribute 2076: "noreturn". */ 2077: return 0; /* not reached */ 2078: } 2079: 2080: #ifdef WIN32 2081: 2082: /* We build this as a GUI subsystem application on Win32, so 2083: "WinMain()", not "main()", gets called. 2084: 2085: Hack shamelessly stolen from the Win32 port of the GIMP. */ 2086: #ifdef __GNUC__ 2087: #define _stdcall __attribute__((stdcall)) 2088: #endif 2089: 2090: int _stdcall 2091: WinMain (struct HINSTANCE__ *hInstance, 2092: struct HINSTANCE__ *hPrevInstance, 2093: char *lpszCmdLine, 2094: int nCmdShow) 2095: { 2096: has_no_console = TRUE; 2097: return main (__argc, __argv); 2098: } 2099: 2100: /* 2101: * If this application has no console window to which its standard output 2102: * would go, create one. 2103: */ 2104: static void 2105: create_console(void) 2106: { 2107: if (has_no_console) { 2108: /* We have no console to which to print the version string, so 2109: create one and make it the standard input, output, and error. */ 2110: if (!AllocConsole()) 2111: return; /* couldn't create console */ 2112: freopen("CONIN$", "r", stdin); 2113: freopen("CONOUT$", "w", stdout); 2114: freopen("CONOUT$", "w", stderr); 2115: 2116: /* Well, we have a console now. */ 2117: has_no_console = FALSE; 2118: console_was_created = TRUE; 2119: 2120: /* Now register "destroy_console()" as a routine to be called just 2121: before the application exits, so that we can destroy the console 2122: after the user has typed a key (so that the console doesn't just 2123: disappear out from under them, giving the user no chance to see 2124: the message(s) we put in there). */ 2125: atexit(destroy_console); 2126: } 2127: } 2128: 2129: static void 2130: destroy_console(void) 2131: { 2132: printf("\n\nPress any key to exit\n"); 2133: _getch(); 2134: FreeConsole(); 2135: } 2136: 2137: /* This routine should not be necessary, at least as I read the GLib 2138: source code, as it looks as if GLib is, on Win32, *supposed* to 2139: create a console window into which to display its output. 2140: 2141: That doesn't happen, however. I suspect there's something completely 2142: broken about that code in GLib-for-Win32, and that it may be related 2143: to the breakage that forces us to just call "printf()" on the message 2144: rather than passing the message on to "g_log_default_handler()" 2145: (which is the routine that does the aforementioned non-functional 2146: console window creation). */ 2147: static void 2148: console_log_handler(const char *log_domain, GLogLevelFlags log_level, 2149: const char *message, gpointer user_data) 2150: { 2151: create_console(); 2152: if (console_was_created) { 2153: /* For some unknown reason, the above doesn't appear to actually cause 2154: anything to be sent to the standard output, so we'll just splat the 2155: message out directly, just to make sure it gets out. */ 2156: printf("%s\n", message); 2157: } else 2158: g_log_default_handler(log_domain, log_level, message, user_data); 2159: } 2160: #endif 2161: 2162: /* Given a font name, construct the name of the next heavier version of 2163: that font. */ 2164: 2165: #define XLFD_WEIGHT 3 /* index of the "weight" field */ 2166: 2167: /* Map from a given weight to the appropriate weight for the "bold" 2168: version of a font. 2169: XXX - the XLFD says these strings shouldn't be used for font matching; 2170: can we get the weight, as a number, from GDK, and ask GDK to find us 2171: a font just like the given font, but with the appropriate higher 2172: weight? */ 2173: static const struct { 2174: char *light; 2175: char *heavier; 2176: } weight_map[] = { 2177: { "ultralight", "light" }, 2178: { "extralight", "semilight" }, 2179: { "light", "medium" }, 2180: { "semilight", "semibold" }, 2181: { "medium", "bold" }, 2182: { "normal", "bold" }, 2183: { "semibold", "extrabold" }, 2184: { "bold", "ultrabold" } 2185: }; 2186: #define N_WEIGHTS (sizeof weight_map / sizeof weight_map[0]) 2187: 2188: char * 2189: boldify(const char *font_name) 2190: { 2191: char *bold_font_name; 2192: gchar **xlfd_tokens; 2193: unsigned int i; 2194: 2195: /* Is this an XLFD font? If it begins with "-", yes, otherwise no. */ 2196: if (font_name[0] == '-') { 2197: xlfd_tokens = g_strsplit(font_name, "-", XLFD_WEIGHT+1); 2198: 2199: /* 2200: * Make sure we *have* a weight (this might not be a valid 2201: * XLFD font name). 2202: */ 2203: for (i = 0; i < XLFD_WEIGHT+1; i++) { 2204: if (xlfd_tokens[i] == NULL) { 2205: /* 2206: * We don't, so treat this as a non-XLFD 2207: * font name. 2208: */ 2209: goto not_xlfd; 2210: } 2211: } 2212: for (i = 0; i < N_WEIGHTS; i++) { 2213: if (strcmp(xlfd_tokens[XLFD_WEIGHT], 2214: weight_map[i].light) == 0) { 2215: g_free(xlfd_tokens[XLFD_WEIGHT]); 2216: xlfd_tokens[XLFD_WEIGHT] = 2217: g_strdup(weight_map[i].heavier); 2218: break; 2219: } 2220: } 2221: bold_font_name = g_strjoinv("-", xlfd_tokens); 2222: g_strfreev(xlfd_tokens); 2223: return bold_font_name; 2224: } 2225: 2226: not_xlfd: 2227: /* 2228: * This isn't an XLFD font name; just append "bold" to the name 2229: * of the font. 2230: */ 2231: bold_font_name = g_strconcat(font_name, "bold", NULL); 2232: return bold_font_name; 2233: } 2234: 2235: 2236: static void 2237: create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs) 2238: { 2239: GtkWidget *main_vbox, *menubar, *u_pane, *l_pane, 2240: *stat_hbox, *column_lb, 2241: *filter_bt, *filter_cm, *filter_te, 2242: *filter_apply, 2243: *filter_reset; 2244: GList *filter_list = NULL; 2245: GtkAccelGroup *accel; 2246: GtkStyle *win_style; 2247: GdkBitmap *ascend_bm, *descend_bm; 2248: GdkPixmap *ascend_pm, *descend_pm; 2249: column_arrows *col_arrows; 2250: int i; 2251: /* Display filter construct dialog has an Apply button, and "OK" not 2252: only sets our text widget, it activates it (i.e., it causes us to 2253: filter the capture). */ 2254: static construct_args_t args = { 2255: "Ethereal: Display Filter", 2256: TRUE, 2257: TRUE 2258: }; 2259: 2260: /* Main window */ 2261: top_level = gtk_window_new(GTK_WINDOW_TOPLEVEL); 2262: gtk_widget_set_name(top_level, "main window"); 2263: gtk_signal_connect(GTK_OBJECT(top_level), "delete_event", 2264: GTK_SIGNAL_FUNC(main_window_delete_event_cb), NULL); 2265: gtk_signal_connect (GTK_OBJECT (top_level), "realize", 2266: GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL); 2267: gtk_window_set_title(GTK_WINDOW(top_level), "The Ethereal Network Analyzer"); 2268: if (prefs->gui_geometry_save_position) { 2269: gtk_widget_set_uposition(GTK_WIDGET(top_level), 2270: prefs->gui_geometry_main_x, prefs->gui_geometry_main_y); 2271: } 2272: if (prefs->gui_geometry_save_size) { 2273: gtk_widget_set_usize(GTK_WIDGET(top_level), 2274: prefs->gui_geometry_main_width, prefs->gui_geometry_main_height); 2275: } else { 2276: gtk_widget_set_usize(GTK_WIDGET(top_level), DEF_WIDTH, -1); 2277: } 2278: gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE); 2279: 2280: /* Container for menu bar, paned windows and progress/info box */ 2281: main_vbox = gtk_vbox_new(FALSE, 1); 2282: gtk_container_border_width(GTK_CONTAINER(main_vbox), 1); 2283: gtk_container_add(GTK_CONTAINER(top_level), main_vbox); 2284: gtk_widget_show(main_vbox); 2285: 2286: /* Menu bar */ 2287: get_main_menu(&menubar, &accel); 2288: gtk_window_add_accel_group(GTK_WINDOW(top_level), accel); 2289: gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0); 2290: gtk_widget_show(menubar); 2291: 2292: /* Panes for the packet list, tree, and byte view */ 2293: u_pane = gtk_vpaned_new(); 2294: gtk_paned_gutter_size(GTK_PANED(u_pane), (GTK_PANED(u_pane))->handle_size); 2295: l_pane = gtk_vpaned_new(); 2296: gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size); 2297: gtk_container_add(GTK_CONTAINER(main_vbox), u_pane); 2298: gtk_widget_show(l_pane); 2299: gtk_paned_add2(GTK_PANED(u_pane), l_pane); 2300: gtk_widget_show(u_pane); 2301: 2302: /* Packet list */ 2303: pkt_scrollw = scrolled_window_new(NULL, NULL); 2304: gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(pkt_scrollw), 2305: GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 2306: gtk_widget_show(pkt_scrollw); 2307: gtk_paned_add1(GTK_PANED(u_pane), pkt_scrollw); 2308: 2309: packet_list = gtk_clist_new(cfile.cinfo.num_cols); 2310: /* Column titles are filled in below */ 2311: gtk_container_add(GTK_CONTAINER(pkt_scrollw), packet_list); 2312: 2313: col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * cfile.cinfo.num_cols); 2314: 2315: set_plist_sel_browse(prefs->gui_plist_sel_browse); 2316: set_plist_font(m_r_font); 2317: gtk_widget_set_name(packet_list, "packet list"); 2318: gtk_signal_connect (GTK_OBJECT (packet_list), "click_column", 2319: GTK_SIGNAL_FUNC(packet_list_click_column_cb), col_arrows); 2320: gtk_signal_connect(GTK_OBJECT(packet_list), "select_row", 2321: GTK_SIGNAL_FUNC(packet_list_select_cb), NULL); 2322: gtk_signal_connect(GTK_OBJECT(packet_list), "unselect_row", 2323: GTK_SIGNAL_FUNC(packet_list_unselect_cb), NULL); 2324: for (i = 0; i < cfile.cinfo.num_cols; i++) { 2325: if (get_column_resize_type(cfile.cinfo.col_fmt[i]) != RESIZE_MANUAL) 2326: gtk_clist_set_column_auto_resize(GTK_CLIST(packet_list), i, TRUE); 2327: 2328: /* Right-justify the packet number column. */ 2329: if (cfile.cinfo.col_fmt[i] == COL_NUMBER) 2330: gtk_clist_set_column_justification(GTK_CLIST(packet_list), i, 2331: GTK_JUSTIFY_RIGHT); 2332: } 2333: gtk_widget_set_usize(packet_list, -1, pl_size); 2334: gtk_signal_connect(GTK_OBJECT(packet_list), "button_press_event", 2335: GTK_SIGNAL_FUNC(popup_menu_handler), 2336: gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY)); 2337: gtk_signal_connect(GTK_OBJECT(packet_list), "button_press_event", 2338: GTK_SIGNAL_FUNC(packet_list_button_pressed_cb), NULL); 2339: gtk_clist_set_compare_func(GTK_CLIST(packet_list), packet_list_compare); 2340: gtk_widget_show(packet_list); 2341: 2342: /* Tree view */ 2343: item_style = gtk_style_new(); 2344: gdk_font_unref(item_style->font); 2345: item_style->font = m_r_font; 2346: create_tree_view(tv_size, prefs, l_pane, &tv_scrollw, &tree_view); 2347: gtk_signal_connect(GTK_OBJECT(tree_view), "tree-select-row", 2348: GTK_SIGNAL_FUNC(tree_view_select_row_cb), NULL); 2349: gtk_signal_connect(GTK_OBJECT(tree_view), "tree-unselect-row", 2350: GTK_SIGNAL_FUNC(tree_view_unselect_row_cb), NULL); 2351: gtk_signal_connect(GTK_OBJECT(tree_view), "button_press_event", 2352: GTK_SIGNAL_FUNC(popup_menu_handler), 2353: gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY)); 2354: gtk_widget_show(tree_view); 2355: 2356: /* Byte view. */ 2357: byte_nb_ptr = create_byte_view(bv_size, l_pane); 2358: 2359: gtk_signal_connect(GTK_OBJECT(byte_nb_ptr), "button_press_event", 2360: GTK_SIGNAL_FUNC(popup_menu_handler), 2361: gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_HEXDUMP_KEY)); 2362: 2363: /* Filter/info box */ 2364: stat_hbox = gtk_hbox_new(FALSE, 1); 2365: gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0); 2366: gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0); 2367: gtk_widget_show(stat_hbox); 2368: 2369: filter_bt = gtk_button_new_with_label("Filter:"); 2370: gtk_signal_connect(GTK_OBJECT(filter_bt), "clicked", 2371: GTK_SIGNAL_FUNC(display_filter_construct_cb), &args); 2372: gtk_box_pack_start(GTK_BOX(stat_hbox), filter_bt, FALSE, TRUE, 0); 2373: gtk_widget_show(filter_bt); 2374: 2375: filter_cm = gtk_combo_new(); 2376: filter_list = g_list_append (filter_list, ""); 2377: gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), filter_list); 2378: gtk_combo_disable_activate(GTK_COMBO(filter_cm)); 2379: gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE); 2380: gtk_object_set_data(GTK_OBJECT(filter_cm), E_DFILTER_FL_KEY, filter_list); 2381: filter_te = GTK_COMBO(filter_cm)->entry; 2382: gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te); 2383: gtk_object_set_data(GTK_OBJECT(filter_te), E_DFILTER_CM_KEY, filter_cm); 2384: gtk_box_pack_start(GTK_BOX(stat_hbox), filter_cm, TRUE, TRUE, 3); 2385: gtk_signal_connect(GTK_OBJECT(filter_te), "activate", 2386: GTK_SIGNAL_FUNC(filter_activate_cb), filter_te); 2387: gtk_widget_show(filter_cm); 2388: 2389: filter_reset = gtk_button_new_with_label("Reset"); 2390: gtk_object_set_data(GTK_OBJECT(filter_reset), E_DFILTER_TE_KEY, filter_te); 2391: gtk_signal_connect(GTK_OBJECT(filter_reset), "clicked", 2392: GTK_SIGNAL_FUNC(filter_reset_cb), NULL); 2393: gtk_box_pack_start(GTK_BOX(stat_hbox), filter_reset, FALSE, TRUE, 1); 2394: gtk_widget_show(filter_reset); 2395: 2396: filter_apply = gtk_button_new_with_label("Apply"); 2397: gtk_object_set_data(GTK_OBJECT(filter_apply), E_DFILTER_CM_KEY, filter_cm); 2398: gtk_signal_connect(GTK_OBJECT(filter_apply), "clicked", 2399: GTK_SIGNAL_FUNC(filter_activate_cb), filter_te); 2400: gtk_box_pack_start(GTK_BOX(stat_hbox), filter_apply, FALSE, TRUE, 1); 2401: gtk_widget_show(filter_apply); 2402: 2403: /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data 2404: * of any widget that ends up calling a callback which needs 2405: * that text entry pointer */ 2406: set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te); 2407: set_menu_object_data("/File/Reload", E_DFILTER_TE_KEY, filter_te); 2408: set_menu_object_data("/Edit/Filters...", E_FILT_TE_PTR_KEY, filter_te); 2409: set_menu_object_data("/Tools/Follow TCP Stream", E_DFILTER_TE_KEY, filter_te); 2410: set_menu_object_data("/Display/Match/Selected", E_DFILTER_TE_KEY, filter_te); 2411: set_menu_object_data("/Display/Match/Not Selected", E_DFILTER_TE_KEY, filter_te); 2412: set_menu_object_data("/Display/Match/And Selected", E_DFILTER_TE_KEY, filter_te); 2413: set_menu_object_data("/Display/Match/Or Selected", E_DFILTER_TE_KEY, filter_te); 2414: set_menu_object_data("/Display/Match/And Not Selected", E_DFILTER_TE_KEY, filter_te); 2415: set_menu_object_data("/Display/Match/Or Not Selected", E_DFILTER_TE_KEY, filter_te); 2416: set_menu_object_data("/Display/Prepare/Selected", E_DFILTER_TE_KEY, filter_te); 2417: set_menu_object_data("/Display/Prepare/Not Selected", E_DFILTER_TE_KEY, filter_te); 2418: set_menu_object_data("/Display/Prepare/And Selected", E_DFILTER_TE_KEY, filter_te); 2419: set_menu_object_data("/Display/Prepare/Or Selected", E_DFILTER_TE_KEY, filter_te); 2420: set_menu_object_data("/Display/Prepare/And Not Selected", E_DFILTER_TE_KEY, filter_te); 2421: set_menu_object_data("/Display/Prepare/Or Not Selected", E_DFILTER_TE_KEY, filter_te); 2422: gtk_object_set_data(GTK_OBJECT(popup_menu_object), E_DFILTER_TE_KEY, filter_te); 2423: gtk_object_set_data(GTK_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY, packet_list); 2424: 2425: info_bar = gtk_statusbar_new(); 2426: main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main"); 2427: file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file"); 2428: help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help"); 2429: gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE); 2430: gtk_box_pack_start(GTK_BOX(stat_hbox), info_bar, TRUE, TRUE, 0); 2431: gtk_widget_show(info_bar); 2432: 2433: gtk_widget_show(top_level); 2434: 2435: /* Fill in column titles. This must be done after the top level window 2436: is displayed. */ 2437: win_style = gtk_widget_get_style(top_level); 2438: ascend_pm = gdk_pixmap_create_from_xpm_d(top_level->window, &ascend_bm, 2439: &win_style->bg[GTK_STATE_NORMAL], (gchar **)clist_ascend_xpm); 2440: descend_pm = gdk_pixmap_create_from_xpm_d(top_level->window, &descend_bm, 2441: &win_style->bg[GTK_STATE_NORMAL], (gchar **)clist_descend_xpm); 2442: for (i = 0; i < cfile.cinfo.num_cols; i++) { 2443: col_arrows[i].table = gtk_table_new(2, 2, FALSE); 2444: gtk_table_set_col_spacings(GTK_TABLE(col_arrows[i].table), 5); 2445: column_lb = gtk_label_new(cfile.cinfo.col_title[i]); 2446: gtk_table_attach(GTK_TABLE(col_arrows[i].table), column_lb, 0, 1, 0, 2, 2447: GTK_SHRINK, GTK_SHRINK, 0, 0); 2448: gtk_widget_show(column_lb); 2449: col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm); 2450: gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm, 2451: 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0); 2452: if (i == 0) { 2453: gtk_widget_show(col_arrows[i].ascend_pm); 2454: } 2455: col_arrows[i].descend_pm = gtk_pixmap_new(descend_pm, descend_bm); 2456: gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].descend_pm, 2457: 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); 2458: gtk_clist_set_column_widget(GTK_CLIST(packet_list), i, col_arrows[i].table); 2459: gtk_widget_show(col_arrows[i].table); 2460: } 2461: gtk_clist_column_titles_show(GTK_CLIST(packet_list)); 2462: } 2463: 2464: 2465: void 2466: set_last_open_dir(char *dirname) 2467: { 2468: int len; 2469: 2470: if (last_open_dir) { 2471: g_free(last_open_dir); 2472: } 2473: 2474: if (dirname) { 2475: len = strlen(dirname); 2476: if (dirname[len-1] != G_DIR_SEPARATOR) { 2477: last_open_dir = g_strconcat(dirname, G_DIR_SEPARATOR_S, 2478: NULL); 2479: } 2480: } 2481: else { 2482: last_open_dir = NULL; 2483: } 2484: } 2485: |
- Follow-Ups:
- Re: [Ethereal-dev] Unhandled exception...
- From: Ashok Narayanan
- Re: [Ethereal-dev] Unhandled exception...
- Prev by Date: RE: [Ethereal-dev] Wireless packet captured
- Next by Date: Re: [Ethereal-dev] Unhandled exception...
- Previous by thread: Re: [Ethereal-dev] Unhandled exception...
- Next by thread: Re: [Ethereal-dev] Unhandled exception...
- Index(es):