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 (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
607 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
608 /* leak a little but safer than ep_ here */
609 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
610 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
611 if (hfi->parent == -1) {
613 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
614 } else if (hfi->type == FT_STRING) {
615 /* Custom string, add quotes */
616 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
617 cfile.cinfo.col_expr.col_expr_val[column]);
621 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
622 cfile.cinfo.col_expr.col_expr_val[column]);
626 epan_dissect_cleanup(&edt);
633 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
635 match_selected_cb_do(data,
637 get_filter_from_packet_list_row_and_column(data));
640 /* This function allows users to right click in the details window and copy the text
641 * information to the operating systems clipboard.
643 * We first check to see if a string representation is setup in the tree and then
644 * read the string. If not available then we try to grab the value. If all else
645 * fails we display a message to the user to indicate the copy could not be completed.
648 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
650 GString *gtk_text_str = g_string_new("");
651 char labelstring[256];
652 char *stringpointer = labelstring;
656 case COPY_SELECTED_DESCRIPTION:
657 if (cfile.finfo_selected->rep->representation != 0) {
658 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
661 case COPY_SELECTED_FIELDNAME:
662 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
663 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
666 case COPY_SELECTED_VALUE:
667 if (cfile.edt !=0 ) {
668 g_string_append(gtk_text_str,
669 get_node_field_value(cfile.finfo_selected, cfile.edt));
676 if (gtk_text_str->len == 0) {
677 /* If no representation then... Try to read the value */
678 proto_item_fill_label(cfile.finfo_selected, stringpointer);
679 g_string_append(gtk_text_str, stringpointer);
682 if (gtk_text_str->len == 0) {
683 /* Could not get item so display error msg */
684 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
686 /* Copy string to clipboard */
687 copy_to_clipboard(gtk_text_str);
689 g_string_free(gtk_text_str, TRUE); /* Free the memory */
693 /* mark as reference time frame */
695 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
699 frame->flags.ref_time=1;
700 cfile.ref_time_count++;
702 frame->flags.ref_time=0;
703 cfile.ref_time_count--;
705 cf_reftime_packets(&cfile);
706 #ifdef NEW_PACKET_LIST
707 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
708 new_packet_list_freeze();
709 cfile.displayed_count--;
710 new_packet_list_recreate_visible_rows();
711 new_packet_list_thaw();
713 new_packet_list_queue_draw();
718 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
722 timestamp_set_type(TS_RELATIVE);
723 recent.gui_time_format = TS_RELATIVE;
724 #ifdef NEW_PACKET_LIST
725 cf_timestamp_auto_precision(&cfile);
726 new_packet_list_queue_draw();
728 cf_change_time_formats(&cfile);
734 g_assert_not_reached();
737 if (cfile.current_frame) {
738 set_frame_reftime(!cfile.current_frame->flags.ref_time,
739 cfile.current_frame, cfile.current_row);
745 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
747 static GtkWidget *reftime_dialog = NULL;
751 if (cfile.current_frame) {
752 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
753 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
754 "%sSwitch to the appropriate Time Display Format?%s\n\n"
755 "Time References don't work well with the currently selected Time Display Format.\n\n"
756 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
757 simple_dialog_primary_start(), simple_dialog_primary_end());
758 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
760 set_frame_reftime(!cfile.current_frame->flags.ref_time,
761 cfile.current_frame, cfile.current_row);
765 case REFTIME_FIND_NEXT:
766 cf_find_packet_time_reference(&cfile, SD_FORWARD);
768 case REFTIME_FIND_PREV:
769 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
775 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
777 cf_find_packet_marked(&cfile, SD_FORWARD);
781 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
783 cf_find_packet_marked(&cfile, SD_BACKWARD);
787 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
790 gchar *help_str = NULL;
791 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
793 gboolean has_blurb = FALSE;
794 guint length = 0, byte_len;
795 GtkWidget *byte_view;
796 const guint8 *byte_data;
801 /* if nothing is selected */
802 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
805 * Which byte view is displaying the current protocol tree
808 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
809 if (byte_view == NULL)
812 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
813 if (byte_data == NULL)
816 cf_unselect_field(&cfile);
817 packet_hex_print(byte_view, byte_data,
818 cfile.current_frame, NULL, byte_len);
819 proto_help_menu_modify(sel, &cfile);
822 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
825 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
827 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
828 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
829 g_assert(byte_data != NULL);
831 cfile.finfo_selected = finfo;
832 set_menus_for_selected_tree_row(&cfile);
835 if (finfo->hfinfo->blurb != NULL &&
836 finfo->hfinfo->blurb[0] != '\0') {
838 length = (guint) strlen(finfo->hfinfo->blurb);
840 length = (guint) strlen(finfo->hfinfo->name);
842 finfo_length = finfo->length + finfo->appendix_length;
844 if (finfo_length == 0) {
846 } else if (finfo_length == 1) {
847 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
849 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
851 statusbar_pop_field_msg(); /* get rid of current help msg */
853 help_str = g_strdup_printf(" %s (%s)%s",
854 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
855 finfo->hfinfo->abbrev, len_str);
856 statusbar_push_field_msg(help_str);
860 * Don't show anything if the field name is zero-length;
861 * the pseudo-field for "proto_tree_add_text()" is such
862 * a field, and we don't want "Text (text)" showing up
863 * on the status line if you've selected such a field.
865 * XXX - there are zero-length fields for which we *do*
866 * want to show the field name.
868 * XXX - perhaps the name and abbrev field should be null
869 * pointers rather than null strings for that pseudo-field,
870 * but we'd have to add checks for null pointers in some
871 * places if we did that.
873 * Or perhaps protocol tree items added with
874 * "proto_tree_add_text()" should have -1 as the field index,
875 * with no pseudo-field being used, but that might also
876 * require special checks for -1 to be added.
878 statusbar_push_field_msg("");
881 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
883 proto_help_menu_modify(sel, &cfile);
886 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
888 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
891 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
893 expand_all_tree(cfile.edt->tree, tree_view_gbl);
896 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
898 if (cfile.finfo_selected) {
899 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
900 cfile.finfo_selected->hfinfo->abbrev);
901 /* Recreate the packet list according to new preferences */
902 #ifdef NEW_PACKET_LIST
903 new_packet_list_recreate ();
905 packet_list_recreate ();
907 if (!prefs.gui_use_pref_save) {
910 cfile.cinfo.columns_changed = FALSE; /* Reset value */
914 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
917 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
919 /* the mouse position is at an entry, expand that one */
920 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
921 gtk_tree_path_free(path);
925 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
926 if (cfile.edt->tree) {
927 guint32 tmp = g_resolv_flags;
928 g_resolv_flags = RESOLV_ALL;
929 proto_tree_draw(cfile.edt->tree, tree_view_gbl);
930 g_resolv_flags = tmp;
935 main_set_for_capture_file(gboolean have_capture_file_in)
937 have_capture_file = have_capture_file_in;
939 main_widgets_show_or_hide();
945 /* get the current geometry, before writing it to disk */
946 main_save_window_geometry(top_level);
948 /* write user's recent file to disk
949 * It is no problem to write this file, even if we do not quit */
950 write_profile_recent();
953 /* XXX - should we check whether the capture file is an
954 unsaved temporary file for a live capture and, if so,
955 pop up a "do you want to exit without saving the capture
956 file?" dialog, and then just return, leaving said dialog
957 box to forcibly quit if the user clicks "OK"?
959 If so, note that this should be done in a subroutine that
960 returns TRUE if we do so, and FALSE otherwise, and if it
961 returns TRUE we should return TRUE without nuking anything.
963 Note that, if we do that, we might also want to check if
964 an "Update list of packets in real time" capture is in
965 progress and, if so, ask whether they want to terminate
966 the capture and discard it, and return TRUE, before nuking
967 any child capture, if they say they don't want to do so. */
970 /* Nuke any child capture in progress. */
971 capture_kill_child(&global_capture_opts);
974 /* Are we in the middle of reading a capture? */
975 if (cfile.state == FILE_READ_IN_PROGRESS) {
976 /* Yes, so we can't just close the file and quit, as
977 that may yank the rug out from under the read in
978 progress; instead, just set the state to
979 "FILE_READ_ABORTED" and return - the code doing the read
980 will check for that and, if it sees that, will clean
982 cfile.state = FILE_READ_ABORTED;
984 /* Say that the window should *not* be deleted;
985 that'll be done by the code that cleans up. */
988 /* Close any capture file we have open; on some OSes, you
989 can't unlink a temporary capture file if you have it
991 "cf_close()" will unlink it after closing it if
992 it's a temporary file.
994 We do this here, rather than after the main loop returns,
995 as, after the main loop returns, the main window may have
996 been destroyed (if this is called due to a "destroy"
997 even on the main window rather than due to the user
998 selecting a menu item), and there may be a crash
999 or other problem when "cf_close()" tries to
1000 clean up stuff in the main window.
1002 XXX - is there a better place to put this?
1003 Or should we have a routine that *just* closes the
1004 capture file, and doesn't do anything with the UI,
1005 which we'd call here, and another routine that
1006 calls that routine and also cleans up the UI, which
1007 we'd call elsewhere? */
1010 /* Exit by leaving the main loop, so that any quit functions
1011 we registered get called. */
1014 /* Say that the window should be deleted. */
1020 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1024 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1025 gtk_window_present(GTK_WINDOW(top_level));
1026 /* user didn't saved his current file, ask him */
1027 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1028 "%sSave capture file before program quit?%s\n\n"
1029 "If you quit the program without saving, your capture data will be discarded.",
1030 simple_dialog_primary_start(), simple_dialog_primary_end());
1031 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1034 /* unchanged file, just exit */
1035 /* "main_do_quit()" indicates whether the main window should be deleted. */
1036 return main_do_quit();
1042 main_pane_load_window_geometry(void)
1044 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1045 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1046 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1047 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1053 main_load_window_geometry(GtkWidget *widget)
1055 window_geometry_t geom;
1057 geom.set_pos = prefs.gui_geometry_save_position;
1058 geom.x = recent.gui_geometry_main_x;
1059 geom.y = recent.gui_geometry_main_y;
1060 geom.set_size = prefs.gui_geometry_save_size;
1061 if (recent.gui_geometry_main_width > 0 &&
1062 recent.gui_geometry_main_height > 0) {
1063 geom.width = recent.gui_geometry_main_width;
1064 geom.height = recent.gui_geometry_main_height;
1065 geom.set_maximized = prefs.gui_geometry_save_maximized;
1067 /* We assume this means the width and height weren't set in
1068 the "recent" file (or that there is no "recent" file),
1069 and weren't set to a default value, so we don't set the
1070 size. (The "recent" file code rejects non-positive width
1071 and height values.) */
1072 geom.set_size = FALSE;
1074 geom.maximized = recent.gui_geometry_main_maximized;
1076 window_set_geometry(widget, &geom);
1078 main_pane_load_window_geometry();
1079 statusbar_load_window_geometry();
1084 main_save_window_geometry(GtkWidget *widget)
1086 window_geometry_t geom;
1088 window_get_geometry(widget, &geom);
1090 if (prefs.gui_geometry_save_position) {
1091 recent.gui_geometry_main_x = geom.x;
1092 recent.gui_geometry_main_y = geom.y;
1095 if (prefs.gui_geometry_save_size) {
1096 recent.gui_geometry_main_width = geom.width;
1097 recent.gui_geometry_main_height = geom.height;
1100 if(prefs.gui_geometry_save_maximized) {
1101 recent.gui_geometry_main_maximized = geom.maximized;
1104 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1105 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1106 statusbar_save_window_geometry();
1109 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1113 /* save file first */
1114 file_save_as_cmd(after_save_exit, NULL);
1116 case(ESD_BTN_QUIT_DONT_SAVE):
1119 case(ESD_BTN_CANCEL):
1122 g_assert_not_reached();
1127 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1131 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1132 /* user didn't saved his current file, ask him */
1133 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1134 "%sSave capture file before program quit?%s\n\n"
1135 "If you quit the program without saving, your capture data will be discarded.",
1136 simple_dialog_primary_start(), simple_dialog_primary_end());
1137 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1139 /* unchanged file, just exit */
1145 print_usage(gboolean print_ver) {
1155 fprintf(output, "Wireshark " VERSION "%s\n"
1156 "Interactively dump and analyze network traffic.\n"
1157 "See http://www.wireshark.org for more information.\n"
1160 wireshark_svnversion, get_copyright_info());
1164 fprintf(output, "\n");
1165 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1166 fprintf(output, "\n");
1169 fprintf(output, "Capture interface:\n");
1170 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1171 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1172 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1173 fprintf(output, " -p don't capture in promiscuous mode\n");
1174 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1175 fprintf(output, " -Q quit Wireshark after capturing\n");
1176 fprintf(output, " -S update packet display when new packets are captured\n");
1177 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1178 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1179 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1181 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1182 fprintf(output, " -D print list of interfaces and exit\n");
1183 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1184 fprintf(output, "\n");
1185 fprintf(output, "Capture stop conditions:\n");
1186 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1187 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1188 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1189 fprintf(output, " files:NUM - stop after NUM files\n");
1190 /*fprintf(output, "\n");*/
1191 fprintf(output, "Capture output:\n");
1192 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1193 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1194 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1195 #endif /* HAVE_LIBPCAP */
1197 /*fprintf(output, "\n");*/
1198 fprintf(output, "Input file:\n");
1199 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1201 fprintf(output, "\n");
1202 fprintf(output, "Processing:\n");
1203 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1204 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1205 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1207 fprintf(output, "\n");
1208 fprintf(output, "User interface:\n");
1209 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1210 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1211 fprintf(output, " -J <jump filter> jump to the first packet matching the (display) filter\n");
1212 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1213 fprintf(output, " -m <font> set the font name used for most text\n");
1214 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1215 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1216 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1217 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1219 fprintf(output, "\n");
1220 fprintf(output, "Output:\n");
1221 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1223 fprintf(output, "\n");
1224 fprintf(output, "Miscellaneous:\n");
1225 fprintf(output, " -h display this help and exit\n");
1226 fprintf(output, " -v display version info and exit\n");
1227 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1228 fprintf(output, " persdata:path - personal data files\n");
1229 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1230 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1232 fprintf(output, " --display=DISPLAY X display to use\n");
1247 printf(PACKAGE " " VERSION "%s\n"
1254 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1255 runtime_info_str->str);
1263 * Print to the standard error. On Windows, create a console for the
1264 * standard error to show up on, if necessary.
1265 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1266 * terminal isn't the standard error?
1269 vfprintf_stderr(const char *fmt, va_list ap)
1274 vfprintf(stderr, fmt, ap);
1278 fprintf_stderr(const char *fmt, ...)
1283 vfprintf_stderr(fmt, ap);
1288 * Report an error in command-line arguments.
1289 * Creates a console on Windows.
1292 cmdarg_err(const char *fmt, ...)
1296 fprintf_stderr("wireshark: ");
1298 vfprintf_stderr(fmt, ap);
1300 fprintf_stderr("\n");
1304 * Report additional information for an error in command-line arguments.
1305 * Creates a console on Windows.
1306 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1307 * terminal isn't the standard error?
1310 cmdarg_err_cont(const char *fmt, ...)
1315 vfprintf_stderr(fmt, ap);
1316 fprintf_stderr("\n");
1320 #if defined(_WIN32) || ! defined USE_THREADS
1322 Once every 3 seconds we get a callback here which we use to update
1323 the tap extensions. Since Gtk1 is single threaded we dont have to
1324 worry about any locking or critical regions.
1327 tap_update_cb(gpointer data _U_)
1329 draw_tap_listeners(FALSE);
1333 /* Restart the tap update display timer with new configured interval */
1334 void reset_tap_update_timer(void)
1336 g_source_remove(tap_update_timer_id);
1337 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1342 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1343 use threads all update_thread_mutex can be dropped and protect/unprotect
1344 would just be empty functions.
1346 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1347 gtk1-wireshark and it will just work.
1349 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1351 update_thread(gpointer data _U_)
1355 g_get_current_time(&tv1);
1356 g_static_mutex_lock(&update_thread_mutex);
1357 gdk_threads_enter();
1358 draw_tap_listeners(FALSE);
1359 gdk_threads_leave();
1360 g_static_mutex_unlock(&update_thread_mutex);
1362 g_get_current_time(&tv2);
1364 /* Assuming it took less than configured time to update tap listeners... */
1365 if( (tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) >
1366 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1367 /* Wait for remainder of configured time */
1368 g_usleep((tv1.tv_sec * 1000000 + tv1.tv_usec + prefs.tap_update_interval * 1000) -
1369 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1376 protect_thread_critical_region(void)
1378 #if !defined(_WIN32) && defined USE_THREADS
1379 g_static_mutex_lock(&update_thread_mutex);
1383 unprotect_thread_critical_region(void)
1385 #if !defined(_WIN32) && defined USE_THREADS
1386 g_static_mutex_unlock(&update_thread_mutex);
1391 * Periodically process outstanding hostname lookups. If we have new items,
1392 * redraw the packet list and tree view.
1396 resolv_update_cb(gpointer data _U_)
1398 /* Anything new show up? */
1399 if (host_name_lookup_process(NULL)) {
1400 if (pkt_scrollw->window)
1401 gdk_window_invalidate_rect(pkt_scrollw->window, NULL, TRUE);
1402 if (tv_scrollw->window)
1403 gdk_window_invalidate_rect(tv_scrollw->window, NULL, TRUE);
1406 /* Always check. Even if we don't do async lookups we could still get
1407 passive updates, e.g. from DNS packets. */
1412 /* Set main_window_name and it's icon title to the capture filename */
1414 set_display_filename(capture_file *cf)
1419 window_name = g_strdup_printf("%s", cf_get_display_name(cf));
1420 set_main_window_name(window_name);
1421 g_free(window_name);
1423 set_main_window_name("The Wireshark Network Analyzer");
1427 GtkWidget *close_dlg = NULL;
1430 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1432 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1437 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1439 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1444 main_cf_cb_file_closing(capture_file *cf)
1447 /* if we have more than 10000 packets, show a splash screen while closing */
1448 /* XXX - don't know a better way to decide whether to show or not,
1449 * as most of the time is spend in a single eth_clist_clear function,
1450 * so we can't use a progress bar here! */
1451 if(cf->count > 10000) {
1452 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1453 "%sClosing file!%s\n\nPlease wait ...",
1454 simple_dialog_primary_start(),
1455 simple_dialog_primary_end());
1456 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1459 /* Destroy all windows, which refer to the
1460 capture file we're closing. */
1461 destroy_packet_wins();
1462 file_save_as_destroy();
1464 /* Restore the standard title bar message. */
1465 set_main_window_name("The Wireshark Network Analyzer");
1467 /* Disable all menu items that make sense only if you have a capture. */
1468 set_menus_for_capture_file(NULL);
1469 set_menus_for_captured_packets(FALSE);
1470 set_menus_for_selected_packet(cf);
1471 set_menus_for_capture_in_progress(FALSE);
1472 set_capture_if_dialog_for_capture_in_progress(FALSE);
1473 set_menus_for_selected_tree_row(cf);
1475 /* Set up main window for no capture file. */
1476 main_set_for_capture_file(FALSE);
1478 main_window_update();
1482 main_cf_cb_file_closed(capture_file *cf _U_)
1484 if(close_dlg != NULL) {
1485 splash_destroy(close_dlg);
1492 main_cf_cb_file_read_started(capture_file *cf _U_)
1494 tap_dfilter_dlg_update();
1496 /* Set up main window for a capture file. */
1497 main_set_for_capture_file(TRUE);
1501 main_cf_cb_file_read_finished(capture_file *cf)
1505 if (!cf->is_tempfile && cf->filename) {
1506 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1507 add_menu_recent_capture_file(cf->filename);
1509 /* Remember folder for next Open dialog and save it in recent */
1510 dir_path = get_dirname(g_strdup(cf->filename));
1511 set_last_open_dir(dir_path);
1514 set_display_filename(cf);
1516 /* Enable menu items that make sense if you have a capture file you've
1517 finished reading. */
1518 set_menus_for_capture_file(cf);
1520 /* Enable menu items that make sense if you have some captured packets. */
1521 set_menus_for_captured_packets(TRUE);
1525 static GList *icon_list_create(
1526 const char **icon16_xpm,
1527 const char **icon32_xpm,
1528 const char **icon48_xpm,
1529 const char **icon64_xpm)
1531 GList *icon_list = NULL;
1532 GdkPixbuf * pixbuf16;
1533 GdkPixbuf * pixbuf32;
1534 GdkPixbuf * pixbuf48;
1535 GdkPixbuf * pixbuf64;
1538 if(icon16_xpm != NULL) {
1539 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1541 icon_list = g_list_append(icon_list, pixbuf16);
1544 if(icon32_xpm != NULL) {
1545 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1547 icon_list = g_list_append(icon_list, pixbuf32);
1550 if(icon48_xpm != NULL) {
1551 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1553 icon_list = g_list_append(icon_list, pixbuf48);
1556 if(icon64_xpm != NULL) {
1557 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1559 icon_list = g_list_append(icon_list, pixbuf64);
1566 main_capture_set_main_window_title(capture_options *capture_opts)
1568 GString *title = g_string_new("");
1570 g_string_append(title, "Capturing ");
1571 if(capture_opts->iface) {
1572 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1574 set_main_window_name(title->str);
1575 g_string_free(title, TRUE);
1579 main_capture_cb_capture_prepared(capture_options *capture_opts)
1581 static GList *icon_list = NULL;
1583 main_capture_set_main_window_title(capture_opts);
1585 if(icon_list == NULL) {
1586 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1588 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1590 /* Disable menu items that make no sense if you're currently running
1592 set_menus_for_capture_in_progress(TRUE);
1593 set_capture_if_dialog_for_capture_in_progress(TRUE);
1595 /* Don't set up main window for a capture file. */
1596 main_set_for_capture_file(FALSE);
1600 main_capture_cb_capture_update_started(capture_options *capture_opts)
1602 /* We've done this in "prepared" above, but it will be cleared while
1603 switching to the next multiple file. */
1604 main_capture_set_main_window_title(capture_opts);
1606 set_menus_for_capture_in_progress(TRUE);
1607 set_capture_if_dialog_for_capture_in_progress(TRUE);
1609 /* Enable menu items that make sense if you have some captured
1610 packets (yes, I know, we don't have any *yet*). */
1611 set_menus_for_captured_packets(TRUE);
1613 /* Set up main window for a capture file. */
1614 main_set_for_capture_file(TRUE);
1618 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1620 capture_file *cf = capture_opts->cf;
1621 static GList *icon_list = NULL;
1623 if (!cf->is_tempfile && cf->filename) {
1624 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1625 add_menu_recent_capture_file(cf->filename);
1627 set_display_filename(cf);
1629 /* Enable menu items that make sense if you're not currently running
1631 set_menus_for_capture_in_progress(FALSE);
1632 set_capture_if_dialog_for_capture_in_progress(FALSE);
1634 /* Enable menu items that make sense if you have a capture file
1635 you've finished reading. */
1636 set_menus_for_capture_file(cf);
1638 /* Set up main window for a capture file. */
1639 main_set_for_capture_file(TRUE);
1641 if(icon_list == NULL) {
1642 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1644 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1646 if(global_capture_opts.quit_after_cap) {
1647 /* command line asked us to quit after the capture */
1648 /* don't pop up a dialog to ask for unsaved files etc. */
1654 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1656 /* Don't set up main window for a capture file. */
1657 main_set_for_capture_file(FALSE);
1661 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1664 capture_file *cf = capture_opts->cf;
1666 static GList *icon_list = NULL;
1668 /*set_display_filename(cf);*/
1670 /* Enable menu items that make sense if you're not currently running
1672 set_menus_for_capture_in_progress(FALSE);
1673 set_capture_if_dialog_for_capture_in_progress(FALSE);
1675 /* Restore the standard title bar message */
1676 /* (just in case we have trouble opening the capture file). */
1677 set_main_window_name("The Wireshark Network Analyzer");
1679 if(icon_list == NULL) {
1680 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1682 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1684 /* We don't have loaded the capture file, this will be done later.
1685 * For now we still have simply a blank screen. */
1687 if(global_capture_opts.quit_after_cap) {
1688 /* command line asked us to quit after the capture */
1689 /* don't pop up a dialog to ask for unsaved files etc. */
1694 #endif /* HAVE_LIBPCAP */
1697 main_cf_cb_packet_selected(gpointer data)
1699 capture_file *cf = data;
1701 /* Display the GUI protocol tree and packet bytes.
1702 XXX - why do we dump core if we call "proto_tree_draw()"
1703 before calling "add_byte_views()"? */
1704 add_main_byte_views(cf->edt);
1705 main_proto_tree_draw(cf->edt->tree);
1707 /* The user is searching for a string in the data or a hex value,
1708 * highlight the field that is found in the tree and hex displays. */
1709 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1710 highlight_field(cf->edt->tvb, cfile.search_pos,
1711 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1712 cfile.search_pos = 0; /* Reset the position */
1715 /* A packet is selected. */
1716 set_menus_for_selected_packet(cf);
1720 main_cf_cb_packet_unselected(capture_file *cf)
1722 /* Clear out the display of that packet. */
1723 clear_tree_and_hex_views();
1725 /* No packet is selected. */
1726 set_menus_for_selected_packet(cf);
1730 main_cf_cb_field_unselected(capture_file *cf)
1732 set_menus_for_selected_tree_row(cf);
1736 main_cf_cb_file_save_reload_finished(gpointer data _U_)
1738 set_display_filename(&cfile);
1739 set_menus_for_capture_file(&cfile);
1743 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1746 case(cf_cb_file_closing):
1747 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1748 main_cf_cb_file_closing(data);
1750 case(cf_cb_file_closed):
1751 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1752 main_cf_cb_file_closed(data);
1754 case(cf_cb_file_read_started):
1755 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1756 main_cf_cb_file_read_started(data);
1758 case(cf_cb_file_read_finished):
1759 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1760 main_cf_cb_file_read_finished(data);
1762 case(cf_cb_packet_selected):
1763 main_cf_cb_packet_selected(data);
1765 case(cf_cb_packet_unselected):
1766 main_cf_cb_packet_unselected(data);
1768 case(cf_cb_field_unselected):
1769 main_cf_cb_field_unselected(data);
1771 case(cf_cb_file_save_started):
1772 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1774 case(cf_cb_file_save_finished):
1775 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1777 case(cf_cb_file_save_reload_finished):
1778 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1779 main_cf_cb_file_save_reload_finished(data);
1781 case(cf_cb_file_save_failed):
1782 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1785 g_warning("main_cf_callback: event %u unknown", event);
1786 g_assert_not_reached();
1792 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1794 #ifdef HAVE_GTKOSXAPPLICATION
1795 GtkOSXApplication *theApp;
1798 case(capture_cb_capture_prepared):
1799 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1800 main_capture_cb_capture_prepared(capture_opts);
1802 case(capture_cb_capture_update_started):
1803 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1804 main_capture_cb_capture_update_started(capture_opts);
1805 #ifdef HAVE_GTKOSXAPPLICATION
1806 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1807 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1810 case(capture_cb_capture_update_continue):
1811 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1813 case(capture_cb_capture_update_finished):
1814 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1815 main_capture_cb_capture_update_finished(capture_opts);
1817 case(capture_cb_capture_fixed_started):
1818 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1819 main_capture_cb_capture_fixed_started(capture_opts);
1821 case(capture_cb_capture_fixed_continue):
1822 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1824 case(capture_cb_capture_fixed_finished):
1825 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1826 main_capture_cb_capture_fixed_finished(capture_opts);
1828 case(capture_cb_capture_stopping):
1829 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1830 /* Beware: this state won't be called, if the capture child
1831 * closes the capturing on it's own! */
1832 #ifdef HAVE_GTKOSXAPPLICATION
1833 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1834 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1838 g_warning("main_capture_callback: event %u unknown", event);
1839 g_assert_not_reached();
1845 get_gui_compiled_info(GString *str)
1847 epan_get_compiled_version_info(str);
1849 g_string_append(str, ", ");
1850 #ifdef HAVE_LIBPORTAUDIO
1851 #ifdef PORTAUDIO_API_1
1852 g_string_append(str, "with PortAudio <= V18");
1853 #else /* PORTAUDIO_API_1 */
1854 g_string_append(str, "with ");
1855 g_string_append(str, Pa_GetVersionText());
1856 #endif /* PORTAUDIO_API_1 */
1857 #else /* HAVE_LIBPORTAUDIO */
1858 g_string_append(str, "without PortAudio");
1859 #endif /* HAVE_LIBPORTAUDIO */
1861 g_string_append(str, ", ");
1863 get_compiled_airpcap_version(str);
1865 g_string_append(str, "without AirPcap");
1867 #ifndef NEW_PACKET_LIST
1868 g_string_append(str, ", with old_packet_list");
1873 get_gui_runtime_info(GString *str)
1875 epan_get_runtime_version_info(str);
1878 g_string_append(str, ", ");
1879 get_runtime_airpcap_version(str);
1883 g_string_append(str, ", ");
1884 u3_runtime_info(str);
1889 read_configuration_files(char **gdp_path, char **dp_path)
1891 int gpf_open_errno, gpf_read_errno;
1892 int cf_open_errno, df_open_errno;
1893 int gdp_open_errno, gdp_read_errno;
1894 int dp_open_errno, dp_read_errno;
1895 char *gpf_path, *pf_path;
1896 char *cf_path, *df_path;
1897 int pf_open_errno, pf_read_errno;
1900 /* Read the preference files. */
1901 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1902 &pf_open_errno, &pf_read_errno, &pf_path);
1904 if (gpf_path != NULL) {
1905 if (gpf_open_errno != 0) {
1906 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1907 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1908 strerror(gpf_open_errno));
1910 if (gpf_read_errno != 0) {
1911 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1912 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1913 strerror(gpf_read_errno));
1916 if (pf_path != NULL) {
1917 if (pf_open_errno != 0) {
1918 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1919 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1920 strerror(pf_open_errno));
1922 if (pf_read_errno != 0) {
1923 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1924 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1925 strerror(pf_read_errno));
1932 /* if the user wants a console to be always there, well, we should open one for him */
1933 if (prefs_p->gui_console_open == console_open_always) {
1938 /* Read the capture filter file. */
1939 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1940 if (cf_path != NULL) {
1941 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1942 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1943 strerror(cf_open_errno));
1947 /* Read the display filter file. */
1948 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1949 if (df_path != NULL) {
1950 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1951 "Could not open your display filter file\n\"%s\": %s.", df_path,
1952 strerror(df_open_errno));
1956 /* Read the disabled protocols file. */
1957 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1958 dp_path, &dp_open_errno, &dp_read_errno);
1959 if (*gdp_path != NULL) {
1960 if (gdp_open_errno != 0) {
1961 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1962 "Could not open global disabled protocols file\n\"%s\": %s.",
1963 *gdp_path, strerror(gdp_open_errno));
1965 if (gdp_read_errno != 0) {
1966 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1967 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1968 *gdp_path, strerror(gdp_read_errno));
1973 if (*dp_path != NULL) {
1974 if (dp_open_errno != 0) {
1975 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1976 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1977 strerror(dp_open_errno));
1979 if (dp_read_errno != 0) {
1980 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1981 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1982 strerror(dp_read_errno));
1991 /* Check if there's something important to tell the user during startup.
1992 * We want to do this *after* showing the main window so that any windows
1993 * we pop up will be above the main window.
1997 check_and_warn_user_startup(gchar *cf_name)
1999 check_and_warn_user_startup(gchar *cf_name _U_)
2002 gchar *cur_user, *cur_group;
2003 gpointer priv_warning_dialog;
2005 /* Tell the user not to run as root. */
2006 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2007 cur_user = get_cur_username();
2008 cur_group = get_cur_groupname();
2009 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2010 "Running as user \"%s\" and group \"%s\".\n"
2011 "This could be dangerous.", cur_user, cur_group);
2014 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2015 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2019 /* Warn the user if npf.sys isn't loaded. */
2020 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2021 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2022 "The NPF driver isn't running. You may have trouble\n"
2023 "capturing or listing interfaces.");
2024 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2025 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2032 /* And now our feature presentation... [ fade to music ] */
2034 main(int argc, char *argv[])
2036 char *init_progfile_dir_error;
2039 gboolean arg_error = FALSE;
2041 extern int info_update_freq; /* Found in about_dlg.c. */
2042 const gchar *filter;
2052 char *gdp_path, *dp_path;
2055 gboolean start_capture = FALSE;
2056 gboolean list_link_layer_types = FALSE;
2060 gboolean capture_option_specified = FALSE;
2067 gint pl_size = 280, tv_size = 95, bv_size = 75;
2068 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *jfilter = NULL;
2069 dfilter_t *rfcode = NULL;
2070 gboolean rfilter_parse_failed = FALSE;
2073 GtkWidget *splash_win = NULL;
2074 GLogLevelFlags log_flags;
2075 guint go_to_packet = 0;
2076 gboolean jump_backwards = FALSE;
2077 dfilter_t *jump_to_filter = NULL;
2080 #ifdef HAVE_GTKOSXAPPLICATION
2081 GtkOSXApplication *theApp;
2085 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2086 #define OPTSTRING_B "B:"
2088 #define OPTSTRING_B ""
2089 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2090 #else /* HAVE_LIBPCAP */
2091 #define OPTSTRING_B ""
2092 #endif /* HAVE_LIBPCAP */
2094 #ifdef HAVE_PCAP_CREATE
2095 #define OPTSTRING_I "I"
2097 #define OPTSTRING_I ""
2100 #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:"
2102 static const char optstring[] = OPTSTRING;
2105 /* Convert our arg list to UTF-8. */
2106 wc_argv = CommandLineToArgvW(GetCommandLineW(), &wc_argc);
2107 if (wc_argv && wc_argc == argc) {
2108 for (i = 0; i < argc; i++) {
2109 argv[i] = g_strdup(utf_16to8(wc_argv[i]));
2111 } /* XXX else bail because something is horribly, horribly wrong? */
2115 * Get credential information for later use, and drop privileges
2116 * before doing anything else.
2117 * Let the user know if anything happened.
2119 get_credential_info();
2120 relinquish_special_privs_perm();
2123 * Attempt to get the pathname of the executable file.
2125 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2127 /* initialize the funnel mini-api */
2128 initialize_funnel_ops();
2130 #ifdef HAVE_AIRPDCAP
2131 AirPDcapInitContext(&airpdcap_ctx);
2135 /* Load wpcap if possible. Do this before collecting the run-time version information */
2138 /* ... and also load the packet.dll from wpcap */
2139 wpcap_packet_load();
2142 /* Load the airpcap.dll. This must also be done before collecting
2143 * run-time version information. */
2144 airpcap_dll_ret_val = load_airpcap();
2146 switch (airpcap_dll_ret_val) {
2147 case AIRPCAP_DLL_OK:
2148 /* load the airpcap interfaces */
2149 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2151 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2152 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2153 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2156 airpcap_if_active = NULL;
2160 /* select the first ad default (THIS SHOULD BE CHANGED) */
2161 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2166 * XXX - Maybe we need to warn the user if one of the following happens???
2168 case AIRPCAP_DLL_OLD:
2169 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2172 case AIRPCAP_DLL_ERROR:
2173 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2176 case AIRPCAP_DLL_NOT_FOUND:
2177 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2181 #endif /* HAVE_AIRPCAP */
2183 /* Start windows sockets */
2184 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2187 profile_store_persconffiles (TRUE);
2189 /* Assemble the compile-time version information string */
2190 comp_info_str = g_string_new("Compiled ");
2192 g_string_append(comp_info_str, "with ");
2193 g_string_append_printf(comp_info_str,
2194 #ifdef GTK_MAJOR_VERSION
2195 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
2198 "GTK+ (version unknown)");
2200 g_string_append(comp_info_str, ", ");
2202 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
2204 /* Assemble the run-time version information string */
2205 runtime_info_str = g_string_new("Running ");
2206 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2208 /* Read the profile independent recent file. We have to do this here so we can */
2209 /* set the profile before it can be set from the command line parameterts */
2210 recent_read_static(&rf_path, &rf_open_errno);
2211 if (rf_path != NULL && rf_open_errno != 0) {
2212 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2213 "Could not open common recent file\n\"%s\": %s.",
2214 rf_path, strerror(rf_open_errno));
2217 /* "pre-scan" the command line parameters, if we have "console only"
2218 parameters. We do this so we don't start GTK+ if we're only showing
2219 command-line help or version information.
2221 XXX - this pre-scan is done before we start GTK+, so we haven't
2222 run gtk_init() on the arguments. That means that GTK+ arguments
2223 have not been removed from the argument list; those arguments
2224 begin with "--", and will be treated as an error by getopt().
2226 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2229 optind_initial = optind;
2230 while ((opt = getopt(argc, argv, optstring)) != -1) {
2232 case 'C': /* Configuration Profile */
2233 if (profile_exists (optarg)) {
2234 set_profile_name (optarg);
2236 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2240 case 'h': /* Print help and exit */
2246 if (strcmp(optarg, "-") == 0)
2247 stdin_capture = TRUE;
2250 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2251 status = filesystem_opt(opt, optarg);
2253 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2257 case 'v': /* Show version and exit */
2263 * Extension command line options have to be processed before
2264 * we call epan_init() as they are supposed to be used by dissectors
2265 * or taps very early in the registration process.
2269 case '?': /* Ignore errors - the "real" scan will catch them. */
2274 /* Init the "Open file" dialog directory */
2275 /* (do this after the path settings are processed) */
2277 /* Read the profile dependent (static part) of the recent file. */
2278 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2279 /* recent lists which is done in the dynamic part. */
2280 /* We have to do this already here, so command line parameters can overwrite these values. */
2281 recent_read_profile_static(&rf_path, &rf_open_errno);
2282 if (rf_path != NULL && rf_open_errno != 0) {
2283 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2284 "Could not open recent file\n\"%s\": %s.",
2285 rf_path, strerror(rf_open_errno));
2288 if (recent.gui_fileopen_remembered_dir &&
2289 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2290 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2292 set_last_open_dir(get_persdatafile_dir());
2295 /* Set getopt index back to initial value, so it will start with the
2296 first command line parameter again. Also reset opterr to 1, so that
2297 error messages are printed by getopt().
2299 XXX - this seems to work on most platforms, but time will tell.
2300 The Single UNIX Specification says "The getopt() function need
2301 not be reentrant", so this isn't guaranteed to work. The Mac
2302 OS X 10.4[.x] getopt() man page says
2304 In order to use getopt() to evaluate multiple sets of arguments, or to
2305 evaluate a single set of arguments multiple times, the variable optreset
2306 must be set to 1 before the second and each additional set of calls to
2307 getopt(), and the variable optind must be reinitialized.
2311 The optreset variable was added to make it possible to call the getopt()
2312 function multiple times. This is an extension to the IEEE Std 1003.2
2313 (``POSIX.2'') specification.
2315 which I think comes from one of the other BSDs.
2317 XXX - if we want to control all the command-line option errors, so
2318 that we can display them where we choose (e.g., in a window), we'd
2319 want to leave opterr as 0, and produce our own messages using optopt.
2320 We'd have to check the value of optopt to see if it's a valid option
2321 letter, in which case *presumably* the error is "this option requires
2322 an argument but none was specified", or not a valid option letter,
2323 in which case *presumably* the error is "this option isn't valid".
2324 Some versions of getopt() let you supply a option string beginning
2325 with ':', which means that getopt() will return ':' rather than '?'
2326 for "this option requires an argument but none was specified", but
2328 optind = optind_initial;
2331 /* Set the current locale according to the program environment.
2332 * We haven't localized anything, but some GTK widgets are localized
2333 * (the file selection dialogue, for example).
2334 * This also sets the C-language locale to the native environment. */
2337 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2338 gtk_init (&argc, &argv);
2340 cf_callback_add(main_cf_callback, NULL);
2342 capture_callback_add(main_capture_callback, NULL);
2344 cf_callback_add(statusbar_cf_callback, NULL);
2346 capture_callback_add(statusbar_capture_callback, NULL);
2349 /* Arrange that if we have no console window, and a GLib message logging
2350 routine is called to log a message, we pop up a console window.
2352 We do that by inserting our own handler for all messages logged
2353 to the default domain; that handler pops up a console if necessary,
2354 and then calls the default handler. */
2356 /* We might want to have component specific log levels later ... */
2360 G_LOG_LEVEL_CRITICAL|
2361 G_LOG_LEVEL_WARNING|
2362 G_LOG_LEVEL_MESSAGE|
2365 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2367 g_log_set_handler(NULL,
2369 console_log_handler, NULL /* user_data */);
2370 g_log_set_handler(LOG_DOMAIN_MAIN,
2372 console_log_handler, NULL /* user_data */);
2375 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2377 console_log_handler, NULL /* user_data */);
2378 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2380 console_log_handler, NULL /* user_data */);
2382 /* Set the initial values in the capture options. This might be overwritten
2383 by preference settings and then again by the command line parameters. */
2384 capture_opts_init(&global_capture_opts, &cfile);
2386 global_capture_opts.snaplen = MIN_PACKET_SIZE;
2387 global_capture_opts.has_ring_num_files = TRUE;
2390 /* Initialize whatever we need to allocate colors for GTK+ */
2393 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2394 filter = get_conn_cfilter();
2395 if ( *filter != '\0' ) {
2396 info_update_freq = 1000; /* Milliseconds */
2399 /* We won't come till here, if we had a "console only" command line parameter. */
2400 splash_win = splash_new("Loading Wireshark ...");
2401 if (init_progfile_dir_error != NULL) {
2402 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2403 "Can't get pathname of Wireshark: %s.\n"
2404 "It won't be possible to capture traffic.\n"
2405 "Report this to the Wireshark developers.",
2406 init_progfile_dir_error);
2407 g_free(init_progfile_dir_error);
2410 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2412 /* Register all dissectors; we must do this before checking for the
2413 "-G" flag, as the "-G" flag dumps information registered by the
2414 dissectors, and we must do it before we read the preferences, in
2415 case any dissectors register preferences. */
2416 epan_init(register_all_protocols,register_all_protocol_handoffs,
2417 splash_update, (gpointer) splash_win,
2418 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2419 write_failure_alert_box);
2421 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2423 /* Register all tap listeners; we do this before we parse the arguments,
2424 as the "-z" argument can specify a registered tap. */
2426 /* we register the plugin taps before the other taps because
2427 stats_tree taps plugins will be registered as tap listeners
2428 by stats_tree_stat.c and need to registered before that */
2431 register_all_plugin_tap_listeners();
2434 register_all_tap_listeners();
2436 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2438 /* Now register the preferences for any non-dissector modules.
2439 We must do that before we read the preferences as well. */
2440 prefs_register_modules();
2442 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2444 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2445 #if !defined(_WIN32) && defined(G_THREADS_ENABLED) && defined USE_THREADS
2448 g_thread_init(NULL);
2450 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2451 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2453 #else /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2454 /* this is to keep tap extensions updating once every 3 seconds */
2455 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2456 #endif /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2458 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2460 cap_file_init(&cfile);
2462 /* Fill in capture options with values from the preferences */
2463 prefs_to_capture_opts();
2465 /* Now get our args */
2466 while ((opt = getopt(argc, argv, optstring)) != -1) {
2468 /*** capture option specific ***/
2469 case 'a': /* autostop criteria */
2470 case 'b': /* Ringbuffer option */
2471 case 'c': /* Capture xxx packets */
2472 case 'f': /* capture filter */
2473 case 'k': /* Start capture immediately */
2474 case 'H': /* Hide capture info dialog box */
2475 case 'i': /* Use interface xxx */
2476 case 'p': /* Don't capture in promiscuous mode */
2477 #ifdef HAVE_PCAP_CREATE
2478 case 'I': /* Capture in monitor mode, if available */
2480 case 'Q': /* Quit after capture (just capture to file) */
2481 case 's': /* Set the snapshot (capture) length */
2482 case 'S': /* "Sync" mode: used for following file ala tail -f */
2483 case 'w': /* Write to capture file xxx */
2484 case 'y': /* Set the pcap data link type */
2485 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2486 case 'B': /* Buffer size */
2487 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2489 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2495 capture_option_specified = TRUE;
2500 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2501 case 'K': /* Kerberos keytab file */
2502 read_keytab_file(optarg);
2506 /*** all non capture option specific ***/
2508 /* Configuration profile settings were already processed just ignore them this time*/
2510 case 'D': /* Print a list of capture devices and exit */
2512 if_list = capture_interface_list(&err, &err_str);
2513 if (if_list == NULL) {
2515 case CANT_GET_INTERFACE_LIST:
2516 cmdarg_err("%s", err_str);
2520 case NO_INTERFACES_FOUND:
2521 cmdarg_err("There are no interfaces on which a capture can be done");
2526 capture_opts_print_interfaces(if_list);
2527 free_interface_list(if_list);
2530 capture_option_specified = TRUE;
2534 case 'j': /* Search backwards for a matching packet from filter in option J */
2535 jump_backwards = TRUE;
2537 case 'g': /* Go to packet with the given packet number */
2538 go_to_packet = get_positive_int(optarg, "go to packet");
2540 case 'J': /* Jump to the first packet which matches the filter criteria */
2543 case 'l': /* Automatic scrolling in live capture mode */
2545 auto_scroll_live = TRUE;
2547 capture_option_specified = TRUE;
2551 case 'L': /* Print list of link-layer types and exit */
2553 list_link_layer_types = TRUE;
2555 capture_option_specified = TRUE;
2559 case 'm': /* Fixed-width font for the display */
2560 g_free(prefs_p->gui_font_name);
2561 prefs_p->gui_font_name = g_strdup(optarg);
2563 case 'n': /* No name resolution */
2564 g_resolv_flags = RESOLV_NONE;
2566 case 'N': /* Select what types of addresses/port #s to resolve */
2567 if (g_resolv_flags == RESOLV_ALL)
2568 g_resolv_flags = RESOLV_NONE;
2569 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2570 if (badopt != '\0') {
2571 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2576 case 'o': /* Override preference from command line */
2577 switch (prefs_set_pref(optarg)) {
2580 case PREFS_SET_SYNTAX_ERR:
2581 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2584 case PREFS_SET_NO_SUCH_PREF:
2585 /* not a preference, might be a recent setting */
2586 switch (recent_set_arg(optarg)) {
2589 case PREFS_SET_SYNTAX_ERR:
2590 /* shouldn't happen, checked already above */
2591 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2594 case PREFS_SET_NO_SUCH_PREF:
2595 case PREFS_SET_OBSOLETE:
2596 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2601 g_assert_not_reached();
2604 case PREFS_SET_OBSOLETE:
2605 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2610 g_assert_not_reached();
2614 /* Path settings were already processed just ignore them this time*/
2616 case 'r': /* Read capture file xxx */
2617 /* We may set "last_open_dir" to "cf_name", and if we change
2618 "last_open_dir" later, we free the old value, so we have to
2619 set "cf_name" to something that's been allocated. */
2620 cf_name = g_strdup(optarg);
2622 case 'R': /* Read file filter */
2625 case 't': /* Time stamp type */
2626 if (strcmp(optarg, "r") == 0)
2627 timestamp_set_type(TS_RELATIVE);
2628 else if (strcmp(optarg, "a") == 0)
2629 timestamp_set_type(TS_ABSOLUTE);
2630 else if (strcmp(optarg, "ad") == 0)
2631 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2632 else if (strcmp(optarg, "d") == 0)
2633 timestamp_set_type(TS_DELTA);
2634 else if (strcmp(optarg, "dd") == 0)
2635 timestamp_set_type(TS_DELTA_DIS);
2636 else if (strcmp(optarg, "e") == 0)
2637 timestamp_set_type(TS_EPOCH);
2639 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2640 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2641 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2645 case 'u': /* Seconds type */
2646 if (strcmp(optarg, "s") == 0)
2647 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2648 else if (strcmp(optarg, "hms") == 0)
2649 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2651 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2652 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2657 /* ext ops were already processed just ignore them this time*/
2660 /* We won't call the init function for the stat this soon
2661 as it would disallow MATE's fields (which are registered
2662 by the preferences set callback) from being used as
2663 part of a tap filter. Instead, we just add the argument
2664 to a list of stat arguments. */
2665 if (!process_stat_cmd_arg(optarg)) {
2666 cmdarg_err("Invalid -z argument.");
2667 cmdarg_err_cont(" -z argument must be one of :");
2668 list_stat_cmd_args();
2673 case '?': /* Bad flag - print usage message */
2681 if (cf_name != NULL) {
2683 * Input file name specified with "-r" *and* specified as a regular
2684 * command-line argument.
2686 cmdarg_err("File name specified both with -r and regular argument");
2690 * Input file name not specified with "-r", and a command-line argument
2691 * was specified; treat it as the input file name.
2693 * Yes, this is different from tshark, where non-flag command-line
2694 * arguments are a filter, but this works better on GUI desktops
2695 * where a command can be specified to be run to open a particular
2696 * file - yes, you could have "-r" as the last part of the command,
2697 * but that's a bit ugly.
2699 cf_name = g_strdup(argv[0]);
2707 * Extra command line arguments were specified; complain.
2709 cmdarg_err("Invalid argument: %s", argv[0]);
2714 #ifndef HAVE_LIBPCAP
2715 if (capture_option_specified) {
2716 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2724 if (start_capture && list_link_layer_types) {
2725 /* Specifying *both* is bogus. */
2726 cmdarg_err("You can't specify both -L and a live capture.");
2730 if (list_link_layer_types) {
2731 /* We're supposed to list the link-layer types for an interface;
2732 did the user also specify a capture file to be read? */
2734 /* Yes - that's bogus. */
2735 cmdarg_err("You can't specify -L and a capture file to be read.");
2738 /* No - did they specify a ring buffer option? */
2739 if (global_capture_opts.multi_files_on) {
2740 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2744 /* We're supposed to do a live capture; did the user also specify
2745 a capture file to be read? */
2746 if (start_capture && cf_name) {
2747 /* Yes - that's bogus. */
2748 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2752 /* No - was the ring buffer option specified and, if so, does it make
2754 if (global_capture_opts.multi_files_on) {
2755 /* Ring buffer works only under certain conditions:
2756 a) ring buffer does not work with temporary files;
2757 b) real_time_mode and multi_files_on are mutually exclusive -
2758 real_time_mode takes precedence;
2759 c) it makes no sense to enable the ring buffer if the maximum
2760 file size is set to "infinite". */
2761 if (global_capture_opts.save_file == NULL) {
2762 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2763 global_capture_opts.multi_files_on = FALSE;
2765 /* if (global_capture_opts.real_time_mode) {
2766 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2767 global_capture_opts.multi_files_on = FALSE;
2769 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2770 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2771 /* XXX - this must be redesigned as the conditions changed */
2772 /* global_capture_opts.multi_files_on = FALSE;*/
2777 if (start_capture || list_link_layer_types) {
2778 /* Did the user specify an interface to use? */
2779 if (!capture_opts_trim_iface(&global_capture_opts,
2780 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2785 if (list_link_layer_types) {
2786 /* Get the list of link-layer types for the capture device. */
2787 if_capabilities_t *caps;
2789 caps = capture_get_if_capabilities(global_capture_opts.iface,
2790 global_capture_opts.monitor_mode,
2793 cmdarg_err("%s", err_str);
2797 if (caps->data_link_types == NULL) {
2798 cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
2801 capture_opts_print_if_capabilities(caps, global_capture_opts.monitor_mode);
2802 free_if_capabilities(caps);
2806 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2807 capture_opts_trim_ring_num_files(&global_capture_opts);
2808 #endif /* HAVE_LIBPCAP */
2810 /* Notify all registered modules that have had any of their preferences
2811 changed either from one of the preferences file or from the command
2812 line that their preferences have changed. */
2815 /* disabled protocols as per configuration file */
2816 if (gdp_path == NULL && dp_path == NULL) {
2817 set_disabled_protos_list();
2820 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2822 /* read in rc file from global and personal configuration paths. */
2823 rc_file = get_datafile_path(RC_FILE);
2824 gtk_rc_parse(rc_file);
2826 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2827 gtk_rc_parse(rc_file);
2836 /* close the splash screen, as we are going to open the main window now */
2837 splash_destroy(splash_win);
2839 /************************************************************************/
2840 /* Everything is prepared now, preferences and command line was read in */
2842 /* Pop up the main window. */
2843 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2845 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2846 recent_read_dynamic(&rf_path, &rf_open_errno);
2847 if (rf_path != NULL && rf_open_errno != 0) {
2848 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2849 "Could not open recent file\n\"%s\": %s.",
2850 rf_path, strerror(rf_open_errno));
2853 color_filters_enable(recent.packet_list_colorize);
2855 /* rearrange all the widgets as we now have all recent settings ready for this */
2856 main_widgets_rearrange();
2858 /* Fill in column titles. This must be done after the top level window
2861 XXX - is that still true, with fixed-width columns? */
2862 #ifndef NEW_PACKET_LIST
2863 packet_list_set_column_titles();
2866 menu_recent_read_finished();
2868 menu_auto_scroll_live_changed(auto_scroll_live);
2871 switch (user_font_apply()) {
2874 case FA_FONT_NOT_RESIZEABLE:
2875 /* "user_font_apply()" popped up an alert box. */
2876 /* turn off zooming - font can't be resized */
2877 case FA_FONT_NOT_AVAILABLE:
2878 /* XXX - did we successfully load the un-zoomed version earlier?
2879 If so, this *probably* means the font is available, but not at
2880 this particular zoom level, but perhaps some other failure
2881 occurred; I'm not sure you can determine which is the case,
2883 /* turn off zooming - zoom level is unavailable */
2885 /* in any other case than FA_SUCCESS, turn off zooming */
2886 recent.gui_zoom_level = 0;
2887 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2890 dnd_init(top_level);
2892 color_filters_init();
2895 /* the window can be sized only, if it's not already shown, so do it now! */
2896 main_load_window_geometry(top_level);
2898 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2901 /* If we were given the name of a capture file, read it in now;
2902 we defer it until now, so that, if we can't open it, and pop
2903 up an alert box, the alert box is more likely to come up on
2904 top of the main window - but before the preference-file-error
2905 alert box, so, if we get one of those, it's more likely to come
2908 show_main_window(TRUE);
2909 check_and_warn_user_startup(cf_name);
2910 if (rfilter != NULL) {
2911 if (!dfilter_compile(rfilter, &rfcode)) {
2912 bad_dfilter_alert_box(rfilter);
2913 rfilter_parse_failed = TRUE;
2916 if (!rfilter_parse_failed) {
2917 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2918 /* "cf_open()" succeeded, so it closed the previous
2919 capture file, and thus destroyed any previous read filter
2920 attached to "cf". */
2922 cfile.rfcode = rfcode;
2923 /* Open stat windows; we do so after creating the main window,
2924 to avoid GTK warnings, and after successfully opening the
2925 capture file, so we know we have something to compute stats
2926 on, and after registering all dissectors, so that MATE will
2927 have registered its field array and we can have a tap filter
2928 with one of MATE's late-registered fields as part of the
2930 start_requested_stats();
2932 /* Read the capture file. */
2933 switch (cf_read(&cfile, FALSE)) {
2937 /* Just because we got an error, that doesn't mean we were unable
2938 to read any of the file; we handle what we could get from the
2940 /* if the user told us to jump to a specific packet, do it now */
2941 if(go_to_packet != 0) {
2942 /* Jump to the specified frame number, kept for backward
2944 cf_goto_frame(&cfile, go_to_packet);
2945 } else if (jfilter != NULL) {
2946 /* try to compile given filter */
2947 if (!dfilter_compile(jfilter, &jump_to_filter)) {
2948 bad_dfilter_alert_box(jfilter);
2950 /* Filter ok, jump to the first packet matching the filter
2951 conditions. Default search direction is forward, but if
2952 option d was given, search backwards */
2953 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
2958 case CF_READ_ABORTED:
2964 /* If the filename is not the absolute path, prepend the current dir. This happens
2965 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
2966 if (!g_path_is_absolute(cf_name)) {
2967 char *old_cf_name = cf_name;
2968 char *pwd = g_get_current_dir();
2969 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
2970 g_free(old_cf_name);
2974 /* Save the name of the containing directory specified in the
2975 path name, if any; we can write over cf_name, which is a
2976 good thing, given that "get_dirname()" does write over its
2978 s = get_dirname(cf_name);
2979 set_last_open_dir(s);
2984 dfilter_free(rfcode);
2985 cfile.rfcode = NULL;
2986 show_main_window(FALSE);
2987 /* Don't call check_and_warn_user_startup(): we did it above */
2988 set_menus_for_capture_in_progress(FALSE);
2989 set_capture_if_dialog_for_capture_in_progress(FALSE);
2994 if (start_capture) {
2995 if (global_capture_opts.save_file != NULL) {
2996 /* Save the directory name for future file dialogs. */
2997 /* (get_dirname overwrites filename) */
2998 s = get_dirname(g_strdup(global_capture_opts.save_file));
2999 set_last_open_dir(s);
3002 /* "-k" was specified; start a capture. */
3003 show_main_window(TRUE);
3004 check_and_warn_user_startup(cf_name);
3005 if (capture_start(&global_capture_opts)) {
3006 /* The capture started. Open stat windows; we do so after creating
3007 the main window, to avoid GTK warnings, and after successfully
3008 opening the capture file, so we know we have something to compute
3009 stats on, and after registering all dissectors, so that MATE will
3010 have registered its field array and we can have a tap filter with
3011 one of MATE's late-registered fields as part of the filter. */
3012 start_requested_stats();
3016 show_main_window(FALSE);
3017 check_and_warn_user_startup(cf_name);
3018 set_menus_for_capture_in_progress(FALSE);
3019 set_capture_if_dialog_for_capture_in_progress(FALSE);
3022 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
3023 if (!start_capture && strlen(global_capture_opts.cfilter) == 0) {
3024 g_free(global_capture_opts.cfilter);
3025 global_capture_opts.cfilter = g_strdup(get_conn_cfilter());
3027 #else /* HAVE_LIBPCAP */
3028 show_main_window(FALSE);
3029 check_and_warn_user_startup(cf_name);
3030 set_menus_for_capture_in_progress(FALSE);
3031 set_capture_if_dialog_for_capture_in_progress(FALSE);
3032 #endif /* HAVE_LIBPCAP */
3035 /* register our pid if we are being run from a U3 device */
3038 profile_store_persconffiles (FALSE);
3040 #ifdef HAVE_GTKOSXAPPLICATION
3041 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3042 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3043 gtk_osxapplication_ready(theApp);
3046 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3048 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3050 /* ... back from GTK, we're going down now! */
3052 /* deregister our pid */
3053 u3_deregister_pid();
3057 #ifdef HAVE_AIRPDCAP
3058 AirPDcapDestroyContext(&airpdcap_ctx);
3062 /* hide the (unresponsive) main window, while asking the user to close the console window */
3063 gtk_widget_hide(top_level);
3065 #ifdef HAVE_GTKOSXAPPLICATION
3066 g_object_unref(theApp);
3069 /* Shutdown windows sockets */
3072 /* For some unknown reason, the "atexit()" call in "create_console()"
3073 doesn't arrange that "destroy_console()" be called when we exit,
3074 so we call it here if a console was created. */
3083 /* We build this as a GUI subsystem application on Win32, so
3084 "WinMain()", not "main()", gets called.
3086 Hack shamelessly stolen from the Win32 port of the GIMP. */
3088 #define _stdcall __attribute__((stdcall))
3092 WinMain (struct HINSTANCE__ *hInstance,
3093 struct HINSTANCE__ *hPrevInstance,
3097 INITCOMMONCONTROLSEX comm_ctrl;
3100 * Initialize our DLL search path. MUST be called before LoadLibrary
3103 ws_init_dll_search_path();
3105 /* Initialize our controls. Required for native Windows file dialogs. */
3106 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3107 comm_ctrl.dwSize = sizeof(comm_ctrl);
3108 /* Includes the animate, header, hot key, list view, progress bar,
3109 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3112 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3113 InitCommonControlsEx(&comm_ctrl);
3115 /* RichEd20.DLL is needed for filter entries. */
3116 ws_load_library("riched20.dll");
3118 has_console = FALSE;
3119 return main (__argc, __argv);
3122 /* The code to create and desstroy console windows should not be necessary,
3123 at least as I read the GLib source code, as it looks as if GLib is, on
3124 Win32, *supposed* to create a console window into which to display its
3127 That doesn't happen, however. I suspect there's something completely
3128 broken about that code in GLib-for-Win32, and that it may be related
3129 to the breakage that forces us to just call "printf()" on the message
3130 rather than passing the message on to "g_log_default_handler()"
3131 (which is the routine that does the aforementioned non-functional
3132 console window creation). */
3135 * If this application has no console window to which its standard output
3136 * would go, create one.
3139 create_console(void)
3141 if (stdin_capture) {
3142 /* We've been handed "-i -". Don't mess with stdio. */
3147 /* We have no console to which to print the version string, so
3148 create one and make it the standard input, output, and error. */
3149 if (!AllocConsole())
3150 return; /* couldn't create console */
3152 ws_freopen("CONIN$", "r", stdin);
3153 ws_freopen("CONOUT$", "w", stdout);
3154 ws_freopen("CONOUT$", "w", stderr);
3156 /* Well, we have a console now. */
3159 /* Now register "destroy_console()" as a routine to be called just
3160 before the application exits, so that we can destroy the console
3161 after the user has typed a key (so that the console doesn't just
3162 disappear out from under them, giving the user no chance to see
3163 the message(s) we put in there). */
3164 atexit(destroy_console);
3166 SetConsoleTitle(_T("Wireshark Debug Console"));
3171 destroy_console(void)
3174 printf("\n\nPress any key to exit\n");
3183 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3184 const char *message, gpointer user_data _U_)
3191 /* ignore log message, if log_level isn't interesting based
3192 upon the console log preferences.
3193 If the preferences haven't been loaded loaded yet, display the
3196 The default console_log_level preference value is such that only
3197 ERROR, CRITICAL and WARNING level messages are processed;
3198 MESSAGE, INFO and DEBUG level messages are ignored. */
3199 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3200 prefs.console_log_level != 0) {
3205 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3206 /* the user wants a console or the application will terminate immediately */
3210 /* For some unknown reason, the above doesn't appear to actually cause
3211 anything to be sent to the standard output, so we'll just splat the
3212 message out directly, just to make sure it gets out. */
3214 switch(log_level & G_LOG_LEVEL_MASK) {
3215 case G_LOG_LEVEL_ERROR:
3218 case G_LOG_LEVEL_CRITICAL:
3221 case G_LOG_LEVEL_WARNING:
3224 case G_LOG_LEVEL_MESSAGE:
3227 case G_LOG_LEVEL_INFO:
3230 case G_LOG_LEVEL_DEBUG:
3234 fprintf(stderr, "unknown log_level %u\n", log_level);
3236 g_assert_not_reached();
3239 /* create a "timestamp" */
3241 today = localtime(&curr);
3243 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3244 today->tm_hour, today->tm_min, today->tm_sec,
3245 log_domain != NULL ? log_domain : "",
3248 if(log_level & G_LOG_LEVEL_ERROR) {
3249 /* wait for a key press before the following error handler will terminate the program
3250 this way the user at least can read the error message */
3251 printf("\n\nPress any key to exit\n");
3255 /* XXX - on UN*X, should we just use g_log_default_handler()?
3256 We want the error messages to go to the standard output;
3257 on Mac OS X, that will cause them to show up in various
3258 per-user logs accessible through Console (details depend
3259 on whether you're running 10.0 through 10.4 or running
3260 10.5 and later), and, on other UN*X desktop environments,
3261 if they don't show up in some form of console log, that's
3262 a deficiency in that desktop environment. (Too bad
3263 Windows doesn't set the standard output and error for
3264 GUI apps to something that shows up in such a log.) */
3265 g_log_default_handler(log_domain, log_level, message, user_data);
3272 * Helper for main_widgets_rearrange()
3274 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3275 gtk_container_remove(GTK_CONTAINER(data), widget);
3278 static GtkWidget *main_widget_layout(gint layout_content)
3280 switch(layout_content) {
3281 case(layout_pane_content_none):
3283 case(layout_pane_content_plist):
3285 case(layout_pane_content_pdetails):
3287 case(layout_pane_content_pbytes):
3288 return byte_nb_ptr_gbl;
3290 g_assert_not_reached();
3297 * Rearrange the main window widgets
3299 void main_widgets_rearrange(void) {
3300 GtkWidget *first_pane_widget1, *first_pane_widget2;
3301 GtkWidget *second_pane_widget1, *second_pane_widget2;
3302 gboolean split_top_left;
3304 /* be a bit faster */
3305 gtk_widget_hide(main_vbox);
3307 /* be sure we don't lose a widget while rearranging */
3308 g_object_ref(G_OBJECT(menubar));
3309 g_object_ref(G_OBJECT(main_tb));
3310 g_object_ref(G_OBJECT(filter_tb));
3312 g_object_ref(G_OBJECT(airpcap_tb));
3314 g_object_ref(G_OBJECT(pkt_scrollw));
3315 g_object_ref(G_OBJECT(tv_scrollw));
3316 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3317 g_object_ref(G_OBJECT(statusbar));
3318 g_object_ref(G_OBJECT(main_pane_v1));
3319 g_object_ref(G_OBJECT(main_pane_v2));
3320 g_object_ref(G_OBJECT(main_pane_h1));
3321 g_object_ref(G_OBJECT(main_pane_h2));
3322 g_object_ref(G_OBJECT(welcome_pane));
3324 /* empty all containers participating */
3325 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3326 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3327 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3328 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3329 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3331 statusbar_widgets_emptying(statusbar);
3333 /* add the menubar always at the top */
3334 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3337 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3339 /* filter toolbar in toolbar area */
3340 if (!prefs.filter_toolbar_show_in_statusbar) {
3341 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3345 /* airpcap toolbar */
3346 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3349 /* fill the main layout panes */
3350 switch(prefs.gui_layout_type) {
3351 case(layout_type_5):
3352 main_first_pane = main_pane_v1;
3353 main_second_pane = main_pane_v2;
3354 split_top_left = FALSE;
3356 case(layout_type_2):
3357 main_first_pane = main_pane_v1;
3358 main_second_pane = main_pane_h1;
3359 split_top_left = FALSE;
3361 case(layout_type_1):
3362 main_first_pane = main_pane_v1;
3363 main_second_pane = main_pane_h1;
3364 split_top_left = TRUE;
3366 case(layout_type_4):
3367 main_first_pane = main_pane_h1;
3368 main_second_pane = main_pane_v1;
3369 split_top_left = FALSE;
3371 case(layout_type_3):
3372 main_first_pane = main_pane_h1;
3373 main_second_pane = main_pane_v1;
3374 split_top_left = TRUE;
3376 case(layout_type_6):
3377 main_first_pane = main_pane_h1;
3378 main_second_pane = main_pane_h2;
3379 split_top_left = FALSE;
3382 main_first_pane = NULL;
3383 main_second_pane = NULL;
3384 split_top_left = FALSE;
3385 g_assert_not_reached();
3387 if (split_top_left) {
3388 first_pane_widget1 = main_second_pane;
3389 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3390 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3391 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3393 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3394 first_pane_widget2 = main_second_pane;
3395 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3396 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3398 if (first_pane_widget1 != NULL)
3399 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3400 if (first_pane_widget2 != NULL)
3401 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3402 if (second_pane_widget1 != NULL)
3403 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3404 if (second_pane_widget2 != NULL)
3405 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3407 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3410 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3413 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3415 /* filter toolbar in statusbar hbox */
3416 if (prefs.filter_toolbar_show_in_statusbar) {
3417 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3421 /* airpcap toolbar */
3422 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3425 /* statusbar widgets */
3426 statusbar_widgets_pack(statusbar);
3428 /* hide widgets on users recent settings */
3429 main_widgets_show_or_hide();
3431 gtk_widget_show(main_vbox);
3435 is_widget_visible(GtkWidget *widget, gpointer data)
3437 gboolean *is_visible = data;
3440 if (GTK_WIDGET_VISIBLE(widget))
3447 main_widgets_show_or_hide(void)
3449 gboolean main_second_pane_show;
3451 if (recent.main_toolbar_show) {
3452 gtk_widget_show(main_tb);
3454 gtk_widget_hide(main_tb);
3457 statusbar_widgets_show_or_hide(statusbar);
3459 if (recent.filter_toolbar_show) {
3460 gtk_widget_show(filter_tb);
3462 gtk_widget_hide(filter_tb);
3466 if (recent.airpcap_toolbar_show) {
3467 gtk_widget_show(airpcap_tb);
3469 gtk_widget_hide(airpcap_tb);
3473 if (recent.packet_list_show && have_capture_file) {
3474 gtk_widget_show(pkt_scrollw);
3476 gtk_widget_hide(pkt_scrollw);
3479 if (recent.tree_view_show && have_capture_file) {
3480 gtk_widget_show(tv_scrollw);
3482 gtk_widget_hide(tv_scrollw);
3485 if (recent.byte_view_show && have_capture_file) {
3486 gtk_widget_show(byte_nb_ptr_gbl);
3488 gtk_widget_hide(byte_nb_ptr_gbl);
3491 if (have_capture_file) {
3492 gtk_widget_show(main_first_pane);
3494 gtk_widget_hide(main_first_pane);
3498 * Is anything in "main_second_pane" visible?
3499 * If so, show it, otherwise hide it.
3501 main_second_pane_show = FALSE;
3502 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3503 &main_second_pane_show);
3504 if (main_second_pane_show) {
3505 gtk_widget_show(main_second_pane);
3507 gtk_widget_hide(main_second_pane);
3510 if (!have_capture_file) {
3512 gtk_widget_show(welcome_pane);
3515 gtk_widget_hide(welcome_pane);
3518 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
3519 #ifndef NEW_PACKET_LIST
3520 packet_list_freeze ();
3521 packet_list_thaw ();
3526 /* called, when the window state changes (minimized, maximized, ...) */
3528 window_state_event_cb (GtkWidget *widget _U_,
3532 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3534 if( (event->type) == (GDK_WINDOW_STATE)) {
3535 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3536 /* we might have dialogs popped up while we where iconified,
3538 display_queued_messages();
3546 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3548 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3550 if (event->keyval == GDK_F8) {
3551 #ifdef NEW_PACKET_LIST
3552 new_packet_list_next();
3557 } else if (event->keyval == GDK_F7) {
3558 #ifdef NEW_PACKET_LIST
3559 new_packet_list_prev();
3564 } else if (event->state & NO_SHIFT_MOD_MASK) {
3565 return FALSE; /* Skip control, alt, and other modifiers */
3567 * A comment in gdkkeysyms.h says that it's autogenerated from
3568 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3569 * don't explicitly say so, isprint() should work as expected
3572 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3573 /* Forward the keypress on to the display filter entry */
3574 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3575 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3576 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3584 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3586 GtkAccelGroup *accel;
3589 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3590 set_main_window_name("The Wireshark Network Analyzer");
3592 gtk_widget_set_name(top_level, "main window");
3593 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3595 g_signal_connect(GTK_OBJECT(top_level), "window_state_event",
3596 G_CALLBACK(window_state_event_cb), NULL);
3597 g_signal_connect(GTK_OBJECT(top_level), "key-press-event",
3598 G_CALLBACK(top_level_key_pressed_cb), NULL );
3600 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3601 main_vbox = gtk_vbox_new(FALSE, 1);
3602 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 1);
3603 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3604 gtk_widget_show(main_vbox);
3607 menubar = main_menu_new(&accel);
3609 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3610 /* Mac OS X native menus are created and displayed by main_menu_new() */
3611 if(!prefs_p->gui_macosx_style) {
3613 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3614 gtk_widget_show(menubar);
3615 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3620 main_tb = toolbar_new();
3621 gtk_widget_show (main_tb);
3623 /* Filter toolbar */
3624 filter_tb = filter_toolbar_new();
3627 #ifdef NEW_PACKET_LIST
3628 pkt_scrollw = new_packet_list_create();
3629 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3630 gtk_widget_show_all(pkt_scrollw);
3632 pkt_scrollw = packet_list_new(prefs_p);
3633 gtk_widget_set_size_request(packet_list, -1, pl_size);
3634 gtk_widget_show(pkt_scrollw);
3638 tv_scrollw = main_tree_view_new(prefs_p, &tree_view_gbl);
3639 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3640 gtk_widget_show(tv_scrollw);
3642 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3643 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3644 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3645 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3646 gtk_widget_show(tree_view_gbl);
3649 byte_nb_ptr_gbl = byte_view_new();
3650 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3651 gtk_widget_show(byte_nb_ptr_gbl);
3653 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3654 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3656 /* Panes for the packet list, tree, and byte view */
3657 main_pane_v1 = gtk_vpaned_new();
3658 gtk_widget_show(main_pane_v1);
3659 main_pane_v2 = gtk_vpaned_new();
3660 gtk_widget_show(main_pane_v2);
3661 main_pane_h1 = gtk_hpaned_new();
3662 gtk_widget_show(main_pane_h1);
3663 main_pane_h2 = gtk_hpaned_new();
3664 gtk_widget_show(main_pane_h2);
3666 airpcap_tb = airpcap_toolbar_new();
3667 gtk_widget_show(airpcap_tb);
3670 statusbar = statusbar_new();
3671 gtk_widget_show(statusbar);
3673 /* Pane for the welcome screen */
3674 welcome_pane = welcome_new();
3675 gtk_widget_show(welcome_pane);
3679 show_main_window(gboolean doing_work)
3681 main_set_for_capture_file(doing_work);
3683 /*** we have finished all init things, show the main window ***/
3684 gtk_widget_show(top_level);
3686 /* the window can be maximized only, if it's visible, so do it after show! */
3687 main_load_window_geometry(top_level);
3689 /* process all pending GUI events before continue */
3690 while (gtk_events_pending()) gtk_main_iteration();
3692 /* Pop up any queued-up alert boxes. */
3693 display_queued_messages();
3695 /* Move the main window to the front, in case it isn't already there */
3696 gdk_window_raise(top_level->window);
3699 airpcap_toolbar_show(airpcap_tb);
3700 #endif /* HAVE_AIRPCAP */
3703 /* Fill in capture options with values from the preferences */
3705 prefs_to_capture_opts(void)
3708 /* Set promiscuous mode from the preferences setting. */
3709 /* the same applies to other preferences settings as well. */
3710 global_capture_opts.promisc_mode = prefs.capture_prom_mode;
3711 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3712 global_capture_opts.show_info = prefs.capture_show_info;
3713 global_capture_opts.real_time_mode = prefs.capture_real_time;
3714 auto_scroll_live = prefs.capture_auto_scroll;
3715 #endif /* HAVE_LIBPCAP */
3717 /* Set the name resolution code's flags from the preferences. */
3718 g_resolv_flags = prefs.name_resolve;
3722 /* Change configuration profile */
3723 void change_configuration_profile (const gchar *profile_name)
3725 char *gdp_path, *dp_path;
3729 /* First check if profile exists */
3730 if (!profile_exists(profile_name)) {
3734 /* Get the current geometry, before writing it to disk */
3735 main_save_window_geometry(top_level);
3737 if (profile_exists(get_profile_name())) {
3738 /* Write recent file for profile we are leaving, if it still exists */
3739 write_profile_recent();
3742 /* Set profile name and update the status bar */
3743 set_profile_name (profile_name);
3744 profile_bar_update ();
3746 /* Reset current preferences and apply the new */
3750 (void) read_configuration_files (&gdp_path, &dp_path);
3752 recent_read_profile_static(&rf_path, &rf_open_errno);
3753 if (rf_path != NULL && rf_open_errno != 0) {
3754 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3755 "Could not open common recent file\n\"%s\": %s.",
3756 rf_path, strerror(rf_open_errno));
3758 if (recent.gui_fileopen_remembered_dir &&
3759 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3760 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3762 timestamp_set_type (recent.gui_time_format);
3763 timestamp_set_seconds_type (recent.gui_seconds_format);
3764 color_filters_enable(recent.packet_list_colorize);
3766 prefs_to_capture_opts();
3769 /* Update window view and redraw the toolbar */
3770 update_main_window_title();
3771 toolbar_redraw_all();
3773 /* Enable all protocols and disable from the disabled list */
3775 if (gdp_path == NULL && dp_path == NULL) {
3776 set_disabled_protos_list();
3779 /* Reload color filters */
3780 color_filters_reload();
3782 /* Reload list of interfaces on welcome page */
3783 welcome_if_panel_reload();
3785 /* Recreate the packet list according to new preferences */
3786 #ifdef NEW_PACKET_LIST
3787 new_packet_list_recreate ();
3789 packet_list_recreate ();
3791 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3794 /* Update menus with new recent values */
3795 menu_recent_read_finished();
3797 /* Reload pane geometry, must be done after recreating the list */
3798 main_pane_load_window_geometry();
3801 /** redissect packets and update UI */
3802 void redissect_packets(void)
3804 cf_redissect_packets(&cfile);
3805 status_expert_update();