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 "../wiretap/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_sprintfa(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_sprintfa(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_sprintfa(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 */
725 /* XXX - should we check whether the capture file is an
726 unsaved temporary file for a live capture and, if so,
727 pop up a "do you want to exit without saving the capture
728 file?" dialog, and then just return, leaving said dialog
729 box to forcibly quit if the user clicks "OK"?
731 If so, note that this should be done in a subroutine that
732 returns TRUE if we do so, and FALSE otherwise, and if it
733 returns TRUE we should return TRUE without nuking anything.
735 Note that, if we do that, we might also want to check if
736 an "Update list of packets in real time" capture is in
737 progress and, if so, ask whether they want to terminate
738 the capture and discard it, and return TRUE, before nuking
739 any child capture, if they say they don't want to do so. */
742 /* Nuke any child capture in progress. */
743 capture_kill_child(capture_opts);
746 /* Are we in the middle of reading a capture? */
747 if (cfile.state == FILE_READ_IN_PROGRESS) {
748 /* Yes, so we can't just close the file and quit, as
749 that may yank the rug out from under the read in
750 progress; instead, just set the state to
751 "FILE_READ_ABORTED" and return - the code doing the read
752 will check for that and, if it sees that, will clean
754 cfile.state = FILE_READ_ABORTED;
756 /* Say that the window should *not* be deleted;
757 that'll be done by the code that cleans up. */
760 /* Close any capture file we have open; on some OSes, you
761 can't unlink a temporary capture file if you have it
763 "cf_close()" will unlink it after closing it if
764 it's a temporary file.
766 We do this here, rather than after the main loop returns,
767 as, after the main loop returns, the main window may have
768 been destroyed (if this is called due to a "destroy"
769 even on the main window rather than due to the user
770 selecting a menu item), and there may be a crash
771 or other problem when "cf_close()" tries to
772 clean up stuff in the main window.
774 XXX - is there a better place to put this?
775 Or should we have a routine that *just* closes the
776 capture file, and doesn't do anything with the UI,
777 which we'd call here, and another routine that
778 calls that routine and also cleans up the UI, which
779 we'd call elsewhere? */
782 /* Exit by leaving the main loop, so that any quit functions
783 we registered get called. */
786 /* Say that the window should be deleted. */
792 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
796 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
797 gtk_window_present(GTK_WINDOW(top_level));
798 /* user didn't saved his current file, ask him */
799 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
800 "%sSave capture file before program quit?%s\n\n"
801 "If you quit the program without saving, your capture data will be discarded.",
802 simple_dialog_primary_start(), simple_dialog_primary_end());
803 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
806 /* unchanged file, just exit */
807 /* "main_do_quit()" indicates whether the main window should be deleted. */
808 return main_do_quit();
815 main_load_window_geometry(GtkWidget *widget)
817 window_geometry_t geom;
819 geom.set_pos = prefs.gui_geometry_save_position;
820 geom.x = recent.gui_geometry_main_x;
821 geom.y = recent.gui_geometry_main_y;
822 geom.set_size = prefs.gui_geometry_save_size;
823 if (recent.gui_geometry_main_width > 0 &&
824 recent.gui_geometry_main_height > 0) {
825 geom.width = recent.gui_geometry_main_width;
826 geom.height = recent.gui_geometry_main_height;
827 geom.set_maximized = prefs.gui_geometry_save_maximized;
829 /* We assume this means the width and height weren't set in
830 the "recent" file (or that there is no "recent" file),
831 and weren't set to a default value, so we don't set the
832 size. (The "recent" file code rejects non-positive width
833 and height values.) */
834 geom.set_size = FALSE;
836 geom.maximized = recent.gui_geometry_main_maximized;
838 window_set_geometry(widget, &geom);
840 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
841 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
842 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
843 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
844 statusbar_load_window_geometry();
849 main_save_window_geometry(GtkWidget *widget)
851 window_geometry_t geom;
853 window_get_geometry(widget, &geom);
855 if (prefs.gui_geometry_save_position) {
856 recent.gui_geometry_main_x = geom.x;
857 recent.gui_geometry_main_y = geom.y;
860 if (prefs.gui_geometry_save_size) {
861 recent.gui_geometry_main_width = geom.width;
862 recent.gui_geometry_main_height = geom.height;
865 if(prefs.gui_geometry_save_maximized) {
866 recent.gui_geometry_main_maximized = geom.maximized;
869 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
870 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
871 statusbar_save_window_geometry();
874 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
878 /* save file first */
879 file_save_as_cmd(after_save_exit, NULL);
881 case(ESD_BTN_DONT_SAVE):
884 case(ESD_BTN_CANCEL):
887 g_assert_not_reached();
892 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
896 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
897 /* user didn't saved his current file, ask him */
898 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
899 "%sSave capture file before program quit?%s\n\n"
900 "If you quit the program without saving, your capture data will be discarded.",
901 simple_dialog_primary_start(), simple_dialog_primary_end());
902 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
904 /* unchanged file, just exit */
910 print_usage(gboolean print_ver) {
920 fprintf(output, "Wireshark " VERSION "%s\n"
921 "Interactively dump and analyze network traffic.\n"
922 "See http://www.wireshark.org for more information.\n"
925 wireshark_svnversion, get_copyright_info());
929 fprintf(output, "\n");
930 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
931 fprintf(output, "\n");
934 fprintf(output, "Capture interface:\n");
935 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
936 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
937 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
938 fprintf(output, " -p don't capture in promiscuous mode\n");
939 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
940 fprintf(output, " -Q quit Wireshark after capturing\n");
941 fprintf(output, " -S update packet display when new packets are captured\n");
942 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
944 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
946 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
947 fprintf(output, " -D print list of interfaces and exit\n");
948 fprintf(output, " -L print list of link-layer types of iface and exit\n");
949 fprintf(output, "\n");
950 fprintf(output, "Capture stop conditions:\n");
951 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
952 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
953 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
954 fprintf(output, " files:NUM - stop after NUM files\n");
955 /*fprintf(output, "\n");*/
956 fprintf(output, "Capture output:\n");
957 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
958 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
959 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
960 #endif /* HAVE_LIBPCAP */
962 /*fprintf(output, "\n");*/
963 fprintf(output, "Input file:\n");
964 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
966 fprintf(output, "\n");
967 fprintf(output, "Processing:\n");
968 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
969 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
970 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
972 fprintf(output, "\n");
973 fprintf(output, "User interface:\n");
974 fprintf(output, " -C <config profile> start with specified configuration profile\n");
975 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
976 fprintf(output, " -m <font> set the font name used for most text\n");
977 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
978 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
979 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
981 fprintf(output, "\n");
982 fprintf(output, "Output:\n");
983 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
985 fprintf(output, "\n");
986 fprintf(output, "Miscellaneous:\n");
987 fprintf(output, " -h display this help and exit\n");
988 fprintf(output, " -v display version info and exit\n");
989 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
990 fprintf(output, " persdata:path - personal data files\n");
991 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
993 fprintf(output, " --display=DISPLAY X display to use\n");
1008 printf(PACKAGE " " VERSION "%s\n"
1015 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1016 runtime_info_str->str);
1024 * Report an error in command-line arguments.
1025 * Creates a console on Windows.
1026 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1027 * terminal isn't the standard error?
1030 cmdarg_err(const char *fmt, ...)
1038 fprintf(stderr, "wireshark: ");
1039 vfprintf(stderr, fmt, ap);
1040 fprintf(stderr, "\n");
1045 * Report additional information for an error in command-line arguments.
1046 * Creates a console on Windows.
1047 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1048 * terminal isn't the standard error?
1051 cmdarg_err_cont(const char *fmt, ...)
1059 vfprintf(stderr, fmt, ap);
1060 fprintf(stderr, "\n");
1064 #if defined(_WIN32) || ! defined USE_THREADS
1066 Once every 3 seconds we get a callback here which we use to update
1067 the tap extensions. Since Gtk1 is single threaded we dont have to
1068 worry about any locking or critical regions.
1071 update_cb(gpointer data _U_)
1073 draw_tap_listeners(FALSE);
1077 /* Restart the tap update display timer with new configured interval */
1078 void reset_tap_update_timer(void)
1080 #if defined(_WIN32) || ! defined USE_THREADS
1081 gtk_timeout_remove(tap_update_timer_id);
1082 tap_update_timer_id = gtk_timeout_add(prefs.tap_update_interval, (GtkFunction)update_cb,(gpointer)NULL);
1088 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1089 use threads all update_thread_mutex can be dropped and protect/unprotect
1090 would just be empty functions.
1092 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1093 gtk1-wireshark and it will just work.
1095 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1097 update_thread(gpointer data _U_)
1101 g_get_current_time(&tv1);
1102 g_static_mutex_lock(&update_thread_mutex);
1103 gdk_threads_enter();
1104 draw_tap_listeners(FALSE);
1105 gdk_threads_leave();
1106 g_static_mutex_unlock(&update_thread_mutex);
1108 g_get_current_time(&tv2);
1110 /* Assuming it took less than configured time to update tap listeners... */
1111 if( (tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) >
1112 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1113 /* Wait for remainder of configured time */
1114 g_usleep((tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) -
1115 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1122 protect_thread_critical_region(void)
1124 #if !defined(_WIN32) && defined USE_THREADS
1125 g_static_mutex_lock(&update_thread_mutex);
1129 unprotect_thread_critical_region(void)
1131 #if !defined(_WIN32) && defined USE_THREADS
1132 g_static_mutex_unlock(&update_thread_mutex);
1136 /* Set the file name in the name for the main window and in the name for the main window's icon. */
1138 set_display_filename(capture_file *cf)
1142 if (!cf->is_tempfile && cf->filename) {
1143 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1144 add_menu_recent_capture_file(cf->filename);
1148 win_name = g_strdup_printf("%s - Wireshark", cf_get_display_name(cf));
1149 set_main_window_name(win_name);
1153 GtkWidget *close_dlg = NULL;
1156 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1158 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1163 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1165 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1170 main_cf_cb_file_closing(capture_file *cf)
1173 /* if we have more than 10000 packets, show a splash screen while closing */
1174 /* XXX - don't know a better way to decide wether to show or not,
1175 * as most of the time is spend in a single eth_clist_clear function,
1176 * so we can't use a progress bar here! */
1177 if(cf->count > 10000) {
1178 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1179 "%sClosing file!%s\n\nPlease wait ...",
1180 simple_dialog_primary_start(),
1181 simple_dialog_primary_end());
1182 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1185 /* Destroy all windows, which refer to the
1186 capture file we're closing. */
1187 destroy_packet_wins();
1188 file_save_as_destroy();
1190 /* Restore the standard title bar message. */
1191 set_main_window_name("The Wireshark Network Analyzer");
1193 /* Disable all menu items that make sense only if you have a capture. */
1194 set_menus_for_capture_file(NULL);
1195 set_menus_for_captured_packets(FALSE);
1196 set_menus_for_selected_packet(cf);
1197 set_menus_for_capture_in_progress(FALSE);
1198 set_capture_if_dialog_for_capture_in_progress(FALSE);
1199 set_menus_for_selected_tree_row(cf);
1201 /* Set up main window for no capture file. */
1202 main_set_for_capture_file(FALSE);
1204 main_window_update();
1208 main_cf_cb_file_closed(capture_file *cf _U_)
1210 if(close_dlg != NULL) {
1211 splash_destroy(close_dlg);
1218 main_cf_cb_file_read_start(capture_file *cf _U_)
1220 tap_dfilter_dlg_update();
1222 /* Set up main window for a capture file. */
1223 main_set_for_capture_file(TRUE);
1227 main_cf_cb_file_read_finished(capture_file *cf)
1229 set_display_filename(cf);
1231 /* Enable menu items that make sense if you have a capture file you've
1232 finished reading. */
1233 set_menus_for_capture_file(cf);
1235 /* Enable menu items that make sense if you have some captured packets. */
1236 set_menus_for_captured_packets(TRUE);
1239 GList *icon_list_create(
1240 const char **icon16_xpm,
1241 const char **icon32_xpm,
1242 const char **icon48_xpm,
1243 const char **icon64_xpm)
1245 GList *icon_list = NULL;
1246 GdkPixbuf * pixbuf16;
1247 GdkPixbuf * pixbuf32;
1248 GdkPixbuf * pixbuf48;
1249 GdkPixbuf * pixbuf64;
1252 if(icon16_xpm != NULL) {
1253 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1255 icon_list = g_list_append(icon_list, pixbuf16);
1258 if(icon32_xpm != NULL) {
1259 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1261 icon_list = g_list_append(icon_list, pixbuf32);
1264 if(icon48_xpm != NULL) {
1265 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1267 icon_list = g_list_append(icon_list, pixbuf48);
1270 if(icon64_xpm != NULL) {
1271 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1273 icon_list = g_list_append(icon_list, pixbuf64);
1281 main_cf_cb_live_capture_prepared(capture_options *capture_opts)
1284 static GList *icon_list = NULL;
1287 if(capture_opts->iface) {
1288 title = g_strdup_printf("%s: Capturing - Wireshark",
1289 get_iface_description(capture_opts));
1291 title = g_strdup_printf("Capturing - Wireshark");
1293 set_main_window_name(title);
1296 if(icon_list == NULL) {
1297 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1299 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1301 /* Disable menu items that make no sense if you're currently running
1303 set_menus_for_capture_in_progress(TRUE);
1304 set_capture_if_dialog_for_capture_in_progress(TRUE);
1306 /* Don't set up main window for a capture file. */
1307 main_set_for_capture_file(FALSE);
1311 main_cf_cb_live_capture_update_started(capture_options *capture_opts)
1315 /* We've done this in "prepared" above, but it will be cleared while
1316 switching to the next multiple file. */
1317 if(capture_opts->iface) {
1318 title = g_strdup_printf("%s: Capturing - Wireshark",
1319 get_iface_description(capture_opts));
1321 title = g_strdup_printf("Capturing - Wireshark");
1323 set_main_window_name(title);
1326 set_menus_for_capture_in_progress(TRUE);
1327 set_capture_if_dialog_for_capture_in_progress(TRUE);
1329 /* Enable menu items that make sense if you have some captured
1330 packets (yes, I know, we don't have any *yet*). */
1331 set_menus_for_captured_packets(TRUE);
1333 /* Set up main window for a capture file. */
1334 main_set_for_capture_file(TRUE);
1338 main_cf_cb_live_capture_update_finished(capture_file *cf)
1340 static GList *icon_list = NULL;
1342 set_display_filename(cf);
1344 /* Enable menu items that make sense if you're not currently running
1346 set_menus_for_capture_in_progress(FALSE);
1347 set_capture_if_dialog_for_capture_in_progress(FALSE);
1349 /* Enable menu items that make sense if you have a capture file
1350 you've finished reading. */
1351 set_menus_for_capture_file(cf);
1353 /* Set up main window for a capture file. */
1354 main_set_for_capture_file(TRUE);
1356 if(icon_list == NULL) {
1357 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1359 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1361 if(capture_opts->quit_after_cap) {
1362 /* command line asked us to quit after the capture */
1363 /* don't pop up a dialog to ask for unsaved files etc. */
1369 main_cf_cb_live_capture_fixed_started(capture_options *capture_opts _U_)
1371 /* Don't set up main window for a capture file. */
1372 main_set_for_capture_file(FALSE);
1376 main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_)
1378 static GList *icon_list = NULL;
1380 /*set_display_filename(cf);*/
1382 /* Enable menu items that make sense if you're not currently running
1384 set_menus_for_capture_in_progress(FALSE);
1385 set_capture_if_dialog_for_capture_in_progress(FALSE);
1387 /* Restore the standard title bar message */
1388 /* (just in case we have trouble opening the capture file). */
1389 set_main_window_name("The Wireshark Network Analyzer");
1391 if(icon_list == NULL) {
1392 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1394 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1396 /* We don't have loaded the capture file, this will be done later.
1397 * For now we still have simply a blank screen. */
1399 if(capture_opts->quit_after_cap) {
1400 /* command line asked us to quit after the capture */
1401 /* don't pop up a dialog to ask for unsaved files etc. */
1406 #endif /* HAVE_LIBPCAP */
1409 main_cf_cb_packet_selected(gpointer data)
1411 capture_file *cf = data;
1413 /* Display the GUI protocol tree and hex dump.
1414 XXX - why do we dump core if we call "proto_tree_draw()"
1415 before calling "add_byte_views()"? */
1416 add_main_byte_views(cf->edt);
1417 main_proto_tree_draw(cf->edt->tree);
1419 /* The user is searching for a string in the data or a hex value,
1420 * highlight the field that is found in the tree and hex displays. */
1421 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1422 highlight_field(cf->edt->tvb, cfile.search_pos,
1423 (GtkTreeView *)tree_view, cf->edt->tree);
1424 cfile.search_pos = 0; /* Reset the position */
1427 /* A packet is selected. */
1428 set_menus_for_selected_packet(cf);
1432 main_cf_cb_packet_unselected(capture_file *cf)
1434 /* Clear out the display of that packet. */
1435 clear_tree_and_hex_views();
1437 /* No packet is selected. */
1438 set_menus_for_selected_packet(cf);
1442 main_cf_cb_field_unselected(capture_file *cf)
1444 set_menus_for_selected_tree_row(cf);
1448 main_cf_cb_file_safe_reload_finished(gpointer data _U_)
1450 set_menus_for_capture_file(&cfile);
1454 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1457 case(cf_cb_file_closing):
1458 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1459 main_cf_cb_file_closing(data);
1461 case(cf_cb_file_closed):
1462 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1463 main_cf_cb_file_closed(data);
1465 case(cf_cb_file_read_start):
1466 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read start");
1467 main_cf_cb_file_read_start(data);
1469 case(cf_cb_file_read_finished):
1470 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1471 main_cf_cb_file_read_finished(data);
1474 case(cf_cb_live_capture_prepared):
1475 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1476 main_cf_cb_live_capture_prepared(data);
1478 case(cf_cb_live_capture_update_started):
1479 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1480 main_cf_cb_live_capture_update_started(data);
1482 case(cf_cb_live_capture_update_continue):
1483 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1485 case(cf_cb_live_capture_update_finished):
1486 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1487 main_cf_cb_live_capture_update_finished(data);
1489 case(cf_cb_live_capture_fixed_started):
1490 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1491 main_cf_cb_live_capture_fixed_started(data);
1493 case(cf_cb_live_capture_fixed_continue):
1494 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1496 case(cf_cb_live_capture_fixed_finished):
1497 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1498 main_cf_cb_live_capture_fixed_finished(data);
1500 case(cf_cb_live_capture_stopping):
1501 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1502 /* Beware: this state won't be called, if the capture child
1503 * closes the capturing on it's own! */
1506 case(cf_cb_packet_selected):
1507 main_cf_cb_packet_selected(data);
1509 case(cf_cb_packet_unselected):
1510 main_cf_cb_packet_unselected(data);
1512 case(cf_cb_field_unselected):
1513 main_cf_cb_field_unselected(data);
1515 case(cf_cb_file_safe_started):
1516 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe started");
1518 case(cf_cb_file_safe_finished):
1519 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe finished");
1521 case(cf_cb_file_safe_reload_finished):
1522 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: reload finished");
1523 main_cf_cb_file_safe_reload_finished(data);
1525 case(cf_cb_file_safe_failed):
1526 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe failed");
1529 g_warning("main_cf_callback: event %u unknown", event);
1530 g_assert_not_reached();
1535 get_gui_compiled_info(GString *str)
1537 get_epan_compiled_version_info(str);
1539 g_string_append(str, ", ");
1540 #ifdef HAVE_LIBPORTAUDIO
1541 #ifdef PORTAUDIO_API_1
1542 g_string_append(str, "with PortAudio <= V18");
1543 #else /* PORTAUDIO_API_1 */
1544 g_string_append(str, "with ");
1545 g_string_append(str, Pa_GetVersionText());
1546 #endif /* PORTAUDIO_API_1 */
1547 #else /* HAVE_LIBPORTAUDIO */
1548 g_string_append(str, "without PortAudio");
1549 #endif /* HAVE_LIBPORTAUDIO */
1551 g_string_append(str, ", ");
1553 get_compiled_airpcap_version(str);
1555 g_string_append(str, "without AirPcap");
1560 get_gui_runtime_info(GString *str)
1563 g_string_append(str, ", ");
1564 get_runtime_airpcap_version(str);
1568 g_string_append(str, ", ");
1569 u3_runtime_info(str);
1575 read_configuration_files(char **gdp_path, char **dp_path)
1577 int gpf_open_errno, gpf_read_errno;
1578 int cf_open_errno, df_open_errno;
1579 int gdp_open_errno, gdp_read_errno;
1580 int dp_open_errno, dp_read_errno;
1581 char *gpf_path, *pf_path;
1582 char *cf_path, *df_path;
1583 int pf_open_errno, pf_read_errno;
1586 /* Read the preference files. */
1587 prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1588 &pf_open_errno, &pf_read_errno, &pf_path);
1590 if (gpf_path != NULL) {
1591 if (gpf_open_errno != 0) {
1592 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1593 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1594 strerror(gpf_open_errno));
1596 if (gpf_read_errno != 0) {
1597 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1598 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1599 strerror(gpf_read_errno));
1602 if (pf_path != NULL) {
1603 if (pf_open_errno != 0) {
1604 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1605 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1606 strerror(pf_open_errno));
1608 if (pf_read_errno != 0) {
1609 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1610 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1611 strerror(pf_read_errno));
1618 /* if the user wants a console to be always there, well, we should open one for him */
1619 if (prefs->gui_console_open == console_open_always) {
1624 /* Read the capture filter file. */
1625 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1626 if (cf_path != NULL) {
1627 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1628 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1629 strerror(cf_open_errno));
1633 /* Read the display filter file. */
1634 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1635 if (df_path != NULL) {
1636 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1637 "Could not open your display filter file\n\"%s\": %s.", df_path,
1638 strerror(df_open_errno));
1642 /* Read the disabled protocols file. */
1643 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1644 dp_path, &dp_open_errno, &dp_read_errno);
1645 if (*gdp_path != NULL) {
1646 if (gdp_open_errno != 0) {
1647 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1648 "Could not open global disabled protocols file\n\"%s\": %s.",
1649 *gdp_path, strerror(gdp_open_errno));
1651 if (gdp_read_errno != 0) {
1652 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1653 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1654 *gdp_path, strerror(gdp_read_errno));
1659 if (*dp_path != NULL) {
1660 if (dp_open_errno != 0) {
1661 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1662 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1663 strerror(dp_open_errno));
1665 if (dp_read_errno != 0) {
1666 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1667 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1668 strerror(dp_read_errno));
1677 /* And now our feature presentation... [ fade to music ] */
1679 main(int argc, char *argv[])
1681 char *init_progfile_dir_error;
1684 extern char *optarg;
1685 gboolean arg_error = FALSE;
1693 char *gdp_path, *dp_path;
1696 gboolean start_capture = FALSE;
1697 gboolean list_link_layer_types = FALSE;
1699 gboolean capture_option_specified = FALSE;
1701 gint pl_size = 280, tv_size = 95, bv_size = 75;
1702 gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
1703 dfilter_t *rfcode = NULL;
1704 gboolean rfilter_parse_failed = FALSE;
1707 GtkWidget *splash_win = NULL;
1708 gpointer priv_warning_dialog;
1709 GLogLevelFlags log_flags;
1710 guint go_to_packet = 0;
1713 gchar *cur_user, *cur_group;
1719 #define OPTSTRING_INIT "a:b:c:C:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
1721 #if defined HAVE_LIBPCAP && defined _WIN32
1722 #define OPTSTRING_WIN32 "B:"
1724 #define OPTSTRING_WIN32 ""
1727 char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
1728 OPTSTRING_INIT OPTSTRING_WIN32;
1731 * Get credential information for later use, and drop privileges
1732 * before doing anything else.
1733 * Let the user know if anything happened.
1735 get_credential_info();
1736 relinquish_special_privs_perm();
1739 * Attempt to get the pathname of the executable file.
1741 init_progfile_dir_error = init_progfile_dir(argv[0]);
1743 /* initialize the funnel mini-api */
1744 initialize_funnel_ops();
1746 #ifdef HAVE_AIRPDCAP
1747 AirPDcapInitContext(&airpdcap_ctx);
1751 /* Load wpcap if possible. Do this before collecting the run-time version information */
1754 /* ... and also load the packet.dll from wpcap */
1755 wpcap_packet_load();
1758 /* Load the airpcap.dll. This must also be done before collecting
1759 * run-time version information. */
1760 airpcap_dll_ret_val = load_airpcap();
1762 switch (airpcap_dll_ret_val) {
1763 case AIRPCAP_DLL_OK:
1764 /* load the airpcap interfaces */
1765 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
1767 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
1768 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
1769 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
1772 airpcap_if_active = NULL;
1776 /* select the first ad default (THIS SHOULD BE CHANGED) */
1777 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
1782 * XXX - Maybe we need to warn the user if one of the following happens???
1784 case AIRPCAP_DLL_OLD:
1785 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
1788 case AIRPCAP_DLL_ERROR:
1789 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
1792 case AIRPCAP_DLL_NOT_FOUND:
1793 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
1797 #endif /* HAVE_AIRPCAP */
1799 /* Start windows sockets */
1800 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
1803 /* Assemble the compile-time version information string */
1804 comp_info_str = g_string_new("Compiled ");
1806 g_string_append(comp_info_str, "with ");
1807 g_string_sprintfa(comp_info_str,
1808 #ifdef GTK_MAJOR_VERSION
1809 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1812 "GTK+ (version unknown)");
1814 g_string_append(comp_info_str, ", ");
1816 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
1818 /* Assemble the run-time version information string */
1819 runtime_info_str = g_string_new("Running ");
1820 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
1823 /* "pre-scan" the command line parameters, if we have "console only"
1824 parameters. We do this so we don't start GTK+ if we're only showing
1825 command-line help or version information.
1827 XXX - this pre-scan is done before we start GTK+, so we haven't
1828 run gtk_init() on the arguments. That means that GTK+ arguments
1829 have not been removed from the argument list; those arguments
1830 begin with "--", and will be treated as an error by getopt().
1832 We thus ignore errors - *and* set "opterr" to 0 to suppress the
1835 optind_initial = optind;
1836 while ((opt = getopt(argc, argv, optstring)) != -1) {
1838 case 'C': /* Configuration Profile */
1839 if (profile_exists (optarg)) {
1840 set_profile_name (optarg);
1842 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
1846 case 'h': /* Print help and exit */
1850 case 'P': /* Path settings - change these before the Preferences and alike are processed */
1851 status = filesystem_opt(opt, optarg);
1853 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
1857 case 'v': /* Show version and exit */
1863 * Extension command line options have to be processed before
1864 * we call epan_init() as they are supposed to be used by dissectors
1865 * or taps very early in the registration process.
1869 case '?': /* Ignore errors - the "real" scan will catch them. */
1874 /* Init the "Open file" dialog directory */
1875 /* (do this after the path settings are processed) */
1876 set_last_open_dir(get_persdatafile_dir());
1878 /* Set getopt index back to initial value, so it will start with the
1879 first command line parameter again. Also reset opterr to 1, so that
1880 error messages are printed by getopt().
1882 XXX - this seems to work on most platforms, but time will tell.
1883 The Single UNIX Specification says "The getopt() function need
1884 not be reentrant", so this isn't guaranteed to work. The Mac
1885 OS X 10.4[.x] getopt() man page says
1887 In order to use getopt() to evaluate multiple sets of arguments, or to
1888 evaluate a single set of arguments multiple times, the variable optreset
1889 must be set to 1 before the second and each additional set of calls to
1890 getopt(), and the variable optind must be reinitialized.
1894 The optreset variable was added to make it possible to call the getopt()
1895 function multiple times. This is an extension to the IEEE Std 1003.2
1896 (``POSIX.2'') specification.
1898 which I think comes from one of the other BSDs.
1900 XXX - if we want to control all the command-line option errors, so
1901 that we can display them where we choose (e.g., in a window), we'd
1902 want to leave opterr as 0, and produce our own messages using optopt.
1903 We'd have to check the value of optopt to see if it's a valid option
1904 letter, in which case *presumably* the error is "this option requires
1905 an argument but none was specified", or not a valid option letter,
1906 in which case *presumably* the error is "this option isn't valid".
1907 Some versions of getopt() let you supply a option string beginning
1908 with ':', which means that getopt() will return ':' rather than '?'
1909 for "this option requires an argument but none was specified", but
1911 optind = optind_initial;
1914 /* Set the current locale according to the program environment.
1915 * We haven't localized anything, but some GTK widgets are localized
1916 * (the file selection dialogue, for example).
1917 * This also sets the C-language locale to the native environment. */
1920 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
1921 gtk_init (&argc, &argv);
1923 cf_callback_add(main_cf_callback, NULL);
1924 cf_callback_add(statusbar_cf_callback, NULL);
1926 /* Arrange that if we have no console window, and a GLib message logging
1927 routine is called to log a message, we pop up a console window.
1929 We do that by inserting our own handler for all messages logged
1930 to the default domain; that handler pops up a console if necessary,
1931 and then calls the default handler. */
1933 /* We might want to have component specific log levels later ... */
1937 G_LOG_LEVEL_CRITICAL|
1938 G_LOG_LEVEL_WARNING|
1939 G_LOG_LEVEL_MESSAGE|
1942 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
1944 g_log_set_handler(NULL,
1946 console_log_handler, NULL /* user_data */);
1947 g_log_set_handler(LOG_DOMAIN_MAIN,
1949 console_log_handler, NULL /* user_data */);
1952 g_log_set_handler(LOG_DOMAIN_CAPTURE,
1954 console_log_handler, NULL /* user_data */);
1955 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
1957 console_log_handler, NULL /* user_data */);
1959 /* Set the initial values in the capture_opts. This might be overwritten
1960 by preference settings and then again by the command line parameters. */
1961 capture_opts_init(capture_opts, &cfile);
1963 capture_opts->snaplen = MIN_PACKET_SIZE;
1964 capture_opts->has_ring_num_files = TRUE;
1967 /* Initialize whatever we need to allocate colors for GTK+ */
1970 /* We won't come till here, if we had a "console only" command line parameter. */
1971 splash_win = splash_new("Loading Wireshark ...");
1972 if (init_progfile_dir_error != NULL) {
1973 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1974 "Can't get pathname of Wireshark: %s.\n"
1975 "It won't be possible to capture traffic.\n"
1976 "Report this to the Wireshark developers.",
1977 init_progfile_dir_error);
1978 g_free(init_progfile_dir_error);
1981 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
1983 /* Register all dissectors; we must do this before checking for the
1984 "-G" flag, as the "-G" flag dumps information registered by the
1985 dissectors, and we must do it before we read the preferences, in
1986 case any dissectors register preferences. */
1987 epan_init(register_all_protocols,register_all_protocol_handoffs,
1988 splash_update, (gpointer) splash_win,
1989 failure_alert_box,open_failure_alert_box,read_failure_alert_box);
1991 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
1993 /* Register all tap listeners; we do this before we parse the arguments,
1994 as the "-z" argument can specify a registered tap. */
1996 /* we register the plugin taps before the other taps because
1997 stats_tree taps plugins will be registered as tap listeners
1998 by stats_tree_stat.c and need to registered before that */
2001 register_all_plugin_tap_listeners();
2004 register_all_tap_listeners();
2006 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2008 /* Now register the preferences for any non-dissector modules.
2009 We must do that before we read the preferences as well. */
2010 prefs_register_modules();
2012 prefs = read_configuration_files (&gdp_path, &dp_path);
2014 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2015 #if !defined(_WIN32) && defined(G_THREADS_ENABLED) && defined USE_THREADS
2018 g_thread_init(NULL);
2020 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2021 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2023 #else /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2024 /* this is to keep tap extensions updating once every 3 seconds */
2025 tap_update_timer_id = gtk_timeout_add(prefs->tap_update_interval, (GtkFunction)update_cb,(gpointer)NULL);
2026 #endif /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2029 gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
2032 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2035 /* Read the (static part) of the recent file. Only the static part of it will be read, */
2036 /* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
2037 /* We have to do this already here, so command line parameters can overwrite these values. */
2038 recent_read_static(&rf_path, &rf_open_errno);
2040 init_cap_file(&cfile);
2042 /* Now get our args */
2043 while ((opt = getopt(argc, argv, optstring)) != -1) {
2045 /*** capture option specific ***/
2046 case 'a': /* autostop criteria */
2047 case 'b': /* Ringbuffer option */
2048 case 'c': /* Capture xxx packets */
2049 case 'f': /* capture filter */
2050 case 'k': /* Start capture immediately */
2051 case 'H': /* Hide capture info dialog box */
2052 case 'i': /* Use interface xxx */
2053 case 'p': /* Don't capture in promiscuous mode */
2054 case 'Q': /* Quit after capture (just capture to file) */
2055 case 's': /* Set the snapshot (capture) length */
2056 case 'S': /* "Sync" mode: used for following file ala tail -f */
2057 case 'w': /* Write to capture file xxx */
2058 case 'y': /* Set the pcap data link type */
2060 case 'B': /* Buffer size */
2063 status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
2068 capture_option_specified = TRUE;
2073 /*** all non capture option specific ***/
2075 /* Configuration profile settings were already processed just ignore them this time*/
2077 case 'D': /* Print a list of capture devices and exit */
2079 capture_opts_list_interfaces(FALSE);
2082 capture_option_specified = TRUE;
2086 case 'g': /* Go to packet */
2087 go_to_packet = get_positive_int(optarg, "go to packet");
2089 case 'l': /* Automatic scrolling in live capture mode */
2091 auto_scroll_live = TRUE;
2093 capture_option_specified = TRUE;
2097 case 'L': /* Print list of link-layer types and exit */
2099 list_link_layer_types = TRUE;
2101 capture_option_specified = TRUE;
2105 case 'm': /* Fixed-width font for the display */
2106 if (prefs->gui_font_name != NULL)
2107 g_free(prefs->gui_font_name);
2108 prefs->gui_font_name = g_strdup(optarg);
2110 case 'n': /* No name resolution */
2111 g_resolv_flags = RESOLV_NONE;
2113 case 'N': /* Select what types of addresses/port #s to resolve */
2114 if (g_resolv_flags == RESOLV_ALL)
2115 g_resolv_flags = RESOLV_NONE;
2116 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2117 if (badopt != '\0') {
2118 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2123 case 'o': /* Override preference from command line */
2124 switch (prefs_set_pref(optarg)) {
2127 case PREFS_SET_SYNTAX_ERR:
2128 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2131 case PREFS_SET_NO_SUCH_PREF:
2132 /* not a preference, might be a recent setting */
2133 switch (recent_set_arg(optarg)) {
2136 case PREFS_SET_SYNTAX_ERR:
2137 /* shouldn't happen, checked already above */
2138 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2141 case PREFS_SET_NO_SUCH_PREF:
2142 case PREFS_SET_OBSOLETE:
2143 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2148 g_assert_not_reached();
2151 case PREFS_SET_OBSOLETE:
2152 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2157 g_assert_not_reached();
2161 /* Path settings were already processed just ignore them this time*/
2163 case 'r': /* Read capture file xxx */
2164 /* We may set "last_open_dir" to "cf_name", and if we change
2165 "last_open_dir" later, we free the old value, so we have to
2166 set "cf_name" to something that's been allocated. */
2167 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2168 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2169 cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2171 cf_name = g_strdup(optarg);
2174 case 'R': /* Read file filter */
2177 case 't': /* Time stamp type */
2178 if (strcmp(optarg, "r") == 0)
2179 timestamp_set_type(TS_RELATIVE);
2180 else if (strcmp(optarg, "a") == 0)
2181 timestamp_set_type(TS_ABSOLUTE);
2182 else if (strcmp(optarg, "ad") == 0)
2183 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2184 else if (strcmp(optarg, "d") == 0)
2185 timestamp_set_type(TS_DELTA);
2186 else if (strcmp(optarg, "dd") == 0)
2187 timestamp_set_type(TS_DELTA_DIS);
2188 else if (strcmp(optarg, "e") == 0)
2189 timestamp_set_type(TS_EPOCH);
2191 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2192 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2193 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2198 /* ext ops were already processed just ignore them this time*/
2201 /* We won't call the init function for the stat this soon
2202 as it would disallow MATE's fields (which are registered
2203 by the preferences set callback) from being used as
2204 part of a tap filter. Instead, we just add the argument
2205 to a list of stat arguments. */
2206 if (!process_stat_cmd_arg(optarg)) {
2207 cmdarg_err("Invalid -z argument.");
2208 cmdarg_err_cont(" -z argument must be one of :");
2209 list_stat_cmd_args();
2214 case '?': /* Bad flag - print usage message */
2222 if (cf_name != NULL) {
2224 * Input file name specified with "-r" *and* specified as a regular
2225 * command-line argument.
2227 cmdarg_err("File name specified both with -r and regular argument");
2231 * Input file name not specified with "-r", and a command-line argument
2232 * was specified; treat it as the input file name.
2234 * Yes, this is different from tshark, where non-flag command-line
2235 * arguments are a filter, but this works better on GUI desktops
2236 * where a command can be specified to be run to open a particular
2237 * file - yes, you could have "-r" as the last part of the command,
2238 * but that's a bit ugly.
2240 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2241 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2242 cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2244 cf_name = g_strdup(argv[0]);
2255 * Extra command line arguments were specified; complain.
2257 cmdarg_err("Invalid argument: %s", argv[0]);
2262 #ifndef HAVE_LIBPCAP
2263 if (capture_option_specified) {
2264 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2272 if (start_capture && list_link_layer_types) {
2273 /* Specifying *both* is bogus. */
2274 cmdarg_err("You can't specify both -L and a live capture.");
2278 if (list_link_layer_types) {
2279 /* We're supposed to list the link-layer types for an interface;
2280 did the user also specify a capture file to be read? */
2282 /* Yes - that's bogus. */
2283 cmdarg_err("You can't specify -L and a capture file to be read.");
2286 /* No - did they specify a ring buffer option? */
2287 if (capture_opts->multi_files_on) {
2288 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2292 /* We're supposed to do a live capture; did the user also specify
2293 a capture file to be read? */
2294 if (start_capture && cf_name) {
2295 /* Yes - that's bogus. */
2296 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2300 /* No - was the ring buffer option specified and, if so, does it make
2302 if (capture_opts->multi_files_on) {
2303 /* Ring buffer works only under certain conditions:
2304 a) ring buffer does not work with temporary files;
2305 b) real_time_mode and multi_files_on are mutually exclusive -
2306 real_time_mode takes precedence;
2307 c) it makes no sense to enable the ring buffer if the maximum
2308 file size is set to "infinite". */
2309 if (capture_opts->save_file == NULL) {
2310 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2311 capture_opts->multi_files_on = FALSE;
2313 /* if (capture_opts->real_time_mode) {
2314 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2315 capture_opts->multi_files_on = FALSE;
2317 if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
2318 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2319 /* XXX - this must be redesigned as the conditions changed */
2320 /* capture_opts->multi_files_on = FALSE;*/
2325 if (start_capture || list_link_layer_types) {
2326 /* Did the user specify an interface to use? */
2327 if (!capture_opts_trim_iface(capture_opts,
2328 (prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
2333 if (list_link_layer_types) {
2334 status = capture_opts_list_link_layer_types(capture_opts, FALSE);
2338 /* Fill in capture options with values from the preferences */
2339 prefs_to_capture_opts();
2341 capture_opts_trim_snaplen(capture_opts, MIN_PACKET_SIZE);
2342 capture_opts_trim_ring_num_files(capture_opts);
2343 #endif /* HAVE_LIBPCAP */
2345 /* Notify all registered modules that have had any of their preferences
2346 changed either from one of the preferences file or from the command
2347 line that their preferences have changed. */
2350 /* disabled protocols as per configuration file */
2351 if (gdp_path == NULL && dp_path == NULL) {
2352 set_disabled_protos_list();
2355 build_column_format_array(&cfile.cinfo, TRUE);
2357 /* read in rc file from global and personal configuration paths. */
2358 rc_file = get_datafile_path(RC_FILE);
2359 gtk_rc_parse(rc_file);
2361 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2362 gtk_rc_parse(rc_file);
2369 /* close the splash screen, as we are going to open the main window now */
2370 splash_destroy(splash_win);
2372 /************************************************************************/
2373 /* Everything is prepared now, preferences and command line was read in */
2375 /* Pop up the main window. */
2376 create_main_window(pl_size, tv_size, bv_size, prefs);
2378 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2379 recent_read_dynamic(&rf_path, &rf_open_errno);
2380 color_filters_enable(recent.packet_list_colorize);
2382 /* rearrange all the widgets as we now have all recent settings ready for this */
2383 main_widgets_rearrange();
2385 /* Fill in column titles. This must be done after the top level window
2388 XXX - is that still true, with fixed-width columns? */
2389 packet_list_set_column_titles();
2391 menu_recent_read_finished();
2393 menu_auto_scroll_live_changed(auto_scroll_live);
2396 switch (user_font_apply(prefs->gui_geometry_save_column_width)) {
2399 case FA_FONT_NOT_RESIZEABLE:
2400 /* "user_font_apply()" popped up an alert box. */
2401 /* turn off zooming - font can't be resized */
2402 case FA_FONT_NOT_AVAILABLE:
2403 /* XXX - did we successfully load the un-zoomed version earlier?
2404 If so, this *probably* means the font is available, but not at
2405 this particular zoom level, but perhaps some other failure
2406 occurred; I'm not sure you can determine which is the case,
2408 /* turn off zooming - zoom level is unavailable */
2410 /* in any other case than FA_SUCCESS, turn off zooming */
2411 recent.gui_zoom_level = 0;
2412 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2415 dnd_init(top_level);
2417 color_filters_init();
2420 /* the window can be sized only, if it's not already shown, so do it now! */
2421 main_load_window_geometry(top_level);
2423 /* Tell the user not to run as root. */
2424 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2425 cur_user = get_cur_username();
2426 cur_group = get_cur_groupname();
2427 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2428 "Running as user \"%s\" and group \"%s\".\n"
2429 "This could be dangerous.", cur_user, cur_group);
2432 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2433 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2437 /* Warn the user if npf.sys isn't loaded. */
2438 if (!npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2439 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2440 "The NPF driver isn't running. You may have trouble\n"
2441 "capturing or listing interfaces.");
2442 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2443 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2447 /* If we were given the name of a capture file, read it in now;
2448 we defer it until now, so that, if we can't open it, and pop
2449 up an alert box, the alert box is more likely to come up on
2450 top of the main window - but before the preference-file-error
2451 alert box, so, if we get one of those, it's more likely to come
2454 show_main_window(TRUE);
2455 if (rfilter != NULL) {
2456 if (!dfilter_compile(rfilter, &rfcode)) {
2457 bad_dfilter_alert_box(rfilter);
2458 rfilter_parse_failed = TRUE;
2461 if (!rfilter_parse_failed) {
2462 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2463 /* "cf_open()" succeeded, so it closed the previous
2464 capture file, and thus destroyed any previous read filter
2465 attached to "cf". */
2467 cfile.rfcode = rfcode;
2468 /* Open stat windows; we do so after creating the main window,
2469 to avoid GTK warnings, and after successfully opening the
2470 capture file, so we know we have something to compute stats
2471 on, and after registering all dissectors, so that MATE will
2472 have registered its field array and we can have a tap filter
2473 with one of MATE's late-registered fields as part of the
2475 start_requested_stats();
2477 /* Read the capture file. */
2478 switch (cf_read(&cfile)) {
2482 /* Just because we got an error, that doesn't mean we were unable
2483 to read any of the file; we handle what we could get from the
2485 /* if the user told us to jump to a specific packet, do it now */
2486 if(go_to_packet != 0) {
2487 cf_goto_frame(&cfile, go_to_packet);
2491 case CF_READ_ABORTED:
2496 /* Save the name of the containing directory specified in the
2497 path name, if any; we can write over cf_name, which is a
2498 good thing, given that "get_dirname()" does write over its
2500 s = get_dirname(cf_name);
2501 set_last_open_dir(s);
2506 dfilter_free(rfcode);
2507 cfile.rfcode = NULL;
2508 show_main_window(FALSE);
2509 set_menus_for_capture_in_progress(FALSE);
2510 set_capture_if_dialog_for_capture_in_progress(FALSE);
2515 if (start_capture) {
2516 if (capture_opts->save_file != NULL) {
2517 /* Save the directory name for future file dialogs. */
2518 /* (get_dirname overwrites filename) */
2519 s = get_dirname(g_strdup(capture_opts->save_file));
2520 set_last_open_dir(s);
2523 /* "-k" was specified; start a capture. */
2524 show_main_window(TRUE);
2525 if (capture_start(capture_opts)) {
2526 /* The capture started. Open stat windows; we do so after creating
2527 the main window, to avoid GTK warnings, and after successfully
2528 opening the capture file, so we know we have something to compute
2529 stats on, and after registering all dissectors, so that MATE will
2530 have registered its field array and we can have a tap filter with
2531 one of MATE's late-registered fields as part of the filter. */
2532 start_requested_stats();
2536 show_main_window(FALSE);
2537 set_menus_for_capture_in_progress(FALSE);
2538 set_capture_if_dialog_for_capture_in_progress(FALSE);
2541 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
2542 if (!start_capture && strlen(capture_opts->cfilter) == 0) {
2543 g_free(capture_opts->cfilter);
2544 capture_opts->cfilter = g_strdup(get_conn_cfilter());
2546 #else /* HAVE_LIBPCAP */
2547 show_main_window(FALSE);
2548 set_menus_for_capture_in_progress(FALSE);
2549 set_capture_if_dialog_for_capture_in_progress(FALSE);
2550 #endif /* HAVE_LIBPCAP */
2553 /* register our pid if we are being run from a U3 device */
2556 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
2558 /* we'll enter the GTK loop now and hand the control over to GTK ... */
2560 /* ... back from GTK, we're going down now! */
2562 /* deregister our pid */
2563 u3_deregister_pid();
2567 #ifdef HAVE_AIRPDCAP
2568 AirPDcapDestroyContext(&airpdcap_ctx);
2572 /* hide the (unresponsive) main window, while asking the user to close the console window */
2573 gtk_widget_hide(top_level);
2575 /* Shutdown windows sockets */
2578 /* For some unknown reason, the "atexit()" call in "create_console()"
2579 doesn't arrange that "destroy_console()" be called when we exit,
2580 so we call it here if a console was created. */
2586 /* This isn't reached, but we need it to keep GCC from complaining
2587 that "main()" returns without returning a value - it knows that
2588 "exit()" never returns, but it doesn't know that "gtk_exit()"
2589 doesn't, as GTK+ doesn't declare it with the attribute
2591 return 0; /* not reached */
2596 /* We build this as a GUI subsystem application on Win32, so
2597 "WinMain()", not "main()", gets called.
2599 Hack shamelessly stolen from the Win32 port of the GIMP. */
2601 #define _stdcall __attribute__((stdcall))
2605 WinMain (struct HINSTANCE__ *hInstance,
2606 struct HINSTANCE__ *hPrevInstance,
2610 INITCOMMONCONTROLSEX comm_ctrl;
2612 /* Initialize our controls. Required for native Windows file dialogs. */
2613 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
2614 comm_ctrl.dwSize = sizeof(comm_ctrl);
2615 /* Includes the animate, header, hot key, list view, progress bar,
2616 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
2619 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
2620 InitCommonControlsEx(&comm_ctrl);
2622 /* RichEd20.DLL is needed for filter entries. */
2623 LoadLibrary(_T("riched20.dll"));
2625 has_console = FALSE;
2626 return main (__argc, __argv);
2630 * If this application has no console window to which its standard output
2631 * would go, create one.
2634 create_console(void)
2637 /* We have no console to which to print the version string, so
2638 create one and make it the standard input, output, and error. */
2639 if (!AllocConsole())
2640 return; /* couldn't create console */
2641 eth_freopen("CONIN$", "r", stdin);
2642 eth_freopen("CONOUT$", "w", stdout);
2643 eth_freopen("CONOUT$", "w", stderr);
2645 /* Well, we have a console now. */
2648 /* Now register "destroy_console()" as a routine to be called just
2649 before the application exits, so that we can destroy the console
2650 after the user has typed a key (so that the console doesn't just
2651 disappear out from under them, giving the user no chance to see
2652 the message(s) we put in there). */
2653 atexit(destroy_console);
2655 SetConsoleTitle(_T("Wireshark Debug Console"));
2660 destroy_console(void)
2663 printf("\n\nPress any key to exit\n");
2671 /* This routine should not be necessary, at least as I read the GLib
2672 source code, as it looks as if GLib is, on Win32, *supposed* to
2673 create a console window into which to display its output.
2675 That doesn't happen, however. I suspect there's something completely
2676 broken about that code in GLib-for-Win32, and that it may be related
2677 to the breakage that forces us to just call "printf()" on the message
2678 rather than passing the message on to "g_log_default_handler()"
2679 (which is the routine that does the aforementioned non-functional
2680 console window creation). */
2682 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
2683 const char *message, gpointer user_data _U_)
2690 /* ignore log message, if log_level isn't interesting.
2691 If preferences aren't loaded yet, display message anyway */
2692 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
2693 prefs.console_log_level != 0) {
2697 /* create a "timestamp" */
2699 today = localtime(&curr);
2702 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
2703 /* the user wants a console or the application will terminate immediately */
2707 /* For some unknown reason, the above doesn't appear to actually cause
2708 anything to be sent to the standard output, so we'll just splat the
2709 message out directly, just to make sure it gets out. */
2711 switch(log_level & G_LOG_LEVEL_MASK) {
2712 case G_LOG_LEVEL_ERROR:
2715 case G_LOG_LEVEL_CRITICAL:
2718 case G_LOG_LEVEL_WARNING:
2721 case G_LOG_LEVEL_MESSAGE:
2724 case G_LOG_LEVEL_INFO:
2727 case G_LOG_LEVEL_DEBUG:
2731 fprintf(stderr, "unknown log_level %u\n", log_level);
2733 g_assert_not_reached();
2736 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
2737 today->tm_hour, today->tm_min, today->tm_sec,
2738 log_domain != NULL ? log_domain : "",
2741 if(log_level & G_LOG_LEVEL_ERROR) {
2742 /* wait for a key press before the following error handler will terminate the program
2743 this way the user at least can read the error message */
2744 printf("\n\nPress any key to exit\n");
2748 g_log_default_handler(log_domain, log_level, message, user_data);
2755 * Helper for main_widgets_rearrange()
2757 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
2758 gtk_container_remove(GTK_CONTAINER(data), widget);
2761 static GtkWidget *main_widget_layout(gint layout_content)
2763 switch(layout_content) {
2764 case(layout_pane_content_none):
2766 case(layout_pane_content_plist):
2768 case(layout_pane_content_pdetails):
2770 case(layout_pane_content_pbytes):
2773 g_assert_not_reached();
2780 * Rearrange the main window widgets
2782 void main_widgets_rearrange(void) {
2783 GtkWidget *first_pane_widget1, *first_pane_widget2;
2784 GtkWidget *second_pane_widget1, *second_pane_widget2;
2785 gboolean split_top_left;
2787 /* be a bit faster */
2788 gtk_widget_hide(main_vbox);
2790 /* be sure, we don't loose a widget while rearranging */
2791 gtk_widget_ref(menubar);
2792 gtk_widget_ref(main_tb);
2793 gtk_widget_ref(filter_tb);
2795 gtk_widget_ref(airpcap_tb);
2797 gtk_widget_ref(pkt_scrollw);
2798 gtk_widget_ref(tv_scrollw);
2799 gtk_widget_ref(byte_nb_ptr);
2800 gtk_widget_ref(statusbar);
2801 gtk_widget_ref(main_pane_v1);
2802 gtk_widget_ref(main_pane_v2);
2803 gtk_widget_ref(main_pane_h1);
2804 gtk_widget_ref(main_pane_h2);
2805 gtk_widget_ref(welcome_pane);
2807 /* empty all containers participating */
2808 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
2809 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
2810 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
2811 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
2812 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
2814 statusbar_widgets_emptying(statusbar);
2816 /* add the menubar always at the top */
2817 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2820 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
2822 /* filter toolbar in toolbar area */
2823 if (!prefs.filter_toolbar_show_in_statusbar) {
2824 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
2828 /* airpcap toolbar */
2829 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
2832 /* fill the main layout panes */
2833 switch(prefs.gui_layout_type) {
2834 case(layout_type_5):
2835 main_first_pane = main_pane_v1;
2836 main_second_pane = main_pane_v2;
2837 split_top_left = FALSE;
2839 case(layout_type_2):
2840 main_first_pane = main_pane_v1;
2841 main_second_pane = main_pane_h1;
2842 split_top_left = FALSE;
2844 case(layout_type_1):
2845 main_first_pane = main_pane_v1;
2846 main_second_pane = main_pane_h1;
2847 split_top_left = TRUE;
2849 case(layout_type_4):
2850 main_first_pane = main_pane_h1;
2851 main_second_pane = main_pane_v1;
2852 split_top_left = FALSE;
2854 case(layout_type_3):
2855 main_first_pane = main_pane_h1;
2856 main_second_pane = main_pane_v1;
2857 split_top_left = TRUE;
2859 case(layout_type_6):
2860 main_first_pane = main_pane_h1;
2861 main_second_pane = main_pane_h2;
2862 split_top_left = FALSE;
2865 main_first_pane = NULL;
2866 main_second_pane = NULL;
2867 split_top_left = FALSE;
2868 g_assert_not_reached();
2870 if (split_top_left) {
2871 first_pane_widget1 = main_second_pane;
2872 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2873 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
2874 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2876 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2877 first_pane_widget2 = main_second_pane;
2878 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
2879 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2881 if (first_pane_widget1 != NULL)
2882 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
2883 if (first_pane_widget2 != NULL)
2884 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
2885 if (second_pane_widget1 != NULL)
2886 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
2887 if (second_pane_widget2 != NULL)
2888 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
2890 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
2893 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
2896 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
2898 /* filter toolbar in statusbar hbox */
2899 if (prefs.filter_toolbar_show_in_statusbar) {
2900 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
2904 /* airpcap toolbar */
2905 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
2908 /* statusbar widgets */
2909 statusbar_widgets_pack(statusbar);
2911 /* hide widgets on users recent settings */
2912 main_widgets_show_or_hide();
2914 gtk_widget_show(main_vbox);
2918 is_widget_visible(GtkWidget *widget, gpointer data)
2920 gboolean *is_visible = data;
2923 if (GTK_WIDGET_VISIBLE(widget))
2930 main_widgets_show_or_hide(void)
2932 gboolean main_second_pane_show;
2934 if (recent.main_toolbar_show) {
2935 gtk_widget_show(main_tb);
2937 gtk_widget_hide(main_tb);
2940 statusbar_widgets_show_or_hide(statusbar);
2942 if (recent.filter_toolbar_show) {
2943 gtk_widget_show(filter_tb);
2945 gtk_widget_hide(filter_tb);
2949 if (recent.airpcap_toolbar_show) {
2950 gtk_widget_show(airpcap_tb);
2952 gtk_widget_hide(airpcap_tb);
2956 if (recent.packet_list_show && have_capture_file) {
2957 gtk_widget_show(pkt_scrollw);
2959 gtk_widget_hide(pkt_scrollw);
2962 if (recent.tree_view_show && have_capture_file) {
2963 gtk_widget_show(tv_scrollw);
2965 gtk_widget_hide(tv_scrollw);
2968 if (recent.byte_view_show && have_capture_file) {
2969 gtk_widget_show(byte_nb_ptr);
2971 gtk_widget_hide(byte_nb_ptr);
2974 if (have_capture_file) {
2975 gtk_widget_show(main_first_pane);
2977 gtk_widget_hide(main_first_pane);
2981 * Is anything in "main_second_pane" visible?
2982 * If so, show it, otherwise hide it.
2984 main_second_pane_show = FALSE;
2985 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
2986 &main_second_pane_show);
2987 if (main_second_pane_show) {
2988 gtk_widget_show(main_second_pane);
2990 gtk_widget_hide(main_second_pane);
2993 if (!have_capture_file) {
2995 gtk_widget_show(welcome_pane);
2998 gtk_widget_hide(welcome_pane);
3001 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
3002 packet_list_freeze ();
3003 packet_list_thaw ();
3007 /* called, when the window state changes (minimized, maximized, ...) */
3009 window_state_event_cb (GtkWidget *widget _U_,
3013 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3015 if( (event->type) == (GDK_WINDOW_STATE)) {
3016 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3017 /* we might have dialogs popped up while we where iconified,
3019 display_queued_messages();
3027 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_LOCK_MASK))
3029 top_level_key_pressed_cb(GtkCTree *ctree _U_, GdkEventKey *event, gpointer user_data _U_)
3031 if (event->keyval == GDK_F8) {
3034 } else if (event->keyval == GDK_F7) {
3037 } else if (event->state & NO_SHIFT_MOD_MASK) {
3038 return FALSE; /* Skip control, alt, and other modifiers */
3040 * A comment in gdkkeysyms.h says that it's autogenerated from
3041 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3042 * don't explicitly say so, isprint() should work as expected
3045 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3046 /* Forward the keypress on to the display filter entry */
3047 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3048 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3049 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3057 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
3059 GtkTooltips *tooltips;
3060 GtkAccelGroup *accel;
3063 /* use user-defined title if preference is set */
3064 title = create_user_window_title("The Wireshark Network Analyzer");
3067 top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
3070 tooltips = gtk_tooltips_new();
3072 gtk_widget_set_name(top_level, "main window");
3073 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3075 g_signal_connect(GTK_OBJECT(top_level), "window_state_event",
3076 G_CALLBACK(window_state_event_cb), NULL);
3077 g_signal_connect(GTK_OBJECT(top_level), "key-press-event",
3078 G_CALLBACK(top_level_key_pressed_cb), NULL );
3080 gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
3082 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3083 main_vbox = gtk_vbox_new(FALSE, 1);
3084 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
3085 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3086 gtk_widget_show(main_vbox);
3089 menubar = main_menu_new(&accel);
3090 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3091 gtk_widget_show(menubar);
3094 main_tb = toolbar_new();
3095 gtk_widget_show (main_tb);
3097 /* filter toolbar */
3098 filter_tb = filter_toolbar_new();
3101 pkt_scrollw = packet_list_new(prefs);
3102 gtk_widget_set_size_request(packet_list, -1, pl_size);
3103 gtk_widget_show(pkt_scrollw);
3106 tv_scrollw = main_tree_view_new(prefs, &tree_view);
3107 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3108 gtk_widget_show(tv_scrollw);
3110 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
3111 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3112 g_signal_connect(tree_view, "button_press_event", G_CALLBACK(popup_menu_handler),
3113 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3114 gtk_widget_show(tree_view);
3117 byte_nb_ptr = byte_view_new();
3118 gtk_widget_set_size_request(byte_nb_ptr, -1, bv_size);
3119 gtk_widget_show(byte_nb_ptr);
3121 g_signal_connect(byte_nb_ptr, "button_press_event", G_CALLBACK(popup_menu_handler),
3122 g_object_get_data(G_OBJECT(popup_menu_object), PM_HEXDUMP_KEY));
3125 /* Panes for the packet list, tree, and byte view */
3126 main_pane_v1 = gtk_vpaned_new();
3127 gtk_widget_show(main_pane_v1);
3128 main_pane_v2 = gtk_vpaned_new();
3129 gtk_widget_show(main_pane_v2);
3130 main_pane_h1 = gtk_hpaned_new();
3131 gtk_widget_show(main_pane_h1);
3132 main_pane_h2 = gtk_hpaned_new();
3133 gtk_widget_show(main_pane_h2);
3135 airpcap_tb = airpcap_toolbar_new();
3136 gtk_widget_show(airpcap_tb);
3139 statusbar = statusbar_new();
3140 gtk_widget_show(statusbar);
3142 /* Pane for the welcome screen */
3143 welcome_pane = welcome_new();
3144 gtk_widget_show(welcome_pane);
3148 show_main_window(gboolean doing_work)
3150 main_set_for_capture_file(doing_work);
3152 /*** we have finished all init things, show the main window ***/
3153 gtk_widget_show(top_level);
3155 /* the window can be maximized only, if it's visible, so do it after show! */
3156 main_load_window_geometry(top_level);
3158 /* process all pending GUI events before continue */
3159 while (gtk_events_pending()) gtk_main_iteration();
3161 /* Pop up any queued-up alert boxes. */
3162 display_queued_messages();
3164 /* Move the main window to the front, in case it isn't already there */
3165 gdk_window_raise(top_level->window);
3168 airpcap_toolbar_show(airpcap_tb);
3169 #endif /* HAVE_AIRPCAP */
3172 /* Fill in capture options with values from the preferences */
3174 prefs_to_capture_opts(void)
3177 /* Set promiscuous mode from the preferences setting. */
3178 /* the same applies to other preferences settings as well. */
3179 capture_opts->promisc_mode = prefs.capture_prom_mode;
3180 capture_opts->show_info = prefs.capture_show_info;
3181 capture_opts->real_time_mode = prefs.capture_real_time;
3182 auto_scroll_live = prefs.capture_auto_scroll;
3183 #endif /* HAVE_LIBPCAP */
3185 /* Set the name resolution code's flags from the preferences. */
3186 g_resolv_flags = prefs.name_resolve;
3190 /* Change configuration profile */
3191 void change_configuration_profile (const gchar *profile_name)
3193 char *gdp_path, *dp_path;
3195 /* First check if profile exists */
3196 if (!profile_exists(profile_name)) {
3200 /* Set profile name and update the status bar */
3201 set_profile_name (profile_name);
3202 profile_bar_update ();
3204 /* Reset current preferences and apply the new */
3206 (void) read_configuration_files (&gdp_path, &dp_path);
3209 /* Update window view and redraw the toolbar */
3210 update_main_window_name();
3211 toolbar_redraw_all();
3213 /* Enable all protocols and disable from the disabled list */
3215 if (gdp_path == NULL && dp_path == NULL) {
3216 set_disabled_protos_list();
3219 /* Reload color filters */
3220 color_filters_reload();
3222 /* Recreate the packet list according to new preferences */
3223 packet_list_recreate ();
3224 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3225 user_font_apply(prefs.gui_geometry_save_column_width);