5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
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
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.
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.
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.
34 #include <gdk/gdkkeysyms.h>
43 #ifdef NEED_STRERROR_H
51 #ifdef _WIN32 /* Needed for console I/O */
56 #ifdef HAVE_LIBPORTAUDIO
57 #include <portaudio.h>
58 #endif /* HAVE_LIBPORTAUDIO */
60 #include <epan/epan.h>
61 #include <epan/filesystem.h>
62 #include <epan/privileges.h>
63 #include <epan/epan_dissect.h>
64 #include <epan/timestamp.h>
65 #include <epan/packet.h>
66 #include <epan/plugins.h>
67 #include <epan/dfilter/dfilter.h>
68 #include <epan/strutil.h>
69 #include <epan/addr_resolv.h>
70 #include <epan/emem.h>
71 #include <epan/ex-opt.h>
72 #include <epan/funnel.h>
73 #include <epan/expert.h>
74 #include <epan/frequency-utils.h>
75 #include <epan/prefs.h>
76 #include <epan/prefs-int.h>
78 #include <epan/stat_cmd_args.h>
80 #include <epan/emem.h>
81 #include <epan/column.h>
83 /* general (not GTK specific) */
85 #include "../summary.h"
86 #include "../filters.h"
87 #include "../disabled_protos.h"
89 #include "../color_filters.h"
91 #include "../simple_dialog.h"
92 #include "../register.h"
93 #include "../ringbuffer.h"
94 #include "../ui_util.h"
96 #include "../clopts_common.h"
97 #include "../cmdarg_err.h"
98 #include "../version_info.h"
100 #include "../alert_box.h"
101 #include "../capture_ui_utils.h"
103 #include <wsutil/file_util.h>
107 #include "../capture-pcap-util.h"
108 #include "../capture.h"
109 #include "../capture_sync.h"
113 #include "../capture-wpcap.h"
114 #include "../capture_wpcap_packet.h"
115 #include <tchar.h> /* Needed for Unicode */
116 #include <commctrl.h>
120 #include "gtk/file_dlg.h"
121 #include "gtk/gtkglobals.h"
122 #include "gtk/color_utils.h"
123 #include "gtk/gui_utils.h"
124 #include "gtk/color_dlg.h"
125 #include "gtk/filter_dlg.h"
126 #include "gtk/uat_gui.h"
128 #include "gtk/main.h"
129 #include "gtk/main_airpcap_toolbar.h"
130 #include "gtk/main_filter_toolbar.h"
131 #include "gtk/main_menu.h"
132 #include "gtk/main_packet_list.h"
133 #include "gtk/main_statusbar.h"
134 #include "gtk/main_toolbar.h"
135 #include "gtk/main_welcome.h"
136 #include "gtk/drag_and_drop.h"
137 #include "gtk/capture_file_dlg.h"
138 #include "gtk/main_proto_draw.h"
139 #include "gtk/keys.h"
140 #include "gtk/packet_win.h"
141 #include "gtk/stock_icons.h"
142 #include "gtk/find_dlg.h"
143 #include "gtk/recent.h"
144 #include "gtk/follow_tcp.h"
145 #include "gtk/font_utils.h"
146 #include "gtk/about_dlg.h"
147 #include "gtk/help_dlg.h"
148 #include "gtk/decode_as_dlg.h"
149 #include "gtk/webbrowser.h"
150 #include "gtk/capture_dlg.h"
151 #include "gtk/tap_dfilter_dlg.h"
154 #include "../image/wsicon16.xpm"
155 #include "../image/wsicon32.xpm"
156 #include "../image/wsicon48.xpm"
157 #include "../image/wsicon64.xpm"
158 #include "../image/wsiconcap16.xpm"
159 #include "../image/wsiconcap32.xpm"
160 #include "../image/wsiconcap48.xpm"
165 #include "airpcap_loader.h"
166 #include "airpcap_dlg.h"
167 #include "airpcap_gui_utils.h"
169 #include "./image/toolbar/wep_closed_24.xpm"
173 #include <epan/crypt/airpdcap_ws.h>
178 * Files under personal and global preferences directories in which
179 * GTK settings for Wireshark are stored.
181 #define RC_FILE "gtkrc"
185 /* "exported" main widgets */
186 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view, *byte_nb_ptr;
188 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
189 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
190 static GtkWidget *main_first_pane, *main_second_pane;
192 /* internally used widgets */
193 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
196 GtkWidget *airpcap_tb;
197 int airpcap_dll_ret_val = -1;
200 GString *comp_info_str, *runtime_info_str;
201 gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
203 guint tap_update_timer_id;
206 static gboolean has_console; /* TRUE if app has console */
207 static void destroy_console(void);
209 static void console_log_handler(const char *log_domain,
210 GLogLevelFlags log_level, const char *message, gpointer user_data);
213 capture_options global_capture_opts;
214 capture_options *capture_opts = &global_capture_opts;
218 static void create_main_window(gint, gint, gint, e_prefs*);
219 static void show_main_window(gboolean);
220 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
221 static void main_save_window_geometry(GtkWidget *widget);
224 /* Match selected byte pattern */
226 match_selected_cb_do(gpointer data, int action, gchar *text)
228 GtkWidget *filter_te;
229 char *cur_filter, *new_filter;
231 if ((!text) || (0 == strlen(text))) {
232 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
237 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
240 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
242 switch (action&MATCH_SELECTED_MASK) {
244 case MATCH_SELECTED_REPLACE:
245 new_filter = g_strdup(text);
248 case MATCH_SELECTED_AND:
249 if ((!cur_filter) || (0 == strlen(cur_filter)))
250 new_filter = g_strdup(text);
252 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
255 case MATCH_SELECTED_OR:
256 if ((!cur_filter) || (0 == strlen(cur_filter)))
257 new_filter = g_strdup(text);
259 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
262 case MATCH_SELECTED_NOT:
263 new_filter = g_strconcat("!(", text, ")", NULL);
266 case MATCH_SELECTED_AND_NOT:
267 if ((!cur_filter) || (0 == strlen(cur_filter)))
268 new_filter = g_strconcat("!(", text, ")", NULL);
270 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
273 case MATCH_SELECTED_OR_NOT:
274 if ((!cur_filter) || (0 == strlen(cur_filter)))
275 new_filter = g_strconcat("!(", text, ")", NULL);
277 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
281 g_assert_not_reached();
286 /* Free up the copy we got of the old filter text. */
289 /* Don't change the current display filter if we only want to copy the filter */
290 if (action&MATCH_SELECTED_COPY_ONLY) {
291 GString *gtk_text_str = g_string_new("");
292 g_string_append_printf(gtk_text_str, "%s", new_filter);
293 copy_to_clipboard(gtk_text_str);
294 g_string_free(gtk_text_str, TRUE);
296 /* create a new one and set the display filter entry accordingly */
297 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
299 /* Run the display filter so it goes in effect. */
300 if (action&MATCH_SELECTED_APPLY_NOW)
301 main_filter_packets(&cfile, new_filter, FALSE);
304 /* Free up the new filter text. */
309 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
313 if (cfile.finfo_selected) {
314 filter = proto_construct_match_selected_string(cfile.finfo_selected,
316 match_selected_cb_do((data ? data : w), action, filter);
321 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
325 if (cfile.finfo_selected) {
326 filter = proto_construct_match_selected_string(cfile.finfo_selected,
328 if ((!filter) || (0 == strlen(filter))) {
329 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
330 "Could not acquire information to build a filter!\n"
331 "Try expanding or choosing another item.");
336 color_display_with_filter(filter);
339 color_filters_reset_tmp();
341 color_filters_set_tmp(filt_nr,filter, FALSE);
343 cf_colorize_packets(&cfile);
349 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
351 gchar *selected_proto_url;
352 gchar *proto_abbrev = data;
357 if (cfile.finfo_selected) {
358 /* open wiki page using the protocol abbreviation */
359 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
360 browser_open_url(selected_proto_url);
361 g_free(selected_proto_url);
364 case(ESD_BTN_CANCEL):
367 g_assert_not_reached();
373 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
376 const gchar *proto_abbrev;
380 if (cfile.finfo_selected) {
381 /* convert selected field to protocol abbreviation */
382 /* XXX - could this conversion be simplified? */
383 field_id = cfile.finfo_selected->hfinfo->id;
384 /* if the selected field isn't a protocol, get it's parent */
385 if(!proto_registrar_is_protocol(field_id)) {
386 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
389 proto_abbrev = proto_registrar_get_abbrev(field_id);
391 /* ask the user if the wiki page really should be opened */
392 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
393 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
395 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
397 "The Wireshark Wiki is a collaborative approach to provide information\n"
398 "about Wireshark in several ways (not limited to protocol specifics).\n"
400 "This Wiki is new, so the page of the selected protocol\n"
401 "may not exist and/or may not contain valuable information.\n"
403 "As everyone can edit the Wiki and add new content (or extend existing),\n"
404 "you are encouraged to add information if you can.\n"
406 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
408 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate,\n"
409 "which will save you a lot of editing and will give a consistent look over the pages.",
410 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
411 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer) proto_abbrev);
417 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
420 const gchar *proto_abbrev;
421 gchar *selected_proto_url;
424 if (cfile.finfo_selected) {
425 /* convert selected field to protocol abbreviation */
426 /* XXX - could this conversion be simplified? */
427 field_id = cfile.finfo_selected->hfinfo->id;
428 /* if the selected field isn't a protocol, get it's parent */
429 if(!proto_registrar_is_protocol(field_id)) {
430 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
433 proto_abbrev = proto_registrar_get_abbrev(field_id);
435 /* open reference page using the protocol abbreviation */
436 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s.html", proto_abbrev[0], proto_abbrev);
437 browser_open_url(selected_proto_url);
438 g_free(selected_proto_url);
443 get_text_from_packet_list(gpointer data)
445 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
446 gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
447 frame_data *fdata = (frame_data *)packet_list_get_row_data(row);
449 if(strlen(fdata->col_expr.col_expr[column]) != 0 &&
450 strlen(fdata->col_expr.col_expr_val[column]) != 0)
451 return ep_strdup_printf("%s == %s",
452 fdata->col_expr.col_expr[column],
453 fdata->col_expr.col_expr_val[column]);
459 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
461 match_selected_cb_do(data,
463 get_text_from_packet_list(data));
466 /* This function allows users to right click in the details window and copy the text
467 * information to the operating systems clipboard.
469 * We first check to see if a string representation is setup in the tree and then
470 * read the string. If not available then we try to grab the value. If all else
471 * fails we display a message to the user to indicate the copy could not be completed.
474 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_)
476 GString *gtk_text_str = g_string_new("");
477 char labelstring[256];
478 char *stringpointer = labelstring;
480 if (cfile.finfo_selected->rep->representation != 0) {
481 g_string_append_printf(gtk_text_str, "%s", cfile.finfo_selected->rep->representation); /* Get the represented data */
483 if (gtk_text_str->len == 0) { /* If no representation then... */
484 proto_item_fill_label(cfile.finfo_selected, stringpointer); /* Try to read the value */
485 g_string_append_printf(gtk_text_str, "%s", stringpointer);
487 if (gtk_text_str->len == 0) { /* Could not get item so display error msg */
488 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
492 copy_to_clipboard(gtk_text_str); /* Copy string to clipboard */
494 g_string_free(gtk_text_str, TRUE); /* Free the memory */
498 /* mark as reference time frame */
500 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
504 frame->flags.ref_time=1;
506 frame->flags.ref_time=0;
508 cf_reftime_packets(&cfile);
512 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
516 timestamp_set_type(TS_RELATIVE);
517 recent.gui_time_format = TS_RELATIVE;
518 cf_change_time_formats(&cfile);
523 g_assert_not_reached();
526 if (cfile.current_frame) {
527 /* XXX hum, should better have a "cfile->current_row" here ... */
528 set_frame_reftime(!cfile.current_frame->flags.ref_time,
530 packet_list_find_row_from_data(cfile.current_frame));
536 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
538 static GtkWidget *reftime_dialog = NULL;
542 if (cfile.current_frame) {
543 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
544 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
545 "%sSwitch to the appropriate Time Display Format?%s\n\n"
546 "Time References don't work well with the currently selected Time Display Format.\n\n"
547 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
548 simple_dialog_primary_start(), simple_dialog_primary_end());
549 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
551 /* XXX hum, should better have a "cfile->current_row" here ... */
552 set_frame_reftime(!cfile.current_frame->flags.ref_time,
554 packet_list_find_row_from_data(cfile.current_frame));
558 case REFTIME_FIND_NEXT:
559 find_previous_next_frame_with_filter("frame.ref_time", FALSE);
561 case REFTIME_FIND_PREV:
562 find_previous_next_frame_with_filter("frame.ref_time", TRUE);
568 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
570 find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
574 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
576 find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
580 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
583 gchar *help_str = NULL;
584 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
586 gboolean has_blurb = FALSE;
587 guint length = 0, byte_len;
588 GtkWidget *byte_view;
589 const guint8 *byte_data;
594 /* if nothing is selected */
595 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
598 * Which byte view is displaying the current protocol tree
601 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
602 if (byte_view == NULL)
605 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
606 if (byte_data == NULL)
609 cf_unselect_field(&cfile);
610 packet_hex_print(byte_view, byte_data,
611 cfile.current_frame, NULL, byte_len);
614 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
617 set_notebook_page(byte_nb_ptr, finfo->ds_tvb);
619 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
620 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
621 g_assert(byte_data != NULL);
623 cfile.finfo_selected = finfo;
624 set_menus_for_selected_tree_row(&cfile);
627 if (finfo->hfinfo->blurb != NULL &&
628 finfo->hfinfo->blurb[0] != '\0') {
630 length = strlen(finfo->hfinfo->blurb);
632 length = strlen(finfo->hfinfo->name);
634 finfo_length = finfo->length + finfo->appendix_length;
636 if (finfo_length == 0) {
638 } else if (finfo_length == 1) {
639 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
641 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
643 statusbar_pop_field_msg(); /* get rid of current help msg */
645 help_str = g_strdup_printf(" %s (%s)%s",
646 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
647 finfo->hfinfo->abbrev, len_str);
648 statusbar_push_field_msg(help_str);
652 * Don't show anything if the field name is zero-length;
653 * the pseudo-field for "proto_tree_add_text()" is such
654 * a field, and we don't want "Text (text)" showing up
655 * on the status line if you've selected such a field.
657 * XXX - there are zero-length fields for which we *do*
658 * want to show the field name.
660 * XXX - perhaps the name and abbrev field should be null
661 * pointers rather than null strings for that pseudo-field,
662 * but we'd have to add checks for null pointers in some
663 * places if we did that.
665 * Or perhaps protocol tree items added with
666 * "proto_tree_add_text()" should have -1 as the field index,
667 * with no pseudo-field being used, but that might also
668 * require special checks for -1 to be added.
670 statusbar_push_field_msg("");
673 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
677 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
679 collapse_all_tree(cfile.edt->tree, tree_view);
682 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
684 expand_all_tree(cfile.edt->tree, tree_view);
687 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
690 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view), cfile.finfo_selected);
692 /* the mouse position is at an entry, expand that one */
693 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view), path, TRUE);
694 gtk_tree_path_free(path);
698 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
699 if (cfile.edt->tree) {
700 guint32 tmp = g_resolv_flags;
701 g_resolv_flags = RESOLV_ALL;
702 proto_tree_draw(cfile.edt->tree, tree_view);
703 g_resolv_flags = tmp;
708 main_set_for_capture_file(gboolean have_capture_file_in)
710 have_capture_file = have_capture_file_in;
712 main_widgets_show_or_hide();
718 /* get the current geometry, before writing it to disk */
719 main_save_window_geometry(top_level);
721 /* write user's recent file to disk
722 * It is no problem to write this file, even if we do not quit */
723 write_profile_recent();
726 /* XXX - should we check whether the capture file is an
727 unsaved temporary file for a live capture and, if so,
728 pop up a "do you want to exit without saving the capture
729 file?" dialog, and then just return, leaving said dialog
730 box to forcibly quit if the user clicks "OK"?
732 If so, note that this should be done in a subroutine that
733 returns TRUE if we do so, and FALSE otherwise, and if it
734 returns TRUE we should return TRUE without nuking anything.
736 Note that, if we do that, we might also want to check if
737 an "Update list of packets in real time" capture is in
738 progress and, if so, ask whether they want to terminate
739 the capture and discard it, and return TRUE, before nuking
740 any child capture, if they say they don't want to do so. */
743 /* Nuke any child capture in progress. */
744 capture_kill_child(capture_opts);
747 /* Are we in the middle of reading a capture? */
748 if (cfile.state == FILE_READ_IN_PROGRESS) {
749 /* Yes, so we can't just close the file and quit, as
750 that may yank the rug out from under the read in
751 progress; instead, just set the state to
752 "FILE_READ_ABORTED" and return - the code doing the read
753 will check for that and, if it sees that, will clean
755 cfile.state = FILE_READ_ABORTED;
757 /* Say that the window should *not* be deleted;
758 that'll be done by the code that cleans up. */
761 /* Close any capture file we have open; on some OSes, you
762 can't unlink a temporary capture file if you have it
764 "cf_close()" will unlink it after closing it if
765 it's a temporary file.
767 We do this here, rather than after the main loop returns,
768 as, after the main loop returns, the main window may have
769 been destroyed (if this is called due to a "destroy"
770 even on the main window rather than due to the user
771 selecting a menu item), and there may be a crash
772 or other problem when "cf_close()" tries to
773 clean up stuff in the main window.
775 XXX - is there a better place to put this?
776 Or should we have a routine that *just* closes the
777 capture file, and doesn't do anything with the UI,
778 which we'd call here, and another routine that
779 calls that routine and also cleans up the UI, which
780 we'd call elsewhere? */
783 /* Exit by leaving the main loop, so that any quit functions
784 we registered get called. */
787 /* Say that the window should be deleted. */
793 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
797 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
798 gtk_window_present(GTK_WINDOW(top_level));
799 /* user didn't saved his current file, ask him */
800 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
801 "%sSave capture file before program quit?%s\n\n"
802 "If you quit the program without saving, your capture data will be discarded.",
803 simple_dialog_primary_start(), simple_dialog_primary_end());
804 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
807 /* unchanged file, just exit */
808 /* "main_do_quit()" indicates whether the main window should be deleted. */
809 return main_do_quit();
815 main_pane_load_window_geometry(void)
817 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
818 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
819 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
820 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
826 main_load_window_geometry(GtkWidget *widget)
828 window_geometry_t geom;
830 geom.set_pos = prefs.gui_geometry_save_position;
831 geom.x = recent.gui_geometry_main_x;
832 geom.y = recent.gui_geometry_main_y;
833 geom.set_size = prefs.gui_geometry_save_size;
834 if (recent.gui_geometry_main_width > 0 &&
835 recent.gui_geometry_main_height > 0) {
836 geom.width = recent.gui_geometry_main_width;
837 geom.height = recent.gui_geometry_main_height;
838 geom.set_maximized = prefs.gui_geometry_save_maximized;
840 /* We assume this means the width and height weren't set in
841 the "recent" file (or that there is no "recent" file),
842 and weren't set to a default value, so we don't set the
843 size. (The "recent" file code rejects non-positive width
844 and height values.) */
845 geom.set_size = FALSE;
847 geom.maximized = recent.gui_geometry_main_maximized;
849 window_set_geometry(widget, &geom);
851 main_pane_load_window_geometry();
852 statusbar_load_window_geometry();
857 main_save_window_geometry(GtkWidget *widget)
859 window_geometry_t geom;
861 window_get_geometry(widget, &geom);
863 if (prefs.gui_geometry_save_position) {
864 recent.gui_geometry_main_x = geom.x;
865 recent.gui_geometry_main_y = geom.y;
868 if (prefs.gui_geometry_save_size) {
869 recent.gui_geometry_main_width = geom.width;
870 recent.gui_geometry_main_height = geom.height;
873 if(prefs.gui_geometry_save_maximized) {
874 recent.gui_geometry_main_maximized = geom.maximized;
877 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
878 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
879 statusbar_save_window_geometry();
882 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
886 /* save file first */
887 file_save_as_cmd(after_save_exit, NULL);
889 case(ESD_BTN_DONT_SAVE):
892 case(ESD_BTN_CANCEL):
895 g_assert_not_reached();
900 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
904 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
905 /* user didn't saved his current file, ask him */
906 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
907 "%sSave capture file before program quit?%s\n\n"
908 "If you quit the program without saving, your capture data will be discarded.",
909 simple_dialog_primary_start(), simple_dialog_primary_end());
910 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
912 /* unchanged file, just exit */
918 print_usage(gboolean print_ver) {
928 fprintf(output, "Wireshark " VERSION "%s\n"
929 "Interactively dump and analyze network traffic.\n"
930 "See http://www.wireshark.org for more information.\n"
933 wireshark_svnversion, get_copyright_info());
937 fprintf(output, "\n");
938 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
939 fprintf(output, "\n");
942 fprintf(output, "Capture interface:\n");
943 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
944 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
945 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
946 fprintf(output, " -p don't capture in promiscuous mode\n");
947 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
948 fprintf(output, " -Q quit Wireshark after capturing\n");
949 fprintf(output, " -S update packet display when new packets are captured\n");
950 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
952 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
954 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
955 fprintf(output, " -D print list of interfaces and exit\n");
956 fprintf(output, " -L print list of link-layer types of iface and exit\n");
957 fprintf(output, "\n");
958 fprintf(output, "Capture stop conditions:\n");
959 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
960 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
961 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
962 fprintf(output, " files:NUM - stop after NUM files\n");
963 /*fprintf(output, "\n");*/
964 fprintf(output, "Capture output:\n");
965 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
966 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
967 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
968 #endif /* HAVE_LIBPCAP */
970 /*fprintf(output, "\n");*/
971 fprintf(output, "Input file:\n");
972 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
974 fprintf(output, "\n");
975 fprintf(output, "Processing:\n");
976 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
977 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
978 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
980 fprintf(output, "\n");
981 fprintf(output, "User interface:\n");
982 fprintf(output, " -C <config profile> start with specified configuration profile\n");
983 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
984 fprintf(output, " -m <font> set the font name used for most text\n");
985 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
986 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
987 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
989 fprintf(output, "\n");
990 fprintf(output, "Output:\n");
991 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
993 fprintf(output, "\n");
994 fprintf(output, "Miscellaneous:\n");
995 fprintf(output, " -h display this help and exit\n");
996 fprintf(output, " -v display version info and exit\n");
997 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
998 fprintf(output, " persdata:path - personal data files\n");
999 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1001 fprintf(output, " --display=DISPLAY X display to use\n");
1016 printf(PACKAGE " " VERSION "%s\n"
1023 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1024 runtime_info_str->str);
1032 * Report an error in command-line arguments.
1033 * Creates a console on Windows.
1034 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1035 * terminal isn't the standard error?
1038 cmdarg_err(const char *fmt, ...)
1046 fprintf(stderr, "wireshark: ");
1047 vfprintf(stderr, fmt, ap);
1048 fprintf(stderr, "\n");
1053 * Report additional information for an error in command-line arguments.
1054 * Creates a console on Windows.
1055 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1056 * terminal isn't the standard error?
1059 cmdarg_err_cont(const char *fmt, ...)
1067 vfprintf(stderr, fmt, ap);
1068 fprintf(stderr, "\n");
1072 #if defined(_WIN32) || ! defined USE_THREADS
1074 Once every 3 seconds we get a callback here which we use to update
1075 the tap extensions. Since Gtk1 is single threaded we dont have to
1076 worry about any locking or critical regions.
1079 update_cb(gpointer data _U_)
1081 draw_tap_listeners(FALSE);
1085 /* Restart the tap update display timer with new configured interval */
1086 void reset_tap_update_timer(void)
1088 #if defined(_WIN32) || ! defined USE_THREADS
1089 gtk_timeout_remove(tap_update_timer_id);
1090 tap_update_timer_id = gtk_timeout_add(prefs.tap_update_interval, (GtkFunction)update_cb,(gpointer)NULL);
1096 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1097 use threads all update_thread_mutex can be dropped and protect/unprotect
1098 would just be empty functions.
1100 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1101 gtk1-wireshark and it will just work.
1103 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1105 update_thread(gpointer data _U_)
1109 g_get_current_time(&tv1);
1110 g_static_mutex_lock(&update_thread_mutex);
1111 gdk_threads_enter();
1112 draw_tap_listeners(FALSE);
1113 gdk_threads_leave();
1114 g_static_mutex_unlock(&update_thread_mutex);
1116 g_get_current_time(&tv2);
1118 /* Assuming it took less than configured time to update tap listeners... */
1119 if( (tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) >
1120 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1121 /* Wait for remainder of configured time */
1122 g_usleep((tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) -
1123 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1130 protect_thread_critical_region(void)
1132 #if !defined(_WIN32) && defined USE_THREADS
1133 g_static_mutex_lock(&update_thread_mutex);
1137 unprotect_thread_critical_region(void)
1139 #if !defined(_WIN32) && defined USE_THREADS
1140 g_static_mutex_unlock(&update_thread_mutex);
1144 /* Set the file name in the name for the main window and in the name for the main window's icon. */
1146 set_display_filename(capture_file *cf)
1150 if (!cf->is_tempfile && cf->filename) {
1151 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1152 add_menu_recent_capture_file(cf->filename);
1156 win_name = g_strdup_printf("%s - Wireshark", cf_get_display_name(cf));
1157 set_main_window_name(win_name);
1161 GtkWidget *close_dlg = NULL;
1164 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1166 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1171 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1173 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1178 main_cf_cb_file_closing(capture_file *cf)
1181 /* if we have more than 10000 packets, show a splash screen while closing */
1182 /* XXX - don't know a better way to decide wether to show or not,
1183 * as most of the time is spend in a single eth_clist_clear function,
1184 * so we can't use a progress bar here! */
1185 if(cf->count > 10000) {
1186 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1187 "%sClosing file!%s\n\nPlease wait ...",
1188 simple_dialog_primary_start(),
1189 simple_dialog_primary_end());
1190 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1193 /* Destroy all windows, which refer to the
1194 capture file we're closing. */
1195 destroy_packet_wins();
1196 file_save_as_destroy();
1198 /* Restore the standard title bar message. */
1199 set_main_window_name("The Wireshark Network Analyzer");
1201 /* Disable all menu items that make sense only if you have a capture. */
1202 set_menus_for_capture_file(NULL);
1203 set_menus_for_captured_packets(FALSE);
1204 set_menus_for_selected_packet(cf);
1205 set_menus_for_capture_in_progress(FALSE);
1206 set_capture_if_dialog_for_capture_in_progress(FALSE);
1207 set_menus_for_selected_tree_row(cf);
1209 /* Set up main window for no capture file. */
1210 main_set_for_capture_file(FALSE);
1212 main_window_update();
1216 main_cf_cb_file_closed(capture_file *cf _U_)
1218 if(close_dlg != NULL) {
1219 splash_destroy(close_dlg);
1226 main_cf_cb_file_read_start(capture_file *cf _U_)
1228 tap_dfilter_dlg_update();
1230 /* Set up main window for a capture file. */
1231 main_set_for_capture_file(TRUE);
1235 main_cf_cb_file_read_finished(capture_file *cf)
1237 set_display_filename(cf);
1239 /* Enable menu items that make sense if you have a capture file you've
1240 finished reading. */
1241 set_menus_for_capture_file(cf);
1243 /* Enable menu items that make sense if you have some captured packets. */
1244 set_menus_for_captured_packets(TRUE);
1247 GList *icon_list_create(
1248 const char **icon16_xpm,
1249 const char **icon32_xpm,
1250 const char **icon48_xpm,
1251 const char **icon64_xpm)
1253 GList *icon_list = NULL;
1254 GdkPixbuf * pixbuf16;
1255 GdkPixbuf * pixbuf32;
1256 GdkPixbuf * pixbuf48;
1257 GdkPixbuf * pixbuf64;
1260 if(icon16_xpm != NULL) {
1261 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1263 icon_list = g_list_append(icon_list, pixbuf16);
1266 if(icon32_xpm != NULL) {
1267 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1269 icon_list = g_list_append(icon_list, pixbuf32);
1272 if(icon48_xpm != NULL) {
1273 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1275 icon_list = g_list_append(icon_list, pixbuf48);
1278 if(icon64_xpm != NULL) {
1279 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1281 icon_list = g_list_append(icon_list, pixbuf64);
1289 main_cf_cb_live_capture_prepared(capture_options *capture_opts)
1292 static GList *icon_list = NULL;
1295 if(capture_opts->iface) {
1296 title = g_strdup_printf("%s: Capturing - Wireshark",
1297 get_iface_description(capture_opts));
1299 title = g_strdup_printf("Capturing - Wireshark");
1301 set_main_window_name(title);
1304 if(icon_list == NULL) {
1305 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1307 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1309 /* Disable menu items that make no sense if you're currently running
1311 set_menus_for_capture_in_progress(TRUE);
1312 set_capture_if_dialog_for_capture_in_progress(TRUE);
1314 /* Don't set up main window for a capture file. */
1315 main_set_for_capture_file(FALSE);
1319 main_cf_cb_live_capture_update_started(capture_options *capture_opts)
1323 /* We've done this in "prepared" above, but it will be cleared while
1324 switching to the next multiple file. */
1325 if(capture_opts->iface) {
1326 title = g_strdup_printf("%s: Capturing - Wireshark",
1327 get_iface_description(capture_opts));
1329 title = g_strdup_printf("Capturing - Wireshark");
1331 set_main_window_name(title);
1334 set_menus_for_capture_in_progress(TRUE);
1335 set_capture_if_dialog_for_capture_in_progress(TRUE);
1337 /* Enable menu items that make sense if you have some captured
1338 packets (yes, I know, we don't have any *yet*). */
1339 set_menus_for_captured_packets(TRUE);
1341 /* Set up main window for a capture file. */
1342 main_set_for_capture_file(TRUE);
1346 main_cf_cb_live_capture_update_finished(capture_file *cf)
1348 static GList *icon_list = NULL;
1350 set_display_filename(cf);
1352 /* Enable menu items that make sense if you're not currently running
1354 set_menus_for_capture_in_progress(FALSE);
1355 set_capture_if_dialog_for_capture_in_progress(FALSE);
1357 /* Enable menu items that make sense if you have a capture file
1358 you've finished reading. */
1359 set_menus_for_capture_file(cf);
1361 /* Set up main window for a capture file. */
1362 main_set_for_capture_file(TRUE);
1364 if(icon_list == NULL) {
1365 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1367 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1369 if(capture_opts->quit_after_cap) {
1370 /* command line asked us to quit after the capture */
1371 /* don't pop up a dialog to ask for unsaved files etc. */
1377 main_cf_cb_live_capture_fixed_started(capture_options *capture_opts _U_)
1379 /* Don't set up main window for a capture file. */
1380 main_set_for_capture_file(FALSE);
1384 main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_)
1386 static GList *icon_list = NULL;
1388 /*set_display_filename(cf);*/
1390 /* Enable menu items that make sense if you're not currently running
1392 set_menus_for_capture_in_progress(FALSE);
1393 set_capture_if_dialog_for_capture_in_progress(FALSE);
1395 /* Restore the standard title bar message */
1396 /* (just in case we have trouble opening the capture file). */
1397 set_main_window_name("The Wireshark Network Analyzer");
1399 if(icon_list == NULL) {
1400 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1402 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1404 /* We don't have loaded the capture file, this will be done later.
1405 * For now we still have simply a blank screen. */
1407 if(capture_opts->quit_after_cap) {
1408 /* command line asked us to quit after the capture */
1409 /* don't pop up a dialog to ask for unsaved files etc. */
1414 #endif /* HAVE_LIBPCAP */
1417 main_cf_cb_packet_selected(gpointer data)
1419 capture_file *cf = data;
1421 /* Display the GUI protocol tree and hex dump.
1422 XXX - why do we dump core if we call "proto_tree_draw()"
1423 before calling "add_byte_views()"? */
1424 add_main_byte_views(cf->edt);
1425 main_proto_tree_draw(cf->edt->tree);
1427 /* The user is searching for a string in the data or a hex value,
1428 * highlight the field that is found in the tree and hex displays. */
1429 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1430 highlight_field(cf->edt->tvb, cfile.search_pos,
1431 (GtkTreeView *)tree_view, cf->edt->tree);
1432 cfile.search_pos = 0; /* Reset the position */
1435 /* A packet is selected. */
1436 set_menus_for_selected_packet(cf);
1440 main_cf_cb_packet_unselected(capture_file *cf)
1442 /* Clear out the display of that packet. */
1443 clear_tree_and_hex_views();
1445 /* No packet is selected. */
1446 set_menus_for_selected_packet(cf);
1450 main_cf_cb_field_unselected(capture_file *cf)
1452 set_menus_for_selected_tree_row(cf);
1456 main_cf_cb_file_safe_reload_finished(gpointer data _U_)
1458 set_menus_for_capture_file(&cfile);
1462 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1465 case(cf_cb_file_closing):
1466 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1467 main_cf_cb_file_closing(data);
1469 case(cf_cb_file_closed):
1470 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1471 main_cf_cb_file_closed(data);
1473 case(cf_cb_file_read_start):
1474 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read start");
1475 main_cf_cb_file_read_start(data);
1477 case(cf_cb_file_read_finished):
1478 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1479 main_cf_cb_file_read_finished(data);
1482 case(cf_cb_live_capture_prepared):
1483 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1484 main_cf_cb_live_capture_prepared(data);
1486 case(cf_cb_live_capture_update_started):
1487 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1488 main_cf_cb_live_capture_update_started(data);
1490 case(cf_cb_live_capture_update_continue):
1491 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1493 case(cf_cb_live_capture_update_finished):
1494 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1495 main_cf_cb_live_capture_update_finished(data);
1497 case(cf_cb_live_capture_fixed_started):
1498 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1499 main_cf_cb_live_capture_fixed_started(data);
1501 case(cf_cb_live_capture_fixed_continue):
1502 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1504 case(cf_cb_live_capture_fixed_finished):
1505 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1506 main_cf_cb_live_capture_fixed_finished(data);
1508 case(cf_cb_live_capture_stopping):
1509 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1510 /* Beware: this state won't be called, if the capture child
1511 * closes the capturing on it's own! */
1514 case(cf_cb_packet_selected):
1515 main_cf_cb_packet_selected(data);
1517 case(cf_cb_packet_unselected):
1518 main_cf_cb_packet_unselected(data);
1520 case(cf_cb_field_unselected):
1521 main_cf_cb_field_unselected(data);
1523 case(cf_cb_file_safe_started):
1524 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe started");
1526 case(cf_cb_file_safe_finished):
1527 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe finished");
1529 case(cf_cb_file_safe_reload_finished):
1530 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: reload finished");
1531 main_cf_cb_file_safe_reload_finished(data);
1533 case(cf_cb_file_safe_failed):
1534 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe failed");
1537 g_warning("main_cf_callback: event %u unknown", event);
1538 g_assert_not_reached();
1543 get_gui_compiled_info(GString *str)
1545 get_epan_compiled_version_info(str);
1547 g_string_append(str, ", ");
1548 #ifdef HAVE_LIBPORTAUDIO
1549 #ifdef PORTAUDIO_API_1
1550 g_string_append(str, "with PortAudio <= V18");
1551 #else /* PORTAUDIO_API_1 */
1552 g_string_append(str, "with ");
1553 g_string_append(str, Pa_GetVersionText());
1554 #endif /* PORTAUDIO_API_1 */
1555 #else /* HAVE_LIBPORTAUDIO */
1556 g_string_append(str, "without PortAudio");
1557 #endif /* HAVE_LIBPORTAUDIO */
1559 g_string_append(str, ", ");
1561 get_compiled_airpcap_version(str);
1563 g_string_append(str, "without AirPcap");
1568 get_gui_runtime_info(GString *str)
1571 g_string_append(str, ", ");
1572 get_runtime_airpcap_version(str);
1576 g_string_append(str, ", ");
1577 u3_runtime_info(str);
1583 read_configuration_files(char **gdp_path, char **dp_path)
1585 int gpf_open_errno, gpf_read_errno;
1586 int cf_open_errno, df_open_errno;
1587 int gdp_open_errno, gdp_read_errno;
1588 int dp_open_errno, dp_read_errno;
1589 char *gpf_path, *pf_path;
1590 char *cf_path, *df_path;
1591 int pf_open_errno, pf_read_errno;
1594 /* Read the preference files. */
1595 prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1596 &pf_open_errno, &pf_read_errno, &pf_path);
1598 if (gpf_path != NULL) {
1599 if (gpf_open_errno != 0) {
1600 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1601 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1602 strerror(gpf_open_errno));
1604 if (gpf_read_errno != 0) {
1605 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1606 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1607 strerror(gpf_read_errno));
1610 if (pf_path != NULL) {
1611 if (pf_open_errno != 0) {
1612 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1613 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1614 strerror(pf_open_errno));
1616 if (pf_read_errno != 0) {
1617 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1618 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1619 strerror(pf_read_errno));
1626 /* if the user wants a console to be always there, well, we should open one for him */
1627 if (prefs->gui_console_open == console_open_always) {
1632 /* Read the capture filter file. */
1633 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1634 if (cf_path != NULL) {
1635 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1636 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1637 strerror(cf_open_errno));
1641 /* Read the display filter file. */
1642 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1643 if (df_path != NULL) {
1644 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1645 "Could not open your display filter file\n\"%s\": %s.", df_path,
1646 strerror(df_open_errno));
1650 /* Read the disabled protocols file. */
1651 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1652 dp_path, &dp_open_errno, &dp_read_errno);
1653 if (*gdp_path != NULL) {
1654 if (gdp_open_errno != 0) {
1655 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1656 "Could not open global disabled protocols file\n\"%s\": %s.",
1657 *gdp_path, strerror(gdp_open_errno));
1659 if (gdp_read_errno != 0) {
1660 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1661 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1662 *gdp_path, strerror(gdp_read_errno));
1667 if (*dp_path != NULL) {
1668 if (dp_open_errno != 0) {
1669 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1670 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1671 strerror(dp_open_errno));
1673 if (dp_read_errno != 0) {
1674 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1675 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1676 strerror(dp_read_errno));
1685 /* And now our feature presentation... [ fade to music ] */
1687 main(int argc, char *argv[])
1689 char *init_progfile_dir_error;
1692 extern char *optarg;
1693 gboolean arg_error = FALSE;
1701 char *gdp_path, *dp_path;
1704 gboolean start_capture = FALSE;
1705 gboolean list_link_layer_types = FALSE;
1707 gboolean capture_option_specified = FALSE;
1709 gint pl_size = 280, tv_size = 95, bv_size = 75;
1710 gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
1711 dfilter_t *rfcode = NULL;
1712 gboolean rfilter_parse_failed = FALSE;
1715 GtkWidget *splash_win = NULL;
1716 gpointer priv_warning_dialog;
1717 GLogLevelFlags log_flags;
1718 guint go_to_packet = 0;
1721 gchar *cur_user, *cur_group;
1727 #define OPTSTRING_INIT "a:b:c:C:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
1729 #if defined HAVE_LIBPCAP && defined _WIN32
1730 #define OPTSTRING_WIN32 "B:"
1732 #define OPTSTRING_WIN32 ""
1735 char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
1736 OPTSTRING_INIT OPTSTRING_WIN32;
1739 * Get credential information for later use, and drop privileges
1740 * before doing anything else.
1741 * Let the user know if anything happened.
1743 get_credential_info();
1744 relinquish_special_privs_perm();
1747 * Attempt to get the pathname of the executable file.
1749 init_progfile_dir_error = init_progfile_dir(argv[0]);
1751 /* initialize the funnel mini-api */
1752 initialize_funnel_ops();
1754 #ifdef HAVE_AIRPDCAP
1755 AirPDcapInitContext(&airpdcap_ctx);
1759 /* Load wpcap if possible. Do this before collecting the run-time version information */
1762 /* ... and also load the packet.dll from wpcap */
1763 wpcap_packet_load();
1766 /* Load the airpcap.dll. This must also be done before collecting
1767 * run-time version information. */
1768 airpcap_dll_ret_val = load_airpcap();
1770 switch (airpcap_dll_ret_val) {
1771 case AIRPCAP_DLL_OK:
1772 /* load the airpcap interfaces */
1773 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
1775 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
1776 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
1777 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
1780 airpcap_if_active = NULL;
1784 /* select the first ad default (THIS SHOULD BE CHANGED) */
1785 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
1790 * XXX - Maybe we need to warn the user if one of the following happens???
1792 case AIRPCAP_DLL_OLD:
1793 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
1796 case AIRPCAP_DLL_ERROR:
1797 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
1800 case AIRPCAP_DLL_NOT_FOUND:
1801 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
1805 #endif /* HAVE_AIRPCAP */
1807 /* Start windows sockets */
1808 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
1811 /* Assemble the compile-time version information string */
1812 comp_info_str = g_string_new("Compiled ");
1814 g_string_append(comp_info_str, "with ");
1815 g_string_append_printf(comp_info_str,
1816 #ifdef GTK_MAJOR_VERSION
1817 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1820 "GTK+ (version unknown)");
1822 g_string_append(comp_info_str, ", ");
1824 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
1826 /* Assemble the run-time version information string */
1827 runtime_info_str = g_string_new("Running ");
1828 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
1831 /* "pre-scan" the command line parameters, if we have "console only"
1832 parameters. We do this so we don't start GTK+ if we're only showing
1833 command-line help or version information.
1835 XXX - this pre-scan is done before we start GTK+, so we haven't
1836 run gtk_init() on the arguments. That means that GTK+ arguments
1837 have not been removed from the argument list; those arguments
1838 begin with "--", and will be treated as an error by getopt().
1840 We thus ignore errors - *and* set "opterr" to 0 to suppress the
1843 optind_initial = optind;
1844 while ((opt = getopt(argc, argv, optstring)) != -1) {
1846 case 'C': /* Configuration Profile */
1847 if (profile_exists (optarg)) {
1848 set_profile_name (optarg);
1850 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
1854 case 'h': /* Print help and exit */
1858 case 'P': /* Path settings - change these before the Preferences and alike are processed */
1859 status = filesystem_opt(opt, optarg);
1861 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
1865 case 'v': /* Show version and exit */
1871 * Extension command line options have to be processed before
1872 * we call epan_init() as they are supposed to be used by dissectors
1873 * or taps very early in the registration process.
1877 case '?': /* Ignore errors - the "real" scan will catch them. */
1882 /* Init the "Open file" dialog directory */
1883 /* (do this after the path settings are processed) */
1884 set_last_open_dir(get_persdatafile_dir());
1886 /* Set getopt index back to initial value, so it will start with the
1887 first command line parameter again. Also reset opterr to 1, so that
1888 error messages are printed by getopt().
1890 XXX - this seems to work on most platforms, but time will tell.
1891 The Single UNIX Specification says "The getopt() function need
1892 not be reentrant", so this isn't guaranteed to work. The Mac
1893 OS X 10.4[.x] getopt() man page says
1895 In order to use getopt() to evaluate multiple sets of arguments, or to
1896 evaluate a single set of arguments multiple times, the variable optreset
1897 must be set to 1 before the second and each additional set of calls to
1898 getopt(), and the variable optind must be reinitialized.
1902 The optreset variable was added to make it possible to call the getopt()
1903 function multiple times. This is an extension to the IEEE Std 1003.2
1904 (``POSIX.2'') specification.
1906 which I think comes from one of the other BSDs.
1908 XXX - if we want to control all the command-line option errors, so
1909 that we can display them where we choose (e.g., in a window), we'd
1910 want to leave opterr as 0, and produce our own messages using optopt.
1911 We'd have to check the value of optopt to see if it's a valid option
1912 letter, in which case *presumably* the error is "this option requires
1913 an argument but none was specified", or not a valid option letter,
1914 in which case *presumably* the error is "this option isn't valid".
1915 Some versions of getopt() let you supply a option string beginning
1916 with ':', which means that getopt() will return ':' rather than '?'
1917 for "this option requires an argument but none was specified", but
1919 optind = optind_initial;
1922 /* Set the current locale according to the program environment.
1923 * We haven't localized anything, but some GTK widgets are localized
1924 * (the file selection dialogue, for example).
1925 * This also sets the C-language locale to the native environment. */
1928 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
1929 gtk_init (&argc, &argv);
1931 cf_callback_add(main_cf_callback, NULL);
1932 cf_callback_add(statusbar_cf_callback, NULL);
1934 /* Arrange that if we have no console window, and a GLib message logging
1935 routine is called to log a message, we pop up a console window.
1937 We do that by inserting our own handler for all messages logged
1938 to the default domain; that handler pops up a console if necessary,
1939 and then calls the default handler. */
1941 /* We might want to have component specific log levels later ... */
1945 G_LOG_LEVEL_CRITICAL|
1946 G_LOG_LEVEL_WARNING|
1947 G_LOG_LEVEL_MESSAGE|
1950 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
1952 g_log_set_handler(NULL,
1954 console_log_handler, NULL /* user_data */);
1955 g_log_set_handler(LOG_DOMAIN_MAIN,
1957 console_log_handler, NULL /* user_data */);
1960 g_log_set_handler(LOG_DOMAIN_CAPTURE,
1962 console_log_handler, NULL /* user_data */);
1963 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
1965 console_log_handler, NULL /* user_data */);
1967 /* Set the initial values in the capture_opts. This might be overwritten
1968 by preference settings and then again by the command line parameters. */
1969 capture_opts_init(capture_opts, &cfile);
1971 capture_opts->snaplen = MIN_PACKET_SIZE;
1972 capture_opts->has_ring_num_files = TRUE;
1975 /* Initialize whatever we need to allocate colors for GTK+ */
1978 /* We won't come till here, if we had a "console only" command line parameter. */
1979 splash_win = splash_new("Loading Wireshark ...");
1980 if (init_progfile_dir_error != NULL) {
1981 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1982 "Can't get pathname of Wireshark: %s.\n"
1983 "It won't be possible to capture traffic.\n"
1984 "Report this to the Wireshark developers.",
1985 init_progfile_dir_error);
1986 g_free(init_progfile_dir_error);
1989 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
1991 /* Register all dissectors; we must do this before checking for the
1992 "-G" flag, as the "-G" flag dumps information registered by the
1993 dissectors, and we must do it before we read the preferences, in
1994 case any dissectors register preferences. */
1995 epan_init(register_all_protocols,register_all_protocol_handoffs,
1996 splash_update, (gpointer) splash_win,
1997 failure_alert_box,open_failure_alert_box,read_failure_alert_box);
1999 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2001 /* Register all tap listeners; we do this before we parse the arguments,
2002 as the "-z" argument can specify a registered tap. */
2004 /* we register the plugin taps before the other taps because
2005 stats_tree taps plugins will be registered as tap listeners
2006 by stats_tree_stat.c and need to registered before that */
2009 register_all_plugin_tap_listeners();
2012 register_all_tap_listeners();
2014 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2016 /* Now register the preferences for any non-dissector modules.
2017 We must do that before we read the preferences as well. */
2018 prefs_register_modules();
2020 prefs = read_configuration_files (&gdp_path, &dp_path);
2022 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2023 #if !defined(_WIN32) && defined(G_THREADS_ENABLED) && defined USE_THREADS
2026 g_thread_init(NULL);
2028 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2029 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2031 #else /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2032 /* this is to keep tap extensions updating once every 3 seconds */
2033 tap_update_timer_id = gtk_timeout_add(prefs->tap_update_interval, (GtkFunction)update_cb,(gpointer)NULL);
2034 #endif /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2037 gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
2040 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2043 /* Read the (static part) of the recent file. Only the static part of it will be read, */
2044 /* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
2045 /* We have to do this already here, so command line parameters can overwrite these values. */
2046 recent_read_static(&rf_path, &rf_open_errno);
2047 if (rf_path != NULL && rf_open_errno != 0) {
2048 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2049 "Could not open common recent file\n\"%s\": %s.",
2050 rf_path, strerror(rf_open_errno));
2052 recent_read_profile_static(&rf_path, &rf_open_errno);
2053 if (rf_path != NULL && rf_open_errno != 0) {
2054 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2055 "Could not open recent file\n\"%s\": %s.",
2056 rf_path, strerror(rf_open_errno));
2059 init_cap_file(&cfile);
2061 /* Now get our args */
2062 while ((opt = getopt(argc, argv, optstring)) != -1) {
2064 /*** capture option specific ***/
2065 case 'a': /* autostop criteria */
2066 case 'b': /* Ringbuffer option */
2067 case 'c': /* Capture xxx packets */
2068 case 'f': /* capture filter */
2069 case 'k': /* Start capture immediately */
2070 case 'H': /* Hide capture info dialog box */
2071 case 'i': /* Use interface xxx */
2072 case 'p': /* Don't capture in promiscuous mode */
2073 case 'Q': /* Quit after capture (just capture to file) */
2074 case 's': /* Set the snapshot (capture) length */
2075 case 'S': /* "Sync" mode: used for following file ala tail -f */
2076 case 'w': /* Write to capture file xxx */
2077 case 'y': /* Set the pcap data link type */
2079 case 'B': /* Buffer size */
2082 status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
2087 capture_option_specified = TRUE;
2092 /*** all non capture option specific ***/
2094 /* Configuration profile settings were already processed just ignore them this time*/
2096 case 'D': /* Print a list of capture devices and exit */
2098 capture_opts_list_interfaces(FALSE);
2101 capture_option_specified = TRUE;
2105 case 'g': /* Go to packet */
2106 go_to_packet = get_positive_int(optarg, "go to packet");
2108 case 'l': /* Automatic scrolling in live capture mode */
2110 auto_scroll_live = TRUE;
2112 capture_option_specified = TRUE;
2116 case 'L': /* Print list of link-layer types and exit */
2118 list_link_layer_types = TRUE;
2120 capture_option_specified = TRUE;
2124 case 'm': /* Fixed-width font for the display */
2125 if (prefs->gui_font_name != NULL)
2126 g_free(prefs->gui_font_name);
2127 prefs->gui_font_name = g_strdup(optarg);
2129 case 'n': /* No name resolution */
2130 g_resolv_flags = RESOLV_NONE;
2132 case 'N': /* Select what types of addresses/port #s to resolve */
2133 if (g_resolv_flags == RESOLV_ALL)
2134 g_resolv_flags = RESOLV_NONE;
2135 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2136 if (badopt != '\0') {
2137 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2142 case 'o': /* Override preference from command line */
2143 switch (prefs_set_pref(optarg)) {
2146 case PREFS_SET_SYNTAX_ERR:
2147 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2150 case PREFS_SET_NO_SUCH_PREF:
2151 /* not a preference, might be a recent setting */
2152 switch (recent_set_arg(optarg)) {
2155 case PREFS_SET_SYNTAX_ERR:
2156 /* shouldn't happen, checked already above */
2157 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2160 case PREFS_SET_NO_SUCH_PREF:
2161 case PREFS_SET_OBSOLETE:
2162 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2167 g_assert_not_reached();
2170 case PREFS_SET_OBSOLETE:
2171 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2176 g_assert_not_reached();
2180 /* Path settings were already processed just ignore them this time*/
2182 case 'r': /* Read capture file xxx */
2183 /* We may set "last_open_dir" to "cf_name", and if we change
2184 "last_open_dir" later, we free the old value, so we have to
2185 set "cf_name" to something that's been allocated. */
2186 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2187 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2188 cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2190 cf_name = g_strdup(optarg);
2193 case 'R': /* Read file filter */
2196 case 't': /* Time stamp type */
2197 if (strcmp(optarg, "r") == 0)
2198 timestamp_set_type(TS_RELATIVE);
2199 else if (strcmp(optarg, "a") == 0)
2200 timestamp_set_type(TS_ABSOLUTE);
2201 else if (strcmp(optarg, "ad") == 0)
2202 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2203 else if (strcmp(optarg, "d") == 0)
2204 timestamp_set_type(TS_DELTA);
2205 else if (strcmp(optarg, "dd") == 0)
2206 timestamp_set_type(TS_DELTA_DIS);
2207 else if (strcmp(optarg, "e") == 0)
2208 timestamp_set_type(TS_EPOCH);
2210 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2211 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2212 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2217 /* ext ops were already processed just ignore them this time*/
2220 /* We won't call the init function for the stat this soon
2221 as it would disallow MATE's fields (which are registered
2222 by the preferences set callback) from being used as
2223 part of a tap filter. Instead, we just add the argument
2224 to a list of stat arguments. */
2225 if (!process_stat_cmd_arg(optarg)) {
2226 cmdarg_err("Invalid -z argument.");
2227 cmdarg_err_cont(" -z argument must be one of :");
2228 list_stat_cmd_args();
2233 case '?': /* Bad flag - print usage message */
2241 if (cf_name != NULL) {
2243 * Input file name specified with "-r" *and* specified as a regular
2244 * command-line argument.
2246 cmdarg_err("File name specified both with -r and regular argument");
2250 * Input file name not specified with "-r", and a command-line argument
2251 * was specified; treat it as the input file name.
2253 * Yes, this is different from tshark, where non-flag command-line
2254 * arguments are a filter, but this works better on GUI desktops
2255 * where a command can be specified to be run to open a particular
2256 * file - yes, you could have "-r" as the last part of the command,
2257 * but that's a bit ugly.
2259 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2260 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2261 cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2263 cf_name = g_strdup(argv[0]);
2274 * Extra command line arguments were specified; complain.
2276 cmdarg_err("Invalid argument: %s", argv[0]);
2281 #ifndef HAVE_LIBPCAP
2282 if (capture_option_specified) {
2283 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2291 if (start_capture && list_link_layer_types) {
2292 /* Specifying *both* is bogus. */
2293 cmdarg_err("You can't specify both -L and a live capture.");
2297 if (list_link_layer_types) {
2298 /* We're supposed to list the link-layer types for an interface;
2299 did the user also specify a capture file to be read? */
2301 /* Yes - that's bogus. */
2302 cmdarg_err("You can't specify -L and a capture file to be read.");
2305 /* No - did they specify a ring buffer option? */
2306 if (capture_opts->multi_files_on) {
2307 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2311 /* We're supposed to do a live capture; did the user also specify
2312 a capture file to be read? */
2313 if (start_capture && cf_name) {
2314 /* Yes - that's bogus. */
2315 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2319 /* No - was the ring buffer option specified and, if so, does it make
2321 if (capture_opts->multi_files_on) {
2322 /* Ring buffer works only under certain conditions:
2323 a) ring buffer does not work with temporary files;
2324 b) real_time_mode and multi_files_on are mutually exclusive -
2325 real_time_mode takes precedence;
2326 c) it makes no sense to enable the ring buffer if the maximum
2327 file size is set to "infinite". */
2328 if (capture_opts->save_file == NULL) {
2329 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2330 capture_opts->multi_files_on = FALSE;
2332 /* if (capture_opts->real_time_mode) {
2333 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2334 capture_opts->multi_files_on = FALSE;
2336 if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
2337 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2338 /* XXX - this must be redesigned as the conditions changed */
2339 /* capture_opts->multi_files_on = FALSE;*/
2344 if (start_capture || list_link_layer_types) {
2345 /* Did the user specify an interface to use? */
2346 if (!capture_opts_trim_iface(capture_opts,
2347 (prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
2352 if (list_link_layer_types) {
2353 status = capture_opts_list_link_layer_types(capture_opts, FALSE);
2357 /* Fill in capture options with values from the preferences */
2358 prefs_to_capture_opts();
2360 capture_opts_trim_snaplen(capture_opts, MIN_PACKET_SIZE);
2361 capture_opts_trim_ring_num_files(capture_opts);
2362 #endif /* HAVE_LIBPCAP */
2364 /* Notify all registered modules that have had any of their preferences
2365 changed either from one of the preferences file or from the command
2366 line that their preferences have changed. */
2369 /* disabled protocols as per configuration file */
2370 if (gdp_path == NULL && dp_path == NULL) {
2371 set_disabled_protos_list();
2374 build_column_format_array(&cfile.cinfo, TRUE);
2376 /* read in rc file from global and personal configuration paths. */
2377 rc_file = get_datafile_path(RC_FILE);
2378 gtk_rc_parse(rc_file);
2380 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2381 gtk_rc_parse(rc_file);
2388 /* close the splash screen, as we are going to open the main window now */
2389 splash_destroy(splash_win);
2391 /************************************************************************/
2392 /* Everything is prepared now, preferences and command line was read in */
2394 /* Pop up the main window. */
2395 create_main_window(pl_size, tv_size, bv_size, prefs);
2397 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2398 recent_read_dynamic(&rf_path, &rf_open_errno);
2399 if (rf_path != NULL && rf_open_errno != 0) {
2400 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2401 "Could not open recent file\n\"%s\": %s.",
2402 rf_path, strerror(rf_open_errno));
2405 color_filters_enable(recent.packet_list_colorize);
2407 /* rearrange all the widgets as we now have all recent settings ready for this */
2408 main_widgets_rearrange();
2410 /* Fill in column titles. This must be done after the top level window
2413 XXX - is that still true, with fixed-width columns? */
2414 packet_list_set_column_titles();
2416 menu_recent_read_finished();
2418 menu_auto_scroll_live_changed(auto_scroll_live);
2421 switch (user_font_apply(prefs->gui_geometry_save_column_width)) {
2424 case FA_FONT_NOT_RESIZEABLE:
2425 /* "user_font_apply()" popped up an alert box. */
2426 /* turn off zooming - font can't be resized */
2427 case FA_FONT_NOT_AVAILABLE:
2428 /* XXX - did we successfully load the un-zoomed version earlier?
2429 If so, this *probably* means the font is available, but not at
2430 this particular zoom level, but perhaps some other failure
2431 occurred; I'm not sure you can determine which is the case,
2433 /* turn off zooming - zoom level is unavailable */
2435 /* in any other case than FA_SUCCESS, turn off zooming */
2436 recent.gui_zoom_level = 0;
2437 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2440 dnd_init(top_level);
2442 color_filters_init();
2445 /* the window can be sized only, if it's not already shown, so do it now! */
2446 main_load_window_geometry(top_level);
2448 /* Tell the user not to run as root. */
2449 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2450 cur_user = get_cur_username();
2451 cur_group = get_cur_groupname();
2452 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2453 "Running as user \"%s\" and group \"%s\".\n"
2454 "This could be dangerous.", cur_user, cur_group);
2457 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2458 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2462 /* Warn the user if npf.sys isn't loaded. */
2463 if (!npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2464 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2465 "The NPF driver isn't running. You may have trouble\n"
2466 "capturing or listing interfaces.");
2467 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2468 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2472 /* If we were given the name of a capture file, read it in now;
2473 we defer it until now, so that, if we can't open it, and pop
2474 up an alert box, the alert box is more likely to come up on
2475 top of the main window - but before the preference-file-error
2476 alert box, so, if we get one of those, it's more likely to come
2479 show_main_window(TRUE);
2480 if (rfilter != NULL) {
2481 if (!dfilter_compile(rfilter, &rfcode)) {
2482 bad_dfilter_alert_box(rfilter);
2483 rfilter_parse_failed = TRUE;
2486 if (!rfilter_parse_failed) {
2487 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2488 /* "cf_open()" succeeded, so it closed the previous
2489 capture file, and thus destroyed any previous read filter
2490 attached to "cf". */
2492 cfile.rfcode = rfcode;
2493 /* Open stat windows; we do so after creating the main window,
2494 to avoid GTK warnings, and after successfully opening the
2495 capture file, so we know we have something to compute stats
2496 on, and after registering all dissectors, so that MATE will
2497 have registered its field array and we can have a tap filter
2498 with one of MATE's late-registered fields as part of the
2500 start_requested_stats();
2502 /* Read the capture file. */
2503 switch (cf_read(&cfile)) {
2507 /* Just because we got an error, that doesn't mean we were unable
2508 to read any of the file; we handle what we could get from the
2510 /* if the user told us to jump to a specific packet, do it now */
2511 if(go_to_packet != 0) {
2512 cf_goto_frame(&cfile, go_to_packet);
2516 case CF_READ_ABORTED:
2521 /* Save the name of the containing directory specified in the
2522 path name, if any; we can write over cf_name, which is a
2523 good thing, given that "get_dirname()" does write over its
2525 s = get_dirname(cf_name);
2526 set_last_open_dir(s);
2531 dfilter_free(rfcode);
2532 cfile.rfcode = NULL;
2533 show_main_window(FALSE);
2534 set_menus_for_capture_in_progress(FALSE);
2535 set_capture_if_dialog_for_capture_in_progress(FALSE);
2540 if (start_capture) {
2541 if (capture_opts->save_file != NULL) {
2542 /* Save the directory name for future file dialogs. */
2543 /* (get_dirname overwrites filename) */
2544 s = get_dirname(g_strdup(capture_opts->save_file));
2545 set_last_open_dir(s);
2548 /* "-k" was specified; start a capture. */
2549 show_main_window(TRUE);
2550 if (capture_start(capture_opts)) {
2551 /* The capture started. Open stat windows; we do so after creating
2552 the main window, to avoid GTK warnings, and after successfully
2553 opening the capture file, so we know we have something to compute
2554 stats on, and after registering all dissectors, so that MATE will
2555 have registered its field array and we can have a tap filter with
2556 one of MATE's late-registered fields as part of the filter. */
2557 start_requested_stats();
2561 show_main_window(FALSE);
2562 set_menus_for_capture_in_progress(FALSE);
2563 set_capture_if_dialog_for_capture_in_progress(FALSE);
2566 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
2567 if (!start_capture && strlen(capture_opts->cfilter) == 0) {
2568 g_free(capture_opts->cfilter);
2569 capture_opts->cfilter = g_strdup(get_conn_cfilter());
2571 #else /* HAVE_LIBPCAP */
2572 show_main_window(FALSE);
2573 set_menus_for_capture_in_progress(FALSE);
2574 set_capture_if_dialog_for_capture_in_progress(FALSE);
2575 #endif /* HAVE_LIBPCAP */
2578 /* register our pid if we are being run from a U3 device */
2581 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
2583 /* we'll enter the GTK loop now and hand the control over to GTK ... */
2585 /* ... back from GTK, we're going down now! */
2587 /* deregister our pid */
2588 u3_deregister_pid();
2592 #ifdef HAVE_AIRPDCAP
2593 AirPDcapDestroyContext(&airpdcap_ctx);
2597 /* hide the (unresponsive) main window, while asking the user to close the console window */
2598 gtk_widget_hide(top_level);
2600 /* Shutdown windows sockets */
2603 /* For some unknown reason, the "atexit()" call in "create_console()"
2604 doesn't arrange that "destroy_console()" be called when we exit,
2605 so we call it here if a console was created. */
2611 /* This isn't reached, but we need it to keep GCC from complaining
2612 that "main()" returns without returning a value - it knows that
2613 "exit()" never returns, but it doesn't know that "gtk_exit()"
2614 doesn't, as GTK+ doesn't declare it with the attribute
2616 return 0; /* not reached */
2621 /* We build this as a GUI subsystem application on Win32, so
2622 "WinMain()", not "main()", gets called.
2624 Hack shamelessly stolen from the Win32 port of the GIMP. */
2626 #define _stdcall __attribute__((stdcall))
2630 WinMain (struct HINSTANCE__ *hInstance,
2631 struct HINSTANCE__ *hPrevInstance,
2635 INITCOMMONCONTROLSEX comm_ctrl;
2637 /* Initialize our controls. Required for native Windows file dialogs. */
2638 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
2639 comm_ctrl.dwSize = sizeof(comm_ctrl);
2640 /* Includes the animate, header, hot key, list view, progress bar,
2641 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
2644 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
2645 InitCommonControlsEx(&comm_ctrl);
2647 /* RichEd20.DLL is needed for filter entries. */
2648 LoadLibrary(_T("riched20.dll"));
2650 has_console = FALSE;
2651 return main (__argc, __argv);
2655 * If this application has no console window to which its standard output
2656 * would go, create one.
2659 create_console(void)
2662 /* We have no console to which to print the version string, so
2663 create one and make it the standard input, output, and error. */
2664 if (!AllocConsole())
2665 return; /* couldn't create console */
2666 ws_freopen("CONIN$", "r", stdin);
2667 ws_freopen("CONOUT$", "w", stdout);
2668 ws_freopen("CONOUT$", "w", stderr);
2670 /* Well, we have a console now. */
2673 /* Now register "destroy_console()" as a routine to be called just
2674 before the application exits, so that we can destroy the console
2675 after the user has typed a key (so that the console doesn't just
2676 disappear out from under them, giving the user no chance to see
2677 the message(s) we put in there). */
2678 atexit(destroy_console);
2680 SetConsoleTitle(_T("Wireshark Debug Console"));
2685 destroy_console(void)
2688 printf("\n\nPress any key to exit\n");
2696 /* This routine should not be necessary, at least as I read the GLib
2697 source code, as it looks as if GLib is, on Win32, *supposed* to
2698 create a console window into which to display its output.
2700 That doesn't happen, however. I suspect there's something completely
2701 broken about that code in GLib-for-Win32, and that it may be related
2702 to the breakage that forces us to just call "printf()" on the message
2703 rather than passing the message on to "g_log_default_handler()"
2704 (which is the routine that does the aforementioned non-functional
2705 console window creation). */
2707 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
2708 const char *message, gpointer user_data _U_)
2715 /* ignore log message, if log_level isn't interesting.
2716 If preferences aren't loaded yet, display message anyway */
2717 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
2718 prefs.console_log_level != 0) {
2722 /* create a "timestamp" */
2724 today = localtime(&curr);
2727 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
2728 /* the user wants a console or the application will terminate immediately */
2732 /* For some unknown reason, the above doesn't appear to actually cause
2733 anything to be sent to the standard output, so we'll just splat the
2734 message out directly, just to make sure it gets out. */
2736 switch(log_level & G_LOG_LEVEL_MASK) {
2737 case G_LOG_LEVEL_ERROR:
2740 case G_LOG_LEVEL_CRITICAL:
2743 case G_LOG_LEVEL_WARNING:
2746 case G_LOG_LEVEL_MESSAGE:
2749 case G_LOG_LEVEL_INFO:
2752 case G_LOG_LEVEL_DEBUG:
2756 fprintf(stderr, "unknown log_level %u\n", log_level);
2758 g_assert_not_reached();
2761 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
2762 today->tm_hour, today->tm_min, today->tm_sec,
2763 log_domain != NULL ? log_domain : "",
2766 if(log_level & G_LOG_LEVEL_ERROR) {
2767 /* wait for a key press before the following error handler will terminate the program
2768 this way the user at least can read the error message */
2769 printf("\n\nPress any key to exit\n");
2773 g_log_default_handler(log_domain, log_level, message, user_data);
2780 * Helper for main_widgets_rearrange()
2782 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
2783 gtk_container_remove(GTK_CONTAINER(data), widget);
2786 static GtkWidget *main_widget_layout(gint layout_content)
2788 switch(layout_content) {
2789 case(layout_pane_content_none):
2791 case(layout_pane_content_plist):
2793 case(layout_pane_content_pdetails):
2795 case(layout_pane_content_pbytes):
2798 g_assert_not_reached();
2805 * Rearrange the main window widgets
2807 void main_widgets_rearrange(void) {
2808 GtkWidget *first_pane_widget1, *first_pane_widget2;
2809 GtkWidget *second_pane_widget1, *second_pane_widget2;
2810 gboolean split_top_left;
2812 /* be a bit faster */
2813 gtk_widget_hide(main_vbox);
2815 /* be sure, we don't loose a widget while rearranging */
2816 gtk_widget_ref(menubar);
2817 gtk_widget_ref(main_tb);
2818 gtk_widget_ref(filter_tb);
2820 gtk_widget_ref(airpcap_tb);
2822 gtk_widget_ref(pkt_scrollw);
2823 gtk_widget_ref(tv_scrollw);
2824 gtk_widget_ref(byte_nb_ptr);
2825 gtk_widget_ref(statusbar);
2826 gtk_widget_ref(main_pane_v1);
2827 gtk_widget_ref(main_pane_v2);
2828 gtk_widget_ref(main_pane_h1);
2829 gtk_widget_ref(main_pane_h2);
2830 gtk_widget_ref(welcome_pane);
2832 /* empty all containers participating */
2833 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
2834 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
2835 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
2836 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
2837 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
2839 statusbar_widgets_emptying(statusbar);
2841 /* add the menubar always at the top */
2842 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2845 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
2847 /* filter toolbar in toolbar area */
2848 if (!prefs.filter_toolbar_show_in_statusbar) {
2849 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
2853 /* airpcap toolbar */
2854 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
2857 /* fill the main layout panes */
2858 switch(prefs.gui_layout_type) {
2859 case(layout_type_5):
2860 main_first_pane = main_pane_v1;
2861 main_second_pane = main_pane_v2;
2862 split_top_left = FALSE;
2864 case(layout_type_2):
2865 main_first_pane = main_pane_v1;
2866 main_second_pane = main_pane_h1;
2867 split_top_left = FALSE;
2869 case(layout_type_1):
2870 main_first_pane = main_pane_v1;
2871 main_second_pane = main_pane_h1;
2872 split_top_left = TRUE;
2874 case(layout_type_4):
2875 main_first_pane = main_pane_h1;
2876 main_second_pane = main_pane_v1;
2877 split_top_left = FALSE;
2879 case(layout_type_3):
2880 main_first_pane = main_pane_h1;
2881 main_second_pane = main_pane_v1;
2882 split_top_left = TRUE;
2884 case(layout_type_6):
2885 main_first_pane = main_pane_h1;
2886 main_second_pane = main_pane_h2;
2887 split_top_left = FALSE;
2890 main_first_pane = NULL;
2891 main_second_pane = NULL;
2892 split_top_left = FALSE;
2893 g_assert_not_reached();
2895 if (split_top_left) {
2896 first_pane_widget1 = main_second_pane;
2897 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2898 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
2899 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2901 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2902 first_pane_widget2 = main_second_pane;
2903 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
2904 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2906 if (first_pane_widget1 != NULL)
2907 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
2908 if (first_pane_widget2 != NULL)
2909 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
2910 if (second_pane_widget1 != NULL)
2911 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
2912 if (second_pane_widget2 != NULL)
2913 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
2915 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
2918 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
2921 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
2923 /* filter toolbar in statusbar hbox */
2924 if (prefs.filter_toolbar_show_in_statusbar) {
2925 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
2929 /* airpcap toolbar */
2930 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
2933 /* statusbar widgets */
2934 statusbar_widgets_pack(statusbar);
2936 /* hide widgets on users recent settings */
2937 main_widgets_show_or_hide();
2939 gtk_widget_show(main_vbox);
2943 is_widget_visible(GtkWidget *widget, gpointer data)
2945 gboolean *is_visible = data;
2948 if (GTK_WIDGET_VISIBLE(widget))
2955 main_widgets_show_or_hide(void)
2957 gboolean main_second_pane_show;
2959 if (recent.main_toolbar_show) {
2960 gtk_widget_show(main_tb);
2962 gtk_widget_hide(main_tb);
2965 statusbar_widgets_show_or_hide(statusbar);
2967 if (recent.filter_toolbar_show) {
2968 gtk_widget_show(filter_tb);
2970 gtk_widget_hide(filter_tb);
2974 if (recent.airpcap_toolbar_show) {
2975 gtk_widget_show(airpcap_tb);
2977 gtk_widget_hide(airpcap_tb);
2981 if (recent.packet_list_show && have_capture_file) {
2982 gtk_widget_show(pkt_scrollw);
2984 gtk_widget_hide(pkt_scrollw);
2987 if (recent.tree_view_show && have_capture_file) {
2988 gtk_widget_show(tv_scrollw);
2990 gtk_widget_hide(tv_scrollw);
2993 if (recent.byte_view_show && have_capture_file) {
2994 gtk_widget_show(byte_nb_ptr);
2996 gtk_widget_hide(byte_nb_ptr);
2999 if (have_capture_file) {
3000 gtk_widget_show(main_first_pane);
3002 gtk_widget_hide(main_first_pane);
3006 * Is anything in "main_second_pane" visible?
3007 * If so, show it, otherwise hide it.
3009 main_second_pane_show = FALSE;
3010 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3011 &main_second_pane_show);
3012 if (main_second_pane_show) {
3013 gtk_widget_show(main_second_pane);
3015 gtk_widget_hide(main_second_pane);
3018 if (!have_capture_file) {
3020 gtk_widget_show(welcome_pane);
3023 gtk_widget_hide(welcome_pane);
3026 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
3027 packet_list_freeze ();
3028 packet_list_thaw ();
3032 /* called, when the window state changes (minimized, maximized, ...) */
3034 window_state_event_cb (GtkWidget *widget _U_,
3038 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3040 if( (event->type) == (GDK_WINDOW_STATE)) {
3041 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3042 /* we might have dialogs popped up while we where iconified,
3044 display_queued_messages();
3052 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_LOCK_MASK))
3054 top_level_key_pressed_cb(GtkCTree *ctree _U_, GdkEventKey *event, gpointer user_data _U_)
3056 if (event->keyval == GDK_F8) {
3059 } else if (event->keyval == GDK_F7) {
3062 } else if (event->state & NO_SHIFT_MOD_MASK) {
3063 return FALSE; /* Skip control, alt, and other modifiers */
3065 * A comment in gdkkeysyms.h says that it's autogenerated from
3066 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3067 * don't explicitly say so, isprint() should work as expected
3070 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3071 /* Forward the keypress on to the display filter entry */
3072 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3073 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3074 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3082 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
3084 GtkTooltips *tooltips;
3085 GtkAccelGroup *accel;
3088 /* use user-defined title if preference is set */
3089 title = create_user_window_title("The Wireshark Network Analyzer");
3092 top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
3095 tooltips = gtk_tooltips_new();
3097 gtk_widget_set_name(top_level, "main window");
3098 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3100 g_signal_connect(GTK_OBJECT(top_level), "window_state_event",
3101 G_CALLBACK(window_state_event_cb), NULL);
3102 g_signal_connect(GTK_OBJECT(top_level), "key-press-event",
3103 G_CALLBACK(top_level_key_pressed_cb), NULL );
3105 gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
3107 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3108 main_vbox = gtk_vbox_new(FALSE, 1);
3109 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
3110 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3111 gtk_widget_show(main_vbox);
3114 menubar = main_menu_new(&accel);
3115 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3116 gtk_widget_show(menubar);
3119 main_tb = toolbar_new();
3120 gtk_widget_show (main_tb);
3122 /* Filter toolbar */
3123 filter_tb = filter_toolbar_new();
3126 pkt_scrollw = packet_list_new(prefs);
3127 gtk_widget_set_size_request(packet_list, -1, pl_size);
3128 gtk_widget_show(pkt_scrollw);
3131 tv_scrollw = main_tree_view_new(prefs, &tree_view);
3132 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3133 gtk_widget_show(tv_scrollw);
3135 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
3136 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3137 g_signal_connect(tree_view, "button_press_event", G_CALLBACK(popup_menu_handler),
3138 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3139 gtk_widget_show(tree_view);
3142 byte_nb_ptr = byte_view_new();
3143 gtk_widget_set_size_request(byte_nb_ptr, -1, bv_size);
3144 gtk_widget_show(byte_nb_ptr);
3146 g_signal_connect(byte_nb_ptr, "button_press_event", G_CALLBACK(popup_menu_handler),
3147 g_object_get_data(G_OBJECT(popup_menu_object), PM_HEXDUMP_KEY));
3150 /* Panes for the packet list, tree, and byte view */
3151 main_pane_v1 = gtk_vpaned_new();
3152 gtk_widget_show(main_pane_v1);
3153 main_pane_v2 = gtk_vpaned_new();
3154 gtk_widget_show(main_pane_v2);
3155 main_pane_h1 = gtk_hpaned_new();
3156 gtk_widget_show(main_pane_h1);
3157 main_pane_h2 = gtk_hpaned_new();
3158 gtk_widget_show(main_pane_h2);
3160 airpcap_tb = airpcap_toolbar_new();
3161 gtk_widget_show(airpcap_tb);
3164 statusbar = statusbar_new();
3165 gtk_widget_show(statusbar);
3167 /* Pane for the welcome screen */
3168 welcome_pane = welcome_new();
3169 gtk_widget_show(welcome_pane);
3173 show_main_window(gboolean doing_work)
3175 main_set_for_capture_file(doing_work);
3177 /*** we have finished all init things, show the main window ***/
3178 gtk_widget_show(top_level);
3180 /* the window can be maximized only, if it's visible, so do it after show! */
3181 main_load_window_geometry(top_level);
3183 /* process all pending GUI events before continue */
3184 while (gtk_events_pending()) gtk_main_iteration();
3186 /* Pop up any queued-up alert boxes. */
3187 display_queued_messages();
3189 /* Move the main window to the front, in case it isn't already there */
3190 gdk_window_raise(top_level->window);
3193 airpcap_toolbar_show(airpcap_tb);
3194 #endif /* HAVE_AIRPCAP */
3197 /* Fill in capture options with values from the preferences */
3199 prefs_to_capture_opts(void)
3202 /* Set promiscuous mode from the preferences setting. */
3203 /* the same applies to other preferences settings as well. */
3204 capture_opts->promisc_mode = prefs.capture_prom_mode;
3205 capture_opts->show_info = prefs.capture_show_info;
3206 capture_opts->real_time_mode = prefs.capture_real_time;
3207 auto_scroll_live = prefs.capture_auto_scroll;
3208 #endif /* HAVE_LIBPCAP */
3210 /* Set the name resolution code's flags from the preferences. */
3211 g_resolv_flags = prefs.name_resolve;
3215 /* Change configuration profile */
3216 void change_configuration_profile (const gchar *profile_name)
3218 char *gdp_path, *dp_path;
3222 /* First check if profile exists */
3223 if (!profile_exists(profile_name)) {
3227 /* Get the current geometry, before writing it to disk */
3228 main_save_window_geometry(top_level);
3230 /* Write recent file for profile we are leaving */
3231 write_profile_recent();
3233 /* Set profile name and update the status bar */
3234 set_profile_name (profile_name);
3235 profile_bar_update ();
3237 /* Reset current preferences and apply the new */
3239 (void) read_configuration_files (&gdp_path, &dp_path);
3241 recent_read_profile_static(&rf_path, &rf_open_errno);
3242 if (rf_path != NULL && rf_open_errno != 0) {
3243 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3244 "Could not open common recent file\n\"%s\": %s.",
3245 rf_path, strerror(rf_open_errno));
3247 timestamp_set_type (recent.gui_time_format);
3248 color_filters_enable(recent.packet_list_colorize);
3249 menu_recent_read_finished();
3250 main_pane_load_window_geometry();
3251 recent.gui_time_format = timestamp_get_type ();
3253 prefs_to_capture_opts();
3256 /* Update window view and redraw the toolbar */
3257 update_main_window_name();
3258 toolbar_redraw_all();
3260 /* Enable all protocols and disable from the disabled list */
3262 if (gdp_path == NULL && dp_path == NULL) {
3263 set_disabled_protos_list();
3266 /* Reload color filters */
3267 color_filters_reload();
3269 /* Recreate the packet list according to new preferences */
3270 packet_list_recreate ();
3271 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3272 user_font_apply(prefs.gui_geometry_save_column_width);