3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * Richard Sharpe, 13-Feb-1999, added support for initializing structures
8 * needed by dissect routines
9 * Jeff Foster, 2001/03/12, added support tabbed hex display windowss
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <gdk/gdkkeysyms.h>
31 #if GTK_CHECK_VERSION(3,0,0)
32 # include <gdk/gdkkeysyms-compat.h>
47 #ifndef HAVE_GETOPT_LONG
48 #include "wsutil/wsgetopt.h"
52 #include <zlib.h> /* to get the libz version number */
55 #ifdef HAVE_LIBPORTAUDIO
56 #include <portaudio.h>
57 #endif /* HAVE_LIBPORTAUDIO */
59 #include <wsutil/clopts_common.h>
60 #include <wsutil/copyright_info.h>
61 #include <wsutil/crash_info.h>
62 #include <wsutil/filesystem.h>
63 #include <wsutil/file_util.h>
64 #include <wsutil/privileges.h>
65 #include <wsutil/report_err.h>
66 #include <wsutil/u3.h>
67 #include <wsutil/ws_diag_control.h>
68 #include <wsutil/ws_version_info.h>
70 #include <wiretap/merge.h>
72 #include <epan/addr_resolv.h>
73 #include <epan/column.h>
74 #include <epan/disabled_protos.h>
75 #include <epan/epan.h>
76 #include <epan/proto.h>
77 #include <epan/epan_dissect.h>
78 #include <epan/dfilter/dfilter.h>
79 #include <epan/strutil.h>
80 #include <epan/ex-opt.h>
81 #include <epan/funnel.h>
82 #include <epan/expert.h>
83 #include <epan/prefs.h>
84 #include <epan/prefs-int.h>
86 #include <epan/stat_tap_ui.h>
88 #include <epan/print.h>
89 #include <epan/timestamp.h>
90 #include <epan/conversation_table.h>
92 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
93 #include <epan/asn1.h>
94 #include <epan/dissectors/packet-kerberos.h>
97 #include <wsutil/cmdarg_err.h>
98 #include <wsutil/plugins.h>
100 /* general (not GTK specific) */
102 #include "../frame_tvbuff.h"
103 #include "../summary.h"
104 #include "../color.h"
105 #include "../color_filters.h"
106 #include "../register.h"
107 #include "../ringbuffer.h"
110 #include "gtk_iface_monitor.h"
112 #include "ui/alert_box.h"
113 #include "ui/console.h"
114 #include "ui/decode_as_utils.h"
115 #include "ui/filters.h"
116 #include "ui/main_statusbar.h"
117 #include "ui/persfilepath_opt.h"
118 #include "ui/preference_utils.h"
119 #include "ui/recent.h"
120 #include "ui/recent_utils.h"
121 #include "ui/software_update.h"
122 #include "ui/ui_util.h"
126 #include "ui/capture_ui_utils.h"
127 #include "ui/capture_globals.h"
128 #include "ui/iface_lists.h"
131 #include "codecs/codecs.h"
133 #include "caputils/capture-pcap-util.h"
136 #include "caputils/capture_ifinfo.h"
137 #include "ui/capture.h"
138 #include <capchild/capture_sync.h>
142 #include "caputils/capture-wpcap.h"
143 #include "caputils/capture_wpcap_packet.h"
144 #include <tchar.h> /* Needed for Unicode */
145 #include <wsutil/os_version_info.h>
146 #include <wsutil/unicode-utils.h>
147 #include <commctrl.h>
148 #include <shellapi.h>
152 #include "ui/gtk/file_dlg.h"
153 #include "ui/gtk/gtkglobals.h"
154 #include "ui/gtk/color_utils.h"
155 #include "ui/gtk/gui_utils.h"
156 #include "ui/gtk/color_dlg.h"
157 #include "ui/gtk/filter_dlg.h"
158 #include "ui/gtk/fileset_dlg.h"
159 #include "ui/gtk/uat_gui.h"
160 #include "ui/gtk/main.h"
161 #include "ui/gtk/main_80211_toolbar.h"
162 #include "ui/gtk/main_airpcap_toolbar.h"
163 #include "ui/gtk/main_filter_toolbar.h"
164 #include "ui/gtk/main_titlebar.h"
165 #include "ui/gtk/menus.h"
166 #include "ui/gtk/main_menubar_private.h"
167 #include "ui/gtk/macros_dlg.h"
168 #include "ui/gtk/main_statusbar_private.h"
169 #include "ui/gtk/main_toolbar.h"
170 #include "ui/gtk/main_toolbar_private.h"
171 #include "ui/gtk/main_welcome.h"
172 #include "ui/gtk/main_welcome_private.h"
173 #include "ui/gtk/drag_and_drop.h"
174 #include "ui/gtk/capture_file_dlg.h"
175 #include "ui/gtk/packet_panes.h"
176 #include "ui/gtk/keys.h"
177 #include "ui/gtk/packet_win.h"
178 #include "ui/gtk/stock_icons.h"
179 #include "ui/gtk/find_dlg.h"
180 #include "ui/gtk/follow_tcp.h"
181 #include "ui/gtk/font_utils.h"
182 #include "ui/gtk/about_dlg.h"
183 #include "ui/gtk/help_dlg.h"
184 #include "ui/gtk/decode_as_dlg.h"
185 #include "ui/gtk/webbrowser.h"
186 #include "ui/gtk/capture_dlg.h"
187 #include "ui/gtk/capture_if_dlg.h"
188 #include "ui/gtk/tap_param_dlg.h"
189 #include "ui/gtk/prefs_column.h"
190 #include "ui/gtk/prefs_dlg.h"
191 #include "ui/gtk/proto_help.h"
192 #include "ui/gtk/packet_list.h"
193 #include "ui/gtk/filter_expression_save_dlg.h"
194 #include "ui/gtk/conversations_table.h"
195 #include "ui/gtk/hostlist_table.h"
196 #include "ui/gtk/service_response_time_table.h"
197 #include "ui/gtk/response_time_delay_table.h"
198 #include "ui/gtk/simple_stattable.h"
199 #include "simple_dialog.h"
201 #include "ui/gtk/old-gtk-compat.h"
205 #include "wsiconcap.h"
209 #include <caputils/airpcap.h>
210 #include <caputils/airpcap_loader.h>
211 #include "airpcap_dlg.h"
212 #include "airpcap_gui_utils.h"
215 #include <epan/crypt/airpdcap_ws.h>
218 #ifdef HAVE_GTKOSXAPPLICATION
219 #include <gtkmacintegration/gtkosxapplication.h>
223 * Files under personal and global preferences directories in which
224 * GTK settings for Wireshark are stored.
226 #define RC_FILE "gtkrc"
229 capture_options global_capture_opts;
230 capture_session global_capture_session;
235 static gboolean capture_stopping;
237 /* "exported" main widgets */
238 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
240 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
241 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
242 static GtkWidget *main_first_pane, *main_second_pane;
244 /* internally used widgets */
245 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
247 GtkWidget *wireless_tb;
249 int airpcap_dll_ret_val = -1;
252 GString *comp_info_str, *runtime_info_str;
254 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
256 static guint tap_update_timer_id;
258 static void create_main_window(gint, gint, gint, e_prefs*);
259 static void show_main_window(gboolean);
260 static void main_save_window_geometry(GtkWidget *widget);
263 /* Match selected byte pattern */
265 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
267 char *cur_filter, *new_filter;
269 if ((!text) || (0 == strlen(text))) {
270 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
276 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
278 switch (action&MATCH_SELECTED_MASK) {
280 case MATCH_SELECTED_REPLACE:
281 new_filter = g_strdup(text);
284 case MATCH_SELECTED_AND:
285 if ((!cur_filter) || (0 == strlen(cur_filter)))
286 new_filter = g_strdup(text);
288 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
291 case MATCH_SELECTED_OR:
292 if ((!cur_filter) || (0 == strlen(cur_filter)))
293 new_filter = g_strdup(text);
295 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
298 case MATCH_SELECTED_NOT:
299 new_filter = g_strconcat("!(", text, ")", NULL);
302 case MATCH_SELECTED_AND_NOT:
303 if ((!cur_filter) || (0 == strlen(cur_filter)))
304 new_filter = g_strconcat("!(", text, ")", NULL);
306 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
309 case MATCH_SELECTED_OR_NOT:
310 if ((!cur_filter) || (0 == strlen(cur_filter)))
311 new_filter = g_strconcat("!(", text, ")", NULL);
313 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
317 g_assert_not_reached();
322 /* Free up the copy we got of the old filter text. */
325 /* Don't change the current display filter if we only want to copy the filter */
326 if (action&MATCH_SELECTED_COPY_ONLY) {
327 GString *gtk_text_str = g_string_new("");
328 g_string_append(gtk_text_str, new_filter);
329 copy_to_clipboard(gtk_text_str);
330 g_string_free(gtk_text_str, TRUE);
332 /* create a new one and set the display filter entry accordingly */
333 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
335 /* Run the display filter so it goes in effect. */
336 if (action&MATCH_SELECTED_APPLY_NOW)
337 main_filter_packets(&cfile, new_filter, FALSE);
340 /* Free up the new filter text. */
345 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
349 if (cfile.finfo_selected) {
350 filter = proto_construct_match_selected_string(cfile.finfo_selected,
352 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
353 wmem_free(NULL, filter);
358 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
362 if (cfile.finfo_selected) {
363 filter = proto_construct_match_selected_string(cfile.finfo_selected,
365 if ((!filter) || (0 == strlen(filter))) {
366 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
367 "Could not acquire information to build a filter!\n"
368 "Try expanding or choosing another item.");
373 color_display_with_filter(filter);
376 color_filters_reset_tmp();
378 color_filters_set_tmp(filt_nr,filter, FALSE);
380 packet_list_colorize_packets();
382 wmem_free(NULL, filter);
387 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
389 gchar *selected_proto_url;
390 gchar *proto_abbrev = (gchar *)data;
395 if (cfile.finfo_selected) {
396 /* open wiki page using the protocol abbreviation */
397 selected_proto_url = g_strdup_printf("https://wiki.wireshark.org/Protocols/%s", proto_abbrev);
398 browser_open_url(selected_proto_url);
399 g_free(selected_proto_url);
402 case(ESD_BTN_CANCEL):
405 g_assert_not_reached();
411 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
414 const gchar *proto_abbrev;
418 if (cfile.finfo_selected) {
419 /* convert selected field to protocol abbreviation */
420 /* XXX - could this conversion be simplified? */
421 field_id = cfile.finfo_selected->hfinfo->id;
422 /* if the selected field isn't a protocol, get its parent */
423 if(!proto_registrar_is_protocol(field_id)) {
424 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
427 proto_abbrev = proto_registrar_get_abbrev(field_id);
429 /* ask the user if the wiki page really should be opened */
430 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
431 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
433 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
435 "The Wireshark Wiki is a collaborative approach to provide information "
436 "about Wireshark in several ways (not limited to protocol specifics).\n"
438 "This Wiki is new, so the page of the selected protocol "
439 "may not exist and/or may not contain valuable information.\n"
441 "As everyone can edit the Wiki and add new content (or extend existing), "
442 "you are encouraged to add information if you can.\n"
444 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
446 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
447 "which will save you a lot of editing and will give a consistent look over the pages.",
448 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
449 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
453 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
455 gchar *selected_proto_url;
456 gchar *proto_abbrev = (gchar *)data;
460 if (cfile.finfo_selected) {
461 /* open reference page using the protocol abbreviation */
462 selected_proto_url = g_strdup_printf("https://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
463 browser_open_url(selected_proto_url);
464 g_free(selected_proto_url);
467 case(ESD_BTN_CANCEL):
470 g_assert_not_reached();
475 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
478 const gchar *proto_abbrev;
482 if (cfile.finfo_selected) {
483 /* convert selected field to protocol abbreviation */
484 /* XXX - could this conversion be simplified? */
485 field_id = cfile.finfo_selected->hfinfo->id;
486 /* if the selected field isn't a protocol, get its parent */
487 if(!proto_registrar_is_protocol(field_id)) {
488 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
491 proto_abbrev = proto_registrar_get_abbrev(field_id);
493 /* ask the user if the wiki page really should be opened */
494 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
495 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
497 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
499 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
500 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
505 is_address_column (gint column)
507 if (((cfile.cinfo.columns[column].col_fmt == COL_DEF_SRC) ||
508 (cfile.cinfo.columns[column].col_fmt == COL_RES_SRC) ||
509 (cfile.cinfo.columns[column].col_fmt == COL_DEF_DST) ||
510 (cfile.cinfo.columns[column].col_fmt == COL_RES_DST)) &&
511 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
520 get_ip_address_list_from_packet_list_row(gpointer data)
522 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
523 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
526 GList *addr_list = NULL;
528 fdata = (frame_data *) packet_list_get_row_data(row);
533 if (!cf_read_record(&cfile, fdata))
534 return NULL; /* error reading the frame */
536 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
537 col_custom_prime_edt(&edt, &cfile.cinfo);
539 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
540 frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
541 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
543 /* First check selected column */
544 if (is_address_column (column)) {
545 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
548 for (col = 0; col < cfile.cinfo.num_cols; col++) {
549 /* Then check all columns except the selected */
550 if ((col != column) && (is_address_column (col))) {
551 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
555 epan_dissect_cleanup(&edt);
562 get_filter_from_packet_list_row_and_column(gpointer data)
564 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
565 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
569 fdata = (frame_data *) packet_list_get_row_data(row);
574 if (!cf_read_record(&cfile, fdata))
575 return NULL; /* error reading the record */
576 /* proto tree, visible. We need a proto tree if there's custom columns */
577 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
578 col_custom_prime_edt(&edt, &cfile.cinfo);
580 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
581 frame_tvbuff_new_buffer(fdata, &cfile.buf),
582 fdata, &cfile.cinfo);
583 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
585 if ((cfile.cinfo.columns[column].col_custom_occurrence) ||
586 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
588 /* Only construct the filter when a single occurrence is displayed
589 * otherwise we might end up with a filter like "ip.proto==1,6".
591 * Or do we want to be able to filter on multiple occurrences so that
592 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
595 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
596 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
597 /* leak a little; is there a safe wmem_ scope here? */
598 if (cfile.cinfo.columns[column].col_fmt == COL_CUSTOM) {
599 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.columns[column].col_custom_field);
600 if (hfi && hfi->parent == -1) {
602 buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
603 } else if (hfi && IS_FT_STRING(hfi->type)) {
604 /* Custom string, add quotes */
605 buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
606 cfile.cinfo.col_expr.col_expr_val[column]);
610 buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
611 cfile.cinfo.col_expr.col_expr_val[column]);
616 epan_dissect_cleanup(&edt);
623 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
627 filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
629 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
635 /* This function allows users to right click in the details window and copy the text
636 * information to the operating systems clipboard.
638 * We first check to see if a string representation is setup in the tree and then
639 * read the string. If not available then we try to grab the value. If all else
640 * fails we display a message to the user to indicate the copy could not be completed.
643 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
645 GString *gtk_text_str = g_string_new("");
646 char labelstring[ITEM_LABEL_LENGTH];
647 char *stringpointer = labelstring;
651 case COPY_SELECTED_DESCRIPTION:
652 if (cfile.finfo_selected->rep &&
653 strlen (cfile.finfo_selected->rep->representation) > 0) {
654 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
657 case COPY_SELECTED_FIELDNAME:
658 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
659 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
662 case COPY_SELECTED_VALUE:
663 if (cfile.edt !=0 ) {
664 gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
665 g_string_append(gtk_text_str, field_str);
673 if (gtk_text_str->len == 0) {
674 /* If no representation then... Try to read the value */
675 proto_item_fill_label(cfile.finfo_selected, stringpointer);
676 g_string_append(gtk_text_str, stringpointer);
679 if (gtk_text_str->len == 0) {
680 /* Could not get item so display error msg */
681 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
683 /* Copy string to clipboard */
684 copy_to_clipboard(gtk_text_str);
686 g_string_free(gtk_text_str, TRUE); /* Free the memory */
690 /* mark as reference time frame */
692 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
696 frame->flags.ref_time=1;
697 cfile.ref_time_count++;
699 frame->flags.ref_time=0;
700 cfile.ref_time_count--;
702 cf_reftime_packets(&cfile);
703 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
704 packet_list_freeze();
705 cfile.displayed_count--;
706 packet_list_recreate_visible_rows();
709 packet_list_queue_draw();
713 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
717 timestamp_set_type(TS_RELATIVE);
718 recent.gui_time_format = TS_RELATIVE;
719 cf_timestamp_auto_precision(&cfile);
720 packet_list_queue_draw();
725 g_assert_not_reached();
728 if (cfile.current_frame) {
729 set_frame_reftime(!cfile.current_frame->flags.ref_time,
730 cfile.current_frame, cfile.current_row);
736 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
738 static GtkWidget *reftime_dialog = NULL;
742 if (cfile.current_frame) {
743 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
744 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
745 "%sSwitch to the appropriate Time Display Format?%s\n\n"
746 "Time References don't work well with the currently selected Time Display Format.\n\n"
747 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
748 simple_dialog_primary_start(), simple_dialog_primary_end());
749 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
751 set_frame_reftime(!cfile.current_frame->flags.ref_time,
752 cfile.current_frame, cfile.current_row);
756 case REFTIME_FIND_NEXT:
757 cf_find_packet_time_reference(&cfile, SD_FORWARD);
759 case REFTIME_FIND_PREV:
760 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
766 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
768 cf_find_packet_marked(&cfile, SD_FORWARD);
772 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
774 cf_find_packet_marked(&cfile, SD_BACKWARD);
778 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
781 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
783 gboolean has_blurb = FALSE;
784 guint length = 0, byte_len;
785 GtkWidget *byte_view;
786 const guint8 *byte_data;
791 /* if nothing is selected */
792 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
795 * Which byte view is displaying the current protocol tree
798 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
799 if (byte_view == NULL)
802 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
803 if (byte_data == NULL)
806 cf_unselect_field(&cfile);
807 packet_hex_print(byte_view, byte_data,
808 cfile.current_frame, NULL, byte_len);
809 proto_help_menu_modify(sel, &cfile);
812 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
815 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
817 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
818 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
819 g_assert(byte_data != NULL);
821 cfile.finfo_selected = finfo;
822 set_menus_for_selected_tree_row(&cfile);
825 if (finfo->hfinfo->blurb != NULL &&
826 finfo->hfinfo->blurb[0] != '\0') {
828 length = (guint) strlen(finfo->hfinfo->blurb);
830 length = (guint) strlen(finfo->hfinfo->name);
832 finfo_length = finfo->length + finfo->appendix_length;
834 if (finfo_length == 0) {
836 } else if (finfo_length == 1) {
837 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
839 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
841 statusbar_pop_field_msg(); /* get rid of current help msg */
843 statusbar_push_field_msg(" %s (%s)%s",
844 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
845 finfo->hfinfo->abbrev, len_str);
848 * Don't show anything if the field name is zero-length;
849 * the pseudo-field for text-only items is such
850 * a field, and we don't want "Text (text)" showing up
851 * on the status line if you've selected such a field.
853 * XXX - there are zero-length fields for which we *do*
854 * want to show the field name.
856 * XXX - perhaps the name and abbrev field should be null
857 * pointers rather than null strings for that pseudo-field,
858 * but we'd have to add checks for null pointers in some
859 * places if we did that.
861 * Or perhaps text-only items should have -1 as the field
862 * index, with no pseudo-field being used, but that might
863 * also require special checks for -1 to be added.
865 statusbar_push_field_msg("%s", "");
868 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
870 proto_help_menu_modify(sel, &cfile);
873 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
876 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
879 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
882 expand_all_tree(cfile.edt->tree, tree_view_gbl);
885 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
887 if (cfile.finfo_selected) {
888 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
889 cfile.finfo_selected->hfinfo->abbrev,0);
890 /* Recreate the packet list according to new preferences */
891 packet_list_recreate ();
892 if (!prefs.gui_use_pref_save) {
895 cfile.columns_changed = FALSE; /* Reset value */
899 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
903 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
905 /* the mouse position is at an entry, expand that one */
906 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
907 gtk_tree_path_free(path);
911 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
915 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
917 /* the mouse position is at an entry, expand that one */
919 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
920 gtk_tree_path_free(path);
924 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
926 static const e_addr_resolve resolv_flags = {
928 TRUE, /* network_name */
929 TRUE, /* transport_name */
930 TRUE, /* concurrent_dns */
931 TRUE, /* dns_pkt_addr_resolution */
932 TRUE, /* use_external_net_name_resolver */
933 FALSE /* load_hosts_file_from_profile_only */
936 if (cfile.edt->tree) {
937 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
941 /* Update main window items based on whether there's a capture in progress. */
943 main_set_for_capture_in_progress(gboolean capture_in_progress)
945 set_menus_for_capture_in_progress(capture_in_progress);
948 set_toolbar_for_capture_in_progress(capture_in_progress);
950 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
954 /* Update main window items based on whether we have a capture file. */
956 main_set_for_capture_file(gboolean have_capture_file_in)
958 have_capture_file = have_capture_file_in;
960 main_widgets_show_or_hide();
963 /* Update main window items based on whether we have captured packets. */
965 main_set_for_captured_packets(gboolean have_captured_packets)
967 set_menus_for_captured_packets(have_captured_packets);
968 set_toolbar_for_captured_packets(have_captured_packets);
971 /* Update main window items based on whether we have a packet history. */
973 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
975 set_menus_for_packet_history(back_history, forward_history);
976 set_toolbar_for_packet_history(back_history, forward_history);
982 /* get the current geometry, before writing it to disk */
983 main_save_window_geometry(top_level);
985 /* write user's recent file to disk
986 * It is no problem to write this file, even if we do not quit */
987 write_profile_recent();
990 /* XXX - should we check whether the capture file is an
991 unsaved temporary file for a live capture and, if so,
992 pop up a "do you want to exit without saving the capture
993 file?" dialog, and then just return, leaving said dialog
994 box to forcibly quit if the user clicks "OK"?
996 If so, note that this should be done in a subroutine that
997 returns TRUE if we do so, and FALSE otherwise, and if it
998 returns TRUE we should return TRUE without nuking anything.
1000 Note that, if we do that, we might also want to check if
1001 an "Update list of packets in real time" capture is in
1002 progress and, if so, ask whether they want to terminate
1003 the capture and discard it, and return TRUE, before nuking
1004 any child capture, if they say they don't want to do so. */
1007 /* Nuke any child capture in progress. */
1008 capture_kill_child(&global_capture_session);
1011 /* Are we in the middle of reading a capture? */
1012 if (cfile.state == FILE_READ_IN_PROGRESS) {
1013 /* Yes, so we can't just close the file and quit, as
1014 that may yank the rug out from under the read in
1015 progress; instead, just set the state to
1016 "FILE_READ_ABORTED" and return - the code doing the read
1017 will check for that and, if it sees that, will clean
1019 cfile.state = FILE_READ_ABORTED;
1021 /* Say that the window should *not* be deleted;
1022 that'll be done by the code that cleans up. */
1025 /* Close any capture file we have open; on some OSes, you
1026 can't unlink a temporary capture file if you have it
1028 "cf_close()" will unlink it after closing it if
1029 it's a temporary file.
1031 We do this here, rather than after the main loop returns,
1032 as, after the main loop returns, the main window may have
1033 been destroyed (if this is called due to a "destroy"
1034 even on the main window rather than due to the user
1035 selecting a menu item), and there may be a crash
1036 or other problem when "cf_close()" tries to
1037 clean up stuff in the main window.
1039 XXX - is there a better place to put this?
1040 Or should we have a routine that *just* closes the
1041 capture file, and doesn't do anything with the UI,
1042 which we'd call here, and another routine that
1043 calls that routine and also cleans up the UI, which
1044 we'd call elsewhere? */
1047 /* Exit by leaving the main loop, so that any quit functions
1048 we registered get called. */
1051 /* Say that the window should be deleted. */
1057 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1059 /* If we're in the middle of stopping a capture, don't do anything;
1060 the user can try deleting the window after the capture stops. */
1061 if (capture_stopping)
1064 /* If there's unsaved data, let the user save it first.
1065 If they cancel out of it, don't quit. */
1066 if (do_file_close(&cfile, TRUE, " before quitting"))
1067 return main_do_quit();
1069 return TRUE; /* will this keep the window from being deleted? */
1074 main_pane_load_window_geometry(void)
1076 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1077 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1078 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1079 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1085 main_load_window_geometry(GtkWidget *widget)
1087 window_geometry_t geom;
1089 geom.set_pos = prefs.gui_geometry_save_position;
1090 geom.x = recent.gui_geometry_main_x;
1091 geom.y = recent.gui_geometry_main_y;
1092 geom.set_size = prefs.gui_geometry_save_size;
1093 if (recent.gui_geometry_main_width > 0 &&
1094 recent.gui_geometry_main_height > 0) {
1095 geom.width = recent.gui_geometry_main_width;
1096 geom.height = recent.gui_geometry_main_height;
1097 geom.set_maximized = prefs.gui_geometry_save_maximized;
1099 /* We assume this means the width and height weren't set in
1100 the "recent" file (or that there is no "recent" file),
1101 and weren't set to a default value, so we don't set the
1102 size. (The "recent" file code rejects non-positive width
1103 and height values.) */
1104 geom.set_size = FALSE;
1106 geom.maximized = recent.gui_geometry_main_maximized;
1108 window_set_geometry(widget, &geom);
1110 main_pane_load_window_geometry();
1111 statusbar_load_window_geometry();
1116 main_save_window_geometry(GtkWidget *widget)
1118 window_geometry_t geom;
1120 window_get_geometry(widget, &geom);
1122 if (prefs.gui_geometry_save_position) {
1123 recent.gui_geometry_main_x = geom.x;
1124 recent.gui_geometry_main_y = geom.y;
1127 if (prefs.gui_geometry_save_size) {
1128 recent.gui_geometry_main_width = geom.width;
1129 recent.gui_geometry_main_height = geom.height;
1132 if(prefs.gui_geometry_save_maximized) {
1133 recent.gui_geometry_main_maximized = geom.maximized;
1136 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1137 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1138 statusbar_save_window_geometry();
1142 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1144 /* If there's unsaved data, let the user save it first. */
1145 if (do_file_close(&cfile, TRUE, " before quitting"))
1150 print_usage(gboolean for_help_option) {
1158 if (for_help_option) {
1160 fprintf(output, "Wireshark %s\n"
1161 "Interactively dump and analyze network traffic.\n"
1162 "See https://www.wireshark.org for more information.\n",
1163 get_ws_vcs_version_info());
1167 fprintf(output, "\n");
1168 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1169 fprintf(output, "\n");
1172 fprintf(output, "Capture interface:\n");
1173 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1174 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1175 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1176 fprintf(output, " -p don't capture in promiscuous mode\n");
1177 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1178 fprintf(output, " -S update packet display when new packets are captured\n");
1179 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1180 #ifdef HAVE_PCAP_CREATE
1181 fprintf(output, " -I capture in monitor mode, if available\n");
1183 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
1184 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1186 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1187 fprintf(output, " -D print list of interfaces and exit\n");
1188 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1189 fprintf(output, "\n");
1190 fprintf(output, "Capture stop conditions:\n");
1191 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1192 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1193 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1194 fprintf(output, " files:NUM - stop after NUM files\n");
1195 /*fprintf(output, "\n");*/
1196 fprintf(output, "Capture output:\n");
1197 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1198 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1199 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1200 #endif /* HAVE_LIBPCAP */
1201 #ifdef HAVE_PCAP_REMOTE
1202 fprintf(output, "RPCAP options:\n");
1203 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1205 /*fprintf(output, "\n");*/
1206 fprintf(output, "Input file:\n");
1207 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1209 fprintf(output, "\n");
1210 fprintf(output, "Processing:\n");
1211 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1212 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1213 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtCd\"\n");
1214 fprintf(output, " --disable-protocol <proto_name>\n");
1215 fprintf(output, " disable dissection of proto_name\n");
1216 fprintf(output, " --enable-heuristic <short_name>\n");
1217 fprintf(output, " enable dissection of heuristic protocol\n");
1218 fprintf(output, " --disable-heuristic <short_name>\n");
1219 fprintf(output, " disable dissection of heuristic protocol\n");
1221 fprintf(output, "\n");
1222 fprintf(output, "User interface:\n");
1223 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1224 fprintf(output, " -Y <display filter> start with the given display filter\n");
1225 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1226 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1227 fprintf(output, " filter\n");
1228 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1229 fprintf(output, " -m <font> set the font name used for most text\n");
1230 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
1231 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1232 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1233 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1235 fprintf(output, "\n");
1236 fprintf(output, "Output:\n");
1237 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1239 fprintf(output, "\n");
1240 fprintf(output, "Miscellaneous:\n");
1241 fprintf(output, " -h display this help and exit\n");
1242 fprintf(output, " -v display version info and exit\n");
1243 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1244 fprintf(output, " persdata:path - personal data files\n");
1245 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1246 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1248 fprintf(output, " --display=DISPLAY X display to use\n");
1257 * Report an error in command-line arguments.
1258 * Creates a console on Windows.
1259 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1260 * terminal isn't the standard error?
1263 wireshark_cmdarg_err(const char *fmt, va_list ap)
1268 fprintf(stderr, "wireshark: ");
1269 vfprintf(stderr, fmt, ap);
1270 fprintf(stderr, "\n");
1274 * Report additional information for an error in command-line arguments.
1275 * Creates a console on Windows.
1276 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1277 * terminal isn't the standard error?
1280 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1285 vfprintf(stderr, fmt, ap);
1286 fprintf(stderr, "\n");
1290 Once every 3 seconds we get a callback here which we use to update
1294 tap_update_cb(gpointer data _U_)
1296 draw_tap_listeners(FALSE);
1301 * Periodically process outstanding hostname lookups. If we have new items,
1302 * redraw the packet list and tree view.
1306 resolv_update_cb(gpointer data _U_)
1308 /* Anything new show up? */
1309 if (host_name_lookup_process()) {
1310 if (gtk_widget_get_window(pkt_scrollw))
1311 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1312 if (gtk_widget_get_window(tv_scrollw))
1313 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1316 /* Always check. Even if we don't do async lookups we could still get
1317 passive updates, e.g. from DNS packets. */
1322 /* Update various parts of the main window for a capture file "unsaved
1323 changes" change - update the title to reflect whether there are
1324 unsaved changes or not, and update the menus and toolbar to
1325 enable or disable the "Save" operation. */
1327 main_update_for_unsaved_changes(capture_file *cf)
1329 set_titlebar_for_capture_file(cf);
1330 set_menus_for_capture_file(cf);
1331 set_toolbar_for_capture_file(cf);
1336 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1338 /* Update menubar and toolbar */
1339 menu_auto_scroll_live_changed(auto_scroll_live_in);
1340 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1342 /* change auto scroll state */
1343 auto_scroll_live = auto_scroll_live_in;
1348 main_colorize_changed(gboolean packet_list_colorize)
1350 /* Update menubar and toolbar */
1351 menu_colorize_changed(packet_list_colorize);
1352 toolbar_colorize_changed(packet_list_colorize);
1354 /* change colorization */
1355 if(packet_list_colorize != recent.packet_list_colorize) {
1356 recent.packet_list_colorize = packet_list_colorize;
1357 color_filters_enable(packet_list_colorize);
1358 packet_list_colorize_packets();
1362 static GtkWidget *close_dlg = NULL;
1365 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1367 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1372 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1374 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1379 main_cf_cb_file_closing(capture_file *cf)
1381 /* if we have more than 10000 packets, show a splash screen while closing */
1382 /* XXX - don't know a better way to decide whether to show or not,
1383 * as most of the time is spend in various calls that destroy various
1384 * data structures, so it wouldn't be easy to use a progress bar,
1385 * rather than, say, a progress spinner, here! */
1386 if(cf->count > 10000) {
1387 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1388 "%sClosing file!%s\n\nPlease wait ...",
1389 simple_dialog_primary_start(),
1390 simple_dialog_primary_end());
1391 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1393 /* Clear maunally resolved addresses */
1394 manually_resolve_cleanup();
1395 /* Destroy all windows that refer to the
1396 capture file we're closing. */
1397 destroy_packet_wins();
1399 /* Update the titlebar to reflect the lack of a capture file. */
1400 set_titlebar_for_capture_file(NULL);
1402 /* Disable all menu and toolbar items that make sense only if
1403 you have a capture. */
1404 set_menus_for_capture_file(NULL);
1405 set_toolbar_for_capture_file(NULL);
1406 main_set_for_captured_packets(FALSE);
1407 set_menus_for_selected_packet(cf);
1408 main_set_for_capture_in_progress(FALSE);
1409 set_capture_if_dialog_for_capture_in_progress(FALSE);
1410 set_menus_for_selected_tree_row(cf);
1412 /* Set up main window for no capture file. */
1413 main_set_for_capture_file(FALSE);
1415 main_window_update();
1420 main_cf_cb_file_closed(capture_file *cf _U_)
1422 if(close_dlg != NULL) {
1423 splash_destroy(close_dlg);
1430 main_cf_cb_file_read_started(capture_file *cf _U_)
1432 tap_param_dlg_update();
1434 /* Set up main window for a capture file. */
1435 main_set_for_capture_file(TRUE);
1439 main_cf_cb_file_read_finished(capture_file *cf)
1443 if (!cf->is_tempfile && cf->filename) {
1444 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1445 add_menu_recent_capture_file(cf->filename);
1447 /* Remember folder for next Open dialog and save it in recent */
1448 dir_path = get_dirname(g_strdup(cf->filename));
1449 set_last_open_dir(dir_path);
1453 /* Update the appropriate parts of the main window. */
1454 main_update_for_unsaved_changes(cf);
1456 /* Enable menu items that make sense if you have some captured packets. */
1457 main_set_for_captured_packets(TRUE);
1461 main_cf_cb_file_rescan_finished(capture_file *cf)
1465 if (!cf->is_tempfile && cf->filename) {
1466 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1467 add_menu_recent_capture_file(cf->filename);
1469 /* Remember folder for next Open dialog and save it in recent */
1470 dir_path = get_dirname(g_strdup(cf->filename));
1471 set_last_open_dir(dir_path);
1475 /* Update the appropriate parts of the main window. */
1476 main_update_for_unsaved_changes(cf);
1480 static GList *icon_list_create(
1481 const guint8 *icon16_pb,
1482 const guint8 *icon32_pb,
1483 const guint8 *icon48_pb,
1484 const guint8 *icon64_pb)
1486 GList *icon_list = NULL;
1487 GdkPixbuf * pixbuf16;
1488 GdkPixbuf * pixbuf32;
1489 GdkPixbuf * pixbuf48;
1490 GdkPixbuf * pixbuf64;
1493 if(icon16_pb != NULL) {
1494 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1496 icon_list = g_list_append(icon_list, pixbuf16);
1499 if(icon32_pb != NULL) {
1500 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1502 icon_list = g_list_append(icon_list, pixbuf32);
1505 if(icon48_pb != NULL) {
1506 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1508 icon_list = g_list_append(icon_list, pixbuf48);
1511 if(icon64_pb != NULL) {
1512 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1514 icon_list = g_list_append(icon_list, pixbuf64);
1521 main_capture_cb_capture_prepared(capture_session *cap_session)
1523 static GList *icon_list = NULL;
1525 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1527 if(icon_list == NULL) {
1528 icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1530 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1532 /* Disable menu items that make no sense if you're currently running
1534 main_set_for_capture_in_progress(TRUE);
1535 set_capture_if_dialog_for_capture_in_progress(TRUE);
1537 /* Don't set up main window for a capture file. */
1538 main_set_for_capture_file(FALSE);
1542 main_capture_cb_capture_update_started(capture_session *cap_session)
1544 /* We've done this in "prepared" above, but it will be cleared while
1545 switching to the next multiple file. */
1546 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1548 main_set_for_capture_in_progress(TRUE);
1549 set_capture_if_dialog_for_capture_in_progress(TRUE);
1551 /* Enable menu items that make sense if you have some captured
1552 packets (yes, I know, we don't have any *yet*). */
1553 main_set_for_captured_packets(TRUE);
1555 /* Set up main window for a capture file. */
1556 main_set_for_capture_file(TRUE);
1560 main_capture_cb_capture_update_finished(capture_session *cap_session)
1562 capture_file *cf = (capture_file *)cap_session->cf;
1563 static GList *icon_list = NULL;
1565 /* The capture isn't stopping any more - it's stopped. */
1566 capture_stopping = FALSE;
1568 if (!cf->is_tempfile && cf->filename) {
1569 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1570 add_menu_recent_capture_file(cf->filename);
1573 /* Enable menu items that make sense if you're not currently running
1575 main_set_for_capture_in_progress(FALSE);
1576 set_capture_if_dialog_for_capture_in_progress(FALSE);
1578 /* Update the main window as appropriate. This has to occur AFTER
1579 * main_set_for_capture_in_progress() or else some of the menus are
1580 * incorrectly disabled (see bug
1581 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1582 main_update_for_unsaved_changes(cf);
1584 /* Set up main window for a capture file. */
1585 main_set_for_capture_file(TRUE);
1587 if(icon_list == NULL) {
1588 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1590 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1592 if(global_capture_opts.quit_after_cap) {
1593 /* command line asked us to quit after the capture */
1594 /* don't pop up a dialog to ask for unsaved files etc. */
1600 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1602 /* Don't set up main window for a capture file. */
1603 main_set_for_capture_file(FALSE);
1607 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1610 capture_file *cf = (capture_file *)cap_session->cf;
1612 static GList *icon_list = NULL;
1614 /* The capture isn't stopping any more - it's stopped. */
1615 capture_stopping = FALSE;
1617 /*set_titlebar_for_capture_file(cf);*/
1619 /* Enable menu items that make sense if you're not currently running
1621 main_set_for_capture_in_progress(FALSE);
1622 set_capture_if_dialog_for_capture_in_progress(FALSE);
1624 /* Restore the standard title bar message */
1625 /* (just in case we have trouble opening the capture file). */
1626 set_titlebar_for_capture_file(NULL);
1628 if(icon_list == NULL) {
1629 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1631 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1633 /* We don't have loaded the capture file, this will be done later.
1634 * For now we still have simply a blank screen. */
1636 if(global_capture_opts.quit_after_cap) {
1637 /* command line asked us to quit after the capture */
1638 /* don't pop up a dialog to ask for unsaved files etc. */
1644 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1646 capture_stopping = TRUE;
1647 set_menus_for_capture_stopping();
1649 set_toolbar_for_capture_stopping();
1651 set_capture_if_dialog_for_capture_stopping();
1656 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1658 static GList *icon_list = NULL;
1660 /* Capture isn't stopping any more. */
1661 capture_stopping = FALSE;
1663 /* the capture failed before the first packet was captured
1664 reset title, menus and icon */
1665 set_titlebar_for_capture_file(NULL);
1667 main_set_for_capture_in_progress(FALSE);
1668 set_capture_if_dialog_for_capture_in_progress(FALSE);
1670 main_set_for_capture_file(FALSE);
1672 if(icon_list == NULL) {
1673 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1675 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1678 if(global_capture_opts.quit_after_cap) {
1679 /* command line asked us to quit after the capture */
1680 /* don't pop up a dialog to ask for unsaved files etc. */
1684 #endif /* HAVE_LIBPCAP */
1687 main_cf_cb_packet_selected(gpointer data)
1689 capture_file *cf = (capture_file *)data;
1691 /* Display the GUI protocol tree and packet bytes.
1692 XXX - why do we dump core if we call "proto_tree_draw()"
1693 before calling "add_byte_views()"? */
1694 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1695 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1697 /* Note: Both string and hex value searches in the packet data produce a non-zero
1698 search_pos if successful */
1699 if(cf->search_in_progress &&
1700 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1701 highlight_field(cf->edt->tvb, cf->search_pos,
1702 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1705 /* A packet is selected. */
1706 set_menus_for_selected_packet(cf);
1710 main_cf_cb_packet_unselected(capture_file *cf)
1712 /* No packet is being displayed; clear the hex dump pane by getting
1713 rid of all the byte views. */
1714 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1715 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1717 /* Add a placeholder byte view so that there's at least something
1718 displayed in the byte view notebook. */
1719 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1721 /* And clear the protocol tree display as well. */
1722 proto_tree_draw(NULL, tree_view_gbl);
1724 /* No packet is selected. */
1725 set_menus_for_selected_packet(cf);
1729 main_cf_cb_field_unselected(capture_file *cf)
1731 set_menus_for_selected_tree_row(cf);
1735 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1737 capture_file *cf = (capture_file *)data;
1739 case(cf_cb_file_opened):
1740 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1741 fileset_file_opened(cf);
1743 case(cf_cb_file_closing):
1744 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1745 main_cf_cb_file_closing(cf);
1747 case(cf_cb_file_closed):
1748 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1749 main_cf_cb_file_closed(cf);
1750 fileset_file_closed();
1752 case(cf_cb_file_read_started):
1753 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1754 main_cf_cb_file_read_started(cf);
1756 case(cf_cb_file_read_finished):
1757 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1758 main_cf_cb_file_read_finished(cf);
1760 case(cf_cb_file_reload_started):
1761 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1762 main_cf_cb_file_read_started(cf);
1764 case(cf_cb_file_reload_finished):
1765 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1766 main_cf_cb_file_read_finished(cf);
1768 case(cf_cb_file_rescan_started):
1769 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1771 case(cf_cb_file_rescan_finished):
1772 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1773 main_cf_cb_file_rescan_finished(cf);
1775 case(cf_cb_file_retap_started):
1776 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap started");
1778 case(cf_cb_file_retap_finished):
1779 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap finished");
1781 case(cf_cb_file_fast_save_finished):
1782 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1783 main_cf_cb_file_rescan_finished(cf);
1785 case(cf_cb_packet_selected):
1786 main_cf_cb_packet_selected(cf);
1788 case(cf_cb_packet_unselected):
1789 main_cf_cb_packet_unselected(cf);
1791 case(cf_cb_field_unselected):
1792 main_cf_cb_field_unselected(cf);
1794 case(cf_cb_file_save_started):
1795 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1797 case(cf_cb_file_save_finished):
1798 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1800 case(cf_cb_file_save_failed):
1801 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1803 case(cf_cb_file_save_stopped):
1804 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1806 case(cf_cb_file_export_specified_packets_started):
1807 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1809 case(cf_cb_file_export_specified_packets_finished):
1810 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1812 case(cf_cb_file_export_specified_packets_failed):
1813 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1815 case(cf_cb_file_export_specified_packets_stopped):
1816 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1819 g_warning("main_cf_callback: event %u unknown", event);
1820 g_assert_not_reached();
1826 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1828 #ifdef HAVE_GTKOSXAPPLICATION
1829 GtkosxApplication *theApp;
1832 case(capture_cb_capture_prepared):
1833 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1834 main_capture_cb_capture_prepared(cap_session);
1836 case(capture_cb_capture_update_started):
1837 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1838 main_capture_cb_capture_update_started(cap_session);
1839 #ifdef HAVE_GTKOSXAPPLICATION
1840 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1841 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1844 case(capture_cb_capture_update_continue):
1845 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1847 case(capture_cb_capture_update_finished):
1848 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1849 main_capture_cb_capture_update_finished(cap_session);
1851 case(capture_cb_capture_fixed_started):
1852 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1853 main_capture_cb_capture_fixed_started(cap_session);
1855 case(capture_cb_capture_fixed_continue):
1856 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1858 case(capture_cb_capture_fixed_finished):
1859 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1860 main_capture_cb_capture_fixed_finished(cap_session);
1862 case(capture_cb_capture_stopping):
1863 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1864 /* Beware: this state won't be called, if the capture child
1865 * closes the capturing on its own! */
1866 #ifdef HAVE_GTKOSXAPPLICATION
1867 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1868 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1870 main_capture_cb_capture_stopping(cap_session);
1872 case(capture_cb_capture_failed):
1873 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1874 main_capture_cb_capture_failed(cap_session);
1877 g_warning("main_capture_callback: event %u unknown", event);
1878 g_assert_not_reached();
1884 get_wireshark_gtk_compiled_info(GString *str)
1886 g_string_append(str, "with ");
1887 g_string_append_printf(str,
1888 #ifdef GTK_MAJOR_VERSION
1889 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1892 "GTK+ (version unknown)");
1896 g_string_append(str, ", with Cairo ");
1897 g_string_append(str, CAIRO_VERSION_STRING);
1900 g_string_append(str, ", with Pango ");
1901 g_string_append(str, PANGO_VERSION_STRING);
1903 /* Capture libraries */
1904 g_string_append(str, ", ");
1905 get_compiled_caplibs_version(str);
1908 g_string_append(str, ", ");
1910 g_string_append(str, "with libz ");
1912 g_string_append(str, ZLIB_VERSION);
1913 #else /* ZLIB_VERSION */
1914 g_string_append(str, "(version unknown)");
1915 #endif /* ZLIB_VERSION */
1916 #else /* HAVE_LIBZ */
1917 g_string_append(str, "without libz");
1918 #endif /* HAVE_LIBZ */
1922 get_gui_compiled_info(GString *str)
1924 epan_get_compiled_version_info(str);
1926 g_string_append(str, ", ");
1927 #ifdef HAVE_LIBPORTAUDIO
1928 #ifdef PORTAUDIO_API_1
1929 g_string_append(str, "with PortAudio <= V18");
1930 #else /* PORTAUDIO_API_1 */
1931 g_string_append(str, "with ");
1932 g_string_append(str, Pa_GetVersionText());
1933 #endif /* PORTAUDIO_API_1 */
1934 #else /* HAVE_LIBPORTAUDIO */
1935 g_string_append(str, "without PortAudio");
1936 #endif /* HAVE_LIBPORTAUDIO */
1938 g_string_append(str, ", ");
1940 get_compiled_airpcap_version(str);
1942 g_string_append(str, "without AirPcap");
1947 get_wireshark_runtime_info(GString *str)
1950 /* Capture libraries */
1951 g_string_append(str, ", ");
1952 get_runtime_caplibs_version(str);
1956 #if defined(HAVE_LIBZ) && !defined(_WIN32)
1957 g_string_append_printf(str, ", with libz %s", zlibVersion());
1960 /* stuff used by libwireshark */
1961 epan_get_runtime_version_info(str);
1964 g_string_append(str, ", ");
1965 get_runtime_airpcap_version(str);
1969 g_string_append(str, ", ");
1970 u3_runtime_info(str);
1975 read_configuration_files(char **gdp_path, char **dp_path)
1977 int gpf_open_errno, gpf_read_errno;
1978 int cf_open_errno, df_open_errno;
1979 int gdp_open_errno, gdp_read_errno;
1980 int dp_open_errno, dp_read_errno;
1981 char *gpf_path, *pf_path;
1982 char *cf_path, *df_path;
1983 int pf_open_errno, pf_read_errno;
1986 /* load the decode as entries of this profile */
1987 load_decode_as_entries();
1989 /* Read the preference files. */
1990 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1991 &pf_open_errno, &pf_read_errno, &pf_path);
1993 if (gpf_path != NULL) {
1994 if (gpf_open_errno != 0) {
1995 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1996 "Could not open global preferences file\n\"%s\": %s.",
1997 gpf_path, g_strerror(gpf_open_errno));
1999 if (gpf_read_errno != 0) {
2000 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2001 "I/O error reading global preferences file\n\"%s\": %s.",
2002 gpf_path, g_strerror(gpf_read_errno));
2005 if (pf_path != NULL) {
2006 if (pf_open_errno != 0) {
2007 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2008 "Could not open your preferences file\n\"%s\": %s.",
2009 pf_path, g_strerror(pf_open_errno));
2011 if (pf_read_errno != 0) {
2012 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2013 "I/O error reading your preferences file\n\"%s\": %s.",
2014 pf_path, g_strerror(pf_read_errno));
2021 /* if the user wants a console to be always there, well, we should open one for him */
2022 if (prefs_p->gui_console_open == console_open_always) {
2027 /* Read the capture filter file. */
2028 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2029 if (cf_path != NULL) {
2030 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2031 "Could not open your capture filter file\n\"%s\": %s.",
2032 cf_path, g_strerror(cf_open_errno));
2036 /* Read the display filter file. */
2037 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2038 if (df_path != NULL) {
2039 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2040 "Could not open your display filter file\n\"%s\": %s.",
2041 df_path, g_strerror(df_open_errno));
2045 /* Read the disabled protocols file. */
2046 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2047 dp_path, &dp_open_errno, &dp_read_errno);
2048 read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2049 dp_path, &dp_open_errno, &dp_read_errno);
2050 if (*gdp_path != NULL) {
2051 if (gdp_open_errno != 0) {
2052 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2053 "Could not open global disabled protocols file\n\"%s\": %s.",
2054 *gdp_path, g_strerror(gdp_open_errno));
2056 if (gdp_read_errno != 0) {
2057 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2058 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2059 *gdp_path, g_strerror(gdp_read_errno));
2064 if (*dp_path != NULL) {
2065 if (dp_open_errno != 0) {
2066 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2067 "Could not open your disabled protocols file\n\"%s\": %s.",
2068 *dp_path, g_strerror(dp_open_errno));
2070 if (dp_read_errno != 0) {
2071 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2072 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2073 *dp_path, g_strerror(dp_read_errno));
2082 /* Check if there's something important to tell the user during startup.
2083 * We want to do this *after* showing the main window so that any windows
2084 * we pop up will be above the main window.
2088 check_and_warn_user_startup(gchar *cf_name)
2090 check_and_warn_user_startup(gchar *cf_name _U_)
2093 gchar *cur_user, *cur_group;
2094 gpointer priv_warning_dialog;
2096 /* Tell the user not to run as root. */
2097 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2098 cur_user = get_cur_username();
2099 cur_group = get_cur_groupname();
2100 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2101 "Running as user \"%s\" and group \"%s\".\n"
2102 "This could be dangerous.\n\n"
2103 "If you're running Wireshark this way in order to perform live capture, "
2104 "you may want to be aware that there is a better way documented at\n"
2105 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2108 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2109 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2113 /* Warn the user if npf.sys isn't loaded. */
2114 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2115 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2116 "The NPF driver isn't running. You may have trouble\n"
2117 "capturing or listing interfaces.");
2118 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2119 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2125 /* And now our feature presentation... [ fade to music ] */
2127 main(int argc, char *argv[])
2129 char *init_progfile_dir_error;
2132 gboolean arg_error = FALSE;
2134 extern int info_update_freq; /* Found in about_dlg.c. */
2135 const gchar *filter;
2143 char *gdp_path, *dp_path;
2146 gboolean start_capture = FALSE;
2147 gboolean list_link_layer_types = FALSE;
2152 gboolean capture_option_specified = FALSE;
2159 gint pl_size = 280, tv_size = 95, bv_size = 75;
2160 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2161 dfilter_t *rfcode = NULL;
2163 gboolean rfilter_parse_failed = FALSE;
2166 GtkWidget *splash_win = NULL;
2167 guint go_to_packet = 0;
2168 search_direction jump_backwards = SD_FORWARD;
2169 dfilter_t *jump_to_filter = NULL;
2170 unsigned int in_file_type = WTAP_TYPE_AUTO;
2171 #ifdef HAVE_GTKOSXAPPLICATION
2172 GtkosxApplication *theApp;
2174 GSList *disable_protocol_slist = NULL;
2175 GSList *enable_heur_slist = NULL;
2176 GSList *disable_heur_slist = NULL;
2178 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
2180 static const struct option long_options[] = {
2181 {(char *)"help", no_argument, NULL, 'h'},
2182 {(char *)"read-file", required_argument, NULL, 'r' },
2183 {(char *)"read-filter", required_argument, NULL, 'R' },
2184 {(char *)"display-filter", required_argument, NULL, 'Y' },
2185 {(char *)"version", no_argument, NULL, 'v'},
2186 LONGOPT_CAPTURE_COMMON
2190 static const char optstring[] = OPTSTRING;
2192 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2194 /* Set the C-language locale to the native environment. */
2195 setlocale(LC_ALL, "");
2197 arg_list_utf_16to8(argc, argv);
2198 create_app_running_mutex();
2202 * Get credential information for later use, and drop privileges
2203 * before doing anything else.
2204 * Let the user know if anything happened.
2206 init_process_policies();
2207 relinquish_special_privs_perm();
2210 * Attempt to get the pathname of the executable file.
2212 init_progfile_dir_error = init_progfile_dir(argv[0], (void *)main);
2214 /* initialize the funnel mini-api */
2215 initialize_funnel_ops();
2217 AirPDcapInitContext(&airpdcap_ctx);
2220 /* Load wpcap if possible. Do this before collecting the run-time version information */
2223 /* ... and also load the packet.dll from wpcap */
2224 wpcap_packet_load();
2227 /* Load the airpcap.dll. This must also be done before collecting
2228 * run-time version information. */
2229 airpcap_dll_ret_val = load_airpcap();
2231 switch (airpcap_dll_ret_val) {
2232 case AIRPCAP_DLL_OK:
2233 /* load the airpcap interfaces */
2234 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2236 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
2237 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2238 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2241 airpcap_if_active = NULL;
2245 /* select the first ad default (THIS SHOULD BE CHANGED) */
2246 airpcap_if_active = airpcap_get_default_if(g_airpcap_if_list);
2251 * XXX - Maybe we need to warn the user if one of the following happens???
2253 case AIRPCAP_DLL_OLD:
2254 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2257 case AIRPCAP_DLL_ERROR:
2258 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2261 case AIRPCAP_DLL_NOT_FOUND:
2262 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2266 #endif /* HAVE_AIRPCAP */
2269 /* Get the compile-time version information string */
2270 comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
2271 get_gui_compiled_info);
2273 /* Get the run-time version information string */
2274 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
2276 /* Add it to the information to be reported on a crash. */
2277 ws_add_crash_info("Wireshark %s\n"
2282 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2285 /* Start windows sockets */
2286 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2289 profile_store_persconffiles (TRUE);
2291 /* Read the profile independent recent file. We have to do this here so we can */
2292 /* set the profile before it can be set from the command line parameter */
2293 recent_read_static(&rf_path, &rf_open_errno);
2294 if (rf_path != NULL && rf_open_errno != 0) {
2295 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2296 "Could not open common recent file\n\"%s\": %s.",
2297 rf_path, g_strerror(rf_open_errno));
2301 * In order to have the -X opts assigned before the wslua machine starts
2302 * we need to call getopt_long before epan_init() gets called.
2304 * In addition, we process "console only" parameters (ones where we
2305 * send output to the console and exit) here, so we don't start GTK+
2306 * if we're only showing command-line help or version information.
2308 * XXX - this pre-scan is done before we start GTK+, so we haven't
2309 * run gtk_init() on the arguments. That means that GTK+ arguments
2310 * have not been removed from the argument list; those arguments
2311 * begin with "--", and will be treated as an error by getopt_long().
2313 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
2316 * XXX - should we, instead, first call gtk_parse_args(), without
2317 * calling gtk_init(), and then call this?
2319 * In order to handle, for example, -o options, we also need to call it
2320 * *after* epan_init() gets called, so that the dissectors have had a
2321 * chance to register their preferences, so we have another getopt_long()
2324 * XXX - can we do this all with one getopt_long() call, saving the
2325 * arguments we can't handle until after initializing libwireshark,
2326 * and then process them after initializing libwireshark?
2328 * Note that we don't want to initialize libwireshark until after the
2329 * GUI is up, as that can take a while, and we want a window of some
2330 * sort up to show progress while that's happening.
2334 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
2336 case 'C': /* Configuration Profile */
2337 if (profile_exists (optarg, FALSE)) {
2338 set_profile_name (optarg);
2340 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2344 case 'D': /* Print a list of capture devices and exit */
2346 if_list = capture_interface_list(&err, &err_str, NULL);
2347 if (if_list == NULL) {
2349 cmdarg_err("There are no interfaces on which a capture can be done");
2351 cmdarg_err("%s", err_str);
2359 capture_opts_print_interfaces(if_list);
2360 free_interface_list(if_list);
2365 #else /* HAVE_LIBPCAP */
2366 capture_option_specified = TRUE;
2368 #endif /* HAVE_LIBPCAP */
2370 case 'h': /* Print help and exit */
2376 if (strcmp(optarg, "-") == 0)
2377 set_stdin_capture(TRUE);
2380 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
2381 if (!persfilepath_opt(opt, optarg)) {
2382 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2386 case 'v': /* Show version and exit */
2390 show_version("Wireshark", comp_info_str, runtime_info_str);
2398 * Extension command line options have to be processed before
2399 * we call epan_init() as they are supposed to be used by dissectors
2400 * or taps very early in the registration process.
2404 case '?': /* Ignore errors - the "real" scan will catch them. */
2409 /* Init the "Open file" dialog directory */
2410 /* (do this after the path settings are processed) */
2412 /* Read the profile dependent (static part) of the recent file. */
2413 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2414 /* recent lists which is done in the dynamic part. */
2415 /* We have to do this already here, so command line parameters can overwrite these values. */
2416 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
2417 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2418 "Could not open recent file\n\"%s\": %s.",
2419 rf_path, g_strerror(rf_open_errno));
2423 if (recent.gui_fileopen_remembered_dir &&
2424 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2425 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2427 set_last_open_dir(get_persdatafile_dir());
2430 #if !GLIB_CHECK_VERSION(2,31,0)
2431 g_thread_init(NULL);
2434 /* Set the current locale according to the program environment.
2435 * We haven't localized anything, but some GTK widgets are localized
2436 * (the file selection dialogue, for example).
2437 * This also sets the C-language locale to the native environment. */
2438 setlocale (LC_ALL, "");
2440 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2441 gtk_init (&argc, &argv);
2443 cf_callback_add(main_cf_callback, NULL);
2445 capture_callback_add(main_capture_callback, NULL);
2448 cf_callback_add(statusbar_cf_callback, NULL);
2450 capture_callback_add(statusbar_capture_callback, NULL);
2453 cf_callback_add(welcome_cf_callback, NULL);
2455 capture_callback_add(welcome_capture_callback, NULL);
2458 set_console_log_handler();
2461 /* Set the initial values in the capture options. This might be overwritten
2462 by preference settings and then again by the command line parameters. */
2463 capture_opts_init(&global_capture_opts);
2465 capture_session_init(&global_capture_session, &cfile);
2468 init_report_err(failure_alert_box, open_failure_alert_box,
2469 read_failure_alert_box, write_failure_alert_box);
2471 /* Initialize whatever we need to allocate colors for GTK+ */
2474 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2475 filter = get_conn_cfilter();
2476 if ( *filter != '\0' ) {
2477 info_update_freq = 1000; /* Milliseconds */
2480 /* We won't come till here, if we had a "console only" command line parameter. */
2481 splash_win = splash_new("Loading Wireshark ...");
2482 if (init_progfile_dir_error != NULL) {
2483 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2484 "Can't get pathname of Wireshark: %s.\n"
2485 "It won't be possible to capture traffic.\n"
2486 "Report this to the Wireshark developers.",
2487 init_progfile_dir_error);
2488 g_free(init_progfile_dir_error);
2491 init_open_routines();
2494 /* Register all the plugin types we have. */
2495 epan_register_plugin_types(); /* Types known to libwireshark */
2496 wtap_register_plugin_types(); /* Types known to libwiretap */
2497 codec_register_plugin_types(); /* Types known to libcodec */
2499 /* Scan for plugins. This does *not* call their registration routines;
2500 that's done later. */
2503 /* Register all libwiretap plugin modules. */
2504 register_all_wiretap_modules();
2506 /* Register all audio codec plugins. */
2507 register_all_codecs();
2510 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2512 /* Register all dissectors; we must do this before checking for the
2513 "-G" flag, as the "-G" flag dumps information registered by the
2514 dissectors, and we must do it before we read the preferences, in
2515 case any dissectors register preferences. */
2516 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
2517 splash_update, (gpointer) splash_win))
2520 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2522 /* Register all tap listeners; we do this before we parse the arguments,
2523 as the "-z" argument can specify a registered tap. */
2525 /* we register the plugin taps before the other taps because
2526 stats_tree taps plugins will be registered as tap listeners
2527 by stats_tree_stat.c and need to registered before that */
2530 register_all_plugin_tap_listeners();
2533 register_all_tap_listeners();
2534 conversation_table_set_gui_info(init_conversation_table);
2535 hostlist_table_set_gui_info(init_hostlist_table);
2536 srt_table_iterate_tables(register_service_response_tables, NULL);
2537 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2538 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2540 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2542 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2543 /* Removed thread code:
2544 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2547 /* this is to keep tap extensions updating once every 3 seconds */
2548 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2550 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2552 cap_file_init(&cfile);
2554 /* Fill in capture options with values from the preferences */
2555 prefs_to_capture_opts();
2557 /*#ifdef HAVE_LIBPCAP
2558 fill_in_local_interfaces();
2561 * To reset the options parser, set optreset to 1 on platforms that
2562 * have optreset (documented in *BSD and OS X, apparently present but
2563 * not documented in Solaris - the Illumos repository seems to
2564 * suggest that the first Solaris getopt_long(), at least as of 2004,
2565 * was based on the NetBSD one, it had optreset) and set optind to 1,
2566 * and set optind to 0 otherwise (documented as working in the GNU
2567 * getopt_long(). Setting optind to 0 didn't originally work in the
2568 * NetBSD one, but that was added later - we don't want to depend on
2569 * it if we have optreset).
2571 * Also reset opterr to 1, so that error messages are printed by
2574 * XXX - if we want to control all the command-line option errors, so
2575 * that we can display them where we choose (e.g., in a window), we'd
2576 * want to leave opterr as 0, and produce our own messages using optopt.
2577 * We'd have to check the value of optopt to see if it's a valid option
2578 * letter, in which case *presumably* the error is "this option requires
2579 * an argument but none was specified", or not a valid option letter,
2580 * in which case *presumably* the error is "this option isn't valid".
2581 * Some versions of getopt() let you supply a option string beginning
2582 * with ':', which means that getopt() will return ':' rather than '?'
2583 * for "this option requires an argument but none was specified", but
2584 * not all do. But we're now using getopt_long() - what does it do?
2586 #ifdef HAVE_OPTRESET
2594 /* Now get our args */
2595 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
2597 /*** capture option specific ***/
2598 case 'a': /* autostop criteria */
2599 case 'b': /* Ringbuffer option */
2600 case 'c': /* Capture xxx packets */
2601 case 'f': /* capture filter */
2602 case 'k': /* Start capture immediately */
2603 case 'H': /* Hide capture info dialog box */
2604 case 'p': /* Don't capture in promiscuous mode */
2605 case 'i': /* Use interface x */
2606 #ifdef HAVE_PCAP_CREATE
2607 case 'I': /* Capture in monitor mode, if available */
2609 #ifdef HAVE_PCAP_REMOTE
2610 case 'A': /* Authentication */
2612 case 's': /* Set the snapshot (capture) length */
2613 case 'S': /* "Sync" mode: used for following file ala tail -f */
2614 case 'w': /* Write to capture file xxx */
2615 case 'y': /* Set the pcap data link type */
2616 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
2617 case 'B': /* Buffer size */
2620 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2626 capture_option_specified = TRUE;
2631 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2632 case 'K': /* Kerberos keytab file */
2633 read_keytab_file(optarg);
2637 /*** all non capture option specific ***/
2639 /* Configuration profile settings were already processed just ignore them this time*/
2641 case 'j': /* Search backwards for a matching packet from filter in option J */
2642 jump_backwards = SD_BACKWARD;
2644 case 'g': /* Go to packet with the given packet number */
2645 go_to_packet = get_positive_int(optarg, "go to packet");
2647 case 'J': /* Jump to the first packet which matches the filter criteria */
2650 case 'l': /* Automatic scrolling in live capture mode */
2652 auto_scroll_live = TRUE;
2654 capture_option_specified = TRUE;
2658 case 'L': /* Print list of link-layer types and exit */
2660 list_link_layer_types = TRUE;
2662 capture_option_specified = TRUE;
2666 case 'm': /* Fixed-width font for the display */
2667 g_free(prefs_p->gui_gtk2_font_name);
2668 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2670 case 'n': /* No name resolution */
2671 disable_name_resolution();
2673 case 'N': /* Select what types of addresses/port #s to resolve */
2674 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2675 if (badopt != '\0') {
2676 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
2681 case 'o': /* Override preference from command line */
2682 switch (prefs_set_pref(optarg)) {
2685 case PREFS_SET_SYNTAX_ERR:
2686 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2689 case PREFS_SET_NO_SUCH_PREF:
2690 /* not a preference, might be a recent setting */
2691 switch (recent_set_arg(optarg)) {
2694 case PREFS_SET_SYNTAX_ERR:
2695 /* shouldn't happen, checked already above */
2696 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2699 case PREFS_SET_NO_SUCH_PREF:
2700 case PREFS_SET_OBSOLETE:
2701 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2706 g_assert_not_reached();
2709 case PREFS_SET_OBSOLETE:
2710 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2715 g_assert_not_reached();
2719 /* Path settings were already processed just ignore them this time*/
2721 case 'r': /* Read capture file xxx */
2722 /* We may set "last_open_dir" to "cf_name", and if we change
2723 "last_open_dir" later, we free the old value, so we have to
2724 set "cf_name" to something that's been allocated. */
2725 cf_name = g_strdup(optarg);
2727 case 'R': /* Read file filter */
2730 case 't': /* Time stamp type */
2731 if (strcmp(optarg, "r") == 0)
2732 timestamp_set_type(TS_RELATIVE);
2733 else if (strcmp(optarg, "a") == 0)
2734 timestamp_set_type(TS_ABSOLUTE);
2735 else if (strcmp(optarg, "ad") == 0)
2736 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2737 else if (strcmp(optarg, "adoy") == 0)
2738 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
2739 else if (strcmp(optarg, "d") == 0)
2740 timestamp_set_type(TS_DELTA);
2741 else if (strcmp(optarg, "dd") == 0)
2742 timestamp_set_type(TS_DELTA_DIS);
2743 else if (strcmp(optarg, "e") == 0)
2744 timestamp_set_type(TS_EPOCH);
2745 else if (strcmp(optarg, "u") == 0)
2746 timestamp_set_type(TS_UTC);
2747 else if (strcmp(optarg, "ud") == 0)
2748 timestamp_set_type(TS_UTC_WITH_YMD);
2749 else if (strcmp(optarg, "udoy") == 0)
2750 timestamp_set_type(TS_UTC_WITH_YDOY);
2752 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2754 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2756 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2758 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2760 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2762 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2766 case 'u': /* Seconds type */
2767 if (strcmp(optarg, "s") == 0)
2768 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2769 else if (strcmp(optarg, "hms") == 0)
2770 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2772 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2774 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2779 /* ext ops were already processed just ignore them this time*/
2785 /* We won't call the init function for the stat this soon
2786 as it would disallow MATE's fields (which are registered
2787 by the preferences set callback) from being used as
2788 part of a tap filter. Instead, we just add the argument
2789 to a list of stat arguments. */
2790 if (strcmp("help", optarg) == 0) {
2791 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
2792 list_stat_cmd_args();
2795 if (!process_stat_cmd_arg(optarg)) {
2796 cmdarg_err("Invalid -z argument.");
2797 cmdarg_err_cont(" -z argument must be one of :");
2798 list_stat_cmd_args();
2802 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
2803 disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
2805 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
2806 enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
2808 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
2809 disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
2812 case '?': /* Bad flag - print usage message */
2821 if (cf_name != NULL) {
2823 * Input file name specified with "-r" *and* specified as a regular
2824 * command-line argument.
2826 cmdarg_err("File name specified both with -r and regular argument");
2830 * Input file name not specified with "-r", and a command-line argument
2831 * was specified; treat it as the input file name.
2833 * Yes, this is different from tshark, where non-flag command-line
2834 * arguments are a filter, but this works better on GUI desktops
2835 * where a command can be specified to be run to open a particular
2836 * file - yes, you could have "-r" as the last part of the command,
2837 * but that's a bit ugly.
2839 #ifndef HAVE_GTKOSXAPPLICATION
2841 * For GTK+ Mac Integration, file name passed as free argument passed
2842 * through grag-and-drop and opened twice sometimes causing crashes.
2843 * Subject to report to GTK+ MAC.
2845 cf_name = g_strdup(argv[0]);
2854 * Extra command line arguments were specified; complain.
2856 cmdarg_err("Invalid argument: %s", argv[0]);
2862 #ifndef HAVE_LIBPCAP
2863 if (capture_option_specified) {
2864 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2872 fill_in_local_interfaces(main_window_update);
2873 if (start_capture && list_link_layer_types) {
2874 /* Specifying *both* is bogus. */
2875 cmdarg_err("You can't specify both -L and a live capture.");
2879 if (list_link_layer_types) {
2880 /* We're supposed to list the link-layer types for an interface;
2881 did the user also specify a capture file to be read? */
2883 /* Yes - that's bogus. */
2884 cmdarg_err("You can't specify -L and a capture file to be read.");
2887 /* No - did they specify a ring buffer option? */
2888 if (global_capture_opts.multi_files_on) {
2889 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2893 /* We're supposed to do a live capture; did the user also specify
2894 a capture file to be read? */
2895 if (start_capture && cf_name) {
2896 /* Yes - that's bogus. */
2897 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2901 /* No - was the ring buffer option specified and, if so, does it make
2903 if (global_capture_opts.multi_files_on) {
2904 /* Ring buffer works only under certain conditions:
2905 a) ring buffer does not work with temporary files;
2906 b) real_time_mode and multi_files_on are mutually exclusive -
2907 real_time_mode takes precedence;
2908 c) it makes no sense to enable the ring buffer if the maximum
2909 file size is set to "infinite". */
2910 if (global_capture_opts.save_file == NULL) {
2911 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2912 global_capture_opts.multi_files_on = FALSE;
2914 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2915 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2916 /* XXX - this must be redesigned as the conditions changed */
2921 if (start_capture || list_link_layer_types) {
2922 /* We're supposed to do a live capture or get a list of link-layer
2923 types for a live capture device; if the user didn't specify an
2924 interface to use, pick a default. */
2925 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2926 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2932 if (list_link_layer_types) {
2933 /* Get the list of link-layer types for the capture devices. */
2934 if_capabilities_t *caps;
2937 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2939 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2940 if (device.selected) {
2941 gchar* auth_str = NULL;
2942 #ifdef HAVE_PCAP_REMOTE
2943 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
2944 auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
2945 device.remote_opts.remote_host_opts.auth_password);
2948 #if defined(HAVE_PCAP_CREATE)
2949 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
2951 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
2955 cmdarg_err("%s", err_str);
2959 if (caps->data_link_types == NULL) {
2960 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2966 #if defined(HAVE_PCAP_CREATE)
2967 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2969 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2974 free_if_capabilities(caps);
2979 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2980 capture_opts_trim_ring_num_files(&global_capture_opts);
2981 #endif /* HAVE_LIBPCAP */
2983 /* Notify all registered modules that have had any of their preferences
2984 changed either from one of the preferences file or from the command
2985 line that their preferences have changed. */
2989 if ((global_capture_opts.num_selected == 0) &&
2990 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2993 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2994 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2995 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2996 device.selected = TRUE;
2997 global_capture_opts.num_selected++;
2998 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2999 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
3004 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
3005 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
3006 device.selected = TRUE;
3007 global_capture_opts.num_selected++;
3008 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
3009 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
3013 /* disabled protocols as per configuration file */
3014 if (gdp_path == NULL && dp_path == NULL) {
3015 set_disabled_protos_list();
3016 set_disabled_heur_dissector_list();
3019 if(disable_protocol_slist) {
3020 GSList *proto_disable;
3021 for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
3023 proto_disable_proto_by_name((char*)proto_disable->data);
3027 if(enable_heur_slist) {
3028 GSList *heur_enable;
3029 for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
3031 proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
3035 if(disable_heur_slist) {
3036 GSList *heur_disable;
3037 for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
3039 proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
3043 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
3045 /* read in rc file from global and personal configuration paths. */
3046 rc_file = get_datafile_path(RC_FILE);
3047 #if GTK_CHECK_VERSION(3,0,0)
3048 /* XXX resolve later */
3050 gtk_rc_parse(rc_file);
3052 rc_file = get_persconffile_path(RC_FILE, FALSE);
3053 gtk_rc_parse(rc_file);
3063 /* close the splash screen, as we are going to open the main window now */
3064 splash_destroy(splash_win);
3066 /************************************************************************/
3067 /* Everything is prepared now, preferences and command line was read in */
3069 /* Pop up the main window. */
3070 create_main_window(pl_size, tv_size, bv_size, prefs_p);
3072 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3073 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
3074 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3075 "Could not open recent file\n\"%s\": %s.",
3076 rf_path, g_strerror(rf_open_errno));
3080 color_filters_enable(recent.packet_list_colorize);
3082 /* rearrange all the widgets as we now have all recent settings ready for this */
3083 main_widgets_rearrange();
3085 /* Fill in column titles. This must be done after the top level window
3088 XXX - is that still true, with fixed-width columns? */
3090 menu_recent_read_finished();
3092 main_auto_scroll_live_changed(auto_scroll_live);
3095 switch (user_font_apply()) {
3098 case FA_FONT_NOT_RESIZEABLE:
3099 /* "user_font_apply()" popped up an alert box. */
3100 /* turn off zooming - font can't be resized */
3101 case FA_FONT_NOT_AVAILABLE:
3102 /* XXX - did we successfully load the un-zoomed version earlier?
3103 If so, this *probably* means the font is available, but not at
3104 this particular zoom level, but perhaps some other failure
3105 occurred; I'm not sure you can determine which is the case,
3107 /* turn off zooming - zoom level is unavailable */
3109 /* in any other case than FA_SUCCESS, turn off zooming */
3110 recent.gui_zoom_level = 0;
3111 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3114 dnd_init(top_level);
3116 color_filters_init();
3118 capture_filter_init();
3121 /* the window can be sized only, if it's not already shown, so do it now! */
3122 main_load_window_geometry(top_level);
3124 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3126 /* If we were given the name of a capture file, read it in now;
3127 we defer it until now, so that, if we can't open it, and pop
3128 up an alert box, the alert box is more likely to come up on
3129 top of the main window - but before the preference-file-error
3130 alert box, so, if we get one of those, it's more likely to come
3133 show_main_window(TRUE);
3134 check_and_warn_user_startup(cf_name);
3135 if (rfilter != NULL) {
3136 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
3137 bad_dfilter_alert_box(top_level, rfilter, err_msg);
3139 rfilter_parse_failed = TRUE;
3142 if (ex_opt_count("read_format") > 0) {
3143 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
3145 if (!rfilter_parse_failed) {
3146 if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
3147 /* "cf_open()" succeeded, so it closed the previous
3148 capture file, and thus destroyed any previous read filter
3149 attached to "cf". */
3151 cfile.rfcode = rfcode;
3152 /* Open stat windows; we do so after creating the main window,
3153 to avoid GTK warnings, and after successfully opening the
3154 capture file, so we know we have something to compute stats
3155 on, and after registering all dissectors, so that MATE will
3156 have registered its field array and we can have a tap filter
3157 with one of MATE's late-registered fields as part of the
3159 start_requested_stats();
3161 /* Read the capture file. */
3162 switch (cf_read(&cfile, FALSE)) {
3166 /* Just because we got an error, that doesn't mean we were unable
3167 to read any of the file; we handle what we could get from the
3169 /* if the user told us to jump to a specific packet, do it now */
3170 if(go_to_packet != 0) {
3171 /* Jump to the specified frame number, kept for backward
3173 cf_goto_frame(&cfile, go_to_packet);
3174 } else if (jfilter != NULL) {
3175 /* try to compile given filter */
3176 if (!dfilter_compile(jfilter, &jump_to_filter, &err_msg)) {
3177 bad_dfilter_alert_box(top_level, jfilter, err_msg);
3180 /* Filter ok, jump to the first packet matching the filter
3181 conditions. Default search direction is forward, but if
3182 option d was given, search backwards */
3183 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3188 case CF_READ_ABORTED:
3194 /* If the filename is not the absolute path, prepend the current dir. This happens
3195 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3196 if (!g_path_is_absolute(cf_name)) {
3197 char *old_cf_name = cf_name;
3198 char *pwd = g_get_current_dir();
3199 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3200 g_free(old_cf_name);
3204 /* Save the name of the containing directory specified in the
3205 path name, if any; we can write over cf_name, which is a
3206 good thing, given that "get_dirname()" does write over its
3208 s = get_dirname(cf_name);
3209 set_last_open_dir(s);
3214 dfilter_free(rfcode);
3215 cfile.rfcode = NULL;
3216 show_main_window(FALSE);
3217 /* Don't call check_and_warn_user_startup(): we did it above */
3218 main_set_for_capture_in_progress(FALSE);
3219 set_capture_if_dialog_for_capture_in_progress(FALSE);
3224 if (start_capture) {
3225 if (global_capture_opts.save_file != NULL) {
3226 /* Save the directory name for future file dialogs. */
3227 /* (get_dirname overwrites filename) */
3228 s = get_dirname(g_strdup(global_capture_opts.save_file));
3229 set_last_open_dir(s);
3232 /* "-k" was specified; start a capture. */
3233 show_main_window(FALSE);
3234 check_and_warn_user_startup(cf_name);
3236 /* If no user interfaces were specified on the command line,
3237 copy the list of selected interfaces to the set of interfaces
3238 to use for this capture. */
3239 if (global_capture_opts.ifaces->len == 0)
3240 collect_ifaces(&global_capture_opts);
3241 if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3242 /* The capture started. Open stat windows; we do so after creating
3243 the main window, to avoid GTK warnings, and after successfully
3244 opening the capture file, so we know we have something to compute
3245 stats on, and after registering all dissectors, so that MATE will
3246 have registered its field array and we can have a tap filter with
3247 one of MATE's late-registered fields as part of the filter. */
3248 start_requested_stats();
3251 show_main_window(FALSE);
3252 check_and_warn_user_startup(cf_name);
3253 main_set_for_capture_in_progress(FALSE);
3254 set_capture_if_dialog_for_capture_in_progress(FALSE);
3256 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3257 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3258 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3260 #else /* HAVE_LIBPCAP */
3261 show_main_window(FALSE);
3262 check_and_warn_user_startup(cf_name);
3263 main_set_for_capture_in_progress(FALSE);
3264 set_capture_if_dialog_for_capture_in_progress(FALSE);
3265 #endif /* HAVE_LIBPCAP */
3269 GtkWidget *filter_te;
3270 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3271 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3273 /* Run the display filter so it goes in effect. */
3274 main_filter_packets(&cfile, dfilter, FALSE);
3278 /* register our pid if we are being run from a U3 device */
3281 profile_store_persconffiles (FALSE);
3283 #ifdef HAVE_GTKOSXAPPLICATION
3284 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3285 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3286 gtkosx_application_ready(theApp);
3289 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3292 gtk_iface_mon_start();
3295 software_update_init();
3297 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3299 /* ... back from GTK, we're going down now! */
3302 gtk_iface_mon_stop();
3305 /* deregister our pid */
3306 u3_deregister_pid();
3310 AirPDcapDestroyContext(&airpdcap_ctx);
3312 #ifdef HAVE_GTKOSXAPPLICATION
3313 g_object_unref(theApp);
3317 /* hide the (unresponsive) main window, while asking the user to close the console window */
3318 if (G_IS_OBJECT(top_level))
3319 gtk_widget_hide(top_level);
3321 software_update_cleanup();
3323 /* Shutdown windows sockets */
3326 /* For some unknown reason, the "atexit()" call in "create_console()"
3327 doesn't arrange that "destroy_console()" be called when we exit,
3328 so we call it here if a console was created. */
3337 /* We build this as a GUI subsystem application on Win32, so
3338 "WinMain()", not "main()", gets called.
3340 Hack shamelessly stolen from the Win32 port of the GIMP. */
3342 #define _stdcall __attribute__((stdcall))
3346 WinMain (struct HINSTANCE__ *hInstance,
3347 struct HINSTANCE__ *hPrevInstance,
3351 INITCOMMONCONTROLSEX comm_ctrl;
3354 * Initialize our DLL search path. MUST be called before LoadLibrary
3357 ws_init_dll_search_path();
3359 /* Initialize our controls. Required for native Windows file dialogs. */
3360 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3361 comm_ctrl.dwSize = sizeof(comm_ctrl);
3362 /* Includes the animate, header, hot key, list view, progress bar,
3363 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3366 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3367 InitCommonControlsEx(&comm_ctrl);
3369 /* RichEd20.DLL is needed for filter entries. */
3370 ws_load_library("riched20.dll");
3372 set_has_console(FALSE);
3373 set_console_wait(FALSE);
3374 return main (__argc, __argv);
3383 * Helper for main_widgets_rearrange()
3385 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3386 gtk_container_remove(GTK_CONTAINER(data), widget);
3389 static GtkWidget *main_widget_layout(gint layout_content)
3391 switch(layout_content) {
3392 case(layout_pane_content_none):
3394 case(layout_pane_content_plist):
3396 case(layout_pane_content_pdetails):
3398 case(layout_pane_content_pbytes):
3399 return byte_nb_ptr_gbl;
3401 g_assert_not_reached();
3407 * Rearrange the main window widgets
3409 void main_widgets_rearrange(void) {
3410 GtkWidget *first_pane_widget1, *first_pane_widget2;
3411 GtkWidget *second_pane_widget1, *second_pane_widget2;
3412 gboolean split_top_left = FALSE;
3414 /* be a bit faster */
3415 gtk_widget_hide(main_vbox);
3417 /* be sure we don't lose a widget while rearranging */
3418 g_object_ref(G_OBJECT(menubar));
3419 g_object_ref(G_OBJECT(main_tb));
3420 g_object_ref(G_OBJECT(filter_tb));
3421 g_object_ref(G_OBJECT(wireless_tb));
3422 g_object_ref(G_OBJECT(pkt_scrollw));
3423 g_object_ref(G_OBJECT(tv_scrollw));
3424 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3425 g_object_ref(G_OBJECT(statusbar));
3426 g_object_ref(G_OBJECT(main_pane_v1));
3427 g_object_ref(G_OBJECT(main_pane_v2));
3428 g_object_ref(G_OBJECT(main_pane_h1));
3429 g_object_ref(G_OBJECT(main_pane_h2));
3430 g_object_ref(G_OBJECT(welcome_pane));
3432 /* empty all containers participating */
3433 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3434 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3435 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3436 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3437 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3439 statusbar_widgets_emptying(statusbar);
3441 /* add the menubar always at the top */
3442 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3445 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3447 /* filter toolbar in toolbar area */
3448 if (!prefs.filter_toolbar_show_in_statusbar) {
3449 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3452 /* airpcap toolbar */
3453 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3455 /* fill the main layout panes */
3456 switch(prefs.gui_layout_type) {
3457 case(layout_type_5):
3458 main_first_pane = main_pane_v1;
3459 main_second_pane = main_pane_v2;
3460 split_top_left = FALSE;
3462 case(layout_type_2):
3463 main_first_pane = main_pane_v1;
3464 main_second_pane = main_pane_h1;
3465 split_top_left = FALSE;
3467 case(layout_type_1):
3468 main_first_pane = main_pane_v1;
3469 main_second_pane = main_pane_h1;
3470 split_top_left = TRUE;
3472 case(layout_type_4):
3473 main_first_pane = main_pane_h1;
3474 main_second_pane = main_pane_v1;
3475 split_top_left = FALSE;
3477 case(layout_type_3):
3478 main_first_pane = main_pane_h1;
3479 main_second_pane = main_pane_v1;
3480 split_top_left = TRUE;
3482 case(layout_type_6):
3483 main_first_pane = main_pane_h1;
3484 main_second_pane = main_pane_h2;
3485 split_top_left = FALSE;
3488 main_first_pane = NULL;
3489 main_second_pane = NULL;
3490 g_assert_not_reached();
3492 if (split_top_left) {
3493 first_pane_widget1 = main_second_pane;
3494 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3495 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3496 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3498 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3499 first_pane_widget2 = main_second_pane;
3500 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3501 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3503 if (first_pane_widget1 != NULL)
3504 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3505 if (first_pane_widget2 != NULL)
3506 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3507 if (second_pane_widget1 != NULL)
3508 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3509 if (second_pane_widget2 != NULL)
3510 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3512 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3515 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3518 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3520 /* filter toolbar in statusbar hbox */
3521 if (prefs.filter_toolbar_show_in_statusbar) {
3522 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3525 /* statusbar widgets */
3526 statusbar_widgets_pack(statusbar);
3528 /* hide widgets on users recent settings */
3529 main_widgets_show_or_hide();
3531 gtk_widget_show(main_vbox);
3535 is_widget_visible(GtkWidget *widget, gpointer data)
3537 gboolean *is_visible = ( gboolean *)data;
3540 if (gtk_widget_get_visible(widget))
3547 main_widgets_show_or_hide(void)
3549 gboolean main_second_pane_show;
3551 if (recent.main_toolbar_show) {
3552 gtk_widget_show(main_tb);
3554 gtk_widget_hide(main_tb);
3557 statusbar_widgets_show_or_hide(statusbar);
3559 if (recent.filter_toolbar_show) {
3560 gtk_widget_show(filter_tb);
3562 gtk_widget_hide(filter_tb);
3565 if (recent.wireless_toolbar_show) {
3566 gtk_widget_show(wireless_tb);
3568 gtk_widget_hide(wireless_tb);
3571 if (recent.packet_list_show && have_capture_file) {
3572 gtk_widget_show(pkt_scrollw);
3574 gtk_widget_hide(pkt_scrollw);
3577 if (recent.tree_view_show && have_capture_file) {
3578 gtk_widget_show(tv_scrollw);
3580 gtk_widget_hide(tv_scrollw);
3583 if (recent.byte_view_show && have_capture_file) {
3584 gtk_widget_show(byte_nb_ptr_gbl);
3586 gtk_widget_hide(byte_nb_ptr_gbl);
3589 if (have_capture_file) {
3590 gtk_widget_show(main_first_pane);
3592 gtk_widget_hide(main_first_pane);
3596 * Is anything in "main_second_pane" visible?
3597 * If so, show it, otherwise hide it.
3599 main_second_pane_show = FALSE;
3600 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3601 &main_second_pane_show);
3602 if (main_second_pane_show) {
3603 gtk_widget_show(main_second_pane);
3605 gtk_widget_hide(main_second_pane);
3608 if (!have_capture_file) {
3610 gtk_widget_show(welcome_pane);
3613 gtk_widget_hide(welcome_pane);
3618 /* called, when the window state changes (minimized, maximized, ...) */
3620 window_state_event_cb (GtkWidget *widget _U_,
3624 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3626 if( (event->type) == (GDK_WINDOW_STATE)) {
3627 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3628 /* we might have dialogs popped up while we where iconified,
3630 display_queued_messages();
3638 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3640 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3642 if (event->keyval == GDK_F8) {
3645 } else if (event->keyval == GDK_F7) {
3648 } else if (event->state & NO_SHIFT_MOD_MASK) {
3649 return FALSE; /* Skip control, alt, and other modifiers */
3651 * A comment in gdkkeysyms.h says that it's autogenerated from
3652 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3653 * don't explicitly say so, g_ascii_isprint() should work as expected
3656 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3657 /* Forward the keypress on to the display filter entry */
3658 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3659 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3660 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3668 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3669 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3674 GtkAccelGroup *accel;
3677 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3678 set_titlebar_for_capture_file(NULL);
3680 gtk_widget_set_name(top_level, "main window");
3681 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3683 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3684 G_CALLBACK(window_state_event_cb), NULL);
3685 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3686 G_CALLBACK(top_level_key_pressed_cb), NULL );
3688 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3689 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3691 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3692 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3693 gtk_widget_show(main_vbox);
3696 menubar = main_menu_new(&accel);
3698 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3699 /* Mac OS X native menus are created and displayed by main_menu_new() */
3700 if(!prefs_p->gui_macosx_style) {
3702 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3703 gtk_widget_show(menubar);
3704 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3706 gtk_widget_hide(menubar);
3711 main_tb = toolbar_new();
3712 gtk_widget_show (main_tb);
3714 /* Filter toolbar */
3715 filter_tb = filter_toolbar_new();
3718 pkt_scrollw = packet_list_create();
3719 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3720 gtk_widget_show_all(pkt_scrollw);
3723 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3724 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3725 gtk_widget_show(tv_scrollw);
3727 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3728 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3729 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3730 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3731 gtk_widget_show(tree_view_gbl);
3734 byte_nb_ptr_gbl = byte_view_new();
3735 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3736 gtk_widget_show(byte_nb_ptr_gbl);
3738 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3739 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3741 /* Panes for the packet list, tree, and byte view */
3742 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3743 gtk_widget_show(main_pane_v1);
3744 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3745 gtk_widget_show(main_pane_v2);
3746 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3747 gtk_widget_show(main_pane_h1);
3748 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3749 gtk_widget_show(main_pane_h2);
3751 wireless_tb = airpcap_toolbar_new();
3753 wireless_tb = ws80211_toolbar_new();
3755 gtk_widget_show(wireless_tb);
3758 statusbar = statusbar_new();
3759 gtk_widget_show(statusbar);
3761 /* Pane for the welcome screen */
3762 welcome_pane = welcome_new();
3763 gtk_widget_show(welcome_pane);
3767 show_main_window(gboolean doing_work)
3769 main_set_for_capture_file(doing_work);
3771 /*** we have finished all init things, show the main window ***/
3772 gtk_widget_show(top_level);
3774 /* the window can be maximized only, if it's visible, so do it after show! */
3775 main_load_window_geometry(top_level);
3777 /* process all pending GUI events before continue */
3778 while (gtk_events_pending()) gtk_main_iteration();
3780 /* Pop up any queued-up alert boxes. */
3781 display_queued_messages();
3783 /* Move the main window to the front, in case it isn't already there */
3784 gdk_window_raise(gtk_widget_get_window(top_level));
3787 airpcap_toolbar_show(wireless_tb);
3788 #endif /* HAVE_AIRPCAP */
3791 static void copy_global_profile (const gchar *profile_name)
3793 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3795 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3796 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3797 "Can't create directory\n\"%s\":\n%s.",
3798 pf_dir_path, g_strerror(errno));
3800 g_free(pf_dir_path);
3803 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3804 &pf_dir_path, &pf_dir_path2) == -1) {
3805 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3806 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3807 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3809 g_free(pf_filename);
3810 g_free(pf_dir_path);
3811 g_free(pf_dir_path2);
3815 /* Change configuration profile */
3816 void change_configuration_profile (const gchar *profile_name)
3818 char *gdp_path, *dp_path;
3822 /* First check if profile exists */
3823 if (!profile_exists(profile_name, FALSE)) {
3824 if (profile_exists(profile_name, TRUE)) {
3825 /* Copy from global profile */
3826 copy_global_profile (profile_name);
3828 /* No personal and no global profile exists */
3833 /* Then check if changing to another profile */
3834 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3838 /* Get the current geometry, before writing it to disk */
3839 main_save_window_geometry(top_level);
3841 if (profile_exists(get_profile_name(), FALSE)) {
3842 /* Write recent file for profile we are leaving, if it still exists */
3843 write_profile_recent();
3846 /* Set profile name and update the status bar */
3847 set_profile_name (profile_name);
3848 profile_bar_update ();
3850 /* Reset current preferences and apply the new */
3854 (void) read_configuration_files (&gdp_path, &dp_path);
3856 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
3857 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3858 "Could not open common recent file\n\"%s\": %s.",
3859 rf_path, g_strerror(rf_open_errno));
3862 if (recent.gui_fileopen_remembered_dir &&
3863 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3864 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3866 timestamp_set_type (recent.gui_time_format);
3867 timestamp_set_seconds_type (recent.gui_seconds_format);
3868 color_filters_enable(recent.packet_list_colorize);
3870 prefs_to_capture_opts();
3872 macros_post_update();
3874 /* Update window view and redraw the toolbar */
3875 main_titlebar_update();
3876 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3877 toolbar_redraw_all();
3879 /* Enable all protocols and disable from the disabled list */
3881 if (gdp_path == NULL && dp_path == NULL) {
3882 set_disabled_protos_list();
3883 set_disabled_heur_dissector_list();
3886 /* Reload color filters */
3887 color_filters_reload();
3889 /* Reload list of interfaces on welcome page */
3890 welcome_if_panel_reload();
3892 /* Recreate the packet list according to new preferences */
3893 packet_list_recreate ();
3894 cfile.columns_changed = FALSE; /* Reset value */
3897 /* Update menus with new recent values */
3898 menu_recent_read_finished();
3900 /* Reload pane geometry, must be done after recreating the list */
3901 main_pane_load_window_geometry();
3905 main_fields_changed (void)
3907 /* Reload color filters */
3908 color_filters_reload();
3910 /* Syntax check filter */
3911 filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3912 if (cfile.dfilter) {
3913 /* Check if filter is still valid */
3914 dfilter_t *dfp = NULL;
3915 if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
3916 /* Not valid. Enable 'Apply' button and remove dfilter. */
3917 g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3918 g_free(cfile.dfilter);
3919 cfile.dfilter = NULL;
3924 if (have_custom_cols(&cfile.cinfo)) {
3925 /* Recreate packet list according to new/changed/deleted fields */
3926 packet_list_recreate();
3927 } else if (cfile.state != FILE_CLOSED) {
3928 /* Redissect packets if we have any */
3929 redissect_packets();
3931 destroy_packet_wins(); /* TODO: close windows until we can recreate */
3933 proto_free_deregistered_fields();
3936 /** redissect packets and update UI */
3937 void redissect_packets(void)
3939 cf_redissect_packets(&cfile);
3940 status_expert_update();
3949 * indent-tabs-mode: nil
3952 * ex: set shiftwidth=4 tabstop=8 expandtab:
3953 * :indentSize=4:tabSize=8:noTabs=true: