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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <gdk/gdkkeysyms.h>
33 #if GTK_CHECK_VERSION(3,0,0)
34 # include <gdk/gdkkeysyms-compat.h>
47 #include "wsutil/wsgetopt.h"
50 #ifdef _WIN32 /* Needed for console I/O */
52 /* AttachConsole() needs this #define! */
53 #define _WIN32_WINNT 0x0501
57 #include <ui/win32/console_win32.h>
60 #ifdef HAVE_LIBPORTAUDIO
61 #include <portaudio.h>
62 #endif /* HAVE_LIBPORTAUDIO */
64 #include <wsutil/crash_info.h>
66 #include <epan/epan.h>
67 #include <epan/filesystem.h>
68 #include <wsutil/privileges.h>
69 #include <epan/epan_dissect.h>
70 #include <epan/timestamp.h>
71 #include <epan/plugins.h>
72 #include <epan/dfilter/dfilter.h>
73 #include <epan/strutil.h>
74 #include <epan/addr_resolv.h>
75 #include <epan/emem.h>
76 #include <epan/ex-opt.h>
77 #include <epan/funnel.h>
78 #include <epan/expert.h>
79 #include <epan/frequency-utils.h>
80 #include <epan/prefs.h>
81 #include <epan/prefs-int.h>
83 #include <epan/stat_cmd_args.h>
85 #include <epan/column.h>
87 /* general (not GTK specific) */
89 #include "../summary.h"
90 #include "../filters.h"
91 #include "../disabled_protos.h"
93 #include "../color_filters.h"
95 #include "../register.h"
96 #include "../ringbuffer.h"
98 #include "../clopts_common.h"
99 #include "../cmdarg_err.h"
100 #include "../version_info.h"
101 #include "../merge.h"
105 #include "gtk_iface_monitor.h"
107 #include "ui/alert_box.h"
108 #include "ui/main_statusbar.h"
109 #include "ui/preference_utils.h"
110 #include "ui/recent.h"
111 #include "ui/recent_utils.h"
112 #include "ui/simple_dialog.h"
113 #include "ui/ui_util.h"
116 #include "ui/capture_globals.h"
117 #include "ui/iface_lists.h"
120 #include <wsutil/file_util.h>
123 #include "capture_ui_utils.h"
124 #include "capture-pcap-util.h"
125 #include "capture_ifinfo.h"
127 #include "capture_sync.h"
131 #include "capture-wpcap.h"
132 #include "capture_wpcap_packet.h"
133 #include <tchar.h> /* Needed for Unicode */
134 #include <wsutil/unicode-utils.h>
135 #include <commctrl.h>
136 #include <shellapi.h>
140 #include "ui/gtk/file_dlg.h"
141 #include "ui/gtk/gtkglobals.h"
142 #include "ui/gtk/color_utils.h"
143 #include "ui/gtk/gui_utils.h"
144 #include "ui/gtk/color_dlg.h"
145 #include "ui/gtk/filter_dlg.h"
146 #include "ui/gtk/fileset_dlg.h"
147 #include "ui/gtk/uat_gui.h"
148 #include "ui/gtk/main.h"
149 #include "ui/gtk/main_80211_toolbar.h"
150 #include "ui/gtk/main_airpcap_toolbar.h"
151 #include "ui/gtk/main_filter_toolbar.h"
152 #include "ui/gtk/main_titlebar.h"
153 #include "ui/gtk/menus.h"
154 #include "ui/gtk/main_menubar_private.h"
155 #include "ui/gtk/macros_dlg.h"
156 #include "ui/gtk/main_statusbar_private.h"
157 #include "ui/gtk/main_toolbar.h"
158 #include "ui/gtk/main_toolbar_private.h"
159 #include "ui/gtk/main_welcome.h"
160 #include "ui/gtk/drag_and_drop.h"
161 #include "ui/gtk/capture_file_dlg.h"
162 #include "ui/gtk/packet_panes.h"
163 #include "ui/gtk/keys.h"
164 #include "ui/gtk/packet_win.h"
165 #include "ui/gtk/stock_icons.h"
166 #include "ui/gtk/find_dlg.h"
167 #include "ui/gtk/follow_tcp.h"
168 #include "ui/gtk/font_utils.h"
169 #include "ui/gtk/about_dlg.h"
170 #include "ui/gtk/help_dlg.h"
171 #include "ui/gtk/decode_as_dlg.h"
172 #include "ui/gtk/webbrowser.h"
173 #include "ui/gtk/capture_dlg.h"
174 #include "ui/gtk/capture_if_dlg.h"
175 #include "ui/gtk/tap_param_dlg.h"
176 #include "ui/gtk/prefs_column.h"
177 #include "ui/gtk/prefs_dlg.h"
178 #include "ui/gtk/proto_help.h"
179 #include "ui/gtk/packet_list.h"
180 #include "ui/gtk/filter_expression_save_dlg.h"
182 #include "ui/gtk/old-gtk-compat.h"
185 #include "../../image/wsicon16.xpm"
186 #include "../../image/wsicon32.xpm"
187 #include "../../image/wsicon48.xpm"
188 #include "../../image/wsicon64.xpm"
189 #include "../../image/wsiconcap16.xpm"
190 #include "../../image/wsiconcap32.xpm"
191 #include "../../image/wsiconcap48.xpm"
196 #include "airpcap_loader.h"
197 #include "airpcap_dlg.h"
198 #include "airpcap_gui_utils.h"
201 #include <epan/crypt/airpdcap_ws.h>
204 #ifdef HAVE_GTKOSXAPPLICATION
205 #include <gtkmacintegration/gtkosxapplication.h>
209 * Files under personal and global preferences directories in which
210 * GTK settings for Wireshark are stored.
212 #define RC_FILE "gtkrc"
216 static gboolean capture_stopping;
218 /* "exported" main widgets */
219 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
221 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
222 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
223 static GtkWidget *main_first_pane, *main_second_pane;
225 /* internally used widgets */
226 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
228 GtkWidget *wireless_tb;
230 int airpcap_dll_ret_val = -1;
233 GString *comp_info_str, *runtime_info_str;
235 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
237 static guint tap_update_timer_id;
239 static void console_log_handler(const char *log_domain,
240 GLogLevelFlags log_level, const char *message, gpointer user_data);
242 static void create_main_window(gint, gint, gint, e_prefs*);
243 static void show_main_window(gboolean);
244 static void main_save_window_geometry(GtkWidget *widget);
247 /* Match selected byte pattern */
249 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
251 char *cur_filter, *new_filter;
253 if ((!text) || (0 == strlen(text))) {
254 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
260 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
262 switch (action&MATCH_SELECTED_MASK) {
264 case MATCH_SELECTED_REPLACE:
265 new_filter = g_strdup(text);
268 case MATCH_SELECTED_AND:
269 if ((!cur_filter) || (0 == strlen(cur_filter)))
270 new_filter = g_strdup(text);
272 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
275 case MATCH_SELECTED_OR:
276 if ((!cur_filter) || (0 == strlen(cur_filter)))
277 new_filter = g_strdup(text);
279 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
282 case MATCH_SELECTED_NOT:
283 new_filter = g_strconcat("!(", text, ")", NULL);
286 case MATCH_SELECTED_AND_NOT:
287 if ((!cur_filter) || (0 == strlen(cur_filter)))
288 new_filter = g_strconcat("!(", text, ")", NULL);
290 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
293 case MATCH_SELECTED_OR_NOT:
294 if ((!cur_filter) || (0 == strlen(cur_filter)))
295 new_filter = g_strconcat("!(", text, ")", NULL);
297 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
301 g_assert_not_reached();
306 /* Free up the copy we got of the old filter text. */
309 /* Don't change the current display filter if we only want to copy the filter */
310 if (action&MATCH_SELECTED_COPY_ONLY) {
311 GString *gtk_text_str = g_string_new("");
312 g_string_append(gtk_text_str, new_filter);
313 copy_to_clipboard(gtk_text_str);
314 g_string_free(gtk_text_str, TRUE);
316 /* create a new one and set the display filter entry accordingly */
317 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
319 /* Run the display filter so it goes in effect. */
320 if (action&MATCH_SELECTED_APPLY_NOW)
321 main_filter_packets(&cfile, new_filter, FALSE);
324 /* Free up the new filter text. */
329 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
333 if (cfile.finfo_selected) {
334 filter = proto_construct_match_selected_string(cfile.finfo_selected,
336 match_selected_cb_do(g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
341 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
345 if (cfile.finfo_selected) {
346 filter = proto_construct_match_selected_string(cfile.finfo_selected,
348 if ((!filter) || (0 == strlen(filter))) {
349 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
350 "Could not acquire information to build a filter!\n"
351 "Try expanding or choosing another item.");
356 color_display_with_filter(filter);
359 color_filters_reset_tmp();
361 color_filters_set_tmp(filt_nr,filter, FALSE);
363 packet_list_colorize_packets();
369 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
371 gchar *selected_proto_url;
372 gchar *proto_abbrev = data;
377 if (cfile.finfo_selected) {
378 /* open wiki page using the protocol abbreviation */
379 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
380 browser_open_url(selected_proto_url);
381 g_free(selected_proto_url);
384 case(ESD_BTN_CANCEL):
387 g_assert_not_reached();
393 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
396 const gchar *proto_abbrev;
400 if (cfile.finfo_selected) {
401 /* convert selected field to protocol abbreviation */
402 /* XXX - could this conversion be simplified? */
403 field_id = cfile.finfo_selected->hfinfo->id;
404 /* if the selected field isn't a protocol, get it's parent */
405 if(!proto_registrar_is_protocol(field_id)) {
406 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
409 proto_abbrev = proto_registrar_get_abbrev(field_id);
411 if (!proto_is_private(field_id)) {
412 /* ask the user if the wiki page really should be opened */
413 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
414 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
416 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
418 "The Wireshark Wiki is a collaborative approach to provide information "
419 "about Wireshark in several ways (not limited to protocol specifics).\n"
421 "This Wiki is new, so the page of the selected protocol "
422 "may not exist and/or may not contain valuable information.\n"
424 "As everyone can edit the Wiki and add new content (or extend existing), "
425 "you are encouraged to add information if you can.\n"
427 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
429 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
430 "which will save you a lot of editing and will give a consistent look over the pages.",
431 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
432 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
434 /* appologize to the user that the wiki page cannot be opened */
435 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
436 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
438 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
440 "Since this is a private protocol, such information is not available in "
441 "a public wiki. Therefore this wiki entry is blocked.\n"
443 "Sorry for the inconvenience.\n",
444 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
449 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
451 gchar *selected_proto_url;
452 gchar *proto_abbrev = data;
456 if (cfile.finfo_selected) {
457 /* open reference page using the protocol abbreviation */
458 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
459 browser_open_url(selected_proto_url);
460 g_free(selected_proto_url);
463 case(ESD_BTN_CANCEL):
466 g_assert_not_reached();
471 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
474 const gchar *proto_abbrev;
478 if (cfile.finfo_selected) {
479 /* convert selected field to protocol abbreviation */
480 /* XXX - could this conversion be simplified? */
481 field_id = cfile.finfo_selected->hfinfo->id;
482 /* if the selected field isn't a protocol, get it's parent */
483 if(!proto_registrar_is_protocol(field_id)) {
484 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
487 proto_abbrev = proto_registrar_get_abbrev(field_id);
489 if (!proto_is_private(field_id)) {
490 /* ask the user if the wiki page really should be opened */
491 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
492 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
494 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
496 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
497 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
499 /* appologize to the user that the wiki page cannot be opened */
500 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
501 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
503 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
505 "Since this is a private protocol, such information is not available on "
506 "a public website. Therefore this filter entry is blocked.\n"
508 "Sorry for the inconvenience.\n",
509 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
515 is_address_column (gint column)
517 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
518 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
519 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
520 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
521 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
530 get_ip_address_list_from_packet_list_row(gpointer data)
532 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
533 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
536 GList *addr_list = NULL;
538 fdata = (frame_data *) packet_list_get_row_data(row);
543 if (!cf_read_frame (&cfile, fdata))
544 return NULL; /* error reading the frame */
546 epan_dissect_init(&edt, FALSE, FALSE);
547 col_custom_prime_edt(&edt, &cfile.cinfo);
549 epan_dissect_run(&edt, &cfile.phdr, cfile.pd, fdata, &cfile.cinfo);
550 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
552 /* First check selected column */
553 if (is_address_column (column)) {
554 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
557 for (col = 0; col < cfile.cinfo.num_cols; col++) {
558 /* Then check all columns except the selected */
559 if ((col != column) && (is_address_column (col))) {
560 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
564 epan_dissect_cleanup(&edt);
571 get_filter_from_packet_list_row_and_column(gpointer data)
573 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
574 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
578 fdata = (frame_data *) packet_list_get_row_data(row);
583 if (!cf_read_frame(&cfile, fdata))
584 return NULL; /* error reading the frame */
585 /* proto tree, visible. We need a proto tree if there's custom columns */
586 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
587 col_custom_prime_edt(&edt, &cfile.cinfo);
589 epan_dissect_run(&edt, &cfile.phdr, cfile.pd, fdata, &cfile.cinfo);
590 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
592 if ((cfile.cinfo.col_custom_occurrence[column]) ||
593 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
595 /* Only construct the filter when a single occurrence is displayed
596 * otherwise we might end up with a filter like "ip.proto==1,6".
598 * Or do we want to be able to filter on multiple occurrences so that
599 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
602 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
603 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
604 /* leak a little but safer than ep_ here */
605 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
606 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
607 if (hfi->parent == -1) {
609 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
610 } else if (hfi->type == FT_STRING) {
611 /* Custom string, add quotes */
612 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
613 cfile.cinfo.col_expr.col_expr_val[column]);
617 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
618 cfile.cinfo.col_expr.col_expr_val[column]);
623 epan_dissect_cleanup(&edt);
630 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
632 match_selected_cb_do(g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
634 get_filter_from_packet_list_row_and_column(data));
637 /* This function allows users to right click in the details window and copy the text
638 * information to the operating systems clipboard.
640 * We first check to see if a string representation is setup in the tree and then
641 * read the string. If not available then we try to grab the value. If all else
642 * fails we display a message to the user to indicate the copy could not be completed.
645 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
647 GString *gtk_text_str = g_string_new("");
648 char labelstring[ITEM_LABEL_LENGTH];
649 char *stringpointer = labelstring;
653 case COPY_SELECTED_DESCRIPTION:
654 if (cfile.finfo_selected->rep &&
655 strlen (cfile.finfo_selected->rep->representation) > 0) {
656 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
659 case COPY_SELECTED_FIELDNAME:
660 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
661 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
664 case COPY_SELECTED_VALUE:
665 if (cfile.edt !=0 ) {
666 g_string_append(gtk_text_str,
667 get_node_field_value(cfile.finfo_selected, cfile.edt));
674 if (gtk_text_str->len == 0) {
675 /* If no representation then... Try to read the value */
676 proto_item_fill_label(cfile.finfo_selected, stringpointer);
677 g_string_append(gtk_text_str, stringpointer);
680 if (gtk_text_str->len == 0) {
681 /* Could not get item so display error msg */
682 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
684 /* Copy string to clipboard */
685 copy_to_clipboard(gtk_text_str);
687 g_string_free(gtk_text_str, TRUE); /* Free the memory */
691 /* mark as reference time frame */
693 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
697 frame->flags.ref_time=1;
698 cfile.ref_time_count++;
700 frame->flags.ref_time=0;
701 cfile.ref_time_count--;
703 cf_reftime_packets(&cfile);
704 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
705 packet_list_freeze();
706 cfile.displayed_count--;
707 packet_list_recreate_visible_rows();
710 packet_list_queue_draw();
714 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
718 timestamp_set_type(TS_RELATIVE);
719 recent.gui_time_format = TS_RELATIVE;
720 cf_timestamp_auto_precision(&cfile);
721 packet_list_queue_draw();
726 g_assert_not_reached();
729 if (cfile.current_frame) {
730 set_frame_reftime(!cfile.current_frame->flags.ref_time,
731 cfile.current_frame, cfile.current_row);
737 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
739 static GtkWidget *reftime_dialog = NULL;
743 if (cfile.current_frame) {
744 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
745 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
746 "%sSwitch to the appropriate Time Display Format?%s\n\n"
747 "Time References don't work well with the currently selected Time Display Format.\n\n"
748 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
749 simple_dialog_primary_start(), simple_dialog_primary_end());
750 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
752 set_frame_reftime(!cfile.current_frame->flags.ref_time,
753 cfile.current_frame, cfile.current_row);
757 case REFTIME_FIND_NEXT:
758 cf_find_packet_time_reference(&cfile, SD_FORWARD);
760 case REFTIME_FIND_PREV:
761 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
767 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
769 cf_find_packet_marked(&cfile, SD_FORWARD);
773 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
775 cf_find_packet_marked(&cfile, SD_BACKWARD);
779 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
782 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
784 gboolean has_blurb = FALSE;
785 guint length = 0, byte_len;
786 GtkWidget *byte_view;
787 const guint8 *byte_data;
792 /* if nothing is selected */
793 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
796 * Which byte view is displaying the current protocol tree
799 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
800 if (byte_view == NULL)
803 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
804 if (byte_data == NULL)
807 cf_unselect_field(&cfile);
808 packet_hex_print(byte_view, byte_data,
809 cfile.current_frame, NULL, byte_len);
810 proto_help_menu_modify(sel, &cfile);
813 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
816 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
818 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
819 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
820 g_assert(byte_data != NULL);
822 cfile.finfo_selected = finfo;
823 set_menus_for_selected_tree_row(&cfile);
826 if (finfo->hfinfo->blurb != NULL &&
827 finfo->hfinfo->blurb[0] != '\0') {
829 length = (guint) strlen(finfo->hfinfo->blurb);
831 length = (guint) strlen(finfo->hfinfo->name);
833 finfo_length = finfo->length + finfo->appendix_length;
835 if (finfo_length == 0) {
837 } else if (finfo_length == 1) {
838 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
840 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
842 statusbar_pop_field_msg(); /* get rid of current help msg */
844 statusbar_push_field_msg(" %s (%s)%s",
845 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
846 finfo->hfinfo->abbrev, len_str);
849 * Don't show anything if the field name is zero-length;
850 * the pseudo-field for "proto_tree_add_text()" is such
851 * a field, and we don't want "Text (text)" showing up
852 * on the status line if you've selected such a field.
854 * XXX - there are zero-length fields for which we *do*
855 * want to show the field name.
857 * XXX - perhaps the name and abbrev field should be null
858 * pointers rather than null strings for that pseudo-field,
859 * but we'd have to add checks for null pointers in some
860 * places if we did that.
862 * Or perhaps protocol tree items added with
863 * "proto_tree_add_text()" should have -1 as the field index,
864 * with no pseudo-field being used, but that might also
865 * require special checks for -1 to be added.
867 statusbar_push_field_msg("%s", "");
870 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
872 proto_help_menu_modify(sel, &cfile);
875 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
877 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
880 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
882 expand_all_tree(cfile.edt->tree, tree_view_gbl);
885 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
887 if (cfile.finfo_selected) {
888 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
889 cfile.finfo_selected->hfinfo->abbrev,0);
890 /* Recreate the packet list according to new preferences */
891 packet_list_recreate ();
892 if (!prefs.gui_use_pref_save) {
895 cfile.columns_changed = FALSE; /* Reset value */
899 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
902 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
904 /* the mouse position is at an entry, expand that one */
905 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
906 gtk_tree_path_free(path);
910 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
911 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
913 if (cfile.edt->tree) {
914 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
918 /* Update main window items based on whether there's a capture in progress. */
920 main_set_for_capture_in_progress(gboolean capture_in_progress)
922 set_menus_for_capture_in_progress(capture_in_progress);
925 set_toolbar_for_capture_in_progress(capture_in_progress);
927 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
931 /* Update main window items based on whether we have a capture file. */
933 main_set_for_capture_file(gboolean have_capture_file_in)
935 have_capture_file = have_capture_file_in;
937 main_widgets_show_or_hide();
940 /* Update main window items based on whether we have captured packets. */
942 main_set_for_captured_packets(gboolean have_captured_packets)
944 set_menus_for_captured_packets(have_captured_packets);
945 set_toolbar_for_captured_packets(have_captured_packets);
948 /* Update main window items based on whether we have a packet history. */
950 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
952 set_menus_for_packet_history(back_history, forward_history);
953 set_toolbar_for_packet_history(back_history, forward_history);
959 /* get the current geometry, before writing it to disk */
960 main_save_window_geometry(top_level);
962 /* write user's recent file to disk
963 * It is no problem to write this file, even if we do not quit */
964 write_profile_recent();
967 /* XXX - should we check whether the capture file is an
968 unsaved temporary file for a live capture and, if so,
969 pop up a "do you want to exit without saving the capture
970 file?" dialog, and then just return, leaving said dialog
971 box to forcibly quit if the user clicks "OK"?
973 If so, note that this should be done in a subroutine that
974 returns TRUE if we do so, and FALSE otherwise, and if it
975 returns TRUE we should return TRUE without nuking anything.
977 Note that, if we do that, we might also want to check if
978 an "Update list of packets in real time" capture is in
979 progress and, if so, ask whether they want to terminate
980 the capture and discard it, and return TRUE, before nuking
981 any child capture, if they say they don't want to do so. */
984 /* Nuke any child capture in progress. */
985 capture_kill_child(&global_capture_opts);
988 /* Are we in the middle of reading a capture? */
989 if (cfile.state == FILE_READ_IN_PROGRESS) {
990 /* Yes, so we can't just close the file and quit, as
991 that may yank the rug out from under the read in
992 progress; instead, just set the state to
993 "FILE_READ_ABORTED" and return - the code doing the read
994 will check for that and, if it sees that, will clean
996 cfile.state = FILE_READ_ABORTED;
998 /* Say that the window should *not* be deleted;
999 that'll be done by the code that cleans up. */
1002 /* Close any capture file we have open; on some OSes, you
1003 can't unlink a temporary capture file if you have it
1005 "cf_close()" will unlink it after closing it if
1006 it's a temporary file.
1008 We do this here, rather than after the main loop returns,
1009 as, after the main loop returns, the main window may have
1010 been destroyed (if this is called due to a "destroy"
1011 even on the main window rather than due to the user
1012 selecting a menu item), and there may be a crash
1013 or other problem when "cf_close()" tries to
1014 clean up stuff in the main window.
1016 XXX - is there a better place to put this?
1017 Or should we have a routine that *just* closes the
1018 capture file, and doesn't do anything with the UI,
1019 which we'd call here, and another routine that
1020 calls that routine and also cleans up the UI, which
1021 we'd call elsewhere? */
1024 /* Exit by leaving the main loop, so that any quit functions
1025 we registered get called. */
1028 /* Say that the window should be deleted. */
1034 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1036 /* If we're in the middle of stopping a capture, don't do anything;
1037 the user can try deleting the window after the capture stops. */
1038 if (capture_stopping)
1041 /* If there's unsaved data, let the user save it first.
1042 If they cancel out of it, don't quit. */
1043 if (do_file_close(&cfile, TRUE, " before quitting"))
1044 return main_do_quit();
1046 return TRUE; /* will this keep the window from being deleted? */
1051 main_pane_load_window_geometry(void)
1053 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1054 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1055 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1056 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1062 main_load_window_geometry(GtkWidget *widget)
1064 window_geometry_t geom;
1066 geom.set_pos = prefs.gui_geometry_save_position;
1067 geom.x = recent.gui_geometry_main_x;
1068 geom.y = recent.gui_geometry_main_y;
1069 geom.set_size = prefs.gui_geometry_save_size;
1070 if (recent.gui_geometry_main_width > 0 &&
1071 recent.gui_geometry_main_height > 0) {
1072 geom.width = recent.gui_geometry_main_width;
1073 geom.height = recent.gui_geometry_main_height;
1074 geom.set_maximized = prefs.gui_geometry_save_maximized;
1076 /* We assume this means the width and height weren't set in
1077 the "recent" file (or that there is no "recent" file),
1078 and weren't set to a default value, so we don't set the
1079 size. (The "recent" file code rejects non-positive width
1080 and height values.) */
1081 geom.set_size = FALSE;
1083 geom.maximized = recent.gui_geometry_main_maximized;
1085 window_set_geometry(widget, &geom);
1087 main_pane_load_window_geometry();
1088 statusbar_load_window_geometry();
1093 main_save_window_geometry(GtkWidget *widget)
1095 window_geometry_t geom;
1097 window_get_geometry(widget, &geom);
1099 if (prefs.gui_geometry_save_position) {
1100 recent.gui_geometry_main_x = geom.x;
1101 recent.gui_geometry_main_y = geom.y;
1104 if (prefs.gui_geometry_save_size) {
1105 recent.gui_geometry_main_width = geom.width;
1106 recent.gui_geometry_main_height = geom.height;
1109 if(prefs.gui_geometry_save_maximized) {
1110 recent.gui_geometry_main_maximized = geom.maximized;
1113 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1114 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1115 statusbar_save_window_geometry();
1119 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1121 /* If there's unsaved data, let the user save it first. */
1122 if (do_file_close(&cfile, TRUE, " before quitting"))
1127 print_usage(gboolean print_ver) {
1137 fprintf(output, "Wireshark " VERSION "%s\n"
1138 "Interactively dump and analyze network traffic.\n"
1139 "See http://www.wireshark.org for more information.\n"
1142 wireshark_svnversion, get_copyright_info());
1146 fprintf(output, "\n");
1147 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1148 fprintf(output, "\n");
1151 fprintf(output, "Capture interface:\n");
1152 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1153 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1154 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1155 fprintf(output, " -p don't capture in promiscuous mode\n");
1156 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1157 fprintf(output, " -S update packet display when new packets are captured\n");
1158 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1159 #ifdef HAVE_PCAP_CREATE
1160 fprintf(output, " -I capture in monitor mode, if available\n");
1162 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1163 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1165 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1166 fprintf(output, " -D print list of interfaces and exit\n");
1167 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1168 fprintf(output, "\n");
1169 fprintf(output, "Capture stop conditions:\n");
1170 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1171 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1172 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1173 fprintf(output, " files:NUM - stop after NUM files\n");
1174 /*fprintf(output, "\n");*/
1175 fprintf(output, "Capture output:\n");
1176 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1177 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1178 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1179 #endif /* HAVE_LIBPCAP */
1180 #ifdef HAVE_PCAP_REMOTE
1181 fprintf(output, "RPCAP options:\n");
1182 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1184 /*fprintf(output, "\n");*/
1185 fprintf(output, "Input file:\n");
1186 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1188 fprintf(output, "\n");
1189 fprintf(output, "Processing:\n");
1190 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1191 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1192 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1194 fprintf(output, "\n");
1195 fprintf(output, "User interface:\n");
1196 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1197 fprintf(output, " -d <display filter> start with the given display filter\n");
1198 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1199 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1200 fprintf(output, " filter\n");
1201 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1202 fprintf(output, " -m <font> set the font name used for most text\n");
1203 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1204 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1205 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1206 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1208 fprintf(output, "\n");
1209 fprintf(output, "Output:\n");
1210 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1212 fprintf(output, "\n");
1213 fprintf(output, "Miscellaneous:\n");
1214 fprintf(output, " -h display this help and exit\n");
1215 fprintf(output, " -v display version info and exit\n");
1216 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1217 fprintf(output, " persdata:path - personal data files\n");
1218 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1219 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1221 fprintf(output, " --display=DISPLAY X display to use\n");
1236 printf(PACKAGE " " VERSION "%s\n"
1243 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1244 runtime_info_str->str);
1252 * Print to the standard error. On Windows, create a console for the
1253 * standard error to show up on, if necessary.
1254 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1255 * terminal isn't the standard error?
1258 vfprintf_stderr(const char *fmt, va_list ap)
1263 vfprintf(stderr, fmt, ap);
1267 fprintf_stderr(const char *fmt, ...)
1272 vfprintf_stderr(fmt, ap);
1277 * Report an error in command-line arguments.
1278 * Creates a console on Windows.
1281 cmdarg_err(const char *fmt, ...)
1285 fprintf_stderr("wireshark: ");
1287 vfprintf_stderr(fmt, ap);
1289 fprintf_stderr("\n");
1293 * Report additional information for an error in command-line arguments.
1294 * Creates a console on Windows.
1295 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1296 * terminal isn't the standard error?
1299 cmdarg_err_cont(const char *fmt, ...)
1304 vfprintf_stderr(fmt, ap);
1305 fprintf_stderr("\n");
1310 Once every 3 seconds we get a callback here which we use to update
1314 tap_update_cb(gpointer data _U_)
1316 draw_tap_listeners(FALSE);
1320 /* Restart the tap update display timer with new configured interval */
1321 void reset_tap_update_timer(void)
1323 g_source_remove(tap_update_timer_id);
1324 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1328 * Periodically process outstanding hostname lookups. If we have new items,
1329 * redraw the packet list and tree view.
1333 resolv_update_cb(gpointer data _U_)
1335 /* Anything new show up? */
1336 if (host_name_lookup_process()) {
1337 if (gtk_widget_get_window(pkt_scrollw))
1338 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1339 if (gtk_widget_get_window(tv_scrollw))
1340 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1343 /* Always check. Even if we don't do async lookups we could still get
1344 passive updates, e.g. from DNS packets. */
1349 /* Set main_window_name and it's icon title to the capture filename */
1351 set_display_filename(capture_file *cf)
1353 gchar *display_name;
1357 display_name = cf_get_display_name(cf);
1358 window_name = g_strdup_printf("%s%s", cf->unsaved_changes ? "*" : "",
1360 g_free(display_name);
1361 main_set_window_name(window_name);
1362 g_free(window_name);
1364 main_set_window_name("The Wireshark Network Analyzer");
1368 /* Update various parts of the main window for a capture file "unsaved
1369 changes" change - update the title to reflect whether there are
1370 unsaved changes or not, and update the menus and toolbar to
1371 enable or disable the "Save" operation. */
1373 main_update_for_unsaved_changes(capture_file *cf)
1375 set_display_filename(cf);
1376 set_menus_for_capture_file(cf);
1377 set_toolbar_for_capture_file(cf);
1382 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1384 /* Update menubar and toolbar */
1385 menu_auto_scroll_live_changed(auto_scroll_live_in);
1386 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1388 /* change auto scroll state */
1389 auto_scroll_live = auto_scroll_live_in;
1394 main_colorize_changed(gboolean packet_list_colorize)
1396 /* Update menubar and toolbar */
1397 menu_colorize_changed(packet_list_colorize);
1398 toolbar_colorize_changed(packet_list_colorize);
1400 /* change colorization */
1401 if(packet_list_colorize != recent.packet_list_colorize) {
1402 recent.packet_list_colorize = packet_list_colorize;
1403 color_filters_enable(packet_list_colorize);
1404 packet_list_colorize_packets();
1408 static GtkWidget *close_dlg = NULL;
1411 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1413 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1418 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1420 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1425 main_cf_cb_file_closing(capture_file *cf)
1427 /* if we have more than 10000 packets, show a splash screen while closing */
1428 /* XXX - don't know a better way to decide whether to show or not,
1429 * as most of the time is spend in various calls that destroy various
1430 * data structures, so it wouldn't be easy to use a progress bar,
1431 * rather than, say, a progress spinner, here! */
1432 if(cf->count > 10000) {
1433 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1434 "%sClosing file!%s\n\nPlease wait ...",
1435 simple_dialog_primary_start(),
1436 simple_dialog_primary_end());
1437 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1440 /* Destroy all windows that refer to the
1441 capture file we're closing. */
1442 destroy_packet_wins();
1444 /* Restore the standard title bar message. */
1445 main_set_window_name("The Wireshark Network Analyzer");
1447 /* Disable all menu items that make sense only if you have a capture. */
1448 set_menus_for_capture_file(NULL);
1449 set_toolbar_for_capture_file(NULL);
1450 main_set_for_captured_packets(FALSE);
1451 set_menus_for_selected_packet(cf);
1452 main_set_for_capture_in_progress(FALSE);
1453 set_capture_if_dialog_for_capture_in_progress(FALSE);
1454 set_menus_for_selected_tree_row(cf);
1456 /* Set up main window for no capture file. */
1457 main_set_for_capture_file(FALSE);
1459 main_window_update();
1463 main_cf_cb_file_closed(capture_file *cf _U_)
1465 if(close_dlg != NULL) {
1466 splash_destroy(close_dlg);
1473 main_cf_cb_file_read_started(capture_file *cf _U_)
1475 tap_param_dlg_update();
1477 /* Set up main window for a capture file. */
1478 main_set_for_capture_file(TRUE);
1482 main_cf_cb_file_read_finished(capture_file *cf)
1486 if (!cf->is_tempfile && cf->filename) {
1487 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1488 add_menu_recent_capture_file(cf->filename);
1490 /* Remember folder for next Open dialog and save it in recent */
1491 dir_path = get_dirname(g_strdup(cf->filename));
1492 set_last_open_dir(dir_path);
1496 /* Update the appropriate parts of the main window. */
1497 main_update_for_unsaved_changes(cf);
1499 /* Enable menu items that make sense if you have some captured packets. */
1500 main_set_for_captured_packets(TRUE);
1504 main_cf_cb_file_rescan_finished(capture_file *cf)
1508 if (!cf->is_tempfile && cf->filename) {
1509 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1510 add_menu_recent_capture_file(cf->filename);
1512 /* Remember folder for next Open dialog and save it in recent */
1513 dir_path = get_dirname(g_strdup(cf->filename));
1514 set_last_open_dir(dir_path);
1518 /* Update the appropriate parts of the main window. */
1519 main_update_for_unsaved_changes(cf);
1523 static GList *icon_list_create(
1524 const char **icon16_xpm,
1525 const char **icon32_xpm,
1526 const char **icon48_xpm,
1527 const char **icon64_xpm)
1529 GList *icon_list = NULL;
1530 GdkPixbuf * pixbuf16;
1531 GdkPixbuf * pixbuf32;
1532 GdkPixbuf * pixbuf48;
1533 GdkPixbuf * pixbuf64;
1536 if(icon16_xpm != NULL) {
1537 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1539 icon_list = g_list_append(icon_list, pixbuf16);
1542 if(icon32_xpm != NULL) {
1543 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1545 icon_list = g_list_append(icon_list, pixbuf32);
1548 if(icon48_xpm != NULL) {
1549 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1551 icon_list = g_list_append(icon_list, pixbuf48);
1554 if(icon64_xpm != NULL) {
1555 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1557 icon_list = g_list_append(icon_list, pixbuf64);
1564 main_capture_set_main_window_title(capture_options *capture_opts)
1566 GString *title = g_string_new("");
1568 g_string_append(title, "Capturing ");
1569 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1570 main_set_window_name(title->str);
1571 g_string_free(title, TRUE);
1575 main_capture_cb_capture_prepared(capture_options *capture_opts)
1577 static GList *icon_list = NULL;
1579 main_capture_set_main_window_title(capture_opts);
1581 if(icon_list == NULL) {
1582 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1584 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1586 /* Disable menu items that make no sense if you're currently running
1588 main_set_for_capture_in_progress(TRUE);
1589 set_capture_if_dialog_for_capture_in_progress(TRUE);
1591 /* Don't set up main window for a capture file. */
1592 main_set_for_capture_file(FALSE);
1596 main_capture_cb_capture_update_started(capture_options *capture_opts)
1598 /* We've done this in "prepared" above, but it will be cleared while
1599 switching to the next multiple file. */
1600 main_capture_set_main_window_title(capture_opts);
1602 main_set_for_capture_in_progress(TRUE);
1603 set_capture_if_dialog_for_capture_in_progress(TRUE);
1605 /* Enable menu items that make sense if you have some captured
1606 packets (yes, I know, we don't have any *yet*). */
1607 main_set_for_captured_packets(TRUE);
1609 /* Set up main window for a capture file. */
1610 main_set_for_capture_file(TRUE);
1614 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1616 capture_file *cf = capture_opts->cf;
1617 static GList *icon_list = NULL;
1619 /* The capture isn't stopping any more - it's stopped. */
1620 capture_stopping = FALSE;
1622 if (!cf->is_tempfile && cf->filename) {
1623 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1624 add_menu_recent_capture_file(cf->filename);
1627 /* Enable menu items that make sense if you're not currently running
1629 main_set_for_capture_in_progress(FALSE);
1630 set_capture_if_dialog_for_capture_in_progress(FALSE);
1632 /* Update the main window as appropriate. This has to occur AFTER
1633 * main_set_for_capture_in_progress() or else some of the menus are
1634 * incorrectly disabled (see bug
1635 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1636 main_update_for_unsaved_changes(cf);
1638 /* Set up main window for a capture file. */
1639 main_set_for_capture_file(TRUE);
1641 if(icon_list == NULL) {
1642 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1644 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1646 if(global_capture_opts.quit_after_cap) {
1647 /* command line asked us to quit after the capture */
1648 /* don't pop up a dialog to ask for unsaved files etc. */
1654 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1656 /* Don't set up main window for a capture file. */
1657 main_set_for_capture_file(FALSE);
1661 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1664 capture_file *cf = capture_opts->cf;
1666 static GList *icon_list = NULL;
1668 /* The capture isn't stopping any more - it's stopped. */
1669 capture_stopping = FALSE;
1671 /*set_display_filename(cf);*/
1673 /* Enable menu items that make sense if you're not currently running
1675 main_set_for_capture_in_progress(FALSE);
1676 set_capture_if_dialog_for_capture_in_progress(FALSE);
1678 /* Restore the standard title bar message */
1679 /* (just in case we have trouble opening the capture file). */
1680 main_set_window_name("The Wireshark Network Analyzer");
1682 if(icon_list == NULL) {
1683 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1685 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1687 /* We don't have loaded the capture file, this will be done later.
1688 * For now we still have simply a blank screen. */
1690 if(global_capture_opts.quit_after_cap) {
1691 /* command line asked us to quit after the capture */
1692 /* don't pop up a dialog to ask for unsaved files etc. */
1698 main_capture_cb_capture_stopping(capture_options *capture_opts _U_)
1700 capture_stopping = TRUE;
1701 set_menus_for_capture_stopping();
1703 set_toolbar_for_capture_stopping();
1705 set_capture_if_dialog_for_capture_stopping();
1710 main_capture_cb_capture_failed(capture_options *capture_opts _U_)
1712 static GList *icon_list = NULL;
1714 /* Capture isn't stopping any more. */
1715 capture_stopping = FALSE;
1717 /* the capture failed before the first packet was captured
1718 reset title, menus and icon */
1720 main_set_window_name("The Wireshark Network Analyzer");
1722 main_set_for_capture_in_progress(FALSE);
1723 set_capture_if_dialog_for_capture_in_progress(FALSE);
1725 main_set_for_capture_file(FALSE);
1727 if(icon_list == NULL) {
1728 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1730 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1733 if(global_capture_opts.quit_after_cap) {
1734 /* command line asked us to quit after the capture */
1735 /* don't pop up a dialog to ask for unsaved files etc. */
1739 #endif /* HAVE_LIBPCAP */
1742 main_cf_cb_packet_selected(gpointer data)
1744 capture_file *cf = data;
1746 /* Display the GUI protocol tree and packet bytes.
1747 XXX - why do we dump core if we call "proto_tree_draw()"
1748 before calling "add_byte_views()"? */
1749 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1750 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1752 /* Note: Both string and hex value searches in the packet data produce a non-zero
1753 search_pos if successful */
1754 if(cf->search_in_progress &&
1755 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1756 highlight_field(cf->edt->tvb, cf->search_pos,
1757 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1760 /* A packet is selected. */
1761 set_menus_for_selected_packet(cf);
1765 main_cf_cb_packet_unselected(capture_file *cf)
1767 /* No packet is being displayed; clear the hex dump pane by getting
1768 rid of all the byte views. */
1769 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1770 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1772 /* Add a placeholder byte view so that there's at least something
1773 displayed in the byte view notebook. */
1774 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1776 /* And clear the protocol tree display as well. */
1777 proto_tree_draw(NULL, tree_view_gbl);
1779 /* No packet is selected. */
1780 set_menus_for_selected_packet(cf);
1784 main_cf_cb_field_unselected(capture_file *cf)
1786 set_menus_for_selected_tree_row(cf);
1790 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1793 case(cf_cb_file_opened):
1794 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1795 fileset_file_opened(data);
1797 case(cf_cb_file_closing):
1798 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1799 main_cf_cb_file_closing(data);
1801 case(cf_cb_file_closed):
1802 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1803 main_cf_cb_file_closed(data);
1804 fileset_file_closed();
1806 case(cf_cb_file_read_started):
1807 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1808 main_cf_cb_file_read_started(data);
1810 case(cf_cb_file_read_finished):
1811 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1812 main_cf_cb_file_read_finished(data);
1814 case(cf_cb_file_reload_started):
1815 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1816 main_cf_cb_file_read_started(data);
1818 case(cf_cb_file_reload_finished):
1819 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1820 main_cf_cb_file_read_finished(data);
1822 case(cf_cb_file_rescan_started):
1823 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1825 case(cf_cb_file_rescan_finished):
1826 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1827 main_cf_cb_file_rescan_finished(data);
1829 case(cf_cb_file_fast_save_finished):
1830 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1831 main_cf_cb_file_rescan_finished(data);
1833 case(cf_cb_packet_selected):
1834 main_cf_cb_packet_selected(data);
1836 case(cf_cb_packet_unselected):
1837 main_cf_cb_packet_unselected(data);
1839 case(cf_cb_field_unselected):
1840 main_cf_cb_field_unselected(data);
1842 case(cf_cb_file_save_started):
1843 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1845 case(cf_cb_file_save_finished):
1846 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1848 case(cf_cb_file_save_failed):
1849 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1851 case(cf_cb_file_save_stopped):
1852 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1854 case(cf_cb_file_export_specified_packets_started):
1855 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1857 case(cf_cb_file_export_specified_packets_finished):
1858 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1860 case(cf_cb_file_export_specified_packets_failed):
1861 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1863 case(cf_cb_file_export_specified_packets_stopped):
1864 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1867 g_warning("main_cf_callback: event %u unknown", event);
1868 g_assert_not_reached();
1874 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1876 #ifdef HAVE_GTKOSXAPPLICATION
1877 GtkosxApplication *theApp;
1880 case(capture_cb_capture_prepared):
1881 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1882 main_capture_cb_capture_prepared(capture_opts);
1884 case(capture_cb_capture_update_started):
1885 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1886 main_capture_cb_capture_update_started(capture_opts);
1887 #ifdef HAVE_GTKOSXAPPLICATION
1888 theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1889 gtkosx_application_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1892 case(capture_cb_capture_update_continue):
1893 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1895 case(capture_cb_capture_update_finished):
1896 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1897 main_capture_cb_capture_update_finished(capture_opts);
1899 case(capture_cb_capture_fixed_started):
1900 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1901 main_capture_cb_capture_fixed_started(capture_opts);
1903 case(capture_cb_capture_fixed_continue):
1904 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1906 case(capture_cb_capture_fixed_finished):
1907 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1908 main_capture_cb_capture_fixed_finished(capture_opts);
1910 case(capture_cb_capture_stopping):
1911 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1912 /* Beware: this state won't be called, if the capture child
1913 * closes the capturing on it's own! */
1914 #ifdef HAVE_GTKOSXAPPLICATION
1915 theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1916 gtkosx_application_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1918 main_capture_cb_capture_stopping(capture_opts);
1920 case(capture_cb_capture_failed):
1921 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1922 main_capture_cb_capture_failed(capture_opts);
1925 g_warning("main_capture_callback: event %u unknown", event);
1926 g_assert_not_reached();
1932 get_gtk_compiled_info(GString *str)
1934 g_string_append(str, "with ");
1935 g_string_append_printf(str,
1936 #ifdef GTK_MAJOR_VERSION
1937 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1940 "GTK+ (version unknown)");
1942 g_string_append(str, ", ");
1944 g_string_append(str, "with Cairo ");
1945 g_string_append(str, CAIRO_VERSION_STRING);
1946 g_string_append(str, ", ");
1949 g_string_append(str, "with Pango ");
1950 g_string_append(str, PANGO_VERSION_STRING);
1951 g_string_append(str, ", ");
1957 get_gui_compiled_info(GString *str)
1959 epan_get_compiled_version_info(str);
1961 g_string_append(str, ", ");
1962 #ifdef HAVE_LIBPORTAUDIO
1963 #ifdef PORTAUDIO_API_1
1964 g_string_append(str, "with PortAudio <= V18");
1965 #else /* PORTAUDIO_API_1 */
1966 g_string_append(str, "with ");
1967 g_string_append(str, Pa_GetVersionText());
1968 #endif /* PORTAUDIO_API_1 */
1969 #else /* HAVE_LIBPORTAUDIO */
1970 g_string_append(str, "without PortAudio");
1971 #endif /* HAVE_LIBPORTAUDIO */
1973 g_string_append(str, ", ");
1975 get_compiled_airpcap_version(str);
1977 g_string_append(str, "without AirPcap");
1982 get_gui_runtime_info(GString *str)
1984 epan_get_runtime_version_info(str);
1987 g_string_append(str, ", ");
1988 get_runtime_airpcap_version(str);
1992 g_string_append(str, ", ");
1993 u3_runtime_info(str);
1998 read_configuration_files(char **gdp_path, char **dp_path)
2000 int gpf_open_errno, gpf_read_errno;
2001 int cf_open_errno, df_open_errno;
2002 int gdp_open_errno, gdp_read_errno;
2003 int dp_open_errno, dp_read_errno;
2004 char *gpf_path, *pf_path;
2005 char *cf_path, *df_path;
2006 int pf_open_errno, pf_read_errno;
2009 /* load the decode as entries of this profile */
2010 load_decode_as_entries();
2012 /* Read the preference files. */
2013 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2014 &pf_open_errno, &pf_read_errno, &pf_path);
2016 if (gpf_path != NULL) {
2017 if (gpf_open_errno != 0) {
2018 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2019 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2020 g_strerror(gpf_open_errno));
2022 if (gpf_read_errno != 0) {
2023 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2024 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2025 g_strerror(gpf_read_errno));
2028 if (pf_path != NULL) {
2029 if (pf_open_errno != 0) {
2030 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2031 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2032 g_strerror(pf_open_errno));
2034 if (pf_read_errno != 0) {
2035 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2036 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2037 g_strerror(pf_read_errno));
2044 /* if the user wants a console to be always there, well, we should open one for him */
2045 if (prefs_p->gui_console_open == console_open_always) {
2050 /* Read the capture filter file. */
2051 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2052 if (cf_path != NULL) {
2053 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2054 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2055 g_strerror(cf_open_errno));
2059 /* Read the display filter file. */
2060 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2061 if (df_path != NULL) {
2062 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2063 "Could not open your display filter file\n\"%s\": %s.", df_path,
2064 g_strerror(df_open_errno));
2068 /* Read the disabled protocols file. */
2069 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2070 dp_path, &dp_open_errno, &dp_read_errno);
2071 if (*gdp_path != NULL) {
2072 if (gdp_open_errno != 0) {
2073 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2074 "Could not open global disabled protocols file\n\"%s\": %s.",
2075 *gdp_path, g_strerror(gdp_open_errno));
2077 if (gdp_read_errno != 0) {
2078 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2079 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2080 *gdp_path, g_strerror(gdp_read_errno));
2085 if (*dp_path != NULL) {
2086 if (dp_open_errno != 0) {
2087 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2088 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2089 g_strerror(dp_open_errno));
2091 if (dp_read_errno != 0) {
2092 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2093 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2094 g_strerror(dp_read_errno));
2103 /* Check if there's something important to tell the user during startup.
2104 * We want to do this *after* showing the main window so that any windows
2105 * we pop up will be above the main window.
2109 check_and_warn_user_startup(gchar *cf_name)
2111 check_and_warn_user_startup(gchar *cf_name _U_)
2114 gchar *cur_user, *cur_group;
2115 gpointer priv_warning_dialog;
2117 /* Tell the user not to run as root. */
2118 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2119 cur_user = get_cur_username();
2120 cur_group = get_cur_groupname();
2121 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2122 "Running as user \"%s\" and group \"%s\".\n"
2123 "This could be dangerous.\n\n"
2124 "If you're running Wireshark this way in order to perform live capture, "
2125 "you may want to be aware that there is a better way documented at\n"
2126 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2129 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2130 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2134 /* Warn the user if npf.sys isn't loaded. */
2135 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2136 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2137 "The NPF driver isn't running. You may have trouble\n"
2138 "capturing or listing interfaces.");
2139 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2140 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2147 /* And now our feature presentation... [ fade to music ] */
2149 main(int argc, char *argv[])
2151 char *init_progfile_dir_error;
2154 gboolean arg_error = FALSE;
2156 extern int info_update_freq; /* Found in about_dlg.c. */
2157 const gchar *filter;
2165 char *gdp_path, *dp_path;
2168 gboolean start_capture = FALSE;
2169 gboolean list_link_layer_types = FALSE;
2173 gboolean capture_option_specified = FALSE;
2180 gint pl_size = 280, tv_size = 95, bv_size = 75;
2181 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2182 dfilter_t *rfcode = NULL;
2183 gboolean rfilter_parse_failed = FALSE;
2186 GtkWidget *splash_win = NULL;
2187 GLogLevelFlags log_flags;
2188 guint go_to_packet = 0;
2189 gboolean jump_backwards = FALSE;
2190 dfilter_t *jump_to_filter = NULL;
2193 #ifdef HAVE_GTKOSXAPPLICATION
2194 GtkosxApplication *theApp;
2198 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2199 #define OPTSTRING_B "B:"
2201 #define OPTSTRING_B ""
2202 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2203 #else /* HAVE_LIBPCAP */
2204 #define OPTSTRING_B ""
2205 #endif /* HAVE_LIBPCAP */
2206 #ifdef HAVE_PCAP_REMOTE
2207 #define OPTSTRING_A "A:"
2209 #define OPTSTRING_A ""
2211 #ifdef HAVE_PCAP_CREATE
2212 #define OPTSTRING_I "I"
2214 #define OPTSTRING_I ""
2217 #define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:d:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:z:"
2219 static const char optstring[] = OPTSTRING;
2222 /* Set the C-language locale to the native environment. */
2223 setlocale(LC_ALL, "");
2225 arg_list_utf_16to8(argc, argv);
2229 * Get credential information for later use, and drop privileges
2230 * before doing anything else.
2231 * Let the user know if anything happened.
2233 init_process_policies();
2234 relinquish_special_privs_perm();
2237 * Attempt to get the pathname of the executable file.
2239 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2241 /* initialize the funnel mini-api */
2242 initialize_funnel_ops();
2244 AirPDcapInitContext(&airpdcap_ctx);
2247 /* Load wpcap if possible. Do this before collecting the run-time version information */
2250 /* ... and also load the packet.dll from wpcap */
2251 wpcap_packet_load();
2254 /* Load the airpcap.dll. This must also be done before collecting
2255 * run-time version information. */
2256 airpcap_dll_ret_val = load_airpcap();
2258 switch (airpcap_dll_ret_val) {
2259 case AIRPCAP_DLL_OK:
2260 /* load the airpcap interfaces */
2261 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2263 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2264 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2265 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2268 airpcap_if_active = NULL;
2272 /* select the first ad default (THIS SHOULD BE CHANGED) */
2273 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2278 * XXX - Maybe we need to warn the user if one of the following happens???
2280 case AIRPCAP_DLL_OLD:
2281 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2284 case AIRPCAP_DLL_ERROR:
2285 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2288 case AIRPCAP_DLL_NOT_FOUND:
2289 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2293 #endif /* HAVE_AIRPCAP */
2296 /* Assemble the compile-time version information string */
2297 comp_info_str = g_string_new("Compiled ");
2299 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2301 /* Assemble the run-time version information string */
2302 runtime_info_str = g_string_new("Running ");
2303 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2306 ws_add_crash_info(PACKAGE " " VERSION "%s\n"
2311 wireshark_svnversion, comp_info_str->str, runtime_info_str->str);
2313 /* Start windows sockets */
2314 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2317 profile_store_persconffiles (TRUE);
2319 /* Read the profile independent recent file. We have to do this here so we can */
2320 /* set the profile before it can be set from the command line parameterts */
2321 recent_read_static(&rf_path, &rf_open_errno);
2322 if (rf_path != NULL && rf_open_errno != 0) {
2323 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2324 "Could not open common recent file\n\"%s\": %s.",
2325 rf_path, g_strerror(rf_open_errno));
2328 /* "pre-scan" the command line parameters, if we have "console only"
2329 parameters. We do this so we don't start GTK+ if we're only showing
2330 command-line help or version information.
2332 XXX - this pre-scan is done before we start GTK+, so we haven't
2333 run gtk_init() on the arguments. That means that GTK+ arguments
2334 have not been removed from the argument list; those arguments
2335 begin with "--", and will be treated as an error by getopt().
2337 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2340 optind_initial = optind;
2341 while ((opt = getopt(argc, argv, optstring)) != -1) {
2343 case 'C': /* Configuration Profile */
2344 if (profile_exists (optarg, FALSE)) {
2345 set_profile_name (optarg);
2347 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2351 case 'D': /* Print a list of capture devices and exit */
2353 if_list = capture_interface_list(&err, &err_str);
2354 if (if_list == NULL) {
2356 case CANT_GET_INTERFACE_LIST:
2357 case DONT_HAVE_PCAP:
2358 cmdarg_err("%s", err_str);
2362 case NO_INTERFACES_FOUND:
2363 cmdarg_err("There are no interfaces on which a capture can be done");
2368 capture_opts_print_interfaces(if_list);
2369 free_interface_list(if_list);
2372 capture_option_specified = TRUE;
2376 case 'h': /* Print help and exit */
2382 if (strcmp(optarg, "-") == 0)
2383 set_stdin_capture(TRUE);
2386 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2387 status = filesystem_opt(opt, optarg);
2389 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2393 case 'v': /* Show version and exit */
2399 * Extension command line options have to be processed before
2400 * we call epan_init() as they are supposed to be used by dissectors
2401 * or taps very early in the registration process.
2405 case '?': /* Ignore errors - the "real" scan will catch them. */
2410 /* Init the "Open file" dialog directory */
2411 /* (do this after the path settings are processed) */
2413 /* Read the profile dependent (static part) of the recent file. */
2414 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2415 /* recent lists which is done in the dynamic part. */
2416 /* We have to do this already here, so command line parameters can overwrite these values. */
2417 recent_read_profile_static(&rf_path, &rf_open_errno);
2418 if (rf_path != NULL && rf_open_errno != 0) {
2419 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2420 "Could not open recent file\n\"%s\": %s.",
2421 rf_path, g_strerror(rf_open_errno));
2424 if (recent.gui_fileopen_remembered_dir &&
2425 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2426 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2428 set_last_open_dir(get_persdatafile_dir());
2431 /* Set getopt index back to initial value, so it will start with the
2432 first command line parameter again. Also reset opterr to 1, so that
2433 error messages are printed by getopt().
2435 XXX - this seems to work on most platforms, but time will tell.
2436 The Single UNIX Specification says "The getopt() function need
2437 not be reentrant", so this isn't guaranteed to work. The Mac
2438 OS X 10.4[.x] getopt() man page says
2440 In order to use getopt() to evaluate multiple sets of arguments, or to
2441 evaluate a single set of arguments multiple times, the variable optreset
2442 must be set to 1 before the second and each additional set of calls to
2443 getopt(), and the variable optind must be reinitialized.
2447 The optreset variable was added to make it possible to call the getopt()
2448 function multiple times. This is an extension to the IEEE Std 1003.2
2449 (``POSIX.2'') specification.
2451 which I think comes from one of the other BSDs.
2453 XXX - if we want to control all the command-line option errors, so
2454 that we can display them where we choose (e.g., in a window), we'd
2455 want to leave opterr as 0, and produce our own messages using optopt.
2456 We'd have to check the value of optopt to see if it's a valid option
2457 letter, in which case *presumably* the error is "this option requires
2458 an argument but none was specified", or not a valid option letter,
2459 in which case *presumably* the error is "this option isn't valid".
2460 Some versions of getopt() let you supply a option string beginning
2461 with ':', which means that getopt() will return ':' rather than '?'
2462 for "this option requires an argument but none was specified", but
2464 optind = optind_initial;
2467 #if !GLIB_CHECK_VERSION(2,31,0)
2468 g_thread_init(NULL);
2471 /* Set the current locale according to the program environment.
2472 * We haven't localized anything, but some GTK widgets are localized
2473 * (the file selection dialogue, for example).
2474 * This also sets the C-language locale to the native environment. */
2475 setlocale (LC_ALL, "");
2477 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2478 gtk_init (&argc, &argv);
2480 cf_callback_add(main_cf_callback, NULL);
2482 capture_callback_add(main_capture_callback, NULL);
2484 cf_callback_add(statusbar_cf_callback, NULL);
2486 capture_callback_add(statusbar_capture_callback, NULL);
2489 /* Arrange that if we have no console window, and a GLib message logging
2490 routine is called to log a message, we pop up a console window.
2492 We do that by inserting our own handler for all messages logged
2493 to the default domain; that handler pops up a console if necessary,
2494 and then calls the default handler. */
2496 /* We might want to have component specific log levels later ... */
2500 G_LOG_LEVEL_CRITICAL|
2501 G_LOG_LEVEL_WARNING|
2502 G_LOG_LEVEL_MESSAGE|
2505 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2507 g_log_set_handler(NULL,
2509 console_log_handler, NULL /* user_data */);
2510 g_log_set_handler(LOG_DOMAIN_MAIN,
2512 console_log_handler, NULL /* user_data */);
2515 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2517 console_log_handler, NULL /* user_data */);
2518 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2520 console_log_handler, NULL /* user_data */);
2522 /* Set the initial values in the capture options. This might be overwritten
2523 by preference settings and then again by the command line parameters. */
2524 capture_opts_init(&global_capture_opts, &cfile);
2527 /* Initialize whatever we need to allocate colors for GTK+ */
2530 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2531 filter = get_conn_cfilter();
2532 if ( *filter != '\0' ) {
2533 info_update_freq = 1000; /* Milliseconds */
2536 /* We won't come till here, if we had a "console only" command line parameter. */
2537 splash_win = splash_new("Loading Wireshark ...");
2538 if (init_progfile_dir_error != NULL) {
2539 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2540 "Can't get pathname of Wireshark: %s.\n"
2541 "It won't be possible to capture traffic.\n"
2542 "Report this to the Wireshark developers.",
2543 init_progfile_dir_error);
2544 g_free(init_progfile_dir_error);
2547 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2549 /* Register all dissectors; we must do this before checking for the
2550 "-G" flag, as the "-G" flag dumps information registered by the
2551 dissectors, and we must do it before we read the preferences, in
2552 case any dissectors register preferences. */
2553 epan_init(register_all_protocols,register_all_protocol_handoffs,
2554 splash_update, (gpointer) splash_win,
2555 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2556 write_failure_alert_box);
2558 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2560 /* Register all tap listeners; we do this before we parse the arguments,
2561 as the "-z" argument can specify a registered tap. */
2563 /* we register the plugin taps before the other taps because
2564 stats_tree taps plugins will be registered as tap listeners
2565 by stats_tree_stat.c and need to registered before that */
2568 register_all_plugin_tap_listeners();
2571 register_all_tap_listeners();
2573 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2575 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2576 /* Removed thread code:
2577 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2580 /* this is to keep tap extensions updating once every 3 seconds */
2581 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2583 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2585 cap_file_init(&cfile);
2587 /* Fill in capture options with values from the preferences */
2588 prefs_to_capture_opts();
2590 /*#ifdef HAVE_LIBPCAP
2591 fill_in_local_interfaces();
2593 /* Now get our args */
2594 while ((opt = getopt(argc, argv, optstring)) != -1) {
2596 /*** capture option specific ***/
2597 case 'a': /* autostop criteria */
2598 case 'b': /* Ringbuffer option */
2599 case 'c': /* Capture xxx packets */
2600 case 'f': /* capture filter */
2601 case 'k': /* Start capture immediately */
2602 case 'H': /* Hide capture info dialog box */
2603 case 'p': /* Don't capture in promiscuous mode */
2604 case 'i': /* Use interface x */
2605 #ifdef HAVE_PCAP_CREATE
2606 case 'I': /* Capture in monitor mode, if available */
2608 #ifdef HAVE_PCAP_REMOTE
2609 case 'A': /* Authentication */
2611 case 's': /* Set the snapshot (capture) length */
2612 case 'S': /* "Sync" mode: used for following file ala tail -f */
2613 case 'w': /* Write to capture file xxx */
2614 case 'y': /* Set the pcap data link type */
2615 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2616 case 'B': /* Buffer size */
2617 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2619 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2625 capture_option_specified = TRUE;
2630 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2631 case 'K': /* Kerberos keytab file */
2632 read_keytab_file(optarg);
2636 /*** all non capture option specific ***/
2638 /* Configuration profile settings were already processed just ignore them this time*/
2643 case 'j': /* Search backwards for a matching packet from filter in option J */
2644 jump_backwards = TRUE;
2646 case 'g': /* Go to packet with the given packet number */
2647 go_to_packet = get_positive_int(optarg, "go to packet");
2649 case 'J': /* Jump to the first packet which matches the filter criteria */
2652 case 'l': /* Automatic scrolling in live capture mode */
2654 auto_scroll_live = TRUE;
2656 capture_option_specified = TRUE;
2660 case 'L': /* Print list of link-layer types and exit */
2662 list_link_layer_types = TRUE;
2664 capture_option_specified = TRUE;
2668 case 'm': /* Fixed-width font for the display */
2669 g_free(prefs_p->gui_gtk2_font_name);
2670 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2672 case 'n': /* No name resolution */
2673 gbl_resolv_flags.mac_name = FALSE;
2674 gbl_resolv_flags.network_name = FALSE;
2675 gbl_resolv_flags.transport_name = FALSE;
2676 gbl_resolv_flags.concurrent_dns = FALSE;
2678 case 'N': /* Select what types of addresses/port #s to resolve */
2679 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2680 if (badopt != '\0') {
2681 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2686 case 'o': /* Override preference from command line */
2687 switch (prefs_set_pref(optarg)) {
2690 case PREFS_SET_SYNTAX_ERR:
2691 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2694 case PREFS_SET_NO_SUCH_PREF:
2695 /* not a preference, might be a recent setting */
2696 switch (recent_set_arg(optarg)) {
2699 case PREFS_SET_SYNTAX_ERR:
2700 /* shouldn't happen, checked already above */
2701 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2704 case PREFS_SET_NO_SUCH_PREF:
2705 case PREFS_SET_OBSOLETE:
2706 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2711 g_assert_not_reached();
2714 case PREFS_SET_OBSOLETE:
2715 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2720 g_assert_not_reached();
2724 /* Path settings were already processed just ignore them this time*/
2726 case 'r': /* Read capture file xxx */
2727 /* We may set "last_open_dir" to "cf_name", and if we change
2728 "last_open_dir" later, we free the old value, so we have to
2729 set "cf_name" to something that's been allocated. */
2730 cf_name = g_strdup(optarg);
2732 case 'R': /* Read file filter */
2735 case 't': /* Time stamp type */
2736 if (strcmp(optarg, "r") == 0)
2737 timestamp_set_type(TS_RELATIVE);
2738 else if (strcmp(optarg, "a") == 0)
2739 timestamp_set_type(TS_ABSOLUTE);
2740 else if (strcmp(optarg, "ad") == 0)
2741 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2742 else if (strcmp(optarg, "d") == 0)
2743 timestamp_set_type(TS_DELTA);
2744 else if (strcmp(optarg, "dd") == 0)
2745 timestamp_set_type(TS_DELTA_DIS);
2746 else if (strcmp(optarg, "e") == 0)
2747 timestamp_set_type(TS_EPOCH);
2748 else if (strcmp(optarg, "u") == 0)
2749 timestamp_set_type(TS_UTC);
2750 else if (strcmp(optarg, "ud") == 0)
2751 timestamp_set_type(TS_UTC_WITH_DATE);
2753 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2754 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2755 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2759 case 'u': /* Seconds type */
2760 if (strcmp(optarg, "s") == 0)
2761 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2762 else if (strcmp(optarg, "hms") == 0)
2763 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2765 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2766 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2771 /* ext ops were already processed just ignore them this time*/
2774 /* We won't call the init function for the stat this soon
2775 as it would disallow MATE's fields (which are registered
2776 by the preferences set callback) from being used as
2777 part of a tap filter. Instead, we just add the argument
2778 to a list of stat arguments. */
2779 if (!process_stat_cmd_arg(optarg)) {
2780 cmdarg_err("Invalid -z argument.");
2781 cmdarg_err_cont(" -z argument must be one of :");
2782 list_stat_cmd_args();
2787 case '?': /* Bad flag - print usage message */
2796 if (cf_name != NULL) {
2798 * Input file name specified with "-r" *and* specified as a regular
2799 * command-line argument.
2801 cmdarg_err("File name specified both with -r and regular argument");
2805 * Input file name not specified with "-r", and a command-line argument
2806 * was specified; treat it as the input file name.
2808 * Yes, this is different from tshark, where non-flag command-line
2809 * arguments are a filter, but this works better on GUI desktops
2810 * where a command can be specified to be run to open a particular
2811 * file - yes, you could have "-r" as the last part of the command,
2812 * but that's a bit ugly.
2814 #ifndef HAVE_GTKOSXAPPLICATION
2816 * For GTK+ Mac Integration, file name passed as free argument passed
2817 * through grag-and-drop and opened twice sometimes causing crashes.
2818 * Subject to report to GTK+ MAC.
2820 cf_name = g_strdup(argv[0]);
2829 * Extra command line arguments were specified; complain.
2831 cmdarg_err("Invalid argument: %s", argv[0]);
2836 #ifndef HAVE_LIBPCAP
2837 if (capture_option_specified) {
2838 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2846 fill_in_local_interfaces();
2847 if (start_capture && list_link_layer_types) {
2848 /* Specifying *both* is bogus. */
2849 cmdarg_err("You can't specify both -L and a live capture.");
2853 if (list_link_layer_types) {
2854 /* We're supposed to list the link-layer types for an interface;
2855 did the user also specify a capture file to be read? */
2857 /* Yes - that's bogus. */
2858 cmdarg_err("You can't specify -L and a capture file to be read.");
2861 /* No - did they specify a ring buffer option? */
2862 if (global_capture_opts.multi_files_on) {
2863 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2867 /* We're supposed to do a live capture; did the user also specify
2868 a capture file to be read? */
2869 if (start_capture && cf_name) {
2870 /* Yes - that's bogus. */
2871 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2875 /* No - was the ring buffer option specified and, if so, does it make
2877 if (global_capture_opts.multi_files_on) {
2878 /* Ring buffer works only under certain conditions:
2879 a) ring buffer does not work with temporary files;
2880 b) real_time_mode and multi_files_on are mutually exclusive -
2881 real_time_mode takes precedence;
2882 c) it makes no sense to enable the ring buffer if the maximum
2883 file size is set to "infinite". */
2884 if (global_capture_opts.save_file == NULL) {
2885 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2886 global_capture_opts.multi_files_on = FALSE;
2888 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2889 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2890 /* XXX - this must be redesigned as the conditions changed */
2895 if (start_capture || list_link_layer_types) {
2896 /* Did the user specify an interface to use? */
2897 status = capture_opts_trim_iface(&global_capture_opts,
2898 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2904 if (list_link_layer_types) {
2905 /* Get the list of link-layer types for the capture devices. */
2906 if_capabilities_t *caps;
2909 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2911 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2912 if (device.selected) {
2913 #if defined(HAVE_PCAP_CREATE)
2914 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2916 caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2919 cmdarg_err("%s", err_str);
2923 if (caps->data_link_types == NULL) {
2924 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2927 #if defined(HAVE_PCAP_CREATE)
2928 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2930 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2932 free_if_capabilities(caps);
2938 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2939 capture_opts_trim_ring_num_files(&global_capture_opts);
2940 #endif /* HAVE_LIBPCAP */
2942 /* Notify all registered modules that have had any of their preferences
2943 changed either from one of the preferences file or from the command
2944 line that their preferences have changed. */
2948 if ((global_capture_opts.num_selected == 0) &&
2949 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2952 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2953 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2954 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2955 device.selected = TRUE;
2956 global_capture_opts.num_selected++;
2957 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2958 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2965 /* disabled protocols as per configuration file */
2966 if (gdp_path == NULL && dp_path == NULL) {
2967 set_disabled_protos_list();
2970 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2972 /* read in rc file from global and personal configuration paths. */
2973 rc_file = get_datafile_path(RC_FILE);
2974 #if GTK_CHECK_VERSION(3,0,0)
2975 /* XXX resolve later */
2977 gtk_rc_parse(rc_file);
2979 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2980 gtk_rc_parse(rc_file);
2990 /* close the splash screen, as we are going to open the main window now */
2991 splash_destroy(splash_win);
2993 /************************************************************************/
2994 /* Everything is prepared now, preferences and command line was read in */
2996 /* Pop up the main window. */
2997 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2999 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3000 recent_read_dynamic(&rf_path, &rf_open_errno);
3001 if (rf_path != NULL && rf_open_errno != 0) {
3002 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3003 "Could not open recent file\n\"%s\": %s.",
3004 rf_path, g_strerror(rf_open_errno));
3007 color_filters_enable(recent.packet_list_colorize);
3009 /* rearrange all the widgets as we now have all recent settings ready for this */
3010 main_widgets_rearrange();
3012 /* Fill in column titles. This must be done after the top level window
3015 XXX - is that still true, with fixed-width columns? */
3017 menu_recent_read_finished();
3019 main_auto_scroll_live_changed(auto_scroll_live);
3022 switch (user_font_apply()) {
3025 case FA_FONT_NOT_RESIZEABLE:
3026 /* "user_font_apply()" popped up an alert box. */
3027 /* turn off zooming - font can't be resized */
3028 case FA_FONT_NOT_AVAILABLE:
3029 /* XXX - did we successfully load the un-zoomed version earlier?
3030 If so, this *probably* means the font is available, but not at
3031 this particular zoom level, but perhaps some other failure
3032 occurred; I'm not sure you can determine which is the case,
3034 /* turn off zooming - zoom level is unavailable */
3036 /* in any other case than FA_SUCCESS, turn off zooming */
3037 recent.gui_zoom_level = 0;
3038 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3041 dnd_init(top_level);
3043 color_filters_init();
3046 capture_filter_init();
3049 /* the window can be sized only, if it's not already shown, so do it now! */
3050 main_load_window_geometry(top_level);
3052 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3055 GtkWidget *filter_te;
3056 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3057 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3059 /* Run the display filter so it goes in effect. */
3060 main_filter_packets(&cfile, dfilter, FALSE);
3063 /* If we were given the name of a capture file, read it in now;
3064 we defer it until now, so that, if we can't open it, and pop
3065 up an alert box, the alert box is more likely to come up on
3066 top of the main window - but before the preference-file-error
3067 alert box, so, if we get one of those, it's more likely to come
3070 show_main_window(TRUE);
3071 check_and_warn_user_startup(cf_name);
3072 if (rfilter != NULL) {
3073 if (!dfilter_compile(rfilter, &rfcode)) {
3074 bad_dfilter_alert_box(top_level, rfilter);
3075 rfilter_parse_failed = TRUE;
3078 if (!rfilter_parse_failed) {
3079 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3080 /* "cf_open()" succeeded, so it closed the previous
3081 capture file, and thus destroyed any previous read filter
3082 attached to "cf". */
3084 cfile.rfcode = rfcode;
3085 /* Open stat windows; we do so after creating the main window,
3086 to avoid GTK warnings, and after successfully opening the
3087 capture file, so we know we have something to compute stats
3088 on, and after registering all dissectors, so that MATE will
3089 have registered its field array and we can have a tap filter
3090 with one of MATE's late-registered fields as part of the
3092 start_requested_stats();
3094 /* Read the capture file. */
3095 switch (cf_read(&cfile, FALSE)) {
3099 /* Just because we got an error, that doesn't mean we were unable
3100 to read any of the file; we handle what we could get from the
3102 /* if the user told us to jump to a specific packet, do it now */
3103 if(go_to_packet != 0) {
3104 /* Jump to the specified frame number, kept for backward
3106 cf_goto_frame(&cfile, go_to_packet);
3107 } else if (jfilter != NULL) {
3108 /* try to compile given filter */
3109 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3110 bad_dfilter_alert_box(top_level, jfilter);
3112 /* Filter ok, jump to the first packet matching the filter
3113 conditions. Default search direction is forward, but if
3114 option d was given, search backwards */
3115 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3120 case CF_READ_ABORTED:
3126 /* If the filename is not the absolute path, prepend the current dir. This happens
3127 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3128 if (!g_path_is_absolute(cf_name)) {
3129 char *old_cf_name = cf_name;
3130 char *pwd = g_get_current_dir();
3131 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3132 g_free(old_cf_name);
3136 /* Save the name of the containing directory specified in the
3137 path name, if any; we can write over cf_name, which is a
3138 good thing, given that "get_dirname()" does write over its
3140 s = get_dirname(cf_name);
3141 set_last_open_dir(s);
3146 dfilter_free(rfcode);
3147 cfile.rfcode = NULL;
3148 show_main_window(FALSE);
3149 /* Don't call check_and_warn_user_startup(): we did it above */
3150 main_set_for_capture_in_progress(FALSE);
3151 set_capture_if_dialog_for_capture_in_progress(FALSE);
3156 if (start_capture) {
3157 if (global_capture_opts.save_file != NULL) {
3158 /* Save the directory name for future file dialogs. */
3159 /* (get_dirname overwrites filename) */
3160 s = get_dirname(g_strdup(global_capture_opts.save_file));
3161 set_last_open_dir(s);
3164 /* "-k" was specified; start a capture. */
3165 show_main_window(FALSE);
3166 check_and_warn_user_startup(cf_name);
3168 /* If no user interfaces were specified on the command line,
3169 copy the list of selected interfaces to the set of interfaces
3170 to use for this capture. */
3171 if (global_capture_opts.ifaces->len == 0)
3172 collect_ifaces(&global_capture_opts);
3173 if (capture_start(&global_capture_opts)) {
3174 /* The capture started. Open stat windows; we do so after creating
3175 the main window, to avoid GTK warnings, and after successfully
3176 opening the capture file, so we know we have something to compute
3177 stats on, and after registering all dissectors, so that MATE will
3178 have registered its field array and we can have a tap filter with
3179 one of MATE's late-registered fields as part of the filter. */
3180 start_requested_stats();
3183 show_main_window(FALSE);
3184 check_and_warn_user_startup(cf_name);
3185 main_set_for_capture_in_progress(FALSE);
3186 set_capture_if_dialog_for_capture_in_progress(FALSE);
3189 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3190 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3191 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3193 #else /* HAVE_LIBPCAP */
3194 show_main_window(FALSE);
3195 check_and_warn_user_startup(cf_name);
3196 main_set_for_capture_in_progress(FALSE);
3197 set_capture_if_dialog_for_capture_in_progress(FALSE);
3198 #endif /* HAVE_LIBPCAP */
3201 /* register our pid if we are being run from a U3 device */
3204 profile_store_persconffiles (FALSE);
3206 #ifdef HAVE_GTKOSXAPPLICATION
3207 theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3208 gtkosx_application_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3209 gtkosx_application_ready(theApp);
3212 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3215 gtk_iface_mon_start();
3218 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3220 /* ... back from GTK, we're going down now! */
3223 gtk_iface_mon_stop();
3226 /* deregister our pid */
3227 u3_deregister_pid();
3231 AirPDcapDestroyContext(&airpdcap_ctx);
3234 /* hide the (unresponsive) main window, while asking the user to close the console window */
3235 gtk_widget_hide(top_level);
3237 #ifdef HAVE_GTKOSXAPPLICATION
3238 g_object_unref(theApp);
3241 /* Shutdown windows sockets */
3244 /* For some unknown reason, the "atexit()" call in "create_console()"
3245 doesn't arrange that "destroy_console()" be called when we exit,
3246 so we call it here if a console was created. */
3255 /* We build this as a GUI subsystem application on Win32, so
3256 "WinMain()", not "main()", gets called.
3258 Hack shamelessly stolen from the Win32 port of the GIMP. */
3260 #define _stdcall __attribute__((stdcall))
3264 WinMain (struct HINSTANCE__ *hInstance,
3265 struct HINSTANCE__ *hPrevInstance,
3269 INITCOMMONCONTROLSEX comm_ctrl;
3272 * Initialize our DLL search path. MUST be called before LoadLibrary
3275 ws_init_dll_search_path();
3277 /* Initialize our controls. Required for native Windows file dialogs. */
3278 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3279 comm_ctrl.dwSize = sizeof(comm_ctrl);
3280 /* Includes the animate, header, hot key, list view, progress bar,
3281 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3284 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3285 InitCommonControlsEx(&comm_ctrl);
3287 /* RichEd20.DLL is needed for filter entries. */
3288 ws_load_library("riched20.dll");
3290 set_has_console(FALSE);
3291 set_console_wait(FALSE);
3292 return main (__argc, __argv);
3299 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3300 const char *message, gpointer user_data _U_)
3307 /* ignore log message, if log_level isn't interesting based
3308 upon the console log preferences.
3309 If the preferences haven't been loaded loaded yet, display the
3312 The default console_log_level preference value is such that only
3313 ERROR, CRITICAL and WARNING level messages are processed;
3314 MESSAGE, INFO and DEBUG level messages are ignored. */
3315 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3316 prefs.console_log_level != 0) {
3321 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3322 /* the user wants a console or the application will terminate immediately */
3325 if (get_has_console()) {
3326 /* For some unknown reason, the above doesn't appear to actually cause
3327 anything to be sent to the standard output, so we'll just splat the
3328 message out directly, just to make sure it gets out. */
3330 switch(log_level & G_LOG_LEVEL_MASK) {
3331 case G_LOG_LEVEL_ERROR:
3334 case G_LOG_LEVEL_CRITICAL:
3337 case G_LOG_LEVEL_WARNING:
3340 case G_LOG_LEVEL_MESSAGE:
3343 case G_LOG_LEVEL_INFO:
3346 case G_LOG_LEVEL_DEBUG:
3350 fprintf(stderr, "unknown log_level %u\n", log_level);
3352 g_assert_not_reached();
3355 /* create a "timestamp" */
3357 today = localtime(&curr);
3359 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3360 today->tm_hour, today->tm_min, today->tm_sec,
3361 log_domain != NULL ? log_domain : "",
3364 if(log_level & G_LOG_LEVEL_ERROR) {
3365 /* wait for a key press before the following error handler will terminate the program
3366 this way the user at least can read the error message */
3367 printf("\n\nPress any key to exit\n");
3371 /* XXX - on UN*X, should we just use g_log_default_handler()?
3372 We want the error messages to go to the standard output;
3373 on Mac OS X, that will cause them to show up in various
3374 per-user logs accessible through Console (details depend
3375 on whether you're running 10.0 through 10.4 or running
3376 10.5 and later), and, on other UN*X desktop environments,
3377 if they don't show up in some form of console log, that's
3378 a deficiency in that desktop environment. (Too bad
3379 Windows doesn't set the standard output and error for
3380 GUI apps to something that shows up in such a log.) */
3381 g_log_default_handler(log_domain, log_level, message, user_data);
3388 * Helper for main_widgets_rearrange()
3390 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3391 gtk_container_remove(GTK_CONTAINER(data), widget);
3394 static GtkWidget *main_widget_layout(gint layout_content)
3396 switch(layout_content) {
3397 case(layout_pane_content_none):
3399 case(layout_pane_content_plist):
3401 case(layout_pane_content_pdetails):
3403 case(layout_pane_content_pbytes):
3404 return byte_nb_ptr_gbl;
3406 g_assert_not_reached();
3413 * Rearrange the main window widgets
3415 void main_widgets_rearrange(void) {
3416 GtkWidget *first_pane_widget1, *first_pane_widget2;
3417 GtkWidget *second_pane_widget1, *second_pane_widget2;
3418 gboolean split_top_left = FALSE;
3420 /* be a bit faster */
3421 gtk_widget_hide(main_vbox);
3423 /* be sure we don't lose a widget while rearranging */
3424 g_object_ref(G_OBJECT(menubar));
3425 g_object_ref(G_OBJECT(main_tb));
3426 g_object_ref(G_OBJECT(filter_tb));
3427 g_object_ref(G_OBJECT(wireless_tb));
3428 g_object_ref(G_OBJECT(pkt_scrollw));
3429 g_object_ref(G_OBJECT(tv_scrollw));
3430 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3431 g_object_ref(G_OBJECT(statusbar));
3432 g_object_ref(G_OBJECT(main_pane_v1));
3433 g_object_ref(G_OBJECT(main_pane_v2));
3434 g_object_ref(G_OBJECT(main_pane_h1));
3435 g_object_ref(G_OBJECT(main_pane_h2));
3436 g_object_ref(G_OBJECT(welcome_pane));
3438 /* empty all containers participating */
3439 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3440 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3441 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3442 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3443 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3445 statusbar_widgets_emptying(statusbar);
3447 /* add the menubar always at the top */
3448 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3451 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3453 /* filter toolbar in toolbar area */
3454 if (!prefs.filter_toolbar_show_in_statusbar) {
3455 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3458 /* airpcap toolbar */
3459 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3461 /* fill the main layout panes */
3462 switch(prefs.gui_layout_type) {
3463 case(layout_type_5):
3464 main_first_pane = main_pane_v1;
3465 main_second_pane = main_pane_v2;
3466 split_top_left = FALSE;
3468 case(layout_type_2):
3469 main_first_pane = main_pane_v1;
3470 main_second_pane = main_pane_h1;
3471 split_top_left = FALSE;
3473 case(layout_type_1):
3474 main_first_pane = main_pane_v1;
3475 main_second_pane = main_pane_h1;
3476 split_top_left = TRUE;
3478 case(layout_type_4):
3479 main_first_pane = main_pane_h1;
3480 main_second_pane = main_pane_v1;
3481 split_top_left = FALSE;
3483 case(layout_type_3):
3484 main_first_pane = main_pane_h1;
3485 main_second_pane = main_pane_v1;
3486 split_top_left = TRUE;
3488 case(layout_type_6):
3489 main_first_pane = main_pane_h1;
3490 main_second_pane = main_pane_h2;
3491 split_top_left = FALSE;
3494 main_first_pane = NULL;
3495 main_second_pane = NULL;
3496 g_assert_not_reached();
3498 if (split_top_left) {
3499 first_pane_widget1 = main_second_pane;
3500 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3501 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3502 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3504 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3505 first_pane_widget2 = main_second_pane;
3506 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3507 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3509 if (first_pane_widget1 != NULL)
3510 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3511 if (first_pane_widget2 != NULL)
3512 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3513 if (second_pane_widget1 != NULL)
3514 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3515 if (second_pane_widget2 != NULL)
3516 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3518 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3521 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3524 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3526 /* filter toolbar in statusbar hbox */
3527 if (prefs.filter_toolbar_show_in_statusbar) {
3528 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3531 /* statusbar widgets */
3532 statusbar_widgets_pack(statusbar);
3534 /* hide widgets on users recent settings */
3535 main_widgets_show_or_hide();
3537 gtk_widget_show(main_vbox);
3541 is_widget_visible(GtkWidget *widget, gpointer data)
3543 gboolean *is_visible = data;
3546 if (gtk_widget_get_visible(widget))
3553 main_widgets_show_or_hide(void)
3555 gboolean main_second_pane_show;
3557 if (recent.main_toolbar_show) {
3558 gtk_widget_show(main_tb);
3560 gtk_widget_hide(main_tb);
3563 statusbar_widgets_show_or_hide(statusbar);
3565 if (recent.filter_toolbar_show) {
3566 gtk_widget_show(filter_tb);
3568 gtk_widget_hide(filter_tb);
3571 if (recent.wireless_toolbar_show) {
3572 gtk_widget_show(wireless_tb);
3574 gtk_widget_hide(wireless_tb);
3577 if (recent.packet_list_show && have_capture_file) {
3578 gtk_widget_show(pkt_scrollw);
3580 gtk_widget_hide(pkt_scrollw);
3583 if (recent.tree_view_show && have_capture_file) {
3584 gtk_widget_show(tv_scrollw);
3586 gtk_widget_hide(tv_scrollw);
3589 if (recent.byte_view_show && have_capture_file) {
3590 gtk_widget_show(byte_nb_ptr_gbl);
3592 gtk_widget_hide(byte_nb_ptr_gbl);
3595 if (have_capture_file) {
3596 gtk_widget_show(main_first_pane);
3598 gtk_widget_hide(main_first_pane);
3602 * Is anything in "main_second_pane" visible?
3603 * If so, show it, otherwise hide it.
3605 main_second_pane_show = FALSE;
3606 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3607 &main_second_pane_show);
3608 if (main_second_pane_show) {
3609 gtk_widget_show(main_second_pane);
3611 gtk_widget_hide(main_second_pane);
3614 if (!have_capture_file) {
3616 gtk_widget_show(welcome_pane);
3619 gtk_widget_hide(welcome_pane);
3624 /* called, when the window state changes (minimized, maximized, ...) */
3626 window_state_event_cb (GtkWidget *widget _U_,
3630 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3632 if( (event->type) == (GDK_WINDOW_STATE)) {
3633 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3634 /* we might have dialogs popped up while we where iconified,
3636 display_queued_messages();
3644 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3646 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3648 if (event->keyval == GDK_F8) {
3651 } else if (event->keyval == GDK_F7) {
3654 } else if (event->state & NO_SHIFT_MOD_MASK) {
3655 return FALSE; /* Skip control, alt, and other modifiers */
3657 * A comment in gdkkeysyms.h says that it's autogenerated from
3658 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3659 * don't explicitly say so, isprint() should work as expected
3662 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3663 /* Forward the keypress on to the display filter entry */
3664 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3665 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3666 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3674 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3675 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3680 GtkAccelGroup *accel;
3683 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3684 main_set_window_name("The Wireshark Network Analyzer");
3686 gtk_widget_set_name(top_level, "main window");
3687 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3689 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3690 G_CALLBACK(window_state_event_cb), NULL);
3691 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3692 G_CALLBACK(top_level_key_pressed_cb), NULL );
3694 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3695 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3697 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3698 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3699 gtk_widget_show(main_vbox);
3702 menubar = main_menu_new(&accel);
3704 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3705 /* Mac OS X native menus are created and displayed by main_menu_new() */
3706 if(!prefs_p->gui_macosx_style) {
3708 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3709 gtk_widget_show(menubar);
3710 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3712 gtk_widget_hide(menubar);
3717 main_tb = toolbar_new();
3718 gtk_widget_show (main_tb);
3720 /* Filter toolbar */
3721 filter_tb = filter_toolbar_new();
3724 pkt_scrollw = packet_list_create();
3725 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3726 gtk_widget_show_all(pkt_scrollw);
3729 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3730 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3731 gtk_widget_show(tv_scrollw);
3733 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3734 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3735 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3736 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3737 gtk_widget_show(tree_view_gbl);
3740 byte_nb_ptr_gbl = byte_view_new();
3741 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3742 gtk_widget_show(byte_nb_ptr_gbl);
3744 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3745 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3747 /* Panes for the packet list, tree, and byte view */
3748 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3749 gtk_widget_show(main_pane_v1);
3750 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3751 gtk_widget_show(main_pane_v2);
3752 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3753 gtk_widget_show(main_pane_h1);
3754 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3755 gtk_widget_show(main_pane_h2);
3757 wireless_tb = airpcap_toolbar_new();
3759 wireless_tb = ws80211_toolbar_new();
3761 gtk_widget_show(wireless_tb);
3764 statusbar = statusbar_new();
3765 gtk_widget_show(statusbar);
3767 /* Pane for the welcome screen */
3768 welcome_pane = welcome_new();
3769 gtk_widget_show(welcome_pane);
3773 show_main_window(gboolean doing_work)
3775 main_set_for_capture_file(doing_work);
3777 /*** we have finished all init things, show the main window ***/
3778 gtk_widget_show(top_level);
3780 /* the window can be maximized only, if it's visible, so do it after show! */
3781 main_load_window_geometry(top_level);
3783 /* process all pending GUI events before continue */
3784 while (gtk_events_pending()) gtk_main_iteration();
3786 /* Pop up any queued-up alert boxes. */
3787 display_queued_messages();
3789 /* Move the main window to the front, in case it isn't already there */
3790 gdk_window_raise(gtk_widget_get_window(top_level));
3793 airpcap_toolbar_show(wireless_tb);
3794 #endif /* HAVE_AIRPCAP */
3797 static void copy_global_profile (const gchar *profile_name)
3799 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3801 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3802 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3803 "Can't create directory\n\"%s\":\n%s.",
3804 pf_dir_path, g_strerror(errno));
3806 g_free(pf_dir_path);
3809 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3810 &pf_dir_path, &pf_dir_path2) == -1) {
3811 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3812 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3813 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3815 g_free(pf_filename);
3816 g_free(pf_dir_path);
3817 g_free(pf_dir_path2);
3821 /* Change configuration profile */
3822 void change_configuration_profile (const gchar *profile_name)
3824 char *gdp_path, *dp_path;
3828 /* First check if profile exists */
3829 if (!profile_exists(profile_name, FALSE)) {
3830 if (profile_exists(profile_name, TRUE)) {
3831 /* Copy from global profile */
3832 copy_global_profile (profile_name);
3834 /* No personal and no global profile exists */
3839 /* Then check if changing to another profile */
3840 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3844 /* Get the current geometry, before writing it to disk */
3845 main_save_window_geometry(top_level);
3847 if (profile_exists(get_profile_name(), FALSE)) {
3848 /* Write recent file for profile we are leaving, if it still exists */
3849 write_profile_recent();
3852 /* Set profile name and update the status bar */
3853 set_profile_name (profile_name);
3854 profile_bar_update ();
3855 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3857 /* Reset current preferences and apply the new */
3861 (void) read_configuration_files (&gdp_path, &dp_path);
3863 recent_read_profile_static(&rf_path, &rf_open_errno);
3864 if (rf_path != NULL && rf_open_errno != 0) {
3865 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3866 "Could not open common recent file\n\"%s\": %s.",
3867 rf_path, g_strerror(rf_open_errno));
3869 if (recent.gui_fileopen_remembered_dir &&
3870 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3871 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3873 timestamp_set_type (recent.gui_time_format);
3874 timestamp_set_seconds_type (recent.gui_seconds_format);
3875 color_filters_enable(recent.packet_list_colorize);
3877 prefs_to_capture_opts();
3879 macros_post_update();
3881 /* Update window view and redraw the toolbar */
3882 main_titlebar_update();
3883 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3884 toolbar_redraw_all();
3886 /* Enable all protocols and disable from the disabled list */
3888 if (gdp_path == NULL && dp_path == NULL) {
3889 set_disabled_protos_list();
3892 /* Reload color filters */
3893 color_filters_reload();
3895 /* Reload list of interfaces on welcome page */
3896 welcome_if_panel_reload();
3898 /* Recreate the packet list according to new preferences */
3899 packet_list_recreate ();
3900 cfile.columns_changed = FALSE; /* Reset value */
3903 /* Update menus with new recent values */
3904 menu_recent_read_finished();
3906 /* Reload pane geometry, must be done after recreating the list */
3907 main_pane_load_window_geometry();
3910 /** redissect packets and update UI */
3911 void redissect_packets(void)
3913 cf_redissect_packets(&cfile);
3914 status_expert_update();