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 <wsutil/unicode-utils.h>
121 #include <commctrl.h>
122 #include <shellapi.h>
126 #include "gtk/file_dlg.h"
127 #include "gtk/gtkglobals.h"
128 #include "gtk/color_utils.h"
129 #include "gtk/gui_utils.h"
130 #include "gtk/color_dlg.h"
131 #include "gtk/filter_dlg.h"
132 #include "gtk/uat_gui.h"
134 #include "gtk/main.h"
135 #include "gtk/main_airpcap_toolbar.h"
136 #include "gtk/main_filter_toolbar.h"
137 #include "gtk/menus.h"
138 #include "gtk/macros_dlg.h"
139 #include "gtk/main_packet_list.h"
140 #include "gtk/main_statusbar.h"
141 #include "gtk/main_statusbar_private.h"
142 #include "gtk/main_toolbar.h"
143 #include "gtk/main_welcome.h"
144 #include "gtk/drag_and_drop.h"
145 #include "gtk/capture_file_dlg.h"
146 #include "gtk/main_proto_draw.h"
147 #include "gtk/keys.h"
148 #include "gtk/packet_win.h"
149 #include "gtk/stock_icons.h"
150 #include "gtk/find_dlg.h"
151 #include "gtk/recent.h"
152 #include "gtk/follow_tcp.h"
153 #include "gtk/font_utils.h"
154 #include "gtk/about_dlg.h"
155 #include "gtk/help_dlg.h"
156 #include "gtk/decode_as_dlg.h"
157 #include "gtk/webbrowser.h"
158 #include "gtk/capture_dlg.h"
159 #include "gtk/capture_if_dlg.h"
160 #include "gtk/tap_dfilter_dlg.h"
161 #include "gtk/prefs_column.h"
162 #include "gtk/prefs_dlg.h"
163 #include "gtk/proto_help.h"
166 #include "../image/wsicon16.xpm"
167 #include "../image/wsicon32.xpm"
168 #include "../image/wsicon48.xpm"
169 #include "../image/wsicon64.xpm"
170 #include "../image/wsiconcap16.xpm"
171 #include "../image/wsiconcap32.xpm"
172 #include "../image/wsiconcap48.xpm"
177 #include "airpcap_loader.h"
178 #include "airpcap_dlg.h"
179 #include "airpcap_gui_utils.h"
183 #include <epan/crypt/airpdcap_ws.h>
186 #ifdef NEW_PACKET_LIST
187 #include "gtk/new_packet_list.h"
190 #ifdef HAVE_GTKOSXAPPLICATION
191 #include <igemacintegration/gtkosxapplication.h>
195 * Files under personal and global preferences directories in which
196 * GTK settings for Wireshark are stored.
198 #define RC_FILE "gtkrc"
202 /* "exported" main widgets */
203 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
205 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
206 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
207 static GtkWidget *main_first_pane, *main_second_pane;
209 /* internally used widgets */
210 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
213 GtkWidget *airpcap_tb;
214 int airpcap_dll_ret_val = -1;
217 GString *comp_info_str, *runtime_info_str;
218 gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
220 guint tap_update_timer_id;
223 static gboolean has_console; /* TRUE if app has console */
224 static void destroy_console(void);
225 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
227 static void console_log_handler(const char *log_domain,
228 GLogLevelFlags log_level, const char *message, gpointer user_data);
231 capture_options global_capture_opts;
235 static void create_main_window(gint, gint, gint, e_prefs*);
236 static void show_main_window(gboolean);
237 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
238 static void main_save_window_geometry(GtkWidget *widget);
241 /* Match selected byte pattern */
243 match_selected_cb_do(gpointer data, int action, gchar *text)
245 GtkWidget *filter_te;
246 char *cur_filter, *new_filter;
248 if ((!text) || (0 == strlen(text))) {
249 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
254 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
257 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
259 switch (action&MATCH_SELECTED_MASK) {
261 case MATCH_SELECTED_REPLACE:
262 new_filter = g_strdup(text);
265 case MATCH_SELECTED_AND:
266 if ((!cur_filter) || (0 == strlen(cur_filter)))
267 new_filter = g_strdup(text);
269 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
272 case MATCH_SELECTED_OR:
273 if ((!cur_filter) || (0 == strlen(cur_filter)))
274 new_filter = g_strdup(text);
276 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
279 case MATCH_SELECTED_NOT:
280 new_filter = g_strconcat("!(", text, ")", NULL);
283 case MATCH_SELECTED_AND_NOT:
284 if ((!cur_filter) || (0 == strlen(cur_filter)))
285 new_filter = g_strconcat("!(", text, ")", NULL);
287 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
290 case MATCH_SELECTED_OR_NOT:
291 if ((!cur_filter) || (0 == strlen(cur_filter)))
292 new_filter = g_strconcat("!(", text, ")", NULL);
294 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
298 g_assert_not_reached();
303 /* Free up the copy we got of the old filter text. */
306 /* Don't change the current display filter if we only want to copy the filter */
307 if (action&MATCH_SELECTED_COPY_ONLY) {
308 GString *gtk_text_str = g_string_new("");
309 g_string_append(gtk_text_str, new_filter);
310 copy_to_clipboard(gtk_text_str);
311 g_string_free(gtk_text_str, TRUE);
313 /* create a new one and set the display filter entry accordingly */
314 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
316 /* Run the display filter so it goes in effect. */
317 if (action&MATCH_SELECTED_APPLY_NOW)
318 main_filter_packets(&cfile, new_filter, FALSE);
321 /* Free up the new filter text. */
326 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
330 if (cfile.finfo_selected) {
331 filter = proto_construct_match_selected_string(cfile.finfo_selected,
333 match_selected_cb_do((data ? data : w), action, filter);
338 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
342 if (cfile.finfo_selected) {
343 filter = proto_construct_match_selected_string(cfile.finfo_selected,
345 if ((!filter) || (0 == strlen(filter))) {
346 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
347 "Could not acquire information to build a filter!\n"
348 "Try expanding or choosing another item.");
353 color_display_with_filter(filter);
356 color_filters_reset_tmp();
358 color_filters_set_tmp(filt_nr,filter, FALSE);
360 cf_colorize_packets(&cfile);
366 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
368 gchar *selected_proto_url;
369 gchar *proto_abbrev = data;
374 if (cfile.finfo_selected) {
375 /* open wiki page using the protocol abbreviation */
376 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
377 browser_open_url(selected_proto_url);
378 g_free(selected_proto_url);
381 case(ESD_BTN_CANCEL):
384 g_assert_not_reached();
390 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
393 const gchar *proto_abbrev;
397 if (cfile.finfo_selected) {
398 /* convert selected field to protocol abbreviation */
399 /* XXX - could this conversion be simplified? */
400 field_id = cfile.finfo_selected->hfinfo->id;
401 /* if the selected field isn't a protocol, get it's parent */
402 if(!proto_registrar_is_protocol(field_id)) {
403 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
406 proto_abbrev = proto_registrar_get_abbrev(field_id);
408 if (!proto_is_private(field_id)) {
409 /* ask the user if the wiki page really should be opened */
410 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
411 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
413 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
415 "The Wireshark Wiki is a collaborative approach to provide information "
416 "about Wireshark in several ways (not limited to protocol specifics).\n"
418 "This Wiki is new, so the page of the selected protocol "
419 "may not exist and/or may not contain valuable information.\n"
421 "As everyone can edit the Wiki and add new content (or extend existing), "
422 "you are encouraged to add information if you can.\n"
424 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
426 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
427 "which will save you a lot of editing and will give a consistent look over the pages.",
428 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
429 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
431 /* appologize to the user that the wiki page cannot be opened */
432 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
433 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
435 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
437 "Since this is a private protocol, such information is not available in "
438 "a public wiki. Therefore this wiki entry is blocked.\n"
440 "Sorry for the inconvenience.\n",
441 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
446 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
448 gchar *selected_proto_url;
449 gchar *proto_abbrev = data;
453 if (cfile.finfo_selected) {
454 /* open reference page using the protocol abbreviation */
455 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
456 browser_open_url(selected_proto_url);
457 g_free(selected_proto_url);
460 case(ESD_BTN_CANCEL):
463 g_assert_not_reached();
468 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
471 const gchar *proto_abbrev;
475 if (cfile.finfo_selected) {
476 /* convert selected field to protocol abbreviation */
477 /* XXX - could this conversion be simplified? */
478 field_id = cfile.finfo_selected->hfinfo->id;
479 /* if the selected field isn't a protocol, get it's parent */
480 if(!proto_registrar_is_protocol(field_id)) {
481 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
484 proto_abbrev = proto_registrar_get_abbrev(field_id);
486 if (!proto_is_private(field_id)) {
487 /* ask the user if the wiki page really should be opened */
488 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
489 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
491 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
493 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
494 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
496 /* appologize to the user that the wiki page cannot be opened */
497 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
498 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
500 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
502 "Since this is a private protocol, such information is not available on "
503 "a public website. Therefore this filter entry is blocked.\n"
505 "Sorry for the inconvenience.\n",
506 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
512 is_address_column (gint column)
514 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
515 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
516 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
517 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
518 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
527 get_ip_address_list_from_packet_list_row(gpointer data)
529 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
530 #ifdef NEW_PACKET_LIST
531 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
533 gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
537 GList *addr_list = NULL;
539 #ifdef NEW_PACKET_LIST
540 fdata = (frame_data *) new_packet_list_get_row_data(row);
542 fdata = (frame_data *) packet_list_get_row_data(row);
548 if (!cf_read_frame (&cfile, fdata))
549 return NULL; /* error reading the frame */
551 epan_dissect_init(&edt, FALSE, FALSE);
552 col_custom_prime_edt(&edt, &cfile.cinfo);
554 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
555 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
557 /* First check selected column */
558 if (is_address_column (column)) {
559 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
562 for (col = 0; col < cfile.cinfo.num_cols; col++) {
563 /* Then check all columns except the selected */
564 if ((col != column) && (is_address_column (col))) {
565 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
569 epan_dissect_cleanup(&edt);
576 get_filter_from_packet_list_row_and_column(gpointer data)
578 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
579 #ifdef NEW_PACKET_LIST
580 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
582 gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
587 #ifdef NEW_PACKET_LIST
588 fdata = (frame_data *) new_packet_list_get_row_data(row);
590 fdata = (frame_data *) packet_list_get_row_data(row);
596 if (!cf_read_frame(&cfile, fdata))
597 return NULL; /* error reading the frame */
598 /* proto tree, visible. We need a proto tree if there's custom columns */
599 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
600 col_custom_prime_edt(&edt, &cfile.cinfo);
602 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
604 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
606 if ((cfile.cinfo.col_custom_occurrence[column]) ||
607 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
609 /* Only construct the filter when a single occurrence is displayed
610 * otherwise we might end up with a filter like "ip.proto==1,6".
612 * Or do we want to be able to filter on multiple occurrences so that
613 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
616 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
617 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
618 /* leak a little but safer than ep_ here */
619 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
620 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
621 if (hfi->parent == -1) {
623 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
624 } else if (hfi->type == FT_STRING) {
625 /* Custom string, add quotes */
626 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
627 cfile.cinfo.col_expr.col_expr_val[column]);
631 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
632 cfile.cinfo.col_expr.col_expr_val[column]);
637 epan_dissect_cleanup(&edt);
644 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
646 match_selected_cb_do(data,
648 get_filter_from_packet_list_row_and_column(data));
651 /* This function allows users to right click in the details window and copy the text
652 * information to the operating systems clipboard.
654 * We first check to see if a string representation is setup in the tree and then
655 * read the string. If not available then we try to grab the value. If all else
656 * fails we display a message to the user to indicate the copy could not be completed.
659 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
661 GString *gtk_text_str = g_string_new("");
662 char labelstring[256];
663 char *stringpointer = labelstring;
667 case COPY_SELECTED_DESCRIPTION:
668 if (cfile.finfo_selected->rep->representation != 0) {
669 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
672 case COPY_SELECTED_FIELDNAME:
673 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
674 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
677 case COPY_SELECTED_VALUE:
678 if (cfile.edt !=0 ) {
679 g_string_append(gtk_text_str,
680 get_node_field_value(cfile.finfo_selected, cfile.edt));
687 if (gtk_text_str->len == 0) {
688 /* If no representation then... Try to read the value */
689 proto_item_fill_label(cfile.finfo_selected, stringpointer);
690 g_string_append(gtk_text_str, stringpointer);
693 if (gtk_text_str->len == 0) {
694 /* Could not get item so display error msg */
695 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
697 /* Copy string to clipboard */
698 copy_to_clipboard(gtk_text_str);
700 g_string_free(gtk_text_str, TRUE); /* Free the memory */
704 /* mark as reference time frame */
706 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
710 frame->flags.ref_time=1;
711 cfile.ref_time_count++;
713 frame->flags.ref_time=0;
714 cfile.ref_time_count--;
716 cf_reftime_packets(&cfile);
717 #ifdef NEW_PACKET_LIST
718 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
719 new_packet_list_freeze();
720 cfile.displayed_count--;
721 new_packet_list_recreate_visible_rows();
722 new_packet_list_thaw();
724 new_packet_list_queue_draw();
729 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
733 timestamp_set_type(TS_RELATIVE);
734 recent.gui_time_format = TS_RELATIVE;
735 #ifdef NEW_PACKET_LIST
736 cf_timestamp_auto_precision(&cfile);
737 new_packet_list_queue_draw();
739 cf_change_time_formats(&cfile);
745 g_assert_not_reached();
748 if (cfile.current_frame) {
749 set_frame_reftime(!cfile.current_frame->flags.ref_time,
750 cfile.current_frame, cfile.current_row);
756 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
758 static GtkWidget *reftime_dialog = NULL;
762 if (cfile.current_frame) {
763 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
764 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
765 "%sSwitch to the appropriate Time Display Format?%s\n\n"
766 "Time References don't work well with the currently selected Time Display Format.\n\n"
767 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
768 simple_dialog_primary_start(), simple_dialog_primary_end());
769 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
771 set_frame_reftime(!cfile.current_frame->flags.ref_time,
772 cfile.current_frame, cfile.current_row);
776 case REFTIME_FIND_NEXT:
777 cf_find_packet_time_reference(&cfile, SD_FORWARD);
779 case REFTIME_FIND_PREV:
780 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
786 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
788 cf_find_packet_marked(&cfile, SD_FORWARD);
792 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
794 cf_find_packet_marked(&cfile, SD_BACKWARD);
798 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
801 gchar *help_str = NULL;
802 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
804 gboolean has_blurb = FALSE;
805 guint length = 0, byte_len;
806 GtkWidget *byte_view;
807 const guint8 *byte_data;
812 /* if nothing is selected */
813 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
816 * Which byte view is displaying the current protocol tree
819 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
820 if (byte_view == NULL)
823 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
824 if (byte_data == NULL)
827 cf_unselect_field(&cfile);
828 packet_hex_print(byte_view, byte_data,
829 cfile.current_frame, NULL, byte_len);
830 proto_help_menu_modify(sel, &cfile);
833 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
836 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
838 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
839 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
840 g_assert(byte_data != NULL);
842 cfile.finfo_selected = finfo;
843 set_menus_for_selected_tree_row(&cfile);
846 if (finfo->hfinfo->blurb != NULL &&
847 finfo->hfinfo->blurb[0] != '\0') {
849 length = (guint) strlen(finfo->hfinfo->blurb);
851 length = (guint) strlen(finfo->hfinfo->name);
853 finfo_length = finfo->length + finfo->appendix_length;
855 if (finfo_length == 0) {
857 } else if (finfo_length == 1) {
858 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
860 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
862 statusbar_pop_field_msg(); /* get rid of current help msg */
864 help_str = g_strdup_printf(" %s (%s)%s",
865 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
866 finfo->hfinfo->abbrev, len_str);
867 statusbar_push_field_msg(help_str);
871 * Don't show anything if the field name is zero-length;
872 * the pseudo-field for "proto_tree_add_text()" is such
873 * a field, and we don't want "Text (text)" showing up
874 * on the status line if you've selected such a field.
876 * XXX - there are zero-length fields for which we *do*
877 * want to show the field name.
879 * XXX - perhaps the name and abbrev field should be null
880 * pointers rather than null strings for that pseudo-field,
881 * but we'd have to add checks for null pointers in some
882 * places if we did that.
884 * Or perhaps protocol tree items added with
885 * "proto_tree_add_text()" should have -1 as the field index,
886 * with no pseudo-field being used, but that might also
887 * require special checks for -1 to be added.
889 statusbar_push_field_msg("");
892 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
894 proto_help_menu_modify(sel, &cfile);
897 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
899 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
902 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
904 expand_all_tree(cfile.edt->tree, tree_view_gbl);
907 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
909 if (cfile.finfo_selected) {
910 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
911 cfile.finfo_selected->hfinfo->abbrev,0);
912 /* Recreate the packet list according to new preferences */
913 #ifdef NEW_PACKET_LIST
914 new_packet_list_recreate ();
916 packet_list_recreate ();
918 if (!prefs.gui_use_pref_save) {
921 cfile.cinfo.columns_changed = FALSE; /* Reset value */
925 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
928 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
930 /* the mouse position is at an entry, expand that one */
931 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
932 gtk_tree_path_free(path);
936 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
937 if (cfile.edt->tree) {
938 guint32 tmp = g_resolv_flags;
939 g_resolv_flags = RESOLV_ALL;
940 proto_tree_draw(cfile.edt->tree, tree_view_gbl);
941 g_resolv_flags = tmp;
946 main_set_for_capture_file(gboolean have_capture_file_in)
948 have_capture_file = have_capture_file_in;
950 main_widgets_show_or_hide();
956 /* get the current geometry, before writing it to disk */
957 main_save_window_geometry(top_level);
959 /* write user's recent file to disk
960 * It is no problem to write this file, even if we do not quit */
961 write_profile_recent();
964 /* XXX - should we check whether the capture file is an
965 unsaved temporary file for a live capture and, if so,
966 pop up a "do you want to exit without saving the capture
967 file?" dialog, and then just return, leaving said dialog
968 box to forcibly quit if the user clicks "OK"?
970 If so, note that this should be done in a subroutine that
971 returns TRUE if we do so, and FALSE otherwise, and if it
972 returns TRUE we should return TRUE without nuking anything.
974 Note that, if we do that, we might also want to check if
975 an "Update list of packets in real time" capture is in
976 progress and, if so, ask whether they want to terminate
977 the capture and discard it, and return TRUE, before nuking
978 any child capture, if they say they don't want to do so. */
981 /* Nuke any child capture in progress. */
982 capture_kill_child(&global_capture_opts);
985 /* Are we in the middle of reading a capture? */
986 if (cfile.state == FILE_READ_IN_PROGRESS) {
987 /* Yes, so we can't just close the file and quit, as
988 that may yank the rug out from under the read in
989 progress; instead, just set the state to
990 "FILE_READ_ABORTED" and return - the code doing the read
991 will check for that and, if it sees that, will clean
993 cfile.state = FILE_READ_ABORTED;
995 /* Say that the window should *not* be deleted;
996 that'll be done by the code that cleans up. */
999 /* Close any capture file we have open; on some OSes, you
1000 can't unlink a temporary capture file if you have it
1002 "cf_close()" will unlink it after closing it if
1003 it's a temporary file.
1005 We do this here, rather than after the main loop returns,
1006 as, after the main loop returns, the main window may have
1007 been destroyed (if this is called due to a "destroy"
1008 even on the main window rather than due to the user
1009 selecting a menu item), and there may be a crash
1010 or other problem when "cf_close()" tries to
1011 clean up stuff in the main window.
1013 XXX - is there a better place to put this?
1014 Or should we have a routine that *just* closes the
1015 capture file, and doesn't do anything with the UI,
1016 which we'd call here, and another routine that
1017 calls that routine and also cleans up the UI, which
1018 we'd call elsewhere? */
1021 /* Exit by leaving the main loop, so that any quit functions
1022 we registered get called. */
1025 /* Say that the window should be deleted. */
1031 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1035 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1036 gtk_window_present(GTK_WINDOW(top_level));
1037 /* user didn't saved his current file, ask him */
1038 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1039 "%sSave capture file before program quit?%s\n\n"
1040 "If you quit the program without saving, your capture data will be discarded.",
1041 simple_dialog_primary_start(), simple_dialog_primary_end());
1042 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1045 /* unchanged file, just exit */
1046 /* "main_do_quit()" indicates whether the main window should be deleted. */
1047 return main_do_quit();
1053 main_pane_load_window_geometry(void)
1055 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1056 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1057 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1058 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1064 main_load_window_geometry(GtkWidget *widget)
1066 window_geometry_t geom;
1068 geom.set_pos = prefs.gui_geometry_save_position;
1069 geom.x = recent.gui_geometry_main_x;
1070 geom.y = recent.gui_geometry_main_y;
1071 geom.set_size = prefs.gui_geometry_save_size;
1072 if (recent.gui_geometry_main_width > 0 &&
1073 recent.gui_geometry_main_height > 0) {
1074 geom.width = recent.gui_geometry_main_width;
1075 geom.height = recent.gui_geometry_main_height;
1076 geom.set_maximized = prefs.gui_geometry_save_maximized;
1078 /* We assume this means the width and height weren't set in
1079 the "recent" file (or that there is no "recent" file),
1080 and weren't set to a default value, so we don't set the
1081 size. (The "recent" file code rejects non-positive width
1082 and height values.) */
1083 geom.set_size = FALSE;
1085 geom.maximized = recent.gui_geometry_main_maximized;
1087 window_set_geometry(widget, &geom);
1089 main_pane_load_window_geometry();
1090 statusbar_load_window_geometry();
1095 main_save_window_geometry(GtkWidget *widget)
1097 window_geometry_t geom;
1099 window_get_geometry(widget, &geom);
1101 if (prefs.gui_geometry_save_position) {
1102 recent.gui_geometry_main_x = geom.x;
1103 recent.gui_geometry_main_y = geom.y;
1106 if (prefs.gui_geometry_save_size) {
1107 recent.gui_geometry_main_width = geom.width;
1108 recent.gui_geometry_main_height = geom.height;
1111 if(prefs.gui_geometry_save_maximized) {
1112 recent.gui_geometry_main_maximized = geom.maximized;
1115 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1116 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1117 statusbar_save_window_geometry();
1120 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1124 /* save file first */
1125 file_save_as_cmd(after_save_exit, NULL);
1127 case(ESD_BTN_QUIT_DONT_SAVE):
1130 case(ESD_BTN_CANCEL):
1133 g_assert_not_reached();
1138 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1142 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1143 /* user didn't saved his current file, ask him */
1144 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1145 "%sSave capture file before program quit?%s\n\n"
1146 "If you quit the program without saving, your capture data will be discarded.",
1147 simple_dialog_primary_start(), simple_dialog_primary_end());
1148 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1150 /* unchanged file, just exit */
1156 print_usage(gboolean print_ver) {
1166 fprintf(output, "Wireshark " VERSION "%s\n"
1167 "Interactively dump and analyze network traffic.\n"
1168 "See http://www.wireshark.org for more information.\n"
1171 wireshark_svnversion, get_copyright_info());
1175 fprintf(output, "\n");
1176 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1177 fprintf(output, "\n");
1180 fprintf(output, "Capture interface:\n");
1181 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1182 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1183 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1184 fprintf(output, " -p don't capture in promiscuous mode\n");
1185 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1186 fprintf(output, " -Q quit Wireshark after capturing\n");
1187 fprintf(output, " -S update packet display when new packets are captured\n");
1188 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1189 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1190 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1192 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1193 fprintf(output, " -D print list of interfaces and exit\n");
1194 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1195 fprintf(output, "\n");
1196 fprintf(output, "Capture stop conditions:\n");
1197 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1198 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1199 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1200 fprintf(output, " files:NUM - stop after NUM files\n");
1201 /*fprintf(output, "\n");*/
1202 fprintf(output, "Capture output:\n");
1203 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1204 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1205 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1206 #endif /* HAVE_LIBPCAP */
1208 /*fprintf(output, "\n");*/
1209 fprintf(output, "Input file:\n");
1210 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1212 fprintf(output, "\n");
1213 fprintf(output, "Processing:\n");
1214 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1215 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1216 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1218 fprintf(output, "\n");
1219 fprintf(output, "User interface:\n");
1220 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1221 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1222 fprintf(output, " -J <jump filter> jump to the first packet matching the (display) filter\n");
1223 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1224 fprintf(output, " -m <font> set the font name used for most text\n");
1225 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1226 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1227 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1228 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1230 fprintf(output, "\n");
1231 fprintf(output, "Output:\n");
1232 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1234 fprintf(output, "\n");
1235 fprintf(output, "Miscellaneous:\n");
1236 fprintf(output, " -h display this help and exit\n");
1237 fprintf(output, " -v display version info and exit\n");
1238 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1239 fprintf(output, " persdata:path - personal data files\n");
1240 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1241 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1243 fprintf(output, " --display=DISPLAY X display to use\n");
1258 printf(PACKAGE " " VERSION "%s\n"
1265 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1266 runtime_info_str->str);
1274 * Print to the standard error. On Windows, create a console for the
1275 * standard error to show up on, if necessary.
1276 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1277 * terminal isn't the standard error?
1280 vfprintf_stderr(const char *fmt, va_list ap)
1285 vfprintf(stderr, fmt, ap);
1289 fprintf_stderr(const char *fmt, ...)
1294 vfprintf_stderr(fmt, ap);
1299 * Report an error in command-line arguments.
1300 * Creates a console on Windows.
1303 cmdarg_err(const char *fmt, ...)
1307 fprintf_stderr("wireshark: ");
1309 vfprintf_stderr(fmt, ap);
1311 fprintf_stderr("\n");
1315 * Report additional information for an error in command-line arguments.
1316 * Creates a console on Windows.
1317 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1318 * terminal isn't the standard error?
1321 cmdarg_err_cont(const char *fmt, ...)
1326 vfprintf_stderr(fmt, ap);
1327 fprintf_stderr("\n");
1331 #if defined(_WIN32) || ! defined USE_THREADS
1333 Once every 3 seconds we get a callback here which we use to update
1334 the tap extensions. Since Gtk1 is single threaded we dont have to
1335 worry about any locking or critical regions.
1338 tap_update_cb(gpointer data _U_)
1340 draw_tap_listeners(FALSE);
1344 /* Restart the tap update display timer with new configured interval */
1345 void reset_tap_update_timer(void)
1347 g_source_remove(tap_update_timer_id);
1348 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1353 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1354 use threads all update_thread_mutex can be dropped and protect/unprotect
1355 would just be empty functions.
1357 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1358 gtk1-wireshark and it will just work.
1360 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1362 update_thread(gpointer data _U_)
1366 g_get_current_time(&tv1);
1367 g_static_mutex_lock(&update_thread_mutex);
1368 gdk_threads_enter();
1369 draw_tap_listeners(FALSE);
1370 gdk_threads_leave();
1371 g_static_mutex_unlock(&update_thread_mutex);
1373 g_get_current_time(&tv2);
1375 /* Assuming it took less than configured time to update tap listeners... */
1376 if( (tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) >
1377 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1378 /* Wait for remainder of configured time */
1379 g_usleep((tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) -
1380 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1387 protect_thread_critical_region(void)
1389 #if !defined(_WIN32) && defined USE_THREADS
1390 g_static_mutex_lock(&update_thread_mutex);
1394 unprotect_thread_critical_region(void)
1396 #if !defined(_WIN32) && defined USE_THREADS
1397 g_static_mutex_unlock(&update_thread_mutex);
1402 * Periodically process outstanding hostname lookups. If we have new items,
1403 * redraw the packet list and tree view.
1407 resolv_update_cb(gpointer data _U_)
1409 /* Anything new show up? */
1410 if (host_name_lookup_process(NULL)) {
1411 if (pkt_scrollw->window)
1412 gdk_window_invalidate_rect(pkt_scrollw->window, NULL, TRUE);
1413 if (tv_scrollw->window)
1414 gdk_window_invalidate_rect(tv_scrollw->window, NULL, TRUE);
1417 /* Always check. Even if we don't do async lookups we could still get
1418 passive updates, e.g. from DNS packets. */
1423 /* Set main_window_name and it's icon title to the capture filename */
1425 set_display_filename(capture_file *cf)
1430 window_name = g_strdup_printf("%s", cf_get_display_name(cf));
1431 set_main_window_name(window_name);
1432 g_free(window_name);
1434 set_main_window_name("The Wireshark Network Analyzer");
1438 GtkWidget *close_dlg = NULL;
1441 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1443 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1448 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1450 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1455 main_cf_cb_file_closing(capture_file *cf)
1458 /* if we have more than 10000 packets, show a splash screen while closing */
1459 /* XXX - don't know a better way to decide whether to show or not,
1460 * as most of the time is spend in a single eth_clist_clear function,
1461 * so we can't use a progress bar here! */
1462 if(cf->count > 10000) {
1463 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1464 "%sClosing file!%s\n\nPlease wait ...",
1465 simple_dialog_primary_start(),
1466 simple_dialog_primary_end());
1467 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1470 /* Destroy all windows, which refer to the
1471 capture file we're closing. */
1472 destroy_packet_wins();
1473 file_save_as_destroy();
1475 /* Restore the standard title bar message. */
1476 set_main_window_name("The Wireshark Network Analyzer");
1478 /* Disable all menu items that make sense only if you have a capture. */
1479 set_menus_for_capture_file(NULL);
1480 set_menus_for_captured_packets(FALSE);
1481 set_menus_for_selected_packet(cf);
1482 set_menus_for_capture_in_progress(FALSE);
1483 set_capture_if_dialog_for_capture_in_progress(FALSE);
1484 set_menus_for_selected_tree_row(cf);
1486 /* Set up main window for no capture file. */
1487 main_set_for_capture_file(FALSE);
1489 main_window_update();
1493 main_cf_cb_file_closed(capture_file *cf _U_)
1495 if(close_dlg != NULL) {
1496 splash_destroy(close_dlg);
1503 main_cf_cb_file_read_started(capture_file *cf _U_)
1505 tap_dfilter_dlg_update();
1507 /* Set up main window for a capture file. */
1508 main_set_for_capture_file(TRUE);
1512 main_cf_cb_file_read_finished(capture_file *cf)
1516 if (!cf->is_tempfile && cf->filename) {
1517 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1518 add_menu_recent_capture_file(cf->filename);
1520 /* Remember folder for next Open dialog and save it in recent */
1521 dir_path = get_dirname(g_strdup(cf->filename));
1522 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;
2063 char *gdp_path, *dp_path;
2066 gboolean start_capture = FALSE;
2067 gboolean list_link_layer_types = FALSE;
2071 gboolean capture_option_specified = FALSE;
2078 gint pl_size = 280, tv_size = 95, bv_size = 75;
2079 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *jfilter = NULL;
2080 dfilter_t *rfcode = NULL;
2081 gboolean rfilter_parse_failed = FALSE;
2084 GtkWidget *splash_win = NULL;
2085 GLogLevelFlags log_flags;
2086 guint go_to_packet = 0;
2087 gboolean jump_backwards = FALSE;
2088 dfilter_t *jump_to_filter = NULL;
2091 #ifdef HAVE_GTKOSXAPPLICATION
2092 GtkOSXApplication *theApp;
2096 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2097 #define OPTSTRING_B "B:"
2099 #define OPTSTRING_B ""
2100 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2101 #else /* HAVE_LIBPCAP */
2102 #define OPTSTRING_B ""
2103 #endif /* HAVE_LIBPCAP */
2105 #ifdef HAVE_PCAP_CREATE
2106 #define OPTSTRING_I "I"
2108 #define OPTSTRING_I ""
2111 #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:"
2113 static const char optstring[] = OPTSTRING;
2116 /* Convert our arg list to UTF-8. */
2117 wc_argv = CommandLineToArgvW(GetCommandLineW(), &wc_argc);
2118 if (wc_argv && wc_argc == argc) {
2119 for (i = 0; i < argc; i++) {
2120 argv[i] = g_strdup(utf_16to8(wc_argv[i]));
2122 } /* XXX else bail because something is horribly, horribly wrong? */
2126 * Get credential information for later use, and drop privileges
2127 * before doing anything else.
2128 * Let the user know if anything happened.
2130 init_process_policies();
2131 relinquish_special_privs_perm();
2134 * Attempt to get the pathname of the executable file.
2136 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2138 /* initialize the funnel mini-api */
2139 initialize_funnel_ops();
2141 #ifdef HAVE_AIRPDCAP
2142 AirPDcapInitContext(&airpdcap_ctx);
2146 /* Load wpcap if possible. Do this before collecting the run-time version information */
2149 /* ... and also load the packet.dll from wpcap */
2150 wpcap_packet_load();
2153 /* Load the airpcap.dll. This must also be done before collecting
2154 * run-time version information. */
2155 airpcap_dll_ret_val = load_airpcap();
2157 switch (airpcap_dll_ret_val) {
2158 case AIRPCAP_DLL_OK:
2159 /* load the airpcap interfaces */
2160 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2162 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2163 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2164 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2167 airpcap_if_active = NULL;
2171 /* select the first ad default (THIS SHOULD BE CHANGED) */
2172 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2177 * XXX - Maybe we need to warn the user if one of the following happens???
2179 case AIRPCAP_DLL_OLD:
2180 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2183 case AIRPCAP_DLL_ERROR:
2184 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2187 case AIRPCAP_DLL_NOT_FOUND:
2188 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2192 #endif /* HAVE_AIRPCAP */
2194 /* Start windows sockets */
2195 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2198 profile_store_persconffiles (TRUE);
2200 /* Assemble the compile-time version information string */
2201 comp_info_str = g_string_new("Compiled ");
2203 g_string_append(comp_info_str, "with ");
2204 g_string_append_printf(comp_info_str,
2205 #ifdef GTK_MAJOR_VERSION
2206 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
2209 "GTK+ (version unknown)");
2211 g_string_append(comp_info_str, ", ");
2213 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
2215 /* Assemble the run-time version information string */
2216 runtime_info_str = g_string_new("Running ");
2217 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2219 /* Read the profile independent recent file. We have to do this here so we can */
2220 /* set the profile before it can be set from the command line parameterts */
2221 recent_read_static(&rf_path, &rf_open_errno);
2222 if (rf_path != NULL && rf_open_errno != 0) {
2223 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2224 "Could not open common recent file\n\"%s\": %s.",
2225 rf_path, strerror(rf_open_errno));
2228 /* "pre-scan" the command line parameters, if we have "console only"
2229 parameters. We do this so we don't start GTK+ if we're only showing
2230 command-line help or version information.
2232 XXX - this pre-scan is done before we start GTK+, so we haven't
2233 run gtk_init() on the arguments. That means that GTK+ arguments
2234 have not been removed from the argument list; those arguments
2235 begin with "--", and will be treated as an error by getopt().
2237 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2240 optind_initial = optind;
2241 while ((opt = getopt(argc, argv, optstring)) != -1) {
2243 case 'C': /* Configuration Profile */
2244 if (profile_exists (optarg)) {
2245 set_profile_name (optarg);
2247 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2251 case 'h': /* Print help and exit */
2257 if (strcmp(optarg, "-") == 0)
2258 stdin_capture = TRUE;
2261 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2262 status = filesystem_opt(opt, optarg);
2264 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2268 case 'v': /* Show version and exit */
2274 * Extension command line options have to be processed before
2275 * we call epan_init() as they are supposed to be used by dissectors
2276 * or taps very early in the registration process.
2280 case '?': /* Ignore errors - the "real" scan will catch them. */
2285 /* Init the "Open file" dialog directory */
2286 /* (do this after the path settings are processed) */
2288 /* Read the profile dependent (static part) of the recent file. */
2289 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2290 /* recent lists which is done in the dynamic part. */
2291 /* We have to do this already here, so command line parameters can overwrite these values. */
2292 recent_read_profile_static(&rf_path, &rf_open_errno);
2293 if (rf_path != NULL && rf_open_errno != 0) {
2294 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2295 "Could not open recent file\n\"%s\": %s.",
2296 rf_path, strerror(rf_open_errno));
2299 if (recent.gui_fileopen_remembered_dir &&
2300 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2301 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2303 set_last_open_dir(get_persdatafile_dir());
2306 /* Set getopt index back to initial value, so it will start with the
2307 first command line parameter again. Also reset opterr to 1, so that
2308 error messages are printed by getopt().
2310 XXX - this seems to work on most platforms, but time will tell.
2311 The Single UNIX Specification says "The getopt() function need
2312 not be reentrant", so this isn't guaranteed to work. The Mac
2313 OS X 10.4[.x] getopt() man page says
2315 In order to use getopt() to evaluate multiple sets of arguments, or to
2316 evaluate a single set of arguments multiple times, the variable optreset
2317 must be set to 1 before the second and each additional set of calls to
2318 getopt(), and the variable optind must be reinitialized.
2322 The optreset variable was added to make it possible to call the getopt()
2323 function multiple times. This is an extension to the IEEE Std 1003.2
2324 (``POSIX.2'') specification.
2326 which I think comes from one of the other BSDs.
2328 XXX - if we want to control all the command-line option errors, so
2329 that we can display them where we choose (e.g., in a window), we'd
2330 want to leave opterr as 0, and produce our own messages using optopt.
2331 We'd have to check the value of optopt to see if it's a valid option
2332 letter, in which case *presumably* the error is "this option requires
2333 an argument but none was specified", or not a valid option letter,
2334 in which case *presumably* the error is "this option isn't valid".
2335 Some versions of getopt() let you supply a option string beginning
2336 with ':', which means that getopt() will return ':' rather than '?'
2337 for "this option requires an argument but none was specified", but
2339 optind = optind_initial;
2342 /* Set the current locale according to the program environment.
2343 * We haven't localized anything, but some GTK widgets are localized
2344 * (the file selection dialogue, for example).
2345 * This also sets the C-language locale to the native environment. */
2348 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2349 gtk_init (&argc, &argv);
2351 cf_callback_add(main_cf_callback, NULL);
2353 capture_callback_add(main_capture_callback, NULL);
2355 cf_callback_add(statusbar_cf_callback, NULL);
2357 capture_callback_add(statusbar_capture_callback, NULL);
2360 /* Arrange that if we have no console window, and a GLib message logging
2361 routine is called to log a message, we pop up a console window.
2363 We do that by inserting our own handler for all messages logged
2364 to the default domain; that handler pops up a console if necessary,
2365 and then calls the default handler. */
2367 /* We might want to have component specific log levels later ... */
2371 G_LOG_LEVEL_CRITICAL|
2372 G_LOG_LEVEL_WARNING|
2373 G_LOG_LEVEL_MESSAGE|
2376 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2378 g_log_set_handler(NULL,
2380 console_log_handler, NULL /* user_data */);
2381 g_log_set_handler(LOG_DOMAIN_MAIN,
2383 console_log_handler, NULL /* user_data */);
2386 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2388 console_log_handler, NULL /* user_data */);
2389 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2391 console_log_handler, NULL /* user_data */);
2393 /* Set the initial values in the capture options. This might be overwritten
2394 by preference settings and then again by the command line parameters. */
2395 capture_opts_init(&global_capture_opts, &cfile);
2398 /* Initialize whatever we need to allocate colors for GTK+ */
2401 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2402 filter = get_conn_cfilter();
2403 if ( *filter != '\0' ) {
2404 info_update_freq = 1000; /* Milliseconds */
2407 /* We won't come till here, if we had a "console only" command line parameter. */
2408 splash_win = splash_new("Loading Wireshark ...");
2409 if (init_progfile_dir_error != NULL) {
2410 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2411 "Can't get pathname of Wireshark: %s.\n"
2412 "It won't be possible to capture traffic.\n"
2413 "Report this to the Wireshark developers.",
2414 init_progfile_dir_error);
2415 g_free(init_progfile_dir_error);
2418 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2420 /* Register all dissectors; we must do this before checking for the
2421 "-G" flag, as the "-G" flag dumps information registered by the
2422 dissectors, and we must do it before we read the preferences, in
2423 case any dissectors register preferences. */
2424 epan_init(register_all_protocols,register_all_protocol_handoffs,
2425 splash_update, (gpointer) splash_win,
2426 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2427 write_failure_alert_box);
2429 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2431 /* Register all tap listeners; we do this before we parse the arguments,
2432 as the "-z" argument can specify a registered tap. */
2434 /* we register the plugin taps before the other taps because
2435 stats_tree taps plugins will be registered as tap listeners
2436 by stats_tree_stat.c and need to registered before that */
2439 register_all_plugin_tap_listeners();
2442 register_all_tap_listeners();
2444 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2446 /* Now register the preferences for any non-dissector modules.
2447 We must do that before we read the preferences as well. */
2448 prefs_register_modules();
2450 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2452 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2453 #if !defined(_WIN32) && defined(G_THREADS_ENABLED) && defined USE_THREADS
2456 g_thread_init(NULL);
2458 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2459 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2461 #else /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2462 /* this is to keep tap extensions updating once every 3 seconds */
2463 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2464 #endif /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2466 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2468 cap_file_init(&cfile);
2470 /* Fill in capture options with values from the preferences */
2471 prefs_to_capture_opts();
2473 /* Now get our args */
2474 while ((opt = getopt(argc, argv, optstring)) != -1) {
2476 /*** capture option specific ***/
2477 case 'a': /* autostop criteria */
2478 case 'b': /* Ringbuffer option */
2479 case 'c': /* Capture xxx packets */
2480 case 'f': /* capture filter */
2481 case 'k': /* Start capture immediately */
2482 case 'H': /* Hide capture info dialog box */
2483 case 'i': /* Use interface xxx */
2484 case 'p': /* Don't capture in promiscuous mode */
2485 #ifdef HAVE_PCAP_CREATE
2486 case 'I': /* Capture in monitor mode, if available */
2488 case 'Q': /* Quit after capture (just capture to file) */
2489 case 's': /* Set the snapshot (capture) length */
2490 case 'S': /* "Sync" mode: used for following file ala tail -f */
2491 case 'w': /* Write to capture file xxx */
2492 case 'y': /* Set the pcap data link type */
2493 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2494 case 'B': /* Buffer size */
2495 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2497 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2503 capture_option_specified = TRUE;
2508 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2509 case 'K': /* Kerberos keytab file */
2510 read_keytab_file(optarg);
2514 /*** all non capture option specific ***/
2516 /* Configuration profile settings were already processed just ignore them this time*/
2518 case 'D': /* Print a list of capture devices and exit */
2520 if_list = capture_interface_list(&err, &err_str);
2521 if (if_list == NULL) {
2523 case CANT_GET_INTERFACE_LIST:
2524 cmdarg_err("%s", err_str);
2528 case NO_INTERFACES_FOUND:
2529 cmdarg_err("There are no interfaces on which a capture can be done");
2534 capture_opts_print_interfaces(if_list);
2535 free_interface_list(if_list);
2538 capture_option_specified = TRUE;
2542 case 'j': /* Search backwards for a matching packet from filter in option J */
2543 jump_backwards = TRUE;
2545 case 'g': /* Go to packet with the given packet number */
2546 go_to_packet = get_positive_int(optarg, "go to packet");
2548 case 'J': /* Jump to the first packet which matches the filter criteria */
2551 case 'l': /* Automatic scrolling in live capture mode */
2553 auto_scroll_live = TRUE;
2555 capture_option_specified = TRUE;
2559 case 'L': /* Print list of link-layer types and exit */
2561 list_link_layer_types = TRUE;
2563 capture_option_specified = TRUE;
2567 case 'm': /* Fixed-width font for the display */
2568 g_free(prefs_p->gui_font_name);
2569 prefs_p->gui_font_name = g_strdup(optarg);
2571 case 'n': /* No name resolution */
2572 g_resolv_flags = RESOLV_NONE;
2574 case 'N': /* Select what types of addresses/port #s to resolve */
2575 if (g_resolv_flags == RESOLV_ALL)
2576 g_resolv_flags = RESOLV_NONE;
2577 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2578 if (badopt != '\0') {
2579 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2584 case 'o': /* Override preference from command line */
2585 switch (prefs_set_pref(optarg)) {
2588 case PREFS_SET_SYNTAX_ERR:
2589 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2592 case PREFS_SET_NO_SUCH_PREF:
2593 /* not a preference, might be a recent setting */
2594 switch (recent_set_arg(optarg)) {
2597 case PREFS_SET_SYNTAX_ERR:
2598 /* shouldn't happen, checked already above */
2599 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2602 case PREFS_SET_NO_SUCH_PREF:
2603 case PREFS_SET_OBSOLETE:
2604 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2609 g_assert_not_reached();
2612 case PREFS_SET_OBSOLETE:
2613 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2618 g_assert_not_reached();
2622 /* Path settings were already processed just ignore them this time*/
2624 case 'r': /* Read capture file xxx */
2625 /* We may set "last_open_dir" to "cf_name", and if we change
2626 "last_open_dir" later, we free the old value, so we have to
2627 set "cf_name" to something that's been allocated. */
2628 cf_name = g_strdup(optarg);
2630 case 'R': /* Read file filter */
2633 case 't': /* Time stamp type */
2634 if (strcmp(optarg, "r") == 0)
2635 timestamp_set_type(TS_RELATIVE);
2636 else if (strcmp(optarg, "a") == 0)
2637 timestamp_set_type(TS_ABSOLUTE);
2638 else if (strcmp(optarg, "ad") == 0)
2639 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2640 else if (strcmp(optarg, "d") == 0)
2641 timestamp_set_type(TS_DELTA);
2642 else if (strcmp(optarg, "dd") == 0)
2643 timestamp_set_type(TS_DELTA_DIS);
2644 else if (strcmp(optarg, "e") == 0)
2645 timestamp_set_type(TS_EPOCH);
2647 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2648 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2649 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2653 case 'u': /* Seconds type */
2654 if (strcmp(optarg, "s") == 0)
2655 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2656 else if (strcmp(optarg, "hms") == 0)
2657 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2659 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2660 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2665 /* ext ops were already processed just ignore them this time*/
2668 /* We won't call the init function for the stat this soon
2669 as it would disallow MATE's fields (which are registered
2670 by the preferences set callback) from being used as
2671 part of a tap filter. Instead, we just add the argument
2672 to a list of stat arguments. */
2673 if (!process_stat_cmd_arg(optarg)) {
2674 cmdarg_err("Invalid -z argument.");
2675 cmdarg_err_cont(" -z argument must be one of :");
2676 list_stat_cmd_args();
2681 case '?': /* Bad flag - print usage message */
2689 if (cf_name != NULL) {
2691 * Input file name specified with "-r" *and* specified as a regular
2692 * command-line argument.
2694 cmdarg_err("File name specified both with -r and regular argument");
2698 * Input file name not specified with "-r", and a command-line argument
2699 * was specified; treat it as the input file name.
2701 * Yes, this is different from tshark, where non-flag command-line
2702 * arguments are a filter, but this works better on GUI desktops
2703 * where a command can be specified to be run to open a particular
2704 * file - yes, you could have "-r" as the last part of the command,
2705 * but that's a bit ugly.
2707 cf_name = g_strdup(argv[0]);
2715 * Extra command line arguments were specified; complain.
2717 cmdarg_err("Invalid argument: %s", argv[0]);
2722 #ifndef HAVE_LIBPCAP
2723 if (capture_option_specified) {
2724 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2732 if (start_capture && list_link_layer_types) {
2733 /* Specifying *both* is bogus. */
2734 cmdarg_err("You can't specify both -L and a live capture.");
2738 if (list_link_layer_types) {
2739 /* We're supposed to list the link-layer types for an interface;
2740 did the user also specify a capture file to be read? */
2742 /* Yes - that's bogus. */
2743 cmdarg_err("You can't specify -L and a capture file to be read.");
2746 /* No - did they specify a ring buffer option? */
2747 if (global_capture_opts.multi_files_on) {
2748 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2752 /* We're supposed to do a live capture; did the user also specify
2753 a capture file to be read? */
2754 if (start_capture && cf_name) {
2755 /* Yes - that's bogus. */
2756 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2760 /* No - was the ring buffer option specified and, if so, does it make
2762 if (global_capture_opts.multi_files_on) {
2763 /* Ring buffer works only under certain conditions:
2764 a) ring buffer does not work with temporary files;
2765 b) real_time_mode and multi_files_on are mutually exclusive -
2766 real_time_mode takes precedence;
2767 c) it makes no sense to enable the ring buffer if the maximum
2768 file size is set to "infinite". */
2769 if (global_capture_opts.save_file == NULL) {
2770 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2771 global_capture_opts.multi_files_on = FALSE;
2773 /* if (global_capture_opts.real_time_mode) {
2774 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2775 global_capture_opts.multi_files_on = FALSE;
2777 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2778 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2779 /* XXX - this must be redesigned as the conditions changed */
2780 /* global_capture_opts.multi_files_on = FALSE;*/
2785 if (start_capture || list_link_layer_types) {
2786 /* Did the user specify an interface to use? */
2787 if (!capture_opts_trim_iface(&global_capture_opts,
2788 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2793 if (list_link_layer_types) {
2794 /* Get the list of link-layer types for the capture device. */
2795 if_capabilities_t *caps;
2797 caps = capture_get_if_capabilities(global_capture_opts.iface,
2798 global_capture_opts.monitor_mode,
2801 cmdarg_err("%s", err_str);
2805 if (caps->data_link_types == NULL) {
2806 cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
2809 capture_opts_print_if_capabilities(caps, global_capture_opts.monitor_mode);
2810 free_if_capabilities(caps);
2814 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2815 capture_opts_trim_ring_num_files(&global_capture_opts);
2816 #endif /* HAVE_LIBPCAP */
2818 /* Notify all registered modules that have had any of their preferences
2819 changed either from one of the preferences file or from the command
2820 line that their preferences have changed. */
2823 /* disabled protocols as per configuration file */
2824 if (gdp_path == NULL && dp_path == NULL) {
2825 set_disabled_protos_list();
2828 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2830 /* read in rc file from global and personal configuration paths. */
2831 rc_file = get_datafile_path(RC_FILE);
2832 gtk_rc_parse(rc_file);
2834 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2835 gtk_rc_parse(rc_file);
2844 /* close the splash screen, as we are going to open the main window now */
2845 splash_destroy(splash_win);
2847 /************************************************************************/
2848 /* Everything is prepared now, preferences and command line was read in */
2850 /* Pop up the main window. */
2851 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2853 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2854 recent_read_dynamic(&rf_path, &rf_open_errno);
2855 if (rf_path != NULL && rf_open_errno != 0) {
2856 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2857 "Could not open recent file\n\"%s\": %s.",
2858 rf_path, strerror(rf_open_errno));
2861 color_filters_enable(recent.packet_list_colorize);
2863 /* rearrange all the widgets as we now have all recent settings ready for this */
2864 main_widgets_rearrange();
2866 /* Fill in column titles. This must be done after the top level window
2869 XXX - is that still true, with fixed-width columns? */
2870 #ifndef NEW_PACKET_LIST
2871 packet_list_set_column_titles();
2874 menu_recent_read_finished();
2876 menu_auto_scroll_live_changed(auto_scroll_live);
2879 switch (user_font_apply()) {
2882 case FA_FONT_NOT_RESIZEABLE:
2883 /* "user_font_apply()" popped up an alert box. */
2884 /* turn off zooming - font can't be resized */
2885 case FA_FONT_NOT_AVAILABLE:
2886 /* XXX - did we successfully load the un-zoomed version earlier?
2887 If so, this *probably* means the font is available, but not at
2888 this particular zoom level, but perhaps some other failure
2889 occurred; I'm not sure you can determine which is the case,
2891 /* turn off zooming - zoom level is unavailable */
2893 /* in any other case than FA_SUCCESS, turn off zooming */
2894 recent.gui_zoom_level = 0;
2895 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2898 dnd_init(top_level);
2900 color_filters_init();
2903 /* the window can be sized only, if it's not already shown, so do it now! */
2904 main_load_window_geometry(top_level);
2906 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2909 /* If we were given the name of a capture file, read it in now;
2910 we defer it until now, so that, if we can't open it, and pop
2911 up an alert box, the alert box is more likely to come up on
2912 top of the main window - but before the preference-file-error
2913 alert box, so, if we get one of those, it's more likely to come
2916 show_main_window(TRUE);
2917 check_and_warn_user_startup(cf_name);
2918 if (rfilter != NULL) {
2919 if (!dfilter_compile(rfilter, &rfcode)) {
2920 bad_dfilter_alert_box(rfilter);
2921 rfilter_parse_failed = TRUE;
2924 if (!rfilter_parse_failed) {
2925 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2926 /* "cf_open()" succeeded, so it closed the previous
2927 capture file, and thus destroyed any previous read filter
2928 attached to "cf". */
2930 cfile.rfcode = rfcode;
2931 /* Open stat windows; we do so after creating the main window,
2932 to avoid GTK warnings, and after successfully opening the
2933 capture file, so we know we have something to compute stats
2934 on, and after registering all dissectors, so that MATE will
2935 have registered its field array and we can have a tap filter
2936 with one of MATE's late-registered fields as part of the
2938 start_requested_stats();
2940 /* Read the capture file. */
2941 switch (cf_read(&cfile, FALSE)) {
2945 /* Just because we got an error, that doesn't mean we were unable
2946 to read any of the file; we handle what we could get from the
2948 /* if the user told us to jump to a specific packet, do it now */
2949 if(go_to_packet != 0) {
2950 /* Jump to the specified frame number, kept for backward
2952 cf_goto_frame(&cfile, go_to_packet);
2953 } else if (jfilter != NULL) {
2954 /* try to compile given filter */
2955 if (!dfilter_compile(jfilter, &jump_to_filter)) {
2956 bad_dfilter_alert_box(jfilter);
2958 /* Filter ok, jump to the first packet matching the filter
2959 conditions. Default search direction is forward, but if
2960 option d was given, search backwards */
2961 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
2966 case CF_READ_ABORTED:
2972 /* If the filename is not the absolute path, prepend the current dir. This happens
2973 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
2974 if (!g_path_is_absolute(cf_name)) {
2975 char *old_cf_name = cf_name;
2976 char *pwd = g_get_current_dir();
2977 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
2978 g_free(old_cf_name);
2982 /* Save the name of the containing directory specified in the
2983 path name, if any; we can write over cf_name, which is a
2984 good thing, given that "get_dirname()" does write over its
2986 s = get_dirname(cf_name);
2987 set_last_open_dir(s);
2992 dfilter_free(rfcode);
2993 cfile.rfcode = NULL;
2994 show_main_window(FALSE);
2995 /* Don't call check_and_warn_user_startup(): we did it above */
2996 set_menus_for_capture_in_progress(FALSE);
2997 set_capture_if_dialog_for_capture_in_progress(FALSE);
3002 if (start_capture) {
3003 if (global_capture_opts.save_file != NULL) {
3004 /* Save the directory name for future file dialogs. */
3005 /* (get_dirname overwrites filename) */
3006 s = get_dirname(g_strdup(global_capture_opts.save_file));
3007 set_last_open_dir(s);
3010 /* "-k" was specified; start a capture. */
3011 show_main_window(TRUE);
3012 check_and_warn_user_startup(cf_name);
3013 if (capture_start(&global_capture_opts)) {
3014 /* The capture started. Open stat windows; we do so after creating
3015 the main window, to avoid GTK warnings, and after successfully
3016 opening the capture file, so we know we have something to compute
3017 stats on, and after registering all dissectors, so that MATE will
3018 have registered its field array and we can have a tap filter with
3019 one of MATE's late-registered fields as part of the filter. */
3020 start_requested_stats();
3024 show_main_window(FALSE);
3025 check_and_warn_user_startup(cf_name);
3026 set_menus_for_capture_in_progress(FALSE);
3027 set_capture_if_dialog_for_capture_in_progress(FALSE);
3030 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
3031 if (!start_capture && strlen(global_capture_opts.cfilter) == 0) {
3032 g_free(global_capture_opts.cfilter);
3033 global_capture_opts.cfilter = g_strdup(get_conn_cfilter());
3035 #else /* HAVE_LIBPCAP */
3036 show_main_window(FALSE);
3037 check_and_warn_user_startup(cf_name);
3038 set_menus_for_capture_in_progress(FALSE);
3039 set_capture_if_dialog_for_capture_in_progress(FALSE);
3040 #endif /* HAVE_LIBPCAP */
3043 /* register our pid if we are being run from a U3 device */
3046 profile_store_persconffiles (FALSE);
3048 #ifdef HAVE_GTKOSXAPPLICATION
3049 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3050 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3051 gtk_osxapplication_ready(theApp);
3054 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3056 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3058 /* ... back from GTK, we're going down now! */
3060 /* deregister our pid */
3061 u3_deregister_pid();
3065 #ifdef HAVE_AIRPDCAP
3066 AirPDcapDestroyContext(&airpdcap_ctx);
3070 /* hide the (unresponsive) main window, while asking the user to close the console window */
3071 gtk_widget_hide(top_level);
3073 #ifdef HAVE_GTKOSXAPPLICATION
3074 g_object_unref(theApp);
3077 /* Shutdown windows sockets */
3080 /* For some unknown reason, the "atexit()" call in "create_console()"
3081 doesn't arrange that "destroy_console()" be called when we exit,
3082 so we call it here if a console was created. */
3091 /* We build this as a GUI subsystem application on Win32, so
3092 "WinMain()", not "main()", gets called.
3094 Hack shamelessly stolen from the Win32 port of the GIMP. */
3096 #define _stdcall __attribute__((stdcall))
3100 WinMain (struct HINSTANCE__ *hInstance,
3101 struct HINSTANCE__ *hPrevInstance,
3105 INITCOMMONCONTROLSEX comm_ctrl;
3108 * Initialize our DLL search path. MUST be called before LoadLibrary
3111 ws_init_dll_search_path();
3113 /* Initialize our controls. Required for native Windows file dialogs. */
3114 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3115 comm_ctrl.dwSize = sizeof(comm_ctrl);
3116 /* Includes the animate, header, hot key, list view, progress bar,
3117 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3120 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3121 InitCommonControlsEx(&comm_ctrl);
3123 /* RichEd20.DLL is needed for filter entries. */
3124 ws_load_library("riched20.dll");
3126 has_console = FALSE;
3127 return main (__argc, __argv);
3130 /* The code to create and desstroy console windows should not be necessary,
3131 at least as I read the GLib source code, as it looks as if GLib is, on
3132 Win32, *supposed* to create a console window into which to display its
3135 That doesn't happen, however. I suspect there's something completely
3136 broken about that code in GLib-for-Win32, and that it may be related
3137 to the breakage that forces us to just call "printf()" on the message
3138 rather than passing the message on to "g_log_default_handler()"
3139 (which is the routine that does the aforementioned non-functional
3140 console window creation). */
3143 * If this application has no console window to which its standard output
3144 * would go, create one.
3147 create_console(void)
3149 if (stdin_capture) {
3150 /* We've been handed "-i -". Don't mess with stdio. */
3155 /* We have no console to which to print the version string, so
3156 create one and make it the standard input, output, and error. */
3157 if (!AllocConsole())
3158 return; /* couldn't create console */
3160 ws_freopen("CONIN$", "r", stdin);
3161 ws_freopen("CONOUT$", "w", stdout);
3162 ws_freopen("CONOUT$", "w", stderr);
3164 /* Well, we have a console now. */
3167 /* Now register "destroy_console()" as a routine to be called just
3168 before the application exits, so that we can destroy the console
3169 after the user has typed a key (so that the console doesn't just
3170 disappear out from under them, giving the user no chance to see
3171 the message(s) we put in there). */
3172 atexit(destroy_console);
3174 SetConsoleTitle(_T("Wireshark Debug Console"));
3179 destroy_console(void)
3182 printf("\n\nPress any key to exit\n");
3191 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3192 const char *message, gpointer user_data _U_)
3199 /* ignore log message, if log_level isn't interesting based
3200 upon the console log preferences.
3201 If the preferences haven't been loaded loaded yet, display the
3204 The default console_log_level preference value is such that only
3205 ERROR, CRITICAL and WARNING level messages are processed;
3206 MESSAGE, INFO and DEBUG level messages are ignored. */
3207 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3208 prefs.console_log_level != 0) {
3213 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3214 /* the user wants a console or the application will terminate immediately */
3218 /* For some unknown reason, the above doesn't appear to actually cause
3219 anything to be sent to the standard output, so we'll just splat the
3220 message out directly, just to make sure it gets out. */
3222 switch(log_level & G_LOG_LEVEL_MASK) {
3223 case G_LOG_LEVEL_ERROR:
3226 case G_LOG_LEVEL_CRITICAL:
3229 case G_LOG_LEVEL_WARNING:
3232 case G_LOG_LEVEL_MESSAGE:
3235 case G_LOG_LEVEL_INFO:
3238 case G_LOG_LEVEL_DEBUG:
3242 fprintf(stderr, "unknown log_level %u\n", log_level);
3244 g_assert_not_reached();
3247 /* create a "timestamp" */
3249 today = localtime(&curr);
3251 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3252 today->tm_hour, today->tm_min, today->tm_sec,
3253 log_domain != NULL ? log_domain : "",
3256 if(log_level & G_LOG_LEVEL_ERROR) {
3257 /* wait for a key press before the following error handler will terminate the program
3258 this way the user at least can read the error message */
3259 printf("\n\nPress any key to exit\n");
3263 /* XXX - on UN*X, should we just use g_log_default_handler()?
3264 We want the error messages to go to the standard output;
3265 on Mac OS X, that will cause them to show up in various
3266 per-user logs accessible through Console (details depend
3267 on whether you're running 10.0 through 10.4 or running
3268 10.5 and later), and, on other UN*X desktop environments,
3269 if they don't show up in some form of console log, that's
3270 a deficiency in that desktop environment. (Too bad
3271 Windows doesn't set the standard output and error for
3272 GUI apps to something that shows up in such a log.) */
3273 g_log_default_handler(log_domain, log_level, message, user_data);
3280 * Helper for main_widgets_rearrange()
3282 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3283 gtk_container_remove(GTK_CONTAINER(data), widget);
3286 static GtkWidget *main_widget_layout(gint layout_content)
3288 switch(layout_content) {
3289 case(layout_pane_content_none):
3291 case(layout_pane_content_plist):
3293 case(layout_pane_content_pdetails):
3295 case(layout_pane_content_pbytes):
3296 return byte_nb_ptr_gbl;
3298 g_assert_not_reached();
3305 * Rearrange the main window widgets
3307 void main_widgets_rearrange(void) {
3308 GtkWidget *first_pane_widget1, *first_pane_widget2;
3309 GtkWidget *second_pane_widget1, *second_pane_widget2;
3310 gboolean split_top_left;
3312 /* be a bit faster */
3313 gtk_widget_hide(main_vbox);
3315 /* be sure we don't lose a widget while rearranging */
3316 g_object_ref(G_OBJECT(menubar));
3317 g_object_ref(G_OBJECT(main_tb));
3318 g_object_ref(G_OBJECT(filter_tb));
3320 g_object_ref(G_OBJECT(airpcap_tb));
3322 g_object_ref(G_OBJECT(pkt_scrollw));
3323 g_object_ref(G_OBJECT(tv_scrollw));
3324 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3325 g_object_ref(G_OBJECT(statusbar));
3326 g_object_ref(G_OBJECT(main_pane_v1));
3327 g_object_ref(G_OBJECT(main_pane_v2));
3328 g_object_ref(G_OBJECT(main_pane_h1));
3329 g_object_ref(G_OBJECT(main_pane_h2));
3330 g_object_ref(G_OBJECT(welcome_pane));
3332 /* empty all containers participating */
3333 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3334 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3335 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3336 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3337 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3339 statusbar_widgets_emptying(statusbar);
3341 /* add the menubar always at the top */
3342 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3345 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3347 /* filter toolbar in toolbar area */
3348 if (!prefs.filter_toolbar_show_in_statusbar) {
3349 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3353 /* airpcap toolbar */
3354 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3357 /* fill the main layout panes */
3358 switch(prefs.gui_layout_type) {
3359 case(layout_type_5):
3360 main_first_pane = main_pane_v1;
3361 main_second_pane = main_pane_v2;
3362 split_top_left = FALSE;
3364 case(layout_type_2):
3365 main_first_pane = main_pane_v1;
3366 main_second_pane = main_pane_h1;
3367 split_top_left = FALSE;
3369 case(layout_type_1):
3370 main_first_pane = main_pane_v1;
3371 main_second_pane = main_pane_h1;
3372 split_top_left = TRUE;
3374 case(layout_type_4):
3375 main_first_pane = main_pane_h1;
3376 main_second_pane = main_pane_v1;
3377 split_top_left = FALSE;
3379 case(layout_type_3):
3380 main_first_pane = main_pane_h1;
3381 main_second_pane = main_pane_v1;
3382 split_top_left = TRUE;
3384 case(layout_type_6):
3385 main_first_pane = main_pane_h1;
3386 main_second_pane = main_pane_h2;
3387 split_top_left = FALSE;
3390 main_first_pane = NULL;
3391 main_second_pane = NULL;
3392 split_top_left = FALSE;
3393 g_assert_not_reached();
3395 if (split_top_left) {
3396 first_pane_widget1 = main_second_pane;
3397 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3398 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3399 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3401 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3402 first_pane_widget2 = main_second_pane;
3403 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3404 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3406 if (first_pane_widget1 != NULL)
3407 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3408 if (first_pane_widget2 != NULL)
3409 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3410 if (second_pane_widget1 != NULL)
3411 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3412 if (second_pane_widget2 != NULL)
3413 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3415 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3418 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3421 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3423 /* filter toolbar in statusbar hbox */
3424 if (prefs.filter_toolbar_show_in_statusbar) {
3425 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3429 /* airpcap toolbar */
3430 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3433 /* statusbar widgets */
3434 statusbar_widgets_pack(statusbar);
3436 /* hide widgets on users recent settings */
3437 main_widgets_show_or_hide();
3439 gtk_widget_show(main_vbox);
3443 is_widget_visible(GtkWidget *widget, gpointer data)
3445 gboolean *is_visible = data;
3448 if (GTK_WIDGET_VISIBLE(widget))
3455 main_widgets_show_or_hide(void)
3457 gboolean main_second_pane_show;
3459 if (recent.main_toolbar_show) {
3460 gtk_widget_show(main_tb);
3462 gtk_widget_hide(main_tb);
3465 statusbar_widgets_show_or_hide(statusbar);
3467 if (recent.filter_toolbar_show) {
3468 gtk_widget_show(filter_tb);
3470 gtk_widget_hide(filter_tb);
3474 if (recent.airpcap_toolbar_show) {
3475 gtk_widget_show(airpcap_tb);
3477 gtk_widget_hide(airpcap_tb);
3481 if (recent.packet_list_show && have_capture_file) {
3482 gtk_widget_show(pkt_scrollw);
3484 gtk_widget_hide(pkt_scrollw);
3487 if (recent.tree_view_show && have_capture_file) {
3488 gtk_widget_show(tv_scrollw);
3490 gtk_widget_hide(tv_scrollw);
3493 if (recent.byte_view_show && have_capture_file) {
3494 gtk_widget_show(byte_nb_ptr_gbl);
3496 gtk_widget_hide(byte_nb_ptr_gbl);
3499 if (have_capture_file) {
3500 gtk_widget_show(main_first_pane);
3502 gtk_widget_hide(main_first_pane);
3506 * Is anything in "main_second_pane" visible?
3507 * If so, show it, otherwise hide it.
3509 main_second_pane_show = FALSE;
3510 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3511 &main_second_pane_show);
3512 if (main_second_pane_show) {
3513 gtk_widget_show(main_second_pane);
3515 gtk_widget_hide(main_second_pane);
3518 if (!have_capture_file) {
3520 gtk_widget_show(welcome_pane);
3523 gtk_widget_hide(welcome_pane);
3526 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
3527 #ifndef NEW_PACKET_LIST
3528 packet_list_freeze ();
3529 packet_list_thaw ();
3534 /* called, when the window state changes (minimized, maximized, ...) */
3536 window_state_event_cb (GtkWidget *widget _U_,
3540 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3542 if( (event->type) == (GDK_WINDOW_STATE)) {
3543 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3544 /* we might have dialogs popped up while we where iconified,
3546 display_queued_messages();
3554 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3556 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3558 if (event->keyval == GDK_F8) {
3559 #ifdef NEW_PACKET_LIST
3560 new_packet_list_next();
3565 } else if (event->keyval == GDK_F7) {
3566 #ifdef NEW_PACKET_LIST
3567 new_packet_list_prev();
3572 } else if (event->state & NO_SHIFT_MOD_MASK) {
3573 return FALSE; /* Skip control, alt, and other modifiers */
3575 * A comment in gdkkeysyms.h says that it's autogenerated from
3576 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3577 * don't explicitly say so, isprint() should work as expected
3580 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3581 /* Forward the keypress on to the display filter entry */
3582 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3583 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3584 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3592 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3594 GtkAccelGroup *accel;
3597 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3598 set_main_window_name("The Wireshark Network Analyzer");
3600 gtk_widget_set_name(top_level, "main window");
3601 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3603 g_signal_connect(GTK_OBJECT(top_level), "window_state_event",
3604 G_CALLBACK(window_state_event_cb), NULL);
3605 g_signal_connect(GTK_OBJECT(top_level), "key-press-event",
3606 G_CALLBACK(top_level_key_pressed_cb), NULL );
3608 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3609 main_vbox = gtk_vbox_new(FALSE, 1);
3610 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3611 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3612 gtk_widget_show(main_vbox);
3615 menubar = main_menu_new(&accel);
3617 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3618 /* Mac OS X native menus are created and displayed by main_menu_new() */
3619 if(!prefs_p->gui_macosx_style) {
3621 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3622 gtk_widget_show(menubar);
3623 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3628 main_tb = toolbar_new();
3629 gtk_widget_show (main_tb);
3631 /* Filter toolbar */
3632 filter_tb = filter_toolbar_new();
3635 #ifdef NEW_PACKET_LIST
3636 pkt_scrollw = new_packet_list_create();
3637 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3638 gtk_widget_show_all(pkt_scrollw);
3640 pkt_scrollw = packet_list_new(prefs_p);
3641 gtk_widget_set_size_request(packet_list, -1, pl_size);
3642 gtk_widget_show(pkt_scrollw);
3646 tv_scrollw = main_tree_view_new(prefs_p, &tree_view_gbl);
3647 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3648 gtk_widget_show(tv_scrollw);
3650 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3651 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3652 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3653 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3654 gtk_widget_show(tree_view_gbl);
3657 byte_nb_ptr_gbl = byte_view_new();
3658 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3659 gtk_widget_show(byte_nb_ptr_gbl);
3661 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3662 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3664 /* Panes for the packet list, tree, and byte view */
3665 main_pane_v1 = gtk_vpaned_new();
3666 gtk_widget_show(main_pane_v1);
3667 main_pane_v2 = gtk_vpaned_new();
3668 gtk_widget_show(main_pane_v2);
3669 main_pane_h1 = gtk_hpaned_new();
3670 gtk_widget_show(main_pane_h1);
3671 main_pane_h2 = gtk_hpaned_new();
3672 gtk_widget_show(main_pane_h2);
3674 airpcap_tb = airpcap_toolbar_new();
3675 gtk_widget_show(airpcap_tb);
3678 statusbar = statusbar_new();
3679 gtk_widget_show(statusbar);
3681 /* Pane for the welcome screen */
3682 welcome_pane = welcome_new();
3683 gtk_widget_show(welcome_pane);
3687 show_main_window(gboolean doing_work)
3689 main_set_for_capture_file(doing_work);
3691 /*** we have finished all init things, show the main window ***/
3692 gtk_widget_show(top_level);
3694 /* the window can be maximized only, if it's visible, so do it after show! */
3695 main_load_window_geometry(top_level);
3697 /* process all pending GUI events before continue */
3698 while (gtk_events_pending()) gtk_main_iteration();
3700 /* Pop up any queued-up alert boxes. */
3701 display_queued_messages();
3703 /* Move the main window to the front, in case it isn't already there */
3704 gdk_window_raise(top_level->window);
3707 airpcap_toolbar_show(airpcap_tb);
3708 #endif /* HAVE_AIRPCAP */
3711 /* Fill in capture options with values from the preferences */
3713 prefs_to_capture_opts(void)
3716 /* Set promiscuous mode from the preferences setting. */
3717 /* the same applies to other preferences settings as well. */
3718 global_capture_opts.promisc_mode = prefs.capture_prom_mode;
3719 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3720 global_capture_opts.show_info = prefs.capture_show_info;
3721 global_capture_opts.real_time_mode = prefs.capture_real_time;
3722 auto_scroll_live = prefs.capture_auto_scroll;
3723 #endif /* HAVE_LIBPCAP */
3725 /* Set the name resolution code's flags from the preferences. */
3726 g_resolv_flags = prefs.name_resolve;
3730 /* Change configuration profile */
3731 void change_configuration_profile (const gchar *profile_name)
3733 char *gdp_path, *dp_path;
3737 /* First check if profile exists */
3738 if (!profile_exists(profile_name)) {
3742 /* Get the current geometry, before writing it to disk */
3743 main_save_window_geometry(top_level);
3745 if (profile_exists(get_profile_name())) {
3746 /* Write recent file for profile we are leaving, if it still exists */
3747 write_profile_recent();
3750 /* Set profile name and update the status bar */
3751 set_profile_name (profile_name);
3752 profile_bar_update ();
3754 /* Reset current preferences and apply the new */
3758 (void) read_configuration_files (&gdp_path, &dp_path);
3760 recent_read_profile_static(&rf_path, &rf_open_errno);
3761 if (rf_path != NULL && rf_open_errno != 0) {
3762 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3763 "Could not open common recent file\n\"%s\": %s.",
3764 rf_path, strerror(rf_open_errno));
3766 if (recent.gui_fileopen_remembered_dir &&
3767 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3768 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3770 timestamp_set_type (recent.gui_time_format);
3771 timestamp_set_seconds_type (recent.gui_seconds_format);
3772 color_filters_enable(recent.packet_list_colorize);
3774 prefs_to_capture_opts();
3776 macros_post_update();
3778 /* Update window view and redraw the toolbar */
3779 update_main_window_title();
3780 toolbar_redraw_all();
3782 /* Enable all protocols and disable from the disabled list */
3784 if (gdp_path == NULL && dp_path == NULL) {
3785 set_disabled_protos_list();
3788 /* Reload color filters */
3789 color_filters_reload();
3791 /* Reload list of interfaces on welcome page */
3792 welcome_if_panel_reload();
3794 /* Recreate the packet list according to new preferences */
3795 #ifdef NEW_PACKET_LIST
3796 new_packet_list_recreate ();
3798 packet_list_recreate ();
3800 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3803 /* Update menus with new recent values */
3804 menu_recent_read_finished();
3806 /* Reload pane geometry, must be done after recreating the list */
3807 main_pane_load_window_geometry();
3810 /** redissect packets and update UI */
3811 void redissect_packets(void)
3813 cf_redissect_packets(&cfile);
3814 status_expert_update();