5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10 * needed by dissect routines
11 * Jeff Foster, 2001/03/12, added support tabbed hex display windowss
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <gdk/gdkkeysyms.h>
44 #ifdef NEED_STRERROR_H
45 #include "wsutil/strerror.h"
51 #include "wsutil/wsgetopt.h"
54 #ifdef _WIN32 /* Needed for console I/O */
59 #ifdef HAVE_LIBPORTAUDIO
60 #include <portaudio.h>
61 #endif /* HAVE_LIBPORTAUDIO */
63 #include <epan/epan.h>
64 #include <epan/filesystem.h>
65 #include <wsutil/privileges.h>
66 #include <epan/epan_dissect.h>
67 #include <epan/timestamp.h>
68 #include <epan/packet.h>
69 #include <epan/plugins.h>
70 #include <epan/dfilter/dfilter.h>
71 #include <epan/strutil.h>
72 #include <epan/addr_resolv.h>
73 #include <epan/emem.h>
74 #include <epan/ex-opt.h>
75 #include <epan/funnel.h>
76 #include <epan/expert.h>
77 #include <epan/frequency-utils.h>
78 #include <epan/prefs.h>
79 #include <epan/prefs-int.h>
81 #include <epan/stat_cmd_args.h>
83 #include <epan/emem.h>
84 #include <epan/column.h>
86 /* general (not GTK specific) */
88 #include "../summary.h"
89 #include "../filters.h"
90 #include "../disabled_protos.h"
92 #include "../color_filters.h"
94 #include "../simple_dialog.h"
95 #include "../register.h"
96 #include "../ringbuffer.h"
97 #include "../ui_util.h"
99 #include "../clopts_common.h"
100 #include "../console_io.h"
101 #include "../cmdarg_err.h"
102 #include "../version_info.h"
103 #include "../merge.h"
104 #include "../alert_box.h"
106 #include <wsutil/file_util.h>
109 #include "../capture_ui_utils.h"
110 #include "../capture-pcap-util.h"
111 #include "../capture_ifinfo.h"
112 #include "../capture.h"
113 #include "../capture_sync.h"
117 #include "../capture-wpcap.h"
118 #include "../capture_wpcap_packet.h"
119 #include <tchar.h> /* Needed for Unicode */
120 #include <commctrl.h>
124 #include "gtk/file_dlg.h"
125 #include "gtk/gtkglobals.h"
126 #include "gtk/color_utils.h"
127 #include "gtk/gui_utils.h"
128 #include "gtk/color_dlg.h"
129 #include "gtk/filter_dlg.h"
130 #include "gtk/uat_gui.h"
132 #include "gtk/main.h"
133 #include "gtk/main_airpcap_toolbar.h"
134 #include "gtk/main_filter_toolbar.h"
135 #include "gtk/menus.h"
136 #include "gtk/main_packet_list.h"
137 #include "gtk/main_statusbar.h"
138 #include "gtk/main_statusbar_private.h"
139 #include "gtk/main_toolbar.h"
140 #include "gtk/main_welcome.h"
141 #include "gtk/drag_and_drop.h"
142 #include "gtk/capture_file_dlg.h"
143 #include "gtk/main_proto_draw.h"
144 #include "gtk/keys.h"
145 #include "gtk/packet_win.h"
146 #include "gtk/stock_icons.h"
147 #include "gtk/find_dlg.h"
148 #include "gtk/recent.h"
149 #include "gtk/follow_tcp.h"
150 #include "gtk/font_utils.h"
151 #include "gtk/about_dlg.h"
152 #include "gtk/help_dlg.h"
153 #include "gtk/decode_as_dlg.h"
154 #include "gtk/webbrowser.h"
155 #include "gtk/capture_dlg.h"
156 #include "gtk/capture_if_dlg.h"
157 #include "gtk/tap_dfilter_dlg.h"
158 #include "gtk/prefs_column.h"
159 #include "gtk/prefs_dlg.h"
160 #include "gtk/proto_help.h"
163 #include "../image/wsicon16.xpm"
164 #include "../image/wsicon32.xpm"
165 #include "../image/wsicon48.xpm"
166 #include "../image/wsicon64.xpm"
167 #include "../image/wsiconcap16.xpm"
168 #include "../image/wsiconcap32.xpm"
169 #include "../image/wsiconcap48.xpm"
174 #include "airpcap_loader.h"
175 #include "airpcap_dlg.h"
176 #include "airpcap_gui_utils.h"
180 #include <epan/crypt/airpdcap_ws.h>
183 #ifdef NEW_PACKET_LIST
184 #include "gtk/new_packet_list.h"
187 #ifdef HAVE_GTKOSXAPPLICATION
188 #include <igemacintegration/gtkosxapplication.h>
192 * Files under personal and global preferences directories in which
193 * GTK settings for Wireshark are stored.
195 #define RC_FILE "gtkrc"
199 /* "exported" main widgets */
200 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
202 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
203 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
204 static GtkWidget *main_first_pane, *main_second_pane;
206 /* internally used widgets */
207 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
210 GtkWidget *airpcap_tb;
211 int airpcap_dll_ret_val = -1;
214 GString *comp_info_str, *runtime_info_str;
215 gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
217 guint tap_update_timer_id;
220 static gboolean has_console; /* TRUE if app has console */
221 static void destroy_console(void);
222 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
224 static void console_log_handler(const char *log_domain,
225 GLogLevelFlags log_level, const char *message, gpointer user_data);
228 capture_options global_capture_opts;
232 static void create_main_window(gint, gint, gint, e_prefs*);
233 static void show_main_window(gboolean);
234 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
235 static void main_save_window_geometry(GtkWidget *widget);
238 /* Match selected byte pattern */
240 match_selected_cb_do(gpointer data, int action, gchar *text)
242 GtkWidget *filter_te;
243 char *cur_filter, *new_filter;
245 if ((!text) || (0 == strlen(text))) {
246 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
251 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
254 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
256 switch (action&MATCH_SELECTED_MASK) {
258 case MATCH_SELECTED_REPLACE:
259 new_filter = g_strdup(text);
262 case MATCH_SELECTED_AND:
263 if ((!cur_filter) || (0 == strlen(cur_filter)))
264 new_filter = g_strdup(text);
266 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
269 case MATCH_SELECTED_OR:
270 if ((!cur_filter) || (0 == strlen(cur_filter)))
271 new_filter = g_strdup(text);
273 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
276 case MATCH_SELECTED_NOT:
277 new_filter = g_strconcat("!(", text, ")", NULL);
280 case MATCH_SELECTED_AND_NOT:
281 if ((!cur_filter) || (0 == strlen(cur_filter)))
282 new_filter = g_strconcat("!(", text, ")", NULL);
284 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
287 case MATCH_SELECTED_OR_NOT:
288 if ((!cur_filter) || (0 == strlen(cur_filter)))
289 new_filter = g_strconcat("!(", text, ")", NULL);
291 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
295 g_assert_not_reached();
300 /* Free up the copy we got of the old filter text. */
303 /* Don't change the current display filter if we only want to copy the filter */
304 if (action&MATCH_SELECTED_COPY_ONLY) {
305 GString *gtk_text_str = g_string_new("");
306 g_string_append(gtk_text_str, new_filter);
307 copy_to_clipboard(gtk_text_str);
308 g_string_free(gtk_text_str, TRUE);
310 /* create a new one and set the display filter entry accordingly */
311 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
313 /* Run the display filter so it goes in effect. */
314 if (action&MATCH_SELECTED_APPLY_NOW)
315 main_filter_packets(&cfile, new_filter, FALSE);
318 /* Free up the new filter text. */
323 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
327 if (cfile.finfo_selected) {
328 filter = proto_construct_match_selected_string(cfile.finfo_selected,
330 match_selected_cb_do((data ? data : w), action, filter);
335 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
339 if (cfile.finfo_selected) {
340 filter = proto_construct_match_selected_string(cfile.finfo_selected,
342 if ((!filter) || (0 == strlen(filter))) {
343 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
344 "Could not acquire information to build a filter!\n"
345 "Try expanding or choosing another item.");
350 color_display_with_filter(filter);
353 color_filters_reset_tmp();
355 color_filters_set_tmp(filt_nr,filter, FALSE);
357 cf_colorize_packets(&cfile);
363 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
365 gchar *selected_proto_url;
366 gchar *proto_abbrev = data;
371 if (cfile.finfo_selected) {
372 /* open wiki page using the protocol abbreviation */
373 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
374 browser_open_url(selected_proto_url);
375 g_free(selected_proto_url);
378 case(ESD_BTN_CANCEL):
381 g_assert_not_reached();
387 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
390 const gchar *proto_abbrev;
394 if (cfile.finfo_selected) {
395 /* convert selected field to protocol abbreviation */
396 /* XXX - could this conversion be simplified? */
397 field_id = cfile.finfo_selected->hfinfo->id;
398 /* if the selected field isn't a protocol, get it's parent */
399 if(!proto_registrar_is_protocol(field_id)) {
400 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
403 proto_abbrev = proto_registrar_get_abbrev(field_id);
405 if (!proto_is_private(field_id)) {
406 /* ask the user if the wiki page really should be opened */
407 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
408 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
410 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
412 "The Wireshark Wiki is a collaborative approach to provide information "
413 "about Wireshark in several ways (not limited to protocol specifics).\n"
415 "This Wiki is new, so the page of the selected protocol "
416 "may not exist and/or may not contain valuable information.\n"
418 "As everyone can edit the Wiki and add new content (or extend existing), "
419 "you are encouraged to add information if you can.\n"
421 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
423 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
424 "which will save you a lot of editing and will give a consistent look over the pages.",
425 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
426 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
428 /* appologize to the user that the wiki page cannot be opened */
429 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
430 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
432 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
434 "Since this is a private protocol, such information is not available in "
435 "a public wiki. Therefore this wiki entry is blocked.\n"
437 "Sorry for the inconvenience.\n",
438 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
443 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
445 gchar *selected_proto_url;
446 gchar *proto_abbrev = data;
450 if (cfile.finfo_selected) {
451 /* open reference page using the protocol abbreviation */
452 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
453 browser_open_url(selected_proto_url);
454 g_free(selected_proto_url);
457 case(ESD_BTN_CANCEL):
460 g_assert_not_reached();
465 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
468 const gchar *proto_abbrev;
472 if (cfile.finfo_selected) {
473 /* convert selected field to protocol abbreviation */
474 /* XXX - could this conversion be simplified? */
475 field_id = cfile.finfo_selected->hfinfo->id;
476 /* if the selected field isn't a protocol, get it's parent */
477 if(!proto_registrar_is_protocol(field_id)) {
478 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
481 proto_abbrev = proto_registrar_get_abbrev(field_id);
483 if (!proto_is_private(field_id)) {
484 /* ask the user if the wiki page really should be opened */
485 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
486 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
488 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
490 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
491 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
493 /* appologize to the user that the wiki page cannot be opened */
494 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
495 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
497 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
499 "Since this is a private protocol, such information is not available on "
500 "a public website. Therefore this filter entry is blocked.\n"
502 "Sorry for the inconvenience.\n",
503 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
509 is_address_column (gint column)
511 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
512 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
513 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
514 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
515 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
524 get_ip_address_list_from_packet_list_row(gpointer data)
526 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
527 #ifdef NEW_PACKET_LIST
528 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
530 gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
534 GList *addr_list = NULL;
538 #ifdef NEW_PACKET_LIST
539 fdata = (frame_data *) new_packet_list_get_row_data(row);
541 fdata = (frame_data *) packet_list_get_row_data(row);
547 if (!cf_read_frame (&cfile, fdata, &err, &err_info))
549 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
550 cf_read_error_message(err, err_info), cfile.filename);
554 epan_dissect_init(&edt, FALSE, FALSE);
555 col_custom_prime_edt(&edt, &cfile.cinfo);
557 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
558 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
560 /* First check selected column */
561 if (is_address_column (column)) {
562 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
565 for (col = 0; col < cfile.cinfo.num_cols; col++) {
566 /* Then check all columns except the selected */
567 if ((col != column) && (is_address_column (col))) {
568 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
572 epan_dissect_cleanup(&edt);
579 get_filter_from_packet_list_row_and_column(gpointer data)
581 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
582 #ifdef NEW_PACKET_LIST
583 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
585 gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
592 #ifdef NEW_PACKET_LIST
593 fdata = (frame_data *) new_packet_list_get_row_data(row);
595 fdata = (frame_data *) packet_list_get_row_data(row);
601 if (!cf_read_frame(&cfile, fdata, &err, &err_info)) {
602 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
603 cf_read_error_message(err, err_info), cfile.filename);
606 /* proto tree, visible. We need a proto tree if there's custom columns */
607 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
608 col_custom_prime_edt(&edt, &cfile.cinfo);
610 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
612 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
614 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
615 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
616 /* leak a little but safer than ep_ here */
617 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
618 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
619 if (hfi->parent == -1) {
621 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
622 } else if (hfi->type == FT_STRING) {
623 /* Custom string, add quotes */
624 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
625 cfile.cinfo.col_expr.col_expr_val[column]);
629 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
630 cfile.cinfo.col_expr.col_expr_val[column]);
634 epan_dissect_cleanup(&edt);
641 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
643 match_selected_cb_do(data,
645 get_filter_from_packet_list_row_and_column(data));
648 /* This function allows users to right click in the details window and copy the text
649 * information to the operating systems clipboard.
651 * We first check to see if a string representation is setup in the tree and then
652 * read the string. If not available then we try to grab the value. If all else
653 * fails we display a message to the user to indicate the copy could not be completed.
656 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
658 GString *gtk_text_str = g_string_new("");
659 char labelstring[256];
660 char *stringpointer = labelstring;
664 case COPY_SELECTED_DESCRIPTION:
665 if (cfile.finfo_selected->rep->representation != 0) {
666 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
669 case COPY_SELECTED_FIELDNAME:
670 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
671 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
674 case COPY_SELECTED_VALUE:
675 if (cfile.edt !=0 ) {
676 g_string_append(gtk_text_str,
677 get_node_field_value(cfile.finfo_selected, cfile.edt));
684 if (gtk_text_str->len == 0) {
685 /* If no representation then... Try to read the value */
686 proto_item_fill_label(cfile.finfo_selected, stringpointer);
687 g_string_append(gtk_text_str, stringpointer);
690 if (gtk_text_str->len == 0) {
691 /* Could not get item so display error msg */
692 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
694 /* Copy string to clipboard */
695 copy_to_clipboard(gtk_text_str);
697 g_string_free(gtk_text_str, TRUE); /* Free the memory */
701 /* mark as reference time frame */
703 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
707 frame->flags.ref_time=1;
709 frame->flags.ref_time=0;
711 cf_reftime_packets(&cfile);
712 #ifdef NEW_PACKET_LIST
713 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
714 new_packet_list_freeze();
715 cfile.displayed_count--;
716 new_packet_list_recreate_visible_rows();
717 new_packet_list_thaw();
719 new_packet_list_queue_draw();
724 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
728 timestamp_set_type(TS_RELATIVE);
729 recent.gui_time_format = TS_RELATIVE;
730 #ifdef NEW_PACKET_LIST
731 cf_timestamp_auto_precision(&cfile);
732 new_packet_list_queue_draw();
734 cf_change_time_formats(&cfile);
740 g_assert_not_reached();
743 if (cfile.current_frame) {
744 set_frame_reftime(!cfile.current_frame->flags.ref_time,
745 cfile.current_frame, cfile.current_row);
751 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
753 static GtkWidget *reftime_dialog = NULL;
757 if (cfile.current_frame) {
758 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
759 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
760 "%sSwitch to the appropriate Time Display Format?%s\n\n"
761 "Time References don't work well with the currently selected Time Display Format.\n\n"
762 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
763 simple_dialog_primary_start(), simple_dialog_primary_end());
764 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
766 set_frame_reftime(!cfile.current_frame->flags.ref_time,
767 cfile.current_frame, cfile.current_row);
771 case REFTIME_FIND_NEXT:
772 find_previous_next_frame_with_filter("frame.ref_time", FALSE);
774 case REFTIME_FIND_PREV:
775 find_previous_next_frame_with_filter("frame.ref_time", TRUE);
781 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
783 find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
787 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
789 find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
793 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
796 gchar *help_str = NULL;
797 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
799 gboolean has_blurb = FALSE;
800 guint length = 0, byte_len;
801 GtkWidget *byte_view;
802 const guint8 *byte_data;
807 /* if nothing is selected */
808 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
811 * Which byte view is displaying the current protocol tree
814 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
815 if (byte_view == NULL)
818 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
819 if (byte_data == NULL)
822 cf_unselect_field(&cfile);
823 packet_hex_print(byte_view, byte_data,
824 cfile.current_frame, NULL, byte_len);
825 proto_help_menu_modify(sel, &cfile);
828 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
831 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
833 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
834 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
835 g_assert(byte_data != NULL);
837 cfile.finfo_selected = finfo;
838 set_menus_for_selected_tree_row(&cfile);
841 if (finfo->hfinfo->blurb != NULL &&
842 finfo->hfinfo->blurb[0] != '\0') {
844 length = (guint) strlen(finfo->hfinfo->blurb);
846 length = (guint) strlen(finfo->hfinfo->name);
848 finfo_length = finfo->length + finfo->appendix_length;
850 if (finfo_length == 0) {
852 } else if (finfo_length == 1) {
853 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
855 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
857 statusbar_pop_field_msg(); /* get rid of current help msg */
859 help_str = g_strdup_printf(" %s (%s)%s",
860 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
861 finfo->hfinfo->abbrev, len_str);
862 statusbar_push_field_msg(help_str);
866 * Don't show anything if the field name is zero-length;
867 * the pseudo-field for "proto_tree_add_text()" is such
868 * a field, and we don't want "Text (text)" showing up
869 * on the status line if you've selected such a field.
871 * XXX - there are zero-length fields for which we *do*
872 * want to show the field name.
874 * XXX - perhaps the name and abbrev field should be null
875 * pointers rather than null strings for that pseudo-field,
876 * but we'd have to add checks for null pointers in some
877 * places if we did that.
879 * Or perhaps protocol tree items added with
880 * "proto_tree_add_text()" should have -1 as the field index,
881 * with no pseudo-field being used, but that might also
882 * require special checks for -1 to be added.
884 statusbar_push_field_msg("");
887 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
889 proto_help_menu_modify(sel, &cfile);
892 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
894 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
897 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
899 expand_all_tree(cfile.edt->tree, tree_view_gbl);
902 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
904 if (cfile.finfo_selected) {
905 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
906 cfile.finfo_selected->hfinfo->abbrev);
907 /* Recreate the packet list according to new preferences */
908 #ifdef NEW_PACKET_LIST
909 new_packet_list_recreate ();
911 packet_list_recreate ();
913 if (!prefs.gui_use_pref_save) {
916 cfile.cinfo.columns_changed = FALSE; /* Reset value */
920 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
923 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
925 /* the mouse position is at an entry, expand that one */
926 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
927 gtk_tree_path_free(path);
931 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
932 if (cfile.edt->tree) {
933 guint32 tmp = g_resolv_flags;
934 g_resolv_flags = RESOLV_ALL;
935 proto_tree_draw(cfile.edt->tree, tree_view_gbl);
936 g_resolv_flags = tmp;
941 main_set_for_capture_file(gboolean have_capture_file_in)
943 have_capture_file = have_capture_file_in;
945 main_widgets_show_or_hide();
951 /* get the current geometry, before writing it to disk */
952 main_save_window_geometry(top_level);
954 /* write user's recent file to disk
955 * It is no problem to write this file, even if we do not quit */
956 write_profile_recent();
959 /* XXX - should we check whether the capture file is an
960 unsaved temporary file for a live capture and, if so,
961 pop up a "do you want to exit without saving the capture
962 file?" dialog, and then just return, leaving said dialog
963 box to forcibly quit if the user clicks "OK"?
965 If so, note that this should be done in a subroutine that
966 returns TRUE if we do so, and FALSE otherwise, and if it
967 returns TRUE we should return TRUE without nuking anything.
969 Note that, if we do that, we might also want to check if
970 an "Update list of packets in real time" capture is in
971 progress and, if so, ask whether they want to terminate
972 the capture and discard it, and return TRUE, before nuking
973 any child capture, if they say they don't want to do so. */
976 /* Nuke any child capture in progress. */
977 capture_kill_child(&global_capture_opts);
980 /* Are we in the middle of reading a capture? */
981 if (cfile.state == FILE_READ_IN_PROGRESS) {
982 /* Yes, so we can't just close the file and quit, as
983 that may yank the rug out from under the read in
984 progress; instead, just set the state to
985 "FILE_READ_ABORTED" and return - the code doing the read
986 will check for that and, if it sees that, will clean
988 cfile.state = FILE_READ_ABORTED;
990 /* Say that the window should *not* be deleted;
991 that'll be done by the code that cleans up. */
994 /* Close any capture file we have open; on some OSes, you
995 can't unlink a temporary capture file if you have it
997 "cf_close()" will unlink it after closing it if
998 it's a temporary file.
1000 We do this here, rather than after the main loop returns,
1001 as, after the main loop returns, the main window may have
1002 been destroyed (if this is called due to a "destroy"
1003 even on the main window rather than due to the user
1004 selecting a menu item), and there may be a crash
1005 or other problem when "cf_close()" tries to
1006 clean up stuff in the main window.
1008 XXX - is there a better place to put this?
1009 Or should we have a routine that *just* closes the
1010 capture file, and doesn't do anything with the UI,
1011 which we'd call here, and another routine that
1012 calls that routine and also cleans up the UI, which
1013 we'd call elsewhere? */
1016 /* Exit by leaving the main loop, so that any quit functions
1017 we registered get called. */
1020 /* Say that the window should be deleted. */
1026 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1030 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1031 gtk_window_present(GTK_WINDOW(top_level));
1032 /* user didn't saved his current file, ask him */
1033 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1034 "%sSave capture file before program quit?%s\n\n"
1035 "If you quit the program without saving, your capture data will be discarded.",
1036 simple_dialog_primary_start(), simple_dialog_primary_end());
1037 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1040 /* unchanged file, just exit */
1041 /* "main_do_quit()" indicates whether the main window should be deleted. */
1042 return main_do_quit();
1048 main_pane_load_window_geometry(void)
1050 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1051 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1052 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1053 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1059 main_load_window_geometry(GtkWidget *widget)
1061 window_geometry_t geom;
1063 geom.set_pos = prefs.gui_geometry_save_position;
1064 geom.x = recent.gui_geometry_main_x;
1065 geom.y = recent.gui_geometry_main_y;
1066 geom.set_size = prefs.gui_geometry_save_size;
1067 if (recent.gui_geometry_main_width > 0 &&
1068 recent.gui_geometry_main_height > 0) {
1069 geom.width = recent.gui_geometry_main_width;
1070 geom.height = recent.gui_geometry_main_height;
1071 geom.set_maximized = prefs.gui_geometry_save_maximized;
1073 /* We assume this means the width and height weren't set in
1074 the "recent" file (or that there is no "recent" file),
1075 and weren't set to a default value, so we don't set the
1076 size. (The "recent" file code rejects non-positive width
1077 and height values.) */
1078 geom.set_size = FALSE;
1080 geom.maximized = recent.gui_geometry_main_maximized;
1082 window_set_geometry(widget, &geom);
1084 main_pane_load_window_geometry();
1085 statusbar_load_window_geometry();
1090 main_save_window_geometry(GtkWidget *widget)
1092 window_geometry_t geom;
1094 window_get_geometry(widget, &geom);
1096 if (prefs.gui_geometry_save_position) {
1097 recent.gui_geometry_main_x = geom.x;
1098 recent.gui_geometry_main_y = geom.y;
1101 if (prefs.gui_geometry_save_size) {
1102 recent.gui_geometry_main_width = geom.width;
1103 recent.gui_geometry_main_height = geom.height;
1106 if(prefs.gui_geometry_save_maximized) {
1107 recent.gui_geometry_main_maximized = geom.maximized;
1110 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1111 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1112 statusbar_save_window_geometry();
1115 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1119 /* save file first */
1120 file_save_as_cmd(after_save_exit, NULL);
1122 case(ESD_BTN_QUIT_DONT_SAVE):
1125 case(ESD_BTN_CANCEL):
1128 g_assert_not_reached();
1133 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1137 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1138 /* user didn't saved his current file, ask him */
1139 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1140 "%sSave capture file before program quit?%s\n\n"
1141 "If you quit the program without saving, your capture data will be discarded.",
1142 simple_dialog_primary_start(), simple_dialog_primary_end());
1143 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1145 /* unchanged file, just exit */
1151 print_usage(gboolean print_ver) {
1161 fprintf(output, "Wireshark " VERSION "%s\n"
1162 "Interactively dump and analyze network traffic.\n"
1163 "See http://www.wireshark.org for more information.\n"
1166 wireshark_svnversion, get_copyright_info());
1170 fprintf(output, "\n");
1171 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1172 fprintf(output, "\n");
1175 fprintf(output, "Capture interface:\n");
1176 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1177 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1178 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1179 fprintf(output, " -p don't capture in promiscuous mode\n");
1180 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1181 fprintf(output, " -Q quit Wireshark after capturing\n");
1182 fprintf(output, " -S update packet display when new packets are captured\n");
1183 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1184 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1185 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1187 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1188 fprintf(output, " -D print list of interfaces and exit\n");
1189 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1190 fprintf(output, "\n");
1191 fprintf(output, "Capture stop conditions:\n");
1192 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1193 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1194 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1195 fprintf(output, " files:NUM - stop after NUM files\n");
1196 /*fprintf(output, "\n");*/
1197 fprintf(output, "Capture output:\n");
1198 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1199 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1200 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1201 #endif /* HAVE_LIBPCAP */
1203 /*fprintf(output, "\n");*/
1204 fprintf(output, "Input file:\n");
1205 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1207 fprintf(output, "\n");
1208 fprintf(output, "Processing:\n");
1209 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1210 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1211 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1213 fprintf(output, "\n");
1214 fprintf(output, "User interface:\n");
1215 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1216 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1217 fprintf(output, " -J <jump filter> jump to the first packet matching the (display) filter\n");
1218 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1219 fprintf(output, " -m <font> set the font name used for most text\n");
1220 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1221 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1222 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1223 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1225 fprintf(output, "\n");
1226 fprintf(output, "Output:\n");
1227 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1229 fprintf(output, "\n");
1230 fprintf(output, "Miscellaneous:\n");
1231 fprintf(output, " -h display this help and exit\n");
1232 fprintf(output, " -v display version info and exit\n");
1233 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1234 fprintf(output, " persdata:path - personal data files\n");
1235 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1236 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1238 fprintf(output, " --display=DISPLAY X display to use\n");
1253 printf(PACKAGE " " VERSION "%s\n"
1260 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1261 runtime_info_str->str);
1269 * Print to the standard error. On Windows, create a console for the
1270 * standard error to show up on, if necessary.
1271 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1272 * terminal isn't the standard error?
1275 vfprintf_stderr(const char *fmt, va_list ap)
1280 vfprintf(stderr, fmt, ap);
1284 fprintf_stderr(const char *fmt, ...)
1289 vfprintf_stderr(fmt, ap);
1294 * Report an error in command-line arguments.
1295 * Creates a console on Windows.
1298 cmdarg_err(const char *fmt, ...)
1302 fprintf_stderr("wireshark: ");
1304 vfprintf_stderr(fmt, ap);
1306 fprintf_stderr("\n");
1310 * Report additional information for an error in command-line arguments.
1311 * Creates a console on Windows.
1312 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1313 * terminal isn't the standard error?
1316 cmdarg_err_cont(const char *fmt, ...)
1321 vfprintf_stderr(fmt, ap);
1322 fprintf_stderr("\n");
1326 #if defined(_WIN32) || ! defined USE_THREADS
1328 Once every 3 seconds we get a callback here which we use to update
1329 the tap extensions. Since Gtk1 is single threaded we dont have to
1330 worry about any locking or critical regions.
1333 tap_update_cb(gpointer data _U_)
1335 draw_tap_listeners(FALSE);
1339 /* Restart the tap update display timer with new configured interval */
1340 void reset_tap_update_timer(void)
1342 g_source_remove(tap_update_timer_id);
1343 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1348 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1349 use threads all update_thread_mutex can be dropped and protect/unprotect
1350 would just be empty functions.
1352 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1353 gtk1-wireshark and it will just work.
1355 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1357 update_thread(gpointer data _U_)
1361 g_get_current_time(&tv1);
1362 g_static_mutex_lock(&update_thread_mutex);
1363 gdk_threads_enter();
1364 draw_tap_listeners(FALSE);
1365 gdk_threads_leave();
1366 g_static_mutex_unlock(&update_thread_mutex);
1368 g_get_current_time(&tv2);
1370 /* Assuming it took less than configured time to update tap listeners... */
1371 if( (tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) >
1372 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1373 /* Wait for remainder of configured time */
1374 g_usleep((tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) -
1375 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1382 protect_thread_critical_region(void)
1384 #if !defined(_WIN32) && defined USE_THREADS
1385 g_static_mutex_lock(&update_thread_mutex);
1389 unprotect_thread_critical_region(void)
1391 #if !defined(_WIN32) && defined USE_THREADS
1392 g_static_mutex_unlock(&update_thread_mutex);
1397 * Periodically process outstanding hostname lookups. If we have new items,
1398 * redraw the packet list and tree view.
1402 resolv_update_cb(gpointer data _U_)
1404 /* Anything new show up? */
1405 if (host_name_lookup_process(NULL)) {
1406 if (pkt_scrollw->window)
1407 gdk_window_invalidate_rect(pkt_scrollw->window, NULL, TRUE);
1408 if (tv_scrollw->window)
1409 gdk_window_invalidate_rect(tv_scrollw->window, NULL, TRUE);
1412 /* Always check. Even if we don't do async lookups we could still get
1413 passive updates, e.g. from DNS packets. */
1418 /* Set main_window_name and it's icon title to the capture filename */
1420 set_display_filename(capture_file *cf)
1425 window_name = g_strdup_printf("%s", cf_get_display_name(cf));
1426 set_main_window_name(window_name);
1427 g_free(window_name);
1429 set_main_window_name("The Wireshark Network Analyzer");
1433 GtkWidget *close_dlg = NULL;
1436 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1438 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1443 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1445 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1450 main_cf_cb_file_closing(capture_file *cf)
1453 /* if we have more than 10000 packets, show a splash screen while closing */
1454 /* XXX - don't know a better way to decide whether to show or not,
1455 * as most of the time is spend in a single eth_clist_clear function,
1456 * so we can't use a progress bar here! */
1457 if(cf->count > 10000) {
1458 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1459 "%sClosing file!%s\n\nPlease wait ...",
1460 simple_dialog_primary_start(),
1461 simple_dialog_primary_end());
1462 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1465 /* Destroy all windows, which refer to the
1466 capture file we're closing. */
1467 destroy_packet_wins();
1468 file_save_as_destroy();
1470 /* Restore the standard title bar message. */
1471 set_main_window_name("The Wireshark Network Analyzer");
1473 /* Disable all menu items that make sense only if you have a capture. */
1474 set_menus_for_capture_file(NULL);
1475 set_menus_for_captured_packets(FALSE);
1476 set_menus_for_selected_packet(cf);
1477 set_menus_for_capture_in_progress(FALSE);
1478 set_capture_if_dialog_for_capture_in_progress(FALSE);
1479 set_menus_for_selected_tree_row(cf);
1481 /* Set up main window for no capture file. */
1482 main_set_for_capture_file(FALSE);
1484 main_window_update();
1488 main_cf_cb_file_closed(capture_file *cf _U_)
1490 if(close_dlg != NULL) {
1491 splash_destroy(close_dlg);
1498 main_cf_cb_file_read_started(capture_file *cf _U_)
1500 tap_dfilter_dlg_update();
1502 /* Set up main window for a capture file. */
1503 main_set_for_capture_file(TRUE);
1507 main_cf_cb_file_read_finished(capture_file *cf)
1511 size_t dir_path_len;
1513 if (!cf->is_tempfile && cf->filename) {
1514 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1515 add_menu_recent_capture_file(cf->filename);
1517 /* Remember folder for next Open dialog and saved in recent */
1518 cf_path_end = find_last_pathname_separator(cf->filename);
1519 dir_path_len = (cf_path_end - cf->filename);
1520 dir_path = g_malloc (dir_path_len + 1);
1521 g_snprintf (dir_path, dir_path_len, "%s", cf->filename);
1522 dir_path[dir_path_len++] = '\0';
1523 set_last_open_dir(dir_path);
1525 set_display_filename(cf);
1527 /* Enable menu items that make sense if you have a capture file you've
1528 finished reading. */
1529 set_menus_for_capture_file(cf);
1531 /* Enable menu items that make sense if you have some captured packets. */
1532 set_menus_for_captured_packets(TRUE);
1536 static GList *icon_list_create(
1537 const char **icon16_xpm,
1538 const char **icon32_xpm,
1539 const char **icon48_xpm,
1540 const char **icon64_xpm)
1542 GList *icon_list = NULL;
1543 GdkPixbuf * pixbuf16;
1544 GdkPixbuf * pixbuf32;
1545 GdkPixbuf * pixbuf48;
1546 GdkPixbuf * pixbuf64;
1549 if(icon16_xpm != NULL) {
1550 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1552 icon_list = g_list_append(icon_list, pixbuf16);
1555 if(icon32_xpm != NULL) {
1556 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1558 icon_list = g_list_append(icon_list, pixbuf32);
1561 if(icon48_xpm != NULL) {
1562 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1564 icon_list = g_list_append(icon_list, pixbuf48);
1567 if(icon64_xpm != NULL) {
1568 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1570 icon_list = g_list_append(icon_list, pixbuf64);
1577 main_capture_set_main_window_title(capture_options *capture_opts)
1579 GString *title = g_string_new("");
1581 g_string_append(title, "Capturing ");
1582 if(capture_opts->iface) {
1583 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1585 set_main_window_name(title->str);
1586 g_string_free(title, TRUE);
1590 main_capture_cb_capture_prepared(capture_options *capture_opts)
1592 static GList *icon_list = NULL;
1594 main_capture_set_main_window_title(capture_opts);
1596 if(icon_list == NULL) {
1597 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1599 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1601 /* Disable menu items that make no sense if you're currently running
1603 set_menus_for_capture_in_progress(TRUE);
1604 set_capture_if_dialog_for_capture_in_progress(TRUE);
1606 /* Don't set up main window for a capture file. */
1607 main_set_for_capture_file(FALSE);
1611 main_capture_cb_capture_update_started(capture_options *capture_opts)
1613 /* We've done this in "prepared" above, but it will be cleared while
1614 switching to the next multiple file. */
1615 main_capture_set_main_window_title(capture_opts);
1617 set_menus_for_capture_in_progress(TRUE);
1618 set_capture_if_dialog_for_capture_in_progress(TRUE);
1620 /* Enable menu items that make sense if you have some captured
1621 packets (yes, I know, we don't have any *yet*). */
1622 set_menus_for_captured_packets(TRUE);
1624 /* Set up main window for a capture file. */
1625 main_set_for_capture_file(TRUE);
1629 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1631 capture_file *cf = capture_opts->cf;
1632 static GList *icon_list = NULL;
1634 if (!cf->is_tempfile && cf->filename) {
1635 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1636 add_menu_recent_capture_file(cf->filename);
1638 set_display_filename(cf);
1640 /* Enable menu items that make sense if you're not currently running
1642 set_menus_for_capture_in_progress(FALSE);
1643 set_capture_if_dialog_for_capture_in_progress(FALSE);
1645 /* Enable menu items that make sense if you have a capture file
1646 you've finished reading. */
1647 set_menus_for_capture_file(cf);
1649 /* Set up main window for a capture file. */
1650 main_set_for_capture_file(TRUE);
1652 if(icon_list == NULL) {
1653 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1655 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1657 if(global_capture_opts.quit_after_cap) {
1658 /* command line asked us to quit after the capture */
1659 /* don't pop up a dialog to ask for unsaved files etc. */
1665 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1667 /* Don't set up main window for a capture file. */
1668 main_set_for_capture_file(FALSE);
1672 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1675 capture_file *cf = capture_opts->cf;
1677 static GList *icon_list = NULL;
1679 /*set_display_filename(cf);*/
1681 /* Enable menu items that make sense if you're not currently running
1683 set_menus_for_capture_in_progress(FALSE);
1684 set_capture_if_dialog_for_capture_in_progress(FALSE);
1686 /* Restore the standard title bar message */
1687 /* (just in case we have trouble opening the capture file). */
1688 set_main_window_name("The Wireshark Network Analyzer");
1690 if(icon_list == NULL) {
1691 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1693 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1695 /* We don't have loaded the capture file, this will be done later.
1696 * For now we still have simply a blank screen. */
1698 if(global_capture_opts.quit_after_cap) {
1699 /* command line asked us to quit after the capture */
1700 /* don't pop up a dialog to ask for unsaved files etc. */
1705 #endif /* HAVE_LIBPCAP */
1708 main_cf_cb_packet_selected(gpointer data)
1710 capture_file *cf = data;
1712 /* Display the GUI protocol tree and packet bytes.
1713 XXX - why do we dump core if we call "proto_tree_draw()"
1714 before calling "add_byte_views()"? */
1715 add_main_byte_views(cf->edt);
1716 main_proto_tree_draw(cf->edt->tree);
1718 /* The user is searching for a string in the data or a hex value,
1719 * highlight the field that is found in the tree and hex displays. */
1720 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1721 highlight_field(cf->edt->tvb, cfile.search_pos,
1722 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1723 cfile.search_pos = 0; /* Reset the position */
1726 /* A packet is selected. */
1727 set_menus_for_selected_packet(cf);
1731 main_cf_cb_packet_unselected(capture_file *cf)
1733 /* Clear out the display of that packet. */
1734 clear_tree_and_hex_views();
1736 /* No packet is selected. */
1737 set_menus_for_selected_packet(cf);
1741 main_cf_cb_field_unselected(capture_file *cf)
1743 set_menus_for_selected_tree_row(cf);
1747 main_cf_cb_file_save_reload_finished(gpointer data _U_)
1749 set_display_filename(&cfile);
1750 set_menus_for_capture_file(&cfile);
1754 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1757 case(cf_cb_file_closing):
1758 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1759 main_cf_cb_file_closing(data);
1761 case(cf_cb_file_closed):
1762 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1763 main_cf_cb_file_closed(data);
1765 case(cf_cb_file_read_started):
1766 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1767 main_cf_cb_file_read_started(data);
1769 case(cf_cb_file_read_finished):
1770 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1771 main_cf_cb_file_read_finished(data);
1773 case(cf_cb_packet_selected):
1774 main_cf_cb_packet_selected(data);
1776 case(cf_cb_packet_unselected):
1777 main_cf_cb_packet_unselected(data);
1779 case(cf_cb_field_unselected):
1780 main_cf_cb_field_unselected(data);
1782 case(cf_cb_file_save_started):
1783 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1785 case(cf_cb_file_save_finished):
1786 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1788 case(cf_cb_file_save_reload_finished):
1789 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1790 main_cf_cb_file_save_reload_finished(data);
1792 case(cf_cb_file_save_failed):
1793 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1796 g_warning("main_cf_callback: event %u unknown", event);
1797 g_assert_not_reached();
1803 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1805 #ifdef HAVE_GTKOSXAPPLICATION
1806 GtkOSXApplication *theApp;
1809 case(capture_cb_capture_prepared):
1810 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1811 main_capture_cb_capture_prepared(capture_opts);
1813 case(capture_cb_capture_update_started):
1814 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1815 main_capture_cb_capture_update_started(capture_opts);
1816 #ifdef HAVE_GTKOSXAPPLICATION
1817 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1818 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1821 case(capture_cb_capture_update_continue):
1822 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1824 case(capture_cb_capture_update_finished):
1825 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1826 main_capture_cb_capture_update_finished(capture_opts);
1828 case(capture_cb_capture_fixed_started):
1829 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1830 main_capture_cb_capture_fixed_started(capture_opts);
1832 case(capture_cb_capture_fixed_continue):
1833 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1835 case(capture_cb_capture_fixed_finished):
1836 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1837 main_capture_cb_capture_fixed_finished(capture_opts);
1839 case(capture_cb_capture_stopping):
1840 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1841 /* Beware: this state won't be called, if the capture child
1842 * closes the capturing on it's own! */
1843 #ifdef HAVE_GTKOSXAPPLICATION
1844 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1845 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1849 g_warning("main_capture_callback: event %u unknown", event);
1850 g_assert_not_reached();
1856 get_gui_compiled_info(GString *str)
1858 epan_get_compiled_version_info(str);
1860 g_string_append(str, ", ");
1861 #ifdef HAVE_LIBPORTAUDIO
1862 #ifdef PORTAUDIO_API_1
1863 g_string_append(str, "with PortAudio <= V18");
1864 #else /* PORTAUDIO_API_1 */
1865 g_string_append(str, "with ");
1866 g_string_append(str, Pa_GetVersionText());
1867 #endif /* PORTAUDIO_API_1 */
1868 #else /* HAVE_LIBPORTAUDIO */
1869 g_string_append(str, "without PortAudio");
1870 #endif /* HAVE_LIBPORTAUDIO */
1872 g_string_append(str, ", ");
1874 get_compiled_airpcap_version(str);
1876 g_string_append(str, "without AirPcap");
1878 #ifndef NEW_PACKET_LIST
1879 g_string_append(str, ", with old_packet_list");
1884 get_gui_runtime_info(GString *str)
1886 epan_get_runtime_version_info(str);
1889 g_string_append(str, ", ");
1890 get_runtime_airpcap_version(str);
1894 g_string_append(str, ", ");
1895 u3_runtime_info(str);
1900 read_configuration_files(char **gdp_path, char **dp_path)
1902 int gpf_open_errno, gpf_read_errno;
1903 int cf_open_errno, df_open_errno;
1904 int gdp_open_errno, gdp_read_errno;
1905 int dp_open_errno, dp_read_errno;
1906 char *gpf_path, *pf_path;
1907 char *cf_path, *df_path;
1908 int pf_open_errno, pf_read_errno;
1911 /* Read the preference files. */
1912 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1913 &pf_open_errno, &pf_read_errno, &pf_path);
1915 if (gpf_path != NULL) {
1916 if (gpf_open_errno != 0) {
1917 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1918 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1919 strerror(gpf_open_errno));
1921 if (gpf_read_errno != 0) {
1922 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1923 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1924 strerror(gpf_read_errno));
1927 if (pf_path != NULL) {
1928 if (pf_open_errno != 0) {
1929 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1930 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1931 strerror(pf_open_errno));
1933 if (pf_read_errno != 0) {
1934 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1935 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1936 strerror(pf_read_errno));
1943 /* if the user wants a console to be always there, well, we should open one for him */
1944 if (prefs_p->gui_console_open == console_open_always) {
1949 /* Read the capture filter file. */
1950 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1951 if (cf_path != NULL) {
1952 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1953 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1954 strerror(cf_open_errno));
1958 /* Read the display filter file. */
1959 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1960 if (df_path != NULL) {
1961 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1962 "Could not open your display filter file\n\"%s\": %s.", df_path,
1963 strerror(df_open_errno));
1967 /* Read the disabled protocols file. */
1968 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1969 dp_path, &dp_open_errno, &dp_read_errno);
1970 if (*gdp_path != NULL) {
1971 if (gdp_open_errno != 0) {
1972 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1973 "Could not open global disabled protocols file\n\"%s\": %s.",
1974 *gdp_path, strerror(gdp_open_errno));
1976 if (gdp_read_errno != 0) {
1977 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1978 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1979 *gdp_path, strerror(gdp_read_errno));
1984 if (*dp_path != NULL) {
1985 if (dp_open_errno != 0) {
1986 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1987 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1988 strerror(dp_open_errno));
1990 if (dp_read_errno != 0) {
1991 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1992 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1993 strerror(dp_read_errno));
2002 /* Check if there's something important to tell the user during startup.
2003 * We want to do this *after* showing the main window so that any windows
2004 * we pop up will be above the main window.
2008 check_and_warn_user_startup(gchar *cf_name)
2010 check_and_warn_user_startup(gchar *cf_name _U_)
2013 gchar *cur_user, *cur_group;
2014 gpointer priv_warning_dialog;
2016 /* Tell the user not to run as root. */
2017 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2018 cur_user = get_cur_username();
2019 cur_group = get_cur_groupname();
2020 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2021 "Running as user \"%s\" and group \"%s\".\n"
2022 "This could be dangerous.", cur_user, cur_group);
2025 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2026 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2030 /* Warn the user if npf.sys isn't loaded. */
2031 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2032 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2033 "The NPF driver isn't running. You may have trouble\n"
2034 "capturing or listing interfaces.");
2035 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2036 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2043 /* And now our feature presentation... [ fade to music ] */
2045 main(int argc, char *argv[])
2047 char *init_progfile_dir_error;
2050 gboolean arg_error = FALSE;
2052 extern int info_update_freq; /* Found in about_dlg.c. */
2053 const gchar *filter;
2061 char *gdp_path, *dp_path;
2064 gboolean start_capture = FALSE;
2065 gboolean list_link_layer_types = FALSE;
2069 gboolean capture_option_specified = FALSE;
2076 gint pl_size = 280, tv_size = 95, bv_size = 75;
2077 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *jfilter = NULL;
2078 dfilter_t *rfcode = NULL;
2079 gboolean rfilter_parse_failed = FALSE;
2082 GtkWidget *splash_win = NULL;
2083 GLogLevelFlags log_flags;
2084 guint go_to_packet = 0;
2085 gboolean jump_backwards = FALSE, saved_bw = FALSE;
2086 dfilter_t *jump_to_filter = NULL;
2089 #ifdef HAVE_GTKOSXAPPLICATION
2090 GtkOSXApplication *theApp;
2094 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2095 #define OPTSTRING_B "B:"
2097 #define OPTSTRING_B ""
2098 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2099 #else /* HAVE_LIBPCAP */
2100 #define OPTSTRING_B ""
2101 #endif /* HAVE_LIBPCAP */
2103 #ifdef HAVE_PCAP_CREATE
2104 #define OPTSTRING_I "I"
2106 #define OPTSTRING_I ""
2109 #define OPTSTRING "a:b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pQr:R:Ss:t:u:vw:X:y:z:"
2111 static const char optstring[] = OPTSTRING;
2114 * Get credential information for later use, and drop privileges
2115 * before doing anything else.
2116 * Let the user know if anything happened.
2118 get_credential_info();
2119 relinquish_special_privs_perm();
2122 * Attempt to get the pathname of the executable file.
2124 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2126 /* initialize the funnel mini-api */
2127 initialize_funnel_ops();
2129 #ifdef HAVE_AIRPDCAP
2130 AirPDcapInitContext(&airpdcap_ctx);
2134 /* Load wpcap if possible. Do this before collecting the run-time version information */
2137 /* ... and also load the packet.dll from wpcap */
2138 wpcap_packet_load();
2141 /* Load the airpcap.dll. This must also be done before collecting
2142 * run-time version information. */
2143 airpcap_dll_ret_val = load_airpcap();
2145 switch (airpcap_dll_ret_val) {
2146 case AIRPCAP_DLL_OK:
2147 /* load the airpcap interfaces */
2148 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2150 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2151 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2152 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2155 airpcap_if_active = NULL;
2159 /* select the first ad default (THIS SHOULD BE CHANGED) */
2160 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2165 * XXX - Maybe we need to warn the user if one of the following happens???
2167 case AIRPCAP_DLL_OLD:
2168 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2171 case AIRPCAP_DLL_ERROR:
2172 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2175 case AIRPCAP_DLL_NOT_FOUND:
2176 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2180 #endif /* HAVE_AIRPCAP */
2182 /* Start windows sockets */
2183 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2186 profile_store_persconffiles (TRUE);
2188 /* Assemble the compile-time version information string */
2189 comp_info_str = g_string_new("Compiled ");
2191 g_string_append(comp_info_str, "with ");
2192 g_string_append_printf(comp_info_str,
2193 #ifdef GTK_MAJOR_VERSION
2194 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
2197 "GTK+ (version unknown)");
2199 g_string_append(comp_info_str, ", ");
2201 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
2203 /* Assemble the run-time version information string */
2204 runtime_info_str = g_string_new("Running ");
2205 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2207 /* Read the profile independent recent file. We have to do this here so we can */
2208 /* set the profile before it can be set from the command line parameterts */
2209 recent_read_static(&rf_path, &rf_open_errno);
2210 if (rf_path != NULL && rf_open_errno != 0) {
2211 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2212 "Could not open common recent file\n\"%s\": %s.",
2213 rf_path, strerror(rf_open_errno));
2216 /* "pre-scan" the command line parameters, if we have "console only"
2217 parameters. We do this so we don't start GTK+ if we're only showing
2218 command-line help or version information.
2220 XXX - this pre-scan is done before we start GTK+, so we haven't
2221 run gtk_init() on the arguments. That means that GTK+ arguments
2222 have not been removed from the argument list; those arguments
2223 begin with "--", and will be treated as an error by getopt().
2225 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2228 optind_initial = optind;
2229 while ((opt = getopt(argc, argv, optstring)) != -1) {
2231 case 'C': /* Configuration Profile */
2232 if (profile_exists (optarg)) {
2233 set_profile_name (optarg);
2235 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2239 case 'h': /* Print help and exit */
2245 if (strcmp(optarg, "-") == 0)
2246 stdin_capture = TRUE;
2249 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2250 status = filesystem_opt(opt, optarg);
2252 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2256 case 'v': /* Show version and exit */
2262 * Extension command line options have to be processed before
2263 * we call epan_init() as they are supposed to be used by dissectors
2264 * or taps very early in the registration process.
2268 case '?': /* Ignore errors - the "real" scan will catch them. */
2273 /* Init the "Open file" dialog directory */
2274 /* (do this after the path settings are processed) */
2276 /* Read the profile dependent (static part) of the recent file. */
2277 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2278 /* recent lists which is done in the dynamic part. */
2279 /* We have to do this already here, so command line parameters can overwrite these values. */
2280 recent_read_profile_static(&rf_path, &rf_open_errno);
2281 if (rf_path != NULL && rf_open_errno != 0) {
2282 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2283 "Could not open recent file\n\"%s\": %s.",
2284 rf_path, strerror(rf_open_errno));
2287 if (recent.gui_fileopen_remembered_dir &&
2288 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2289 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2291 set_last_open_dir(get_persdatafile_dir());
2294 /* Set getopt index back to initial value, so it will start with the
2295 first command line parameter again. Also reset opterr to 1, so that
2296 error messages are printed by getopt().
2298 XXX - this seems to work on most platforms, but time will tell.
2299 The Single UNIX Specification says "The getopt() function need
2300 not be reentrant", so this isn't guaranteed to work. The Mac
2301 OS X 10.4[.x] getopt() man page says
2303 In order to use getopt() to evaluate multiple sets of arguments, or to
2304 evaluate a single set of arguments multiple times, the variable optreset
2305 must be set to 1 before the second and each additional set of calls to
2306 getopt(), and the variable optind must be reinitialized.
2310 The optreset variable was added to make it possible to call the getopt()
2311 function multiple times. This is an extension to the IEEE Std 1003.2
2312 (``POSIX.2'') specification.
2314 which I think comes from one of the other BSDs.
2316 XXX - if we want to control all the command-line option errors, so
2317 that we can display them where we choose (e.g., in a window), we'd
2318 want to leave opterr as 0, and produce our own messages using optopt.
2319 We'd have to check the value of optopt to see if it's a valid option
2320 letter, in which case *presumably* the error is "this option requires
2321 an argument but none was specified", or not a valid option letter,
2322 in which case *presumably* the error is "this option isn't valid".
2323 Some versions of getopt() let you supply a option string beginning
2324 with ':', which means that getopt() will return ':' rather than '?'
2325 for "this option requires an argument but none was specified", but
2327 optind = optind_initial;
2330 /* Set the current locale according to the program environment.
2331 * We haven't localized anything, but some GTK widgets are localized
2332 * (the file selection dialogue, for example).
2333 * This also sets the C-language locale to the native environment. */
2336 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2337 gtk_init (&argc, &argv);
2339 cf_callback_add(main_cf_callback, NULL);
2341 capture_callback_add(main_capture_callback, NULL);
2343 cf_callback_add(statusbar_cf_callback, NULL);
2345 capture_callback_add(statusbar_capture_callback, NULL);
2348 /* Arrange that if we have no console window, and a GLib message logging
2349 routine is called to log a message, we pop up a console window.
2351 We do that by inserting our own handler for all messages logged
2352 to the default domain; that handler pops up a console if necessary,
2353 and then calls the default handler. */
2355 /* We might want to have component specific log levels later ... */
2359 G_LOG_LEVEL_CRITICAL|
2360 G_LOG_LEVEL_WARNING|
2361 G_LOG_LEVEL_MESSAGE|
2364 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2366 g_log_set_handler(NULL,
2368 console_log_handler, NULL /* user_data */);
2369 g_log_set_handler(LOG_DOMAIN_MAIN,
2371 console_log_handler, NULL /* user_data */);
2374 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2376 console_log_handler, NULL /* user_data */);
2377 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2379 console_log_handler, NULL /* user_data */);
2381 /* Set the initial values in the capture options. This might be overwritten
2382 by preference settings and then again by the command line parameters. */
2383 capture_opts_init(&global_capture_opts, &cfile);
2385 global_capture_opts.snaplen = MIN_PACKET_SIZE;
2386 global_capture_opts.has_ring_num_files = TRUE;
2389 /* Initialize whatever we need to allocate colors for GTK+ */
2392 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2393 filter = get_conn_cfilter();
2394 if ( *filter != '\0' ) {
2395 info_update_freq = 1000; /* Milliseconds */
2398 /* We won't come till here, if we had a "console only" command line parameter. */
2399 splash_win = splash_new("Loading Wireshark ...");
2400 if (init_progfile_dir_error != NULL) {
2401 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2402 "Can't get pathname of Wireshark: %s.\n"
2403 "It won't be possible to capture traffic.\n"
2404 "Report this to the Wireshark developers.",
2405 init_progfile_dir_error);
2406 g_free(init_progfile_dir_error);
2409 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2411 /* Register all dissectors; we must do this before checking for the
2412 "-G" flag, as the "-G" flag dumps information registered by the
2413 dissectors, and we must do it before we read the preferences, in
2414 case any dissectors register preferences. */
2415 epan_init(register_all_protocols,register_all_protocol_handoffs,
2416 splash_update, (gpointer) splash_win,
2417 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2418 write_failure_alert_box);
2420 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2422 /* Register all tap listeners; we do this before we parse the arguments,
2423 as the "-z" argument can specify a registered tap. */
2425 /* we register the plugin taps before the other taps because
2426 stats_tree taps plugins will be registered as tap listeners
2427 by stats_tree_stat.c and need to registered before that */
2430 register_all_plugin_tap_listeners();
2433 register_all_tap_listeners();
2435 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2437 /* Now register the preferences for any non-dissector modules.
2438 We must do that before we read the preferences as well. */
2439 prefs_register_modules();
2441 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2443 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2444 #if !defined(_WIN32) && defined(G_THREADS_ENABLED) && defined USE_THREADS
2447 g_thread_init(NULL);
2449 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2450 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2452 #else /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2453 /* this is to keep tap extensions updating once every 3 seconds */
2454 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2455 #endif /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2457 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2459 cap_file_init(&cfile);
2461 /* Fill in capture options with values from the preferences */
2462 prefs_to_capture_opts();
2464 /* Now get our args */
2465 while ((opt = getopt(argc, argv, optstring)) != -1) {
2467 /*** capture option specific ***/
2468 case 'a': /* autostop criteria */
2469 case 'b': /* Ringbuffer option */
2470 case 'c': /* Capture xxx packets */
2471 case 'f': /* capture filter */
2472 case 'k': /* Start capture immediately */
2473 case 'H': /* Hide capture info dialog box */
2474 case 'i': /* Use interface xxx */
2475 case 'p': /* Don't capture in promiscuous mode */
2476 #ifdef HAVE_PCAP_CREATE
2477 case 'I': /* Capture in monitor mode, if available */
2479 case 'Q': /* Quit after capture (just capture to file) */
2480 case 's': /* Set the snapshot (capture) length */
2481 case 'S': /* "Sync" mode: used for following file ala tail -f */
2482 case 'w': /* Write to capture file xxx */
2483 case 'y': /* Set the pcap data link type */
2484 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2485 case 'B': /* Buffer size */
2486 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2488 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2494 capture_option_specified = TRUE;
2499 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2500 case 'K': /* Kerberos keytab file */
2501 read_keytab_file(optarg);
2505 /*** all non capture option specific ***/
2507 /* Configuration profile settings were already processed just ignore them this time*/
2509 case 'D': /* Print a list of capture devices and exit */
2511 if_list = capture_interface_list(&err, &err_str);
2512 if (if_list == NULL) {
2514 case CANT_GET_INTERFACE_LIST:
2515 cmdarg_err("%s", err_str);
2519 case NO_INTERFACES_FOUND:
2520 cmdarg_err("There are no interfaces on which a capture can be done");
2525 capture_opts_print_interfaces(if_list);
2526 free_interface_list(if_list);
2529 capture_option_specified = TRUE;
2533 case 'j': /* Search backwards for a matching packet from filter in option J */
2534 jump_backwards = TRUE;
2536 case 'g': /* Go to packet with the given packet number */
2537 go_to_packet = get_positive_int(optarg, "go to packet");
2539 case 'J': /* Jump to the first packet which matches the filter criteria */
2542 case 'l': /* Automatic scrolling in live capture mode */
2544 auto_scroll_live = TRUE;
2546 capture_option_specified = TRUE;
2550 case 'L': /* Print list of link-layer types and exit */
2552 list_link_layer_types = TRUE;
2554 capture_option_specified = TRUE;
2558 case 'm': /* Fixed-width font for the display */
2559 g_free(prefs_p->gui_font_name);
2560 prefs_p->gui_font_name = g_strdup(optarg);
2562 case 'n': /* No name resolution */
2563 g_resolv_flags = RESOLV_NONE;
2565 case 'N': /* Select what types of addresses/port #s to resolve */
2566 if (g_resolv_flags == RESOLV_ALL)
2567 g_resolv_flags = RESOLV_NONE;
2568 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2569 if (badopt != '\0') {
2570 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2575 case 'o': /* Override preference from command line */
2576 switch (prefs_set_pref(optarg)) {
2579 case PREFS_SET_SYNTAX_ERR:
2580 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2583 case PREFS_SET_NO_SUCH_PREF:
2584 /* not a preference, might be a recent setting */
2585 switch (recent_set_arg(optarg)) {
2588 case PREFS_SET_SYNTAX_ERR:
2589 /* shouldn't happen, checked already above */
2590 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2593 case PREFS_SET_NO_SUCH_PREF:
2594 case PREFS_SET_OBSOLETE:
2595 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2600 g_assert_not_reached();
2603 case PREFS_SET_OBSOLETE:
2604 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2609 g_assert_not_reached();
2613 /* Path settings were already processed just ignore them this time*/
2615 case 'r': /* Read capture file xxx */
2616 /* We may set "last_open_dir" to "cf_name", and if we change
2617 "last_open_dir" later, we free the old value, so we have to
2618 set "cf_name" to something that's been allocated. */
2619 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2620 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2621 cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2623 cf_name = g_strdup(optarg);
2626 case 'R': /* Read file filter */
2629 case 't': /* Time stamp type */
2630 if (strcmp(optarg, "r") == 0)
2631 timestamp_set_type(TS_RELATIVE);
2632 else if (strcmp(optarg, "a") == 0)
2633 timestamp_set_type(TS_ABSOLUTE);
2634 else if (strcmp(optarg, "ad") == 0)
2635 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2636 else if (strcmp(optarg, "d") == 0)
2637 timestamp_set_type(TS_DELTA);
2638 else if (strcmp(optarg, "dd") == 0)
2639 timestamp_set_type(TS_DELTA_DIS);
2640 else if (strcmp(optarg, "e") == 0)
2641 timestamp_set_type(TS_EPOCH);
2643 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2644 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2645 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2649 case 'u': /* Seconds type */
2650 if (strcmp(optarg, "s") == 0)
2651 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2652 else if (strcmp(optarg, "hms") == 0)
2653 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2655 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2656 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2661 /* ext ops were already processed just ignore them this time*/
2664 /* We won't call the init function for the stat this soon
2665 as it would disallow MATE's fields (which are registered
2666 by the preferences set callback) from being used as
2667 part of a tap filter. Instead, we just add the argument
2668 to a list of stat arguments. */
2669 if (!process_stat_cmd_arg(optarg)) {
2670 cmdarg_err("Invalid -z argument.");
2671 cmdarg_err_cont(" -z argument must be one of :");
2672 list_stat_cmd_args();
2677 case '?': /* Bad flag - print usage message */
2685 if (cf_name != NULL) {
2687 * Input file name specified with "-r" *and* specified as a regular
2688 * command-line argument.
2690 cmdarg_err("File name specified both with -r and regular argument");
2694 * Input file name not specified with "-r", and a command-line argument
2695 * was specified; treat it as the input file name.
2697 * Yes, this is different from tshark, where non-flag command-line
2698 * arguments are a filter, but this works better on GUI desktops
2699 * where a command can be specified to be run to open a particular
2700 * file - yes, you could have "-r" as the last part of the command,
2701 * but that's a bit ugly.
2703 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2704 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2705 cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2707 cf_name = g_strdup(argv[0]);
2718 * Extra command line arguments were specified; complain.
2720 cmdarg_err("Invalid argument: %s", argv[0]);
2725 #ifndef HAVE_LIBPCAP
2726 if (capture_option_specified) {
2727 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2735 if (start_capture && list_link_layer_types) {
2736 /* Specifying *both* is bogus. */
2737 cmdarg_err("You can't specify both -L and a live capture.");
2741 if (list_link_layer_types) {
2742 /* We're supposed to list the link-layer types for an interface;
2743 did the user also specify a capture file to be read? */
2745 /* Yes - that's bogus. */
2746 cmdarg_err("You can't specify -L and a capture file to be read.");
2749 /* No - did they specify a ring buffer option? */
2750 if (global_capture_opts.multi_files_on) {
2751 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2755 /* We're supposed to do a live capture; did the user also specify
2756 a capture file to be read? */
2757 if (start_capture && cf_name) {
2758 /* Yes - that's bogus. */
2759 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2763 /* No - was the ring buffer option specified and, if so, does it make
2765 if (global_capture_opts.multi_files_on) {
2766 /* Ring buffer works only under certain conditions:
2767 a) ring buffer does not work with temporary files;
2768 b) real_time_mode and multi_files_on are mutually exclusive -
2769 real_time_mode takes precedence;
2770 c) it makes no sense to enable the ring buffer if the maximum
2771 file size is set to "infinite". */
2772 if (global_capture_opts.save_file == NULL) {
2773 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2774 global_capture_opts.multi_files_on = FALSE;
2776 /* if (global_capture_opts.real_time_mode) {
2777 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2778 global_capture_opts.multi_files_on = FALSE;
2780 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2781 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2782 /* XXX - this must be redesigned as the conditions changed */
2783 /* global_capture_opts.multi_files_on = FALSE;*/
2788 if (start_capture || list_link_layer_types) {
2789 /* Did the user specify an interface to use? */
2790 if (!capture_opts_trim_iface(&global_capture_opts,
2791 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2796 if (list_link_layer_types) {
2797 /* Get the list of link-layer types for the capture device. */
2798 if_capabilities_t *caps;
2800 caps = capture_get_if_capabilities(global_capture_opts.iface,
2801 global_capture_opts.monitor_mode,
2804 cmdarg_err("%s", err_str);
2808 if (caps->data_link_types == NULL) {
2809 cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
2812 capture_opts_print_if_capabilities(caps, global_capture_opts.monitor_mode);
2813 free_if_capabilities(caps);
2817 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2818 capture_opts_trim_ring_num_files(&global_capture_opts);
2819 #endif /* HAVE_LIBPCAP */
2821 /* Notify all registered modules that have had any of their preferences
2822 changed either from one of the preferences file or from the command
2823 line that their preferences have changed. */
2826 /* disabled protocols as per configuration file */
2827 if (gdp_path == NULL && dp_path == NULL) {
2828 set_disabled_protos_list();
2831 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2833 /* read in rc file from global and personal configuration paths. */
2834 rc_file = get_datafile_path(RC_FILE);
2835 gtk_rc_parse(rc_file);
2837 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2838 gtk_rc_parse(rc_file);
2845 /* close the splash screen, as we are going to open the main window now */
2846 splash_destroy(splash_win);
2848 /************************************************************************/
2849 /* Everything is prepared now, preferences and command line was read in */
2851 /* Pop up the main window. */
2852 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2854 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2855 recent_read_dynamic(&rf_path, &rf_open_errno);
2856 if (rf_path != NULL && rf_open_errno != 0) {
2857 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2858 "Could not open recent file\n\"%s\": %s.",
2859 rf_path, strerror(rf_open_errno));
2862 color_filters_enable(recent.packet_list_colorize);
2864 /* rearrange all the widgets as we now have all recent settings ready for this */
2865 main_widgets_rearrange();
2867 /* Fill in column titles. This must be done after the top level window
2870 XXX - is that still true, with fixed-width columns? */
2871 #ifndef NEW_PACKET_LIST
2872 packet_list_set_column_titles();
2875 menu_recent_read_finished();
2877 menu_auto_scroll_live_changed(auto_scroll_live);
2880 switch (user_font_apply()) {
2883 case FA_FONT_NOT_RESIZEABLE:
2884 /* "user_font_apply()" popped up an alert box. */
2885 /* turn off zooming - font can't be resized */
2886 case FA_FONT_NOT_AVAILABLE:
2887 /* XXX - did we successfully load the un-zoomed version earlier?
2888 If so, this *probably* means the font is available, but not at
2889 this particular zoom level, but perhaps some other failure
2890 occurred; I'm not sure you can determine which is the case,
2892 /* turn off zooming - zoom level is unavailable */
2894 /* in any other case than FA_SUCCESS, turn off zooming */
2895 recent.gui_zoom_level = 0;
2896 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2899 dnd_init(top_level);
2901 color_filters_init();
2904 /* the window can be sized only, if it's not already shown, so do it now! */
2905 main_load_window_geometry(top_level);
2907 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2910 /* If we were given the name of a capture file, read it in now;
2911 we defer it until now, so that, if we can't open it, and pop
2912 up an alert box, the alert box is more likely to come up on
2913 top of the main window - but before the preference-file-error
2914 alert box, so, if we get one of those, it's more likely to come
2917 show_main_window(TRUE);
2918 check_and_warn_user_startup(cf_name);
2919 if (rfilter != NULL) {
2920 if (!dfilter_compile(rfilter, &rfcode)) {
2921 bad_dfilter_alert_box(rfilter);
2922 rfilter_parse_failed = TRUE;
2925 if (!rfilter_parse_failed) {
2926 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2927 /* "cf_open()" succeeded, so it closed the previous
2928 capture file, and thus destroyed any previous read filter
2929 attached to "cf". */
2931 cfile.rfcode = rfcode;
2932 /* Open stat windows; we do so after creating the main window,
2933 to avoid GTK warnings, and after successfully opening the
2934 capture file, so we know we have something to compute stats
2935 on, and after registering all dissectors, so that MATE will
2936 have registered its field array and we can have a tap filter
2937 with one of MATE's late-registered fields as part of the
2939 start_requested_stats();
2941 /* Read the capture file. */
2942 switch (cf_read(&cfile, FALSE)) {
2946 /* Just because we got an error, that doesn't mean we were unable
2947 to read any of the file; we handle what we could get from the
2949 /* if the user told us to jump to a specific packet, do it now */
2950 if(go_to_packet != 0) {
2951 /* Jump to the specified frame number, kept for backward
2953 cf_goto_frame(&cfile, go_to_packet);
2954 } else if (jfilter != NULL) {
2955 /* try to compile given filter */
2956 if (!dfilter_compile(jfilter, &jump_to_filter)) {
2957 bad_dfilter_alert_box(jfilter);
2960 /* Filter ok, jump to the first packet matching the filter
2961 conditions. Default search direction is forward, but if
2962 option d was given, search backwards */
2963 saved_bw = cfile.sbackward;
2964 cfile.sbackward = jump_backwards;
2965 cf_find_packet_dfilter(&cfile, jump_to_filter);
2966 cfile.sbackward = saved_bw;
2971 case CF_READ_ABORTED:
2976 /* Save the name of the containing directory specified in the
2977 path name, if any; we can write over cf_name, which is a
2978 good thing, given that "get_dirname()" does write over its
2980 s = get_dirname(cf_name);
2981 set_last_open_dir(s);
2986 dfilter_free(rfcode);
2987 cfile.rfcode = NULL;
2988 show_main_window(FALSE);
2989 /* Don't call check_and_warn_user_startup(): we did it above */
2990 set_menus_for_capture_in_progress(FALSE);
2991 set_capture_if_dialog_for_capture_in_progress(FALSE);
2996 if (start_capture) {
2997 if (global_capture_opts.save_file != NULL) {
2998 /* Save the directory name for future file dialogs. */
2999 /* (get_dirname overwrites filename) */
3000 s = get_dirname(g_strdup(global_capture_opts.save_file));
3001 set_last_open_dir(s);
3004 /* "-k" was specified; start a capture. */
3005 show_main_window(TRUE);
3006 check_and_warn_user_startup(cf_name);
3007 if (capture_start(&global_capture_opts)) {
3008 /* The capture started. Open stat windows; we do so after creating
3009 the main window, to avoid GTK warnings, and after successfully
3010 opening the capture file, so we know we have something to compute
3011 stats on, and after registering all dissectors, so that MATE will
3012 have registered its field array and we can have a tap filter with
3013 one of MATE's late-registered fields as part of the filter. */
3014 start_requested_stats();
3018 show_main_window(FALSE);
3019 check_and_warn_user_startup(cf_name);
3020 set_menus_for_capture_in_progress(FALSE);
3021 set_capture_if_dialog_for_capture_in_progress(FALSE);
3024 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
3025 if (!start_capture && strlen(global_capture_opts.cfilter) == 0) {
3026 g_free(global_capture_opts.cfilter);
3027 global_capture_opts.cfilter = g_strdup(get_conn_cfilter());
3029 #else /* HAVE_LIBPCAP */
3030 show_main_window(FALSE);
3031 check_and_warn_user_startup(cf_name);
3032 set_menus_for_capture_in_progress(FALSE);
3033 set_capture_if_dialog_for_capture_in_progress(FALSE);
3034 #endif /* HAVE_LIBPCAP */
3037 /* register our pid if we are being run from a U3 device */
3040 profile_store_persconffiles (FALSE);
3042 #ifdef HAVE_GTKOSXAPPLICATION
3043 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3044 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3045 gtk_osxapplication_ready(theApp);
3048 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3050 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3052 /* ... back from GTK, we're going down now! */
3054 /* deregister our pid */
3055 u3_deregister_pid();
3059 #ifdef HAVE_AIRPDCAP
3060 AirPDcapDestroyContext(&airpdcap_ctx);
3064 /* hide the (unresponsive) main window, while asking the user to close the console window */
3065 gtk_widget_hide(top_level);
3067 #ifdef HAVE_GTKOSXAPPLICATION
3068 g_object_unref(theApp);
3071 /* Shutdown windows sockets */
3074 /* For some unknown reason, the "atexit()" call in "create_console()"
3075 doesn't arrange that "destroy_console()" be called when we exit,
3076 so we call it here if a console was created. */
3085 /* We build this as a GUI subsystem application on Win32, so
3086 "WinMain()", not "main()", gets called.
3088 Hack shamelessly stolen from the Win32 port of the GIMP. */
3090 #define _stdcall __attribute__((stdcall))
3094 WinMain (struct HINSTANCE__ *hInstance,
3095 struct HINSTANCE__ *hPrevInstance,
3099 INITCOMMONCONTROLSEX comm_ctrl;
3101 /* Initialize our controls. Required for native Windows file dialogs. */
3102 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3103 comm_ctrl.dwSize = sizeof(comm_ctrl);
3104 /* Includes the animate, header, hot key, list view, progress bar,
3105 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3108 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3109 InitCommonControlsEx(&comm_ctrl);
3111 /* RichEd20.DLL is needed for filter entries. */
3112 LoadLibrary(_T("riched20.dll"));
3114 has_console = FALSE;
3115 return main (__argc, __argv);
3118 /* The code to create and desstroy console windows should not be necessary,
3119 at least as I read the GLib source code, as it looks as if GLib is, on
3120 Win32, *supposed* to create a console window into which to display its
3123 That doesn't happen, however. I suspect there's something completely
3124 broken about that code in GLib-for-Win32, and that it may be related
3125 to the breakage that forces us to just call "printf()" on the message
3126 rather than passing the message on to "g_log_default_handler()"
3127 (which is the routine that does the aforementioned non-functional
3128 console window creation). */
3131 * If this application has no console window to which its standard output
3132 * would go, create one.
3135 create_console(void)
3137 if (stdin_capture) {
3138 /* We've been handed "-i -". Don't mess with stdio. */
3143 /* We have no console to which to print the version string, so
3144 create one and make it the standard input, output, and error. */
3145 if (!AllocConsole())
3146 return; /* couldn't create console */
3148 ws_freopen("CONIN$", "r", stdin);
3149 ws_freopen("CONOUT$", "w", stdout);
3150 ws_freopen("CONOUT$", "w", stderr);
3152 /* Well, we have a console now. */
3155 /* Now register "destroy_console()" as a routine to be called just
3156 before the application exits, so that we can destroy the console
3157 after the user has typed a key (so that the console doesn't just
3158 disappear out from under them, giving the user no chance to see
3159 the message(s) we put in there). */
3160 atexit(destroy_console);
3162 SetConsoleTitle(_T("Wireshark Debug Console"));
3167 destroy_console(void)
3170 printf("\n\nPress any key to exit\n");
3179 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3180 const char *message, gpointer user_data _U_)
3187 /* ignore log message, if log_level isn't interesting based
3188 upon the console log preferences.
3189 If the preferences haven't been loaded loaded yet, display the
3192 The default console_log_level preference value is such that only
3193 ERROR, CRITICAL and WARNING level messages are processed;
3194 MESSAGE, INFO and DEBUG level messages are ignored. */
3195 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3196 prefs.console_log_level != 0) {
3201 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3202 /* the user wants a console or the application will terminate immediately */
3206 /* For some unknown reason, the above doesn't appear to actually cause
3207 anything to be sent to the standard output, so we'll just splat the
3208 message out directly, just to make sure it gets out. */
3210 switch(log_level & G_LOG_LEVEL_MASK) {
3211 case G_LOG_LEVEL_ERROR:
3214 case G_LOG_LEVEL_CRITICAL:
3217 case G_LOG_LEVEL_WARNING:
3220 case G_LOG_LEVEL_MESSAGE:
3223 case G_LOG_LEVEL_INFO:
3226 case G_LOG_LEVEL_DEBUG:
3230 fprintf(stderr, "unknown log_level %u\n", log_level);
3232 g_assert_not_reached();
3235 /* create a "timestamp" */
3237 today = localtime(&curr);
3239 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3240 today->tm_hour, today->tm_min, today->tm_sec,
3241 log_domain != NULL ? log_domain : "",
3244 if(log_level & G_LOG_LEVEL_ERROR) {
3245 /* wait for a key press before the following error handler will terminate the program
3246 this way the user at least can read the error message */
3247 printf("\n\nPress any key to exit\n");
3251 /* XXX - on UN*X, should we just use g_log_default_handler()?
3252 We want the error messages to go to the standard output;
3253 on Mac OS X, that will cause them to show up in various
3254 per-user logs accessible through Console (details depend
3255 on whether you're running 10.0 through 10.4 or running
3256 10.5 and later), and, on other UN*X desktop environments,
3257 if they don't show up in some form of console log, that's
3258 a deficiency in that desktop environment. (Too bad
3259 Windows doesn't set the standard output and error for
3260 GUI apps to something that shows up in such a log.) */
3261 g_log_default_handler(log_domain, log_level, message, user_data);
3268 * Helper for main_widgets_rearrange()
3270 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3271 gtk_container_remove(GTK_CONTAINER(data), widget);
3274 static GtkWidget *main_widget_layout(gint layout_content)
3276 switch(layout_content) {
3277 case(layout_pane_content_none):
3279 case(layout_pane_content_plist):
3281 case(layout_pane_content_pdetails):
3283 case(layout_pane_content_pbytes):
3284 return byte_nb_ptr_gbl;
3286 g_assert_not_reached();
3293 * Rearrange the main window widgets
3295 void main_widgets_rearrange(void) {
3296 GtkWidget *first_pane_widget1, *first_pane_widget2;
3297 GtkWidget *second_pane_widget1, *second_pane_widget2;
3298 gboolean split_top_left;
3300 /* be a bit faster */
3301 gtk_widget_hide(main_vbox);
3303 /* be sure we don't lose a widget while rearranging */
3304 g_object_ref(G_OBJECT(menubar));
3305 g_object_ref(G_OBJECT(main_tb));
3306 g_object_ref(G_OBJECT(filter_tb));
3308 g_object_ref(G_OBJECT(airpcap_tb));
3310 g_object_ref(G_OBJECT(pkt_scrollw));
3311 g_object_ref(G_OBJECT(tv_scrollw));
3312 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3313 g_object_ref(G_OBJECT(statusbar));
3314 g_object_ref(G_OBJECT(main_pane_v1));
3315 g_object_ref(G_OBJECT(main_pane_v2));
3316 g_object_ref(G_OBJECT(main_pane_h1));
3317 g_object_ref(G_OBJECT(main_pane_h2));
3318 g_object_ref(G_OBJECT(welcome_pane));
3320 /* empty all containers participating */
3321 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3322 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3323 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3324 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3325 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3327 statusbar_widgets_emptying(statusbar);
3329 /* add the menubar always at the top */
3330 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3333 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3335 /* filter toolbar in toolbar area */
3336 if (!prefs.filter_toolbar_show_in_statusbar) {
3337 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3341 /* airpcap toolbar */
3342 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3345 /* fill the main layout panes */
3346 switch(prefs.gui_layout_type) {
3347 case(layout_type_5):
3348 main_first_pane = main_pane_v1;
3349 main_second_pane = main_pane_v2;
3350 split_top_left = FALSE;
3352 case(layout_type_2):
3353 main_first_pane = main_pane_v1;
3354 main_second_pane = main_pane_h1;
3355 split_top_left = FALSE;
3357 case(layout_type_1):
3358 main_first_pane = main_pane_v1;
3359 main_second_pane = main_pane_h1;
3360 split_top_left = TRUE;
3362 case(layout_type_4):
3363 main_first_pane = main_pane_h1;
3364 main_second_pane = main_pane_v1;
3365 split_top_left = FALSE;
3367 case(layout_type_3):
3368 main_first_pane = main_pane_h1;
3369 main_second_pane = main_pane_v1;
3370 split_top_left = TRUE;
3372 case(layout_type_6):
3373 main_first_pane = main_pane_h1;
3374 main_second_pane = main_pane_h2;
3375 split_top_left = FALSE;
3378 main_first_pane = NULL;
3379 main_second_pane = NULL;
3380 split_top_left = FALSE;
3381 g_assert_not_reached();
3383 if (split_top_left) {
3384 first_pane_widget1 = main_second_pane;
3385 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3386 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3387 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3389 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3390 first_pane_widget2 = main_second_pane;
3391 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3392 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3394 if (first_pane_widget1 != NULL)
3395 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3396 if (first_pane_widget2 != NULL)
3397 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3398 if (second_pane_widget1 != NULL)
3399 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3400 if (second_pane_widget2 != NULL)
3401 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3403 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3406 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3409 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3411 /* filter toolbar in statusbar hbox */
3412 if (prefs.filter_toolbar_show_in_statusbar) {
3413 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3417 /* airpcap toolbar */
3418 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3421 /* statusbar widgets */
3422 statusbar_widgets_pack(statusbar);
3424 /* hide widgets on users recent settings */
3425 main_widgets_show_or_hide();
3427 gtk_widget_show(main_vbox);
3431 is_widget_visible(GtkWidget *widget, gpointer data)
3433 gboolean *is_visible = data;
3436 if (GTK_WIDGET_VISIBLE(widget))
3443 main_widgets_show_or_hide(void)
3445 gboolean main_second_pane_show;
3447 if (recent.main_toolbar_show) {
3448 gtk_widget_show(main_tb);
3450 gtk_widget_hide(main_tb);
3453 statusbar_widgets_show_or_hide(statusbar);
3455 if (recent.filter_toolbar_show) {
3456 gtk_widget_show(filter_tb);
3458 gtk_widget_hide(filter_tb);
3462 if (recent.airpcap_toolbar_show) {
3463 gtk_widget_show(airpcap_tb);
3465 gtk_widget_hide(airpcap_tb);
3469 if (recent.packet_list_show && have_capture_file) {
3470 gtk_widget_show(pkt_scrollw);
3472 gtk_widget_hide(pkt_scrollw);
3475 if (recent.tree_view_show && have_capture_file) {
3476 gtk_widget_show(tv_scrollw);
3478 gtk_widget_hide(tv_scrollw);
3481 if (recent.byte_view_show && have_capture_file) {
3482 gtk_widget_show(byte_nb_ptr_gbl);
3484 gtk_widget_hide(byte_nb_ptr_gbl);
3487 if (have_capture_file) {
3488 gtk_widget_show(main_first_pane);
3490 gtk_widget_hide(main_first_pane);
3494 * Is anything in "main_second_pane" visible?
3495 * If so, show it, otherwise hide it.
3497 main_second_pane_show = FALSE;
3498 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3499 &main_second_pane_show);
3500 if (main_second_pane_show) {
3501 gtk_widget_show(main_second_pane);
3503 gtk_widget_hide(main_second_pane);
3506 if (!have_capture_file) {
3508 gtk_widget_show(welcome_pane);
3511 gtk_widget_hide(welcome_pane);
3514 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
3515 #ifndef NEW_PACKET_LIST
3516 packet_list_freeze ();
3517 packet_list_thaw ();
3522 /* called, when the window state changes (minimized, maximized, ...) */
3524 window_state_event_cb (GtkWidget *widget _U_,
3528 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3530 if( (event->type) == (GDK_WINDOW_STATE)) {
3531 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3532 /* we might have dialogs popped up while we where iconified,
3534 display_queued_messages();
3542 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3544 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3546 if (event->keyval == GDK_F8) {
3547 #ifdef NEW_PACKET_LIST
3548 new_packet_list_next();
3553 } else if (event->keyval == GDK_F7) {
3554 #ifdef NEW_PACKET_LIST
3555 new_packet_list_prev();
3560 } else if (event->state & NO_SHIFT_MOD_MASK) {
3561 return FALSE; /* Skip control, alt, and other modifiers */
3563 * A comment in gdkkeysyms.h says that it's autogenerated from
3564 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3565 * don't explicitly say so, isprint() should work as expected
3568 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3569 /* Forward the keypress on to the display filter entry */
3570 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3571 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3572 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3580 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3582 GtkAccelGroup *accel;
3585 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3586 set_main_window_name("The Wireshark Network Analyzer");
3588 gtk_widget_set_name(top_level, "main window");
3589 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3591 g_signal_connect(GTK_OBJECT(top_level), "window_state_event",
3592 G_CALLBACK(window_state_event_cb), NULL);
3593 g_signal_connect(GTK_OBJECT(top_level), "key-press-event",
3594 G_CALLBACK(top_level_key_pressed_cb), NULL );
3596 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3597 main_vbox = gtk_vbox_new(FALSE, 1);
3598 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 1);
3599 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3600 gtk_widget_show(main_vbox);
3603 menubar = main_menu_new(&accel);
3605 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3606 /* Mac OS X native menus are created and displayed by main_menu_new() */
3607 if(!prefs_p->gui_macosx_style) {
3609 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3610 gtk_widget_show(menubar);
3611 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3616 main_tb = toolbar_new();
3617 gtk_widget_show (main_tb);
3619 /* Filter toolbar */
3620 filter_tb = filter_toolbar_new();
3623 #ifdef NEW_PACKET_LIST
3624 pkt_scrollw = new_packet_list_create();
3625 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3626 gtk_widget_show_all(pkt_scrollw);
3628 pkt_scrollw = packet_list_new(prefs_p);
3629 gtk_widget_set_size_request(packet_list, -1, pl_size);
3630 gtk_widget_show(pkt_scrollw);
3634 tv_scrollw = main_tree_view_new(prefs_p, &tree_view_gbl);
3635 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3636 gtk_widget_show(tv_scrollw);
3638 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3639 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3640 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3641 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3642 gtk_widget_show(tree_view_gbl);
3645 byte_nb_ptr_gbl = byte_view_new();
3646 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3647 gtk_widget_show(byte_nb_ptr_gbl);
3649 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3650 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3652 /* Panes for the packet list, tree, and byte view */
3653 main_pane_v1 = gtk_vpaned_new();
3654 gtk_widget_show(main_pane_v1);
3655 main_pane_v2 = gtk_vpaned_new();
3656 gtk_widget_show(main_pane_v2);
3657 main_pane_h1 = gtk_hpaned_new();
3658 gtk_widget_show(main_pane_h1);
3659 main_pane_h2 = gtk_hpaned_new();
3660 gtk_widget_show(main_pane_h2);
3662 airpcap_tb = airpcap_toolbar_new();
3663 gtk_widget_show(airpcap_tb);
3666 statusbar = statusbar_new();
3667 gtk_widget_show(statusbar);
3669 /* Pane for the welcome screen */
3670 welcome_pane = welcome_new();
3671 gtk_widget_show(welcome_pane);
3675 show_main_window(gboolean doing_work)
3677 main_set_for_capture_file(doing_work);
3679 /*** we have finished all init things, show the main window ***/
3680 gtk_widget_show(top_level);
3682 /* the window can be maximized only, if it's visible, so do it after show! */
3683 main_load_window_geometry(top_level);
3685 /* process all pending GUI events before continue */
3686 while (gtk_events_pending()) gtk_main_iteration();
3688 /* Pop up any queued-up alert boxes. */
3689 display_queued_messages();
3691 /* Move the main window to the front, in case it isn't already there */
3692 gdk_window_raise(top_level->window);
3695 airpcap_toolbar_show(airpcap_tb);
3696 #endif /* HAVE_AIRPCAP */
3699 /* Fill in capture options with values from the preferences */
3701 prefs_to_capture_opts(void)
3704 /* Set promiscuous mode from the preferences setting. */
3705 /* the same applies to other preferences settings as well. */
3706 global_capture_opts.promisc_mode = prefs.capture_prom_mode;
3707 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3708 global_capture_opts.show_info = prefs.capture_show_info;
3709 global_capture_opts.real_time_mode = prefs.capture_real_time;
3710 auto_scroll_live = prefs.capture_auto_scroll;
3711 #endif /* HAVE_LIBPCAP */
3713 /* Set the name resolution code's flags from the preferences. */
3714 g_resolv_flags = prefs.name_resolve;
3718 /* Change configuration profile */
3719 void change_configuration_profile (const gchar *profile_name)
3721 char *gdp_path, *dp_path;
3725 /* First check if profile exists */
3726 if (!profile_exists(profile_name)) {
3730 /* Get the current geometry, before writing it to disk */
3731 main_save_window_geometry(top_level);
3733 if (profile_exists(get_profile_name())) {
3734 /* Write recent file for profile we are leaving, if it still exists */
3735 write_profile_recent();
3738 /* Set profile name and update the status bar */
3739 set_profile_name (profile_name);
3740 profile_bar_update ();
3742 /* Reset current preferences and apply the new */
3746 (void) read_configuration_files (&gdp_path, &dp_path);
3748 recent_read_profile_static(&rf_path, &rf_open_errno);
3749 if (rf_path != NULL && rf_open_errno != 0) {
3750 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3751 "Could not open common recent file\n\"%s\": %s.",
3752 rf_path, strerror(rf_open_errno));
3754 if (recent.gui_fileopen_remembered_dir &&
3755 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3756 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3758 timestamp_set_type (recent.gui_time_format);
3759 timestamp_set_seconds_type (recent.gui_seconds_format);
3760 color_filters_enable(recent.packet_list_colorize);
3762 prefs_to_capture_opts();
3765 /* Update window view and redraw the toolbar */
3766 update_main_window_title();
3767 toolbar_redraw_all();
3769 /* Enable all protocols and disable from the disabled list */
3771 if (gdp_path == NULL && dp_path == NULL) {
3772 set_disabled_protos_list();
3775 /* Reload color filters */
3776 color_filters_reload();
3778 /* Reload list of interfaces on welcome page */
3779 welcome_if_panel_reload();
3781 /* Recreate the packet list according to new preferences */
3782 #ifdef NEW_PACKET_LIST
3783 new_packet_list_recreate ();
3785 packet_list_recreate ();
3787 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3790 /* Update menus with new recent values */
3791 menu_recent_read_finished();
3793 /* Reload pane geometry, must be done after recreating the list */
3794 main_pane_load_window_geometry();
3797 /** redissect packets and update UI */
3798 void redissect_packets(void)
3800 cf_redissect_packets(&cfile);
3801 status_expert_update();