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 #ifdef HAVE_LIBPORTAUDIO
48 #include <portaudio.h>
49 #endif /* HAVE_LIBPORTAUDIO */
51 #include <wsutil/copyright_info.h>
52 #include <wsutil/crash_info.h>
53 #include <wsutil/filesystem.h>
54 #include <wsutil/file_util.h>
55 #include <wsutil/privileges.h>
56 #include <wsutil/report_message.h>
57 #include <ws_version_info.h>
59 #include <wiretap/merge.h>
61 #include <epan/addr_resolv.h>
62 #include <epan/column.h>
63 #include <epan/disabled_protos.h>
64 #include <epan/epan.h>
65 #include <epan/decode_as.h>
66 #include <epan/proto.h>
67 #include <epan/epan_dissect.h>
68 #include <epan/dfilter/dfilter.h>
69 #include <epan/strutil.h>
70 #include <epan/ex-opt.h>
71 #include <epan/funnel.h>
72 #include <epan/expert.h>
73 #include <epan/prefs.h>
74 #include <epan/prefs-int.h>
76 #include <epan/stat_tap_ui.h>
78 #include <epan/print.h>
79 #include <epan/timestamp.h>
80 #include <epan/conversation_table.h>
82 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
83 #include <epan/asn1.h>
84 #include <epan/dissectors/packet-kerberos.h>
87 #include <wsutil/cmdarg_err.h>
88 #include <wsutil/plugins.h>
90 /* general (not GTK specific) */
91 #include "../../file.h"
92 #include "../../frame_tvbuff.h"
93 #include "../../summary.h"
94 #include <epan/color_filters.h>
95 #include "../../register.h"
96 #include "../../ringbuffer.h"
97 #include "../../log.h"
99 #include "gtk_iface_monitor.h"
101 #include "ui/alert_box.h"
102 #include "ui/console.h"
103 #include "ui/decode_as_utils.h"
104 #include "filter_files.h"
105 #include "ui/main_statusbar.h"
106 #include "ui/persfilepath_opt.h"
107 #include "ui/preference_utils.h"
108 #include "ui/recent.h"
109 #include "ui/recent_utils.h"
110 #include "ui/software_update.h"
111 #include "ui/ui_util.h"
113 #include "ui/dissect_opts.h"
114 #include "ui/commandline.h"
117 #include "ui/capture_ui_utils.h"
118 #include "ui/capture_globals.h"
119 #include "ui/iface_lists.h"
122 #include "codecs/codecs.h"
124 #include "caputils/capture-pcap-util.h"
127 #include "caputils/capture_ifinfo.h"
128 #include "ui/capture.h"
129 #include <capchild/capture_sync.h>
133 #include "caputils/capture-wpcap.h"
134 #include "caputils/capture_wpcap_packet.h"
135 #include <tchar.h> /* Needed for Unicode */
136 #include <wsutil/os_version_info.h>
137 #include <wsutil/unicode-utils.h>
138 #include <commctrl.h>
139 #include <shellapi.h>
143 #include "ui/gtk/file_dlg.h"
144 #include "ui/gtk/gtkglobals.h"
145 #include "ui/gtk/color_utils.h"
146 #include "ui/gtk/gui_utils.h"
147 #include "ui/gtk/color_dlg.h"
148 #include "ui/gtk/filter_dlg.h"
149 #include "ui/gtk/fileset_dlg.h"
150 #include "ui/gtk/uat_gui.h"
151 #include "ui/gtk/main.h"
152 #include "ui/gtk/main_80211_toolbar.h"
153 #include "ui/gtk/main_airpcap_toolbar.h"
154 #include "ui/gtk/main_filter_toolbar.h"
155 #include "ui/gtk/main_titlebar.h"
156 #include "ui/gtk/menus.h"
157 #include "ui/gtk/main_menubar_private.h"
158 #include "ui/gtk/macros_dlg.h"
159 #include "ui/gtk/main_statusbar_private.h"
160 #include "ui/gtk/main_toolbar.h"
161 #include "ui/gtk/main_toolbar_private.h"
162 #include "ui/gtk/main_welcome.h"
163 #include "ui/gtk/main_welcome_private.h"
164 #include "ui/gtk/drag_and_drop.h"
165 #include "ui/gtk/capture_file_dlg.h"
166 #include "ui/gtk/packet_panes.h"
167 #include "ui/gtk/keys.h"
168 #include "ui/gtk/packet_win.h"
169 #include "ui/gtk/stock_icons.h"
170 #include "ui/gtk/find_dlg.h"
171 #include "ui/gtk/font_utils.h"
172 #include "ui/gtk/about_dlg.h"
173 #include "ui/gtk/help_dlg.h"
174 #include "ui/gtk/decode_as_dlg.h"
175 #include "ui/gtk/webbrowser.h"
176 #include "ui/gtk/capture_dlg.h"
177 #include "ui/gtk/capture_if_dlg.h"
178 #include "ui/gtk/tap_param_dlg.h"
179 #include "ui/gtk/prefs_column.h"
180 #include "ui/gtk/prefs_dlg.h"
181 #include "ui/gtk/packet_list.h"
182 #include "ui/gtk/filter_expression_save_dlg.h"
183 #include "ui/gtk/conversations_table.h"
184 #include "ui/gtk/hostlist_table.h"
185 #include "ui/gtk/service_response_time_table.h"
186 #include "ui/gtk/response_time_delay_table.h"
187 #include "ui/gtk/simple_stattable.h"
188 #include "simple_dialog.h"
189 #ifdef HAVE_GDK_GRESOURCE
190 #include "wireshark-gresources.h"
192 #include "ui/gtk/pixbuf-csource.h"
195 #include "ui/gtk/old-gtk-compat.h"
198 #include <caputils/airpcap.h>
199 #include <caputils/airpcap_loader.h>
200 #include "airpcap_dlg.h"
201 #include "airpcap_gui_utils.h"
204 #include <epan/crypt/airpdcap_ws.h>
207 #ifdef HAVE_GTKOSXAPPLICATION
208 #include <gtkmacintegration/gtkosxapplication.h>
211 #define INVALID_OPTION 1
212 #define INIT_FAILED 2
213 #define INVALID_CAPABILITY 2
214 #define INVALID_LINK_TYPE 2
217 * Files under personal and global preferences directories in which
218 * GTK settings for Wireshark are stored.
220 #define RC_FILE "gtkrc"
223 capture_session global_capture_session;
224 info_data_t global_info_data;
229 static gboolean capture_stopping;
231 /* "exported" main widgets */
232 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
234 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
235 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
236 static GtkWidget *main_first_pane, *main_second_pane;
238 /* internally used widgets */
239 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
241 GtkWidget *wireless_tb;
243 int airpcap_dll_ret_val = -1;
246 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
248 static guint tap_update_timer_id;
250 static void create_main_window(gint, gint, gint, e_prefs*);
251 static void show_main_window(gboolean);
252 static void main_save_window_geometry(GtkWidget *widget);
255 /* Match selected byte pattern */
257 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
259 char *cur_filter, *new_filter;
261 if ((!text) || (0 == strlen(text))) {
262 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter.\nTry expanding or choosing another item.");
268 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
270 switch (action&MATCH_SELECTED_MASK) {
272 case MATCH_SELECTED_REPLACE:
273 new_filter = g_strdup(text);
276 case MATCH_SELECTED_AND:
277 if ((!cur_filter) || (0 == strlen(cur_filter)))
278 new_filter = g_strdup(text);
280 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
283 case MATCH_SELECTED_OR:
284 if ((!cur_filter) || (0 == strlen(cur_filter)))
285 new_filter = g_strdup(text);
287 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
290 case MATCH_SELECTED_NOT:
291 new_filter = g_strconcat("!(", text, ")", NULL);
294 case MATCH_SELECTED_AND_NOT:
295 if ((!cur_filter) || (0 == strlen(cur_filter)))
296 new_filter = g_strconcat("!(", text, ")", NULL);
298 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
301 case MATCH_SELECTED_OR_NOT:
302 if ((!cur_filter) || (0 == strlen(cur_filter)))
303 new_filter = g_strconcat("!(", text, ")", NULL);
305 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
309 g_assert_not_reached();
314 /* Free up the copy we got of the old filter text. */
317 /* Don't change the current display filter if we only want to copy the filter */
318 if (action&MATCH_SELECTED_COPY_ONLY) {
319 GString *gtk_text_str = g_string_new("");
320 g_string_append(gtk_text_str, new_filter);
321 copy_to_clipboard(gtk_text_str);
322 g_string_free(gtk_text_str, TRUE);
324 /* create a new one and set the display filter entry accordingly */
325 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
327 /* Run the display filter so it goes in effect. */
328 if (action&MATCH_SELECTED_APPLY_NOW)
329 main_filter_packets(&cfile, new_filter, FALSE);
332 /* Free up the new filter text. */
337 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
341 if (cfile.finfo_selected) {
342 filter = proto_construct_match_selected_string(cfile.finfo_selected,
344 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
345 wmem_free(NULL, filter);
350 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
353 gchar *err_msg = NULL;
355 if (cfile.finfo_selected) {
356 filter = proto_construct_match_selected_string(cfile.finfo_selected,
358 if ((!filter) || (0 == strlen(filter))) {
359 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
360 "Could not acquire information to build a filter.\n"
361 "Try expanding or choosing another item.");
366 color_display_with_filter(filter);
369 if (!color_filters_reset_tmp(&err_msg)) {
370 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
374 if (!color_filters_set_tmp(filt_nr,filter, FALSE, &err_msg)) {
375 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
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(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(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_fields);
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);
811 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
814 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
816 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
817 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
818 g_assert(byte_data != NULL);
820 cfile.finfo_selected = finfo;
821 set_menus_for_selected_tree_row(&cfile);
824 if (finfo->hfinfo->blurb != NULL &&
825 finfo->hfinfo->blurb[0] != '\0') {
827 length = (guint) strlen(finfo->hfinfo->blurb);
829 length = (guint) strlen(finfo->hfinfo->name);
831 finfo_length = finfo->length + finfo->appendix_length;
833 if (finfo_length == 0) {
835 } else if (finfo_length == 1) {
836 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
838 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
840 statusbar_pop_field_msg(); /* get rid of current help msg */
842 statusbar_push_field_msg(" %s (%s)%s",
843 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
844 finfo->hfinfo->abbrev, len_str);
847 * Don't show anything if the field name is zero-length;
848 * the pseudo-field for text-only items is such
849 * a field, and we don't want "Text (text)" showing up
850 * on the status line if you've selected such a field.
852 * XXX - there are zero-length fields for which we *do*
853 * want to show the field name.
855 * XXX - perhaps the name and abbrev field should be null
856 * pointers rather than null strings for that pseudo-field,
857 * but we'd have to add checks for null pointers in some
858 * places if we did that.
860 * Or perhaps text-only items should have -1 as the field
861 * index, with no pseudo-field being used, but that might
862 * also require special checks for -1 to be added.
864 statusbar_push_field_msg("%s", "");
867 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
871 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
874 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
877 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
880 expand_all_tree(cfile.edt->tree, tree_view_gbl);
883 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
885 if (cfile.finfo_selected) {
886 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
887 cfile.finfo_selected->hfinfo->abbrev,0);
888 /* Recreate the packet list according to new preferences */
889 packet_list_recreate ();
890 if (!prefs.gui_use_pref_save) {
893 cfile.columns_changed = FALSE; /* Reset value */
897 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
901 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
903 /* the mouse position is at an entry, expand that one */
904 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
905 gtk_tree_path_free(path);
909 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
913 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
915 /* the mouse position is at an entry, expand that one */
917 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
918 gtk_tree_path_free(path);
922 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
924 static const e_addr_resolve resolv_flags = {
926 TRUE, /* network_name */
927 TRUE, /* transport_name */
928 TRUE, /* dns_pkt_addr_resolution */
929 TRUE, /* use_external_net_name_resolver */
930 FALSE, /* load_hosts_file_from_profile_only */
931 FALSE, /* vlan_name */
932 FALSE, /* ss7pc_name */
935 if (cfile.edt->tree) {
936 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
940 /* Update main window items based on whether there's a capture in progress. */
942 main_set_for_capture_in_progress(gboolean capture_in_progress)
944 set_menus_for_capture_in_progress(capture_in_progress);
947 set_toolbar_for_capture_in_progress(capture_in_progress);
949 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
953 /* Update main window items based on whether we have a capture file. */
955 main_set_for_capture_file(gboolean have_capture_file_in)
957 have_capture_file = have_capture_file_in;
959 main_widgets_show_or_hide();
962 /* Update main window items based on whether we have captured packets. */
964 main_set_for_captured_packets(gboolean have_captured_packets)
966 set_menus_for_captured_packets(have_captured_packets);
967 set_toolbar_for_captured_packets(have_captured_packets);
970 /* Update main window items based on whether we have a packet history. */
972 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
974 set_menus_for_packet_history(back_history, forward_history);
975 set_toolbar_for_packet_history(back_history, forward_history);
981 /* get the current geometry, before writing it to disk */
982 main_save_window_geometry(top_level);
984 /* write user's recent file to disk
985 * It is no problem to write this file, even if we do not quit */
986 write_profile_recent();
989 /* XXX - should we check whether the capture file is an
990 unsaved temporary file for a live capture and, if so,
991 pop up a "do you want to exit without saving the capture
992 file?" dialog, and then just return, leaving said dialog
993 box to forcibly quit if the user clicks "OK"?
995 If so, note that this should be done in a subroutine that
996 returns TRUE if we do so, and FALSE otherwise, and if it
997 returns TRUE we should return TRUE without nuking anything.
999 Note that, if we do that, we might also want to check if
1000 an "Update list of packets in real time" capture is in
1001 progress and, if so, ask whether they want to terminate
1002 the capture and discard it, and return TRUE, before nuking
1003 any child capture, if they say they don't want to do so. */
1006 /* Nuke any child capture in progress. */
1007 capture_kill_child(&global_capture_session);
1010 /* Are we in the middle of reading a capture? */
1011 if (cfile.state == FILE_READ_IN_PROGRESS) {
1012 /* Yes, so we can't just close the file and quit, as
1013 that may yank the rug out from under the read in
1014 progress; instead, just set the state to
1015 "FILE_READ_ABORTED" and return - the code doing the read
1016 will check for that and, if it sees that, will clean
1018 cfile.state = FILE_READ_ABORTED;
1020 /* Say that the window should *not* be deleted;
1021 that'll be done by the code that cleans up. */
1024 /* Close any capture file we have open; on some OSes, you
1025 can't unlink a temporary capture file if you have it
1027 "cf_close()" will unlink it after closing it if
1028 it's a temporary file.
1030 We do this here, rather than after the main loop returns,
1031 as, after the main loop returns, the main window may have
1032 been destroyed (if this is called due to a "destroy"
1033 even on the main window rather than due to the user
1034 selecting a menu item), and there may be a crash
1035 or other problem when "cf_close()" tries to
1036 clean up stuff in the main window.
1038 XXX - is there a better place to put this?
1039 Or should we have a routine that *just* closes the
1040 capture file, and doesn't do anything with the UI,
1041 which we'd call here, and another routine that
1042 calls that routine and also cleans up the UI, which
1043 we'd call elsewhere? */
1046 /* Exit by leaving the main loop, so that any quit functions
1047 we registered get called. */
1050 /* Say that the window should be deleted. */
1056 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1058 /* If we're in the middle of stopping a capture, don't do anything;
1059 the user can try deleting the window after the capture stops. */
1060 if (capture_stopping)
1063 /* If there's unsaved data, let the user save it first.
1064 If they cancel out of it, don't quit. */
1065 if (do_file_close(&cfile, TRUE, " before quitting"))
1066 return main_do_quit();
1068 return TRUE; /* will this keep the window from being deleted? */
1073 main_pane_load_window_geometry(void)
1075 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1076 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1077 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1078 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1084 main_load_window_geometry(GtkWidget *widget)
1086 window_geometry_t geom;
1088 geom.set_pos = prefs.gui_geometry_save_position;
1089 geom.x = recent.gui_gtk_geometry_main_x;
1090 geom.y = recent.gui_gtk_geometry_main_y;
1091 geom.set_size = prefs.gui_geometry_save_size;
1092 geom.set_maximized = FALSE;
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_gtk_geometry_main_x = geom.x;
1124 recent.gui_gtk_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 * Report an error in command-line arguments.
1151 * Creates a console on Windows.
1152 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1153 * terminal isn't the standard error?
1156 wireshark_cmdarg_err(const char *fmt, va_list ap)
1161 fprintf(stderr, "wireshark: ");
1162 vfprintf(stderr, fmt, ap);
1163 fprintf(stderr, "\n");
1167 * Report additional information for an error in command-line arguments.
1168 * Creates a console on Windows.
1169 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1170 * terminal isn't the standard error?
1173 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1178 vfprintf(stderr, fmt, ap);
1179 fprintf(stderr, "\n");
1183 Once every 3 seconds we get a callback here which we use to update
1187 tap_update_cb(gpointer data _U_)
1189 draw_tap_listeners(FALSE);
1194 * Periodically process outstanding hostname lookups. If we have new items,
1195 * redraw the packet list and tree view.
1199 resolv_update_cb(gpointer data _U_)
1201 /* Anything new show up? */
1202 if (host_name_lookup_process()) {
1203 if (gtk_widget_get_window(pkt_scrollw))
1204 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1205 if (gtk_widget_get_window(tv_scrollw))
1206 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1209 /* Always check. Even if we don't do async lookups we could still get
1210 passive updates, e.g. from DNS packets. */
1215 /* Update various parts of the main window for a capture file "unsaved
1216 changes" change - update the title to reflect whether there are
1217 unsaved changes or not, and update the menus and toolbar to
1218 enable or disable the "Save" operation. */
1220 main_update_for_unsaved_changes(capture_file *cf)
1222 set_titlebar_for_capture_file(cf);
1223 set_menus_for_capture_file(cf);
1224 set_toolbar_for_capture_file(cf);
1229 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1231 /* Update menubar and toolbar */
1232 menu_auto_scroll_live_changed(auto_scroll_live_in);
1233 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1235 /* change auto scroll state */
1236 auto_scroll_live = auto_scroll_live_in;
1241 main_colorize_changed(gboolean packet_list_colorize)
1243 /* Update menubar and toolbar */
1244 menu_colorize_changed(packet_list_colorize);
1245 toolbar_colorize_changed(packet_list_colorize);
1247 /* change colorization */
1248 if(packet_list_colorize != recent.packet_list_colorize) {
1249 recent.packet_list_colorize = packet_list_colorize;
1250 packet_list_enable_color(packet_list_colorize);
1251 packet_list_colorize_packets();
1255 static GtkWidget *close_dlg = NULL;
1258 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1260 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1265 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1267 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1272 main_cf_cb_file_closing(capture_file *cf)
1274 /* if we have more than 10000 packets, show a splash screen while closing */
1275 /* XXX - don't know a better way to decide whether to show or not,
1276 * as most of the time is spend in various calls that destroy various
1277 * data structures, so it wouldn't be easy to use a progress bar,
1278 * rather than, say, a progress spinner, here! */
1279 if(cf->count > 10000) {
1280 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1281 "%sClosing file.%s\n\nPlease wait ...",
1282 simple_dialog_primary_start(),
1283 simple_dialog_primary_end());
1284 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1286 /* Clear maunally resolved addresses */
1287 manually_resolve_cleanup();
1288 /* Destroy all windows that refer to the
1289 capture file we're closing. */
1290 destroy_packet_wins();
1292 /* Update the titlebar to reflect the lack of a capture file. */
1293 set_titlebar_for_capture_file(NULL);
1295 /* Disable all menu and toolbar items that make sense only if
1296 you have a capture. */
1297 set_menus_for_capture_file(NULL);
1298 set_toolbar_for_capture_file(NULL);
1299 main_set_for_captured_packets(FALSE);
1300 set_menus_for_selected_packet(cf);
1301 main_set_for_capture_in_progress(FALSE);
1302 set_capture_if_dialog_for_capture_in_progress(FALSE);
1303 set_menus_for_selected_tree_row(cf);
1305 /* Set up main window for no capture file. */
1306 main_set_for_capture_file(FALSE);
1308 main_window_update();
1313 main_cf_cb_file_closed(capture_file *cf _U_)
1315 if(close_dlg != NULL) {
1316 splash_destroy(close_dlg);
1323 main_cf_cb_file_read_started(capture_file *cf _U_)
1325 tap_param_dlg_update();
1327 /* Set up main window for a capture file. */
1328 main_set_for_capture_file(TRUE);
1332 main_cf_cb_file_read_finished(capture_file *cf)
1336 if (!cf->is_tempfile && cf->filename) {
1337 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1338 add_menu_recent_capture_file(cf->filename);
1340 /* Remember folder for next Open dialog and save it in recent */
1341 dir_path = g_strdup(cf->filename);
1342 set_last_open_dir(get_dirname(dir_path));
1346 /* Update the appropriate parts of the main window. */
1347 main_update_for_unsaved_changes(cf);
1349 /* Enable menu items that make sense if you have some captured packets. */
1350 main_set_for_captured_packets(TRUE);
1354 main_cf_cb_file_rescan_finished(capture_file *cf)
1358 if (!cf->is_tempfile && cf->filename) {
1359 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1360 add_menu_recent_capture_file(cf->filename);
1362 /* Remember folder for next Open dialog and save it in recent */
1363 dir_path = g_strdup(cf->filename);
1364 set_last_open_dir(get_dirname(dir_path));
1368 /* Update the appropriate parts of the main window. */
1369 main_update_for_unsaved_changes(cf);
1373 static GList *icon_list_create(
1374 #ifdef HAVE_GDK_GRESOURCE
1375 const gchar *icon16_path,
1376 const gchar *icon32_path,
1377 const gchar *icon48_path,
1378 const gchar *icon64_path)
1380 const guint8 *icon16_pb,
1381 const guint8 *icon32_pb,
1382 const guint8 *icon48_pb,
1383 const guint8 *icon64_pb)
1386 GList *icon_list = NULL;
1387 GdkPixbuf *pixbuf16 = NULL;
1388 GdkPixbuf *pixbuf32 = NULL;
1389 GdkPixbuf *pixbuf48 = NULL;
1390 GdkPixbuf *pixbuf64 = NULL;
1392 #ifdef HAVE_GDK_GRESOURCE
1393 if (icon16_path != NULL)
1394 pixbuf16 = ws_gdk_pixbuf_new_from_resource(icon16_path);
1395 if (icon32_path != NULL)
1396 pixbuf32 = ws_gdk_pixbuf_new_from_resource(icon32_path);
1397 if (icon48_path != NULL)
1398 pixbuf48 = ws_gdk_pixbuf_new_from_resource(icon48_path);
1399 if (icon64_path != NULL)
1400 pixbuf64 = ws_gdk_pixbuf_new_from_resource(icon64_path);
1402 if (icon16_pb != NULL)
1403 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1404 if (icon32_pb != NULL)
1405 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1406 if (icon48_pb != NULL)
1407 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1408 if (icon64_pb != NULL)
1409 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1412 if (pixbuf16 != NULL)
1413 icon_list = g_list_append(icon_list, pixbuf16);
1414 if (pixbuf32 != NULL)
1415 icon_list = g_list_append(icon_list, pixbuf32);
1416 if (pixbuf48 != NULL)
1417 icon_list = g_list_append(icon_list, pixbuf48);
1418 if (pixbuf64 != NULL)
1419 icon_list = g_list_append(icon_list, pixbuf64);
1425 main_capture_cb_capture_prepared(capture_session *cap_session)
1427 static GList *icon_list = NULL;
1429 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1431 if(icon_list == NULL) {
1432 #ifdef HAVE_GDK_GRESOURCE
1433 icon_list = icon_list_create("/org/wireshark/image/wsiconcap16.png",
1434 "/org/wireshark/image/wsiconcap32.png",
1435 "/org/wireshark/image/wsiconcap48.png",
1436 "/org/wireshark/image/wsiconcap64.png");
1438 icon_list = icon_list_create(wsiconcap_16_pb_data,
1439 wsiconcap_32_pb_data,
1440 wsiconcap_48_pb_data,
1441 wsiconcap_64_pb_data);
1444 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1446 /* Disable menu items that make no sense if you're currently running
1448 main_set_for_capture_in_progress(TRUE);
1449 set_capture_if_dialog_for_capture_in_progress(TRUE);
1451 /* Don't set up main window for a capture file. */
1452 main_set_for_capture_file(FALSE);
1456 main_capture_cb_capture_update_started(capture_session *cap_session)
1458 /* We've done this in "prepared" above, but it will be cleared while
1459 switching to the next multiple file. */
1460 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1462 main_set_for_capture_in_progress(TRUE);
1463 set_capture_if_dialog_for_capture_in_progress(TRUE);
1465 /* Enable menu items that make sense if you have some captured
1466 packets (yes, I know, we don't have any *yet*). */
1467 main_set_for_captured_packets(TRUE);
1469 /* Set up main window for a capture file. */
1470 main_set_for_capture_file(TRUE);
1474 main_capture_cb_capture_update_finished(capture_session *cap_session)
1476 capture_file *cf = (capture_file *)cap_session->cf;
1477 static GList *icon_list = NULL;
1479 /* The capture isn't stopping any more - it's stopped. */
1480 capture_stopping = FALSE;
1482 if (!cf->is_tempfile && cf->filename) {
1483 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1484 add_menu_recent_capture_file(cf->filename);
1487 /* Enable menu items that make sense if you're not currently running
1489 main_set_for_capture_in_progress(FALSE);
1490 set_capture_if_dialog_for_capture_in_progress(FALSE);
1492 /* Update the main window as appropriate. This has to occur AFTER
1493 * main_set_for_capture_in_progress() or else some of the menus are
1494 * incorrectly disabled (see bug
1495 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1496 main_update_for_unsaved_changes(cf);
1498 /* Set up main window for a capture file. */
1499 main_set_for_capture_file(TRUE);
1501 if(icon_list == NULL) {
1502 #ifdef HAVE_GDK_GRESOURCE
1503 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1504 "/org/wireshark/image/wsicon32.png",
1505 "/org/wireshark/image/wsicon48.png",
1506 "/org/wireshark/image/wsicon64.png");
1508 icon_list = icon_list_create(wsicon_16_pb_data,
1514 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1516 if(global_commandline_info.quit_after_cap) {
1517 /* command line asked us to quit after the capture */
1518 /* don't pop up a dialog to ask for unsaved files etc. */
1524 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1526 /* Don't set up main window for a capture file. */
1527 main_set_for_capture_file(FALSE);
1531 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1534 capture_file *cf = (capture_file *)cap_session->cf;
1536 static GList *icon_list = NULL;
1538 /* The capture isn't stopping any more - it's stopped. */
1539 capture_stopping = FALSE;
1541 /*set_titlebar_for_capture_file(cf);*/
1543 /* Enable menu items that make sense if you're not currently running
1545 main_set_for_capture_in_progress(FALSE);
1546 set_capture_if_dialog_for_capture_in_progress(FALSE);
1548 /* Restore the standard title bar message */
1549 /* (just in case we have trouble opening the capture file). */
1550 set_titlebar_for_capture_file(NULL);
1552 if(icon_list == NULL) {
1553 #ifdef HAVE_GDK_GRESOURCE
1554 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1555 "/org/wireshark/image/wsicon32.png",
1556 "/org/wireshark/image/wsicon48.png",
1557 "/org/wireshark/image/wsicon64.png");
1559 icon_list = icon_list_create(wsicon_16_pb_data,
1565 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1567 /* We don't have loaded the capture file, this will be done later.
1568 * For now we still have simply a blank screen. */
1570 if(global_commandline_info.quit_after_cap) {
1571 /* command line asked us to quit after the capture */
1572 /* don't pop up a dialog to ask for unsaved files etc. */
1578 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1580 capture_stopping = TRUE;
1581 set_menus_for_capture_stopping();
1583 set_toolbar_for_capture_stopping();
1585 set_capture_if_dialog_for_capture_stopping();
1590 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1592 static GList *icon_list = NULL;
1594 /* Capture isn't stopping any more. */
1595 capture_stopping = FALSE;
1597 /* the capture failed before the first packet was captured
1598 reset title, menus and icon */
1599 set_titlebar_for_capture_file(NULL);
1601 main_set_for_capture_in_progress(FALSE);
1602 set_capture_if_dialog_for_capture_in_progress(FALSE);
1604 main_set_for_capture_file(FALSE);
1606 if(icon_list == NULL) {
1607 #ifdef HAVE_GDK_GRESOURCE
1608 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1609 "/org/wireshark/image/wsicon32.png",
1610 "/org/wireshark/image/wsicon48.png",
1611 "/org/wireshark/image/wsicon64.png");
1613 icon_list = icon_list_create(wsicon_16_pb_data,
1619 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1622 if(global_commandline_info.quit_after_cap) {
1623 /* command line asked us to quit after the capture */
1624 /* don't pop up a dialog to ask for unsaved files etc. */
1628 #endif /* HAVE_LIBPCAP */
1631 main_cf_cb_packet_selected(gpointer data)
1633 capture_file *cf = (capture_file *)data;
1635 /* Display the GUI protocol tree and packet bytes.
1636 XXX - why do we dump core if we call "proto_tree_draw()"
1637 before calling "add_byte_views()"? */
1638 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1639 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1641 /* Note: Both string and hex value searches in the packet data produce a non-zero
1642 search_pos if successful */
1643 if(cf->search_in_progress &&
1644 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1645 highlight_field(cf->edt->tvb, cf->search_pos,
1646 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1649 /* A packet is selected. */
1650 set_menus_for_selected_packet(cf);
1654 main_cf_cb_packet_unselected(capture_file *cf)
1656 /* No packet is being displayed; clear the hex dump pane by getting
1657 rid of all the byte views. */
1658 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1659 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1661 /* Add a placeholder byte view so that there's at least something
1662 displayed in the byte view notebook. */
1663 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1665 /* And clear the protocol tree display as well. */
1666 proto_tree_draw(NULL, tree_view_gbl);
1668 /* No packet is selected. */
1669 set_menus_for_selected_packet(cf);
1673 main_cf_cb_field_unselected(capture_file *cf)
1675 set_menus_for_selected_tree_row(cf);
1679 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1681 capture_file *cf = (capture_file *)data;
1683 case(cf_cb_file_opened):
1684 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1685 fileset_file_opened(cf);
1687 case(cf_cb_file_closing):
1688 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1689 main_cf_cb_file_closing(cf);
1691 case(cf_cb_file_closed):
1692 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1693 main_cf_cb_file_closed(cf);
1694 fileset_file_closed();
1696 case(cf_cb_file_read_started):
1697 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1698 main_cf_cb_file_read_started(cf);
1700 case(cf_cb_file_read_finished):
1701 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1702 main_cf_cb_file_read_finished(cf);
1704 case(cf_cb_file_reload_started):
1705 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1706 main_cf_cb_file_read_started(cf);
1708 case(cf_cb_file_reload_finished):
1709 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1710 main_cf_cb_file_read_finished(cf);
1712 case(cf_cb_file_rescan_started):
1713 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1715 case(cf_cb_file_rescan_finished):
1716 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1717 main_cf_cb_file_rescan_finished(cf);
1719 case(cf_cb_file_retap_started):
1720 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap started");
1722 case(cf_cb_file_retap_finished):
1723 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap finished");
1725 case(cf_cb_file_fast_save_finished):
1726 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1727 main_cf_cb_file_rescan_finished(cf);
1729 case(cf_cb_packet_selected):
1730 main_cf_cb_packet_selected(cf);
1732 case(cf_cb_packet_unselected):
1733 main_cf_cb_packet_unselected(cf);
1735 case(cf_cb_field_unselected):
1736 main_cf_cb_field_unselected(cf);
1738 case(cf_cb_file_save_started):
1739 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1741 case(cf_cb_file_save_finished):
1742 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1744 case(cf_cb_file_save_failed):
1745 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1747 case(cf_cb_file_save_stopped):
1748 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1750 case(cf_cb_file_export_specified_packets_started):
1751 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1753 case(cf_cb_file_export_specified_packets_finished):
1754 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1756 case(cf_cb_file_export_specified_packets_failed):
1757 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1759 case(cf_cb_file_export_specified_packets_stopped):
1760 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1763 g_warning("main_cf_callback: event %u unknown", event);
1764 g_assert_not_reached();
1770 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1772 #ifdef HAVE_GTKOSXAPPLICATION
1773 GtkosxApplication *theApp;
1776 case(capture_cb_capture_prepared):
1777 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1778 main_capture_cb_capture_prepared(cap_session);
1780 case(capture_cb_capture_update_started):
1781 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1782 main_capture_cb_capture_update_started(cap_session);
1783 #ifdef HAVE_GTKOSXAPPLICATION
1784 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1785 #ifdef HAVE_GDK_GRESOURCE
1786 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon48.png"));
1788 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_48_pb_data, FALSE, NULL));
1792 case(capture_cb_capture_update_continue):
1793 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1795 case(capture_cb_capture_update_finished):
1796 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1797 main_capture_cb_capture_update_finished(cap_session);
1799 case(capture_cb_capture_fixed_started):
1800 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1801 main_capture_cb_capture_fixed_started(cap_session);
1803 case(capture_cb_capture_fixed_continue):
1804 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1806 case(capture_cb_capture_fixed_finished):
1807 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1808 main_capture_cb_capture_fixed_finished(cap_session);
1810 case(capture_cb_capture_stopping):
1811 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1812 /* Beware: this state won't be called, if the capture child
1813 * closes the capturing on its own! */
1814 #ifdef HAVE_GTKOSXAPPLICATION
1815 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1816 #ifdef HAVE_GDK_GRESOURCE
1817 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
1819 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1822 main_capture_cb_capture_stopping(cap_session);
1824 case(capture_cb_capture_failed):
1825 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1826 main_capture_cb_capture_failed(cap_session);
1829 g_warning("main_capture_callback: event %u unknown", event);
1830 g_assert_not_reached();
1836 get_wireshark_gtk_compiled_info(GString *str)
1838 g_string_append(str, "with ");
1839 g_string_append_printf(str,
1840 #ifdef GTK_MAJOR_VERSION
1841 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1844 "GTK+ (version unknown)");
1848 g_string_append(str, ", with Cairo ");
1849 g_string_append(str, CAIRO_VERSION_STRING);
1852 g_string_append(str, ", with Pango ");
1853 g_string_append(str, PANGO_VERSION_STRING);
1855 /* Capture libraries */
1856 g_string_append(str, ", ");
1857 get_compiled_caplibs_version(str);
1861 get_gui_compiled_info(GString *str)
1863 epan_get_compiled_version_info(str);
1865 g_string_append(str, ", ");
1866 #ifdef HAVE_LIBPORTAUDIO
1867 #ifdef PORTAUDIO_API_1
1868 g_string_append(str, "with PortAudio <= V18");
1869 #else /* PORTAUDIO_API_1 */
1870 g_string_append(str, "with ");
1871 g_string_append(str, Pa_GetVersionText());
1872 #endif /* PORTAUDIO_API_1 */
1873 #else /* HAVE_LIBPORTAUDIO */
1874 g_string_append(str, "without PortAudio");
1875 #endif /* HAVE_LIBPORTAUDIO */
1877 g_string_append(str, ", ");
1879 get_compiled_airpcap_version(str);
1881 g_string_append(str, "without AirPcap");
1884 codec_get_compiled_version_info(str);
1888 get_wireshark_runtime_info(GString *str)
1891 /* Capture libraries */
1892 g_string_append(str, ", ");
1893 get_runtime_caplibs_version(str);
1896 /* stuff used by libwireshark */
1897 epan_get_runtime_version_info(str);
1900 g_string_append(str, ", ");
1901 get_runtime_airpcap_version(str);
1906 read_configuration_files(void)
1908 int gpf_open_errno, gpf_read_errno;
1909 int cf_open_errno, df_open_errno;
1910 char *gpf_path, *pf_path;
1911 char *cf_path, *df_path;
1912 int pf_open_errno, pf_read_errno;
1915 /* load the decode as entries of this profile */
1916 load_decode_as_entries();
1918 /* Read the preference files. */
1919 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1920 &pf_open_errno, &pf_read_errno, &pf_path);
1922 if (gpf_path != NULL) {
1923 if (gpf_open_errno != 0) {
1924 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1925 "Could not open global preferences file\n\"%s\": %s.",
1926 gpf_path, g_strerror(gpf_open_errno));
1928 if (gpf_read_errno != 0) {
1929 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1930 "I/O error reading global preferences file\n\"%s\": %s.",
1931 gpf_path, g_strerror(gpf_read_errno));
1934 if (pf_path != NULL) {
1935 if (pf_open_errno != 0) {
1936 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1937 "Could not open your preferences file\n\"%s\": %s.",
1938 pf_path, g_strerror(pf_open_errno));
1940 if (pf_read_errno != 0) {
1941 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1942 "I/O error reading your preferences file\n\"%s\": %s.",
1943 pf_path, g_strerror(pf_read_errno));
1950 /* if the user wants a console to be always there, well, we should open one for him */
1951 if (prefs_p->gui_console_open == console_open_always) {
1956 /* Read the capture filter file. */
1957 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1958 if (cf_path != NULL) {
1959 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1960 "Could not open your capture filter file\n\"%s\": %s.",
1961 cf_path, g_strerror(cf_open_errno));
1965 /* Read the display filter file. */
1966 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1967 if (df_path != NULL) {
1968 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1969 "Could not open your display filter file\n\"%s\": %s.",
1970 df_path, g_strerror(df_open_errno));
1975 * Read the files that enable and disable protocols and heuristic
1978 read_enabled_and_disabled_lists();
1983 /* Check if there's something important to tell the user during startup.
1984 * We want to do this *after* showing the main window so that any windows
1985 * we pop up will be above the main window.
1989 check_and_warn_user_startup(gchar *cf_name)
1991 check_and_warn_user_startup(gchar *cf_name _U_)
1994 gchar *cur_user, *cur_group;
1995 gpointer priv_warning_dialog;
1997 /* Tell the user not to run as root. */
1998 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
1999 cur_user = get_cur_username();
2000 cur_group = get_cur_groupname();
2001 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2002 "Running as user \"%s\" and group \"%s\".\n"
2003 "This could be dangerous.\n\n"
2004 "If you're running Wireshark this way in order to perform live capture, "
2005 "you may want to be aware that there is a better way documented at\n"
2006 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2009 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2010 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2014 /* Warn the user if npf.sys isn't loaded. */
2015 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2016 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2017 "The NPF driver isn't running. You may have trouble\n"
2018 "capturing or listing interfaces.");
2019 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2020 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2026 /* And now our feature presentation... [ fade to music ] */
2028 main(int argc, char *argv[])
2030 char *init_progfile_dir_error;
2032 int ret = EXIT_SUCCESS;
2033 extern int info_update_freq; /* Found in about_dlg.c. */
2034 const gchar *filter;
2053 gint pl_size = 280, tv_size = 95, bv_size = 75;
2055 dfilter_t *rfcode = NULL;
2056 gchar *err_msg = NULL;
2057 gboolean rfilter_parse_failed = FALSE;
2058 GtkWidget *splash_win = NULL;
2059 dfilter_t *jump_to_filter = NULL;
2060 unsigned int in_file_type = WTAP_TYPE_AUTO;
2061 #ifdef HAVE_GTKOSXAPPLICATION
2062 GtkosxApplication *theApp;
2064 GString *comp_info_str = NULL;
2065 GString *runtime_info_str = NULL;
2067 #ifdef HAVE_GDK_GRESOURCE
2068 main_register_resource();
2071 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2073 /* Set the current locale according to the program environment.
2074 * We haven't localized anything, but some GTK widgets are localized
2075 * (the file selection dialogue, for example).
2076 * This also sets the C-language locale to the native environment. */
2077 setlocale(LC_ALL, "");
2079 arg_list_utf_16to8(argc, argv);
2080 create_app_running_mutex();
2084 * Get credential information for later use, and drop privileges
2085 * before doing anything else.
2086 * Let the user know if anything happened.
2088 init_process_policies();
2089 relinquish_special_privs_perm();
2092 * Attempt to get the pathname of the directory containing the
2095 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2097 /* initialize the funnel mini-api */
2098 initialize_funnel_ops();
2100 AirPDcapInitContext(&airpdcap_ctx);
2103 /* Load wpcap if possible. Do this before collecting the run-time version information */
2106 /* ... and also load the packet.dll from wpcap */
2107 wpcap_packet_load();
2110 /* Load the airpcap.dll. This must also be done before collecting
2111 * run-time version information. */
2112 airpcap_dll_ret_val = load_airpcap();
2114 switch (airpcap_dll_ret_val) {
2115 case AIRPCAP_DLL_OK:
2116 /* load the airpcap interfaces */
2117 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2119 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
2120 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2121 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2124 airpcap_if_active = NULL;
2128 /* select the first ad default (THIS SHOULD BE CHANGED) */
2129 airpcap_if_active = airpcap_get_default_if(g_airpcap_if_list);
2134 * XXX - Maybe we need to warn the user if one of the following happens???
2136 case AIRPCAP_DLL_OLD:
2137 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2140 case AIRPCAP_DLL_ERROR:
2141 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2144 case AIRPCAP_DLL_NOT_FOUND:
2145 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2149 #endif /* HAVE_AIRPCAP */
2152 /* Get the compile-time version information string */
2153 comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
2154 get_gui_compiled_info);
2156 /* Get the run-time version information string */
2157 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
2159 /* Add it to the information to be reported on a crash. */
2160 ws_add_crash_info("Wireshark %s\n"
2165 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2168 /* Start windows sockets */
2169 result = WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2171 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2172 "Error: WSAStartup failed with error: %d", result);
2178 profile_store_persconffiles (TRUE);
2180 /* Read the profile independent recent file. We have to do this here so we can */
2181 /* set the profile before it can be set from the command line parameter */
2182 recent_read_static(&rf_path, &rf_open_errno);
2183 if (rf_path != NULL && rf_open_errno != 0) {
2184 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2185 "Could not open common recent file\n\"%s\": %s.",
2186 rf_path, g_strerror(rf_open_errno));
2189 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
2191 /* Init the "Open file" dialog directory */
2192 /* (do this after the path settings are processed) */
2194 /* Read the profile dependent (static part) of the recent file. */
2195 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2196 /* recent lists which is done in the dynamic part. */
2197 /* We have to do this already here, so command line parameters can overwrite these values. */
2198 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
2199 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2200 "Could not open recent file\n\"%s\": %s.",
2201 rf_path, g_strerror(rf_open_errno));
2205 if (recent.gui_fileopen_remembered_dir &&
2206 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2207 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2209 set_last_open_dir(get_persdatafile_dir());
2212 #if !GLIB_CHECK_VERSION(2,31,0)
2213 g_thread_init(NULL);
2216 /* Disable liboverlay scrollbar which broke Wireshark on Ubuntu */
2217 #if !GTK_CHECK_VERSION(3,16,0)
2218 if (NULL == g_getenv("LIBOVERLAY_SCROLLBAR")) {
2219 g_setenv("LIBOVERLAY_SCROLLBAR", "0", FALSE);
2223 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2224 gtk_init (&argc, &argv);
2226 cf_callback_add(main_cf_callback, NULL);
2228 capture_callback_add(main_capture_callback, NULL);
2231 cf_callback_add(statusbar_cf_callback, NULL);
2233 capture_callback_add(statusbar_capture_callback, NULL);
2236 cf_callback_add(welcome_cf_callback, NULL);
2238 capture_callback_add(welcome_capture_callback, NULL);
2241 set_console_log_handler();
2244 /* Set the initial values in the capture options. This might be overwritten
2245 by preference settings and then again by the command line parameters. */
2246 capture_opts_init(&global_capture_opts);
2248 capture_session_init(&global_capture_session, &cfile);
2251 init_report_message(vfailure_alert_box, vwarning_alert_box,
2252 open_failure_alert_box, read_failure_alert_box,
2253 write_failure_alert_box);
2255 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2256 filter = get_conn_cfilter();
2257 if ( *filter != '\0' ) {
2258 info_update_freq = 1000; /* Milliseconds */
2261 /* We won't come till here, if we had a "console only" command line parameter. */
2262 splash_win = splash_new("Loading Wireshark ...");
2263 if (init_progfile_dir_error != NULL) {
2264 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2265 "Can't get pathname of directory containing Wireshark: %s.\n"
2266 "It won't be possible to capture traffic.\n"
2267 "Report this to the Wireshark developers.",
2268 init_progfile_dir_error);
2269 g_free(init_progfile_dir_error);
2275 /* Register all the plugin types we have. */
2276 epan_register_plugin_types(); /* Types known to libwireshark */
2277 codec_register_plugin_types(); /* Types known to libwscodecs */
2279 /* Scan for plugins. This does *not* call their registration routines;
2280 that's done later. */
2281 scan_plugins(REPORT_LOAD_FAILURE);
2283 /* Register all libwiretap plugin modules. */
2284 register_all_wiretap_modules();
2287 /* Register all audio codec plugins. */
2288 register_all_codecs();
2290 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2292 /* Register all dissectors; we must do this before checking for the
2293 "-G" flag, as the "-G" flag dumps information registered by the
2294 dissectors, and we must do it before we read the preferences, in
2295 case any dissectors register preferences. */
2296 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
2297 splash_update, (gpointer) splash_win)) {
2302 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2304 /* Register all tap listeners; we do this before we parse the arguments,
2305 as the "-z" argument can specify a registered tap. */
2307 /* we register the plugin taps before the other taps because
2308 stats_tree taps plugins will be registered as tap listeners
2309 by stats_tree_stat.c and need to registered before that */
2312 register_all_plugin_tap_listeners();
2315 register_all_tap_listeners();
2316 conversation_table_set_gui_info(init_conversation_table);
2317 hostlist_table_set_gui_info(init_hostlist_table);
2318 srt_table_iterate_tables(register_service_response_tables, NULL);
2319 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2320 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2323 splash_update(RA_EXTCAP, NULL, (gpointer)splash_win);
2324 extcap_register_preferences();
2327 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2329 global_commandline_info.prefs_p = read_configuration_files();
2330 /* Removed thread code:
2331 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2334 cap_file_init(&cfile);
2336 /* Fill in capture options with values from the preferences */
2337 prefs_to_capture_opts();
2339 /*#ifdef HAVE_LIBPCAP
2340 fill_in_local_interfaces();
2343 /* Now get our args */
2344 commandline_other_options(argc, argv, TRUE);
2347 splash_update(RA_INTERFACES, NULL, (gpointer)splash_win);
2349 fill_in_local_interfaces(main_window_update);
2351 if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) {
2352 /* We're supposed to do a live capture or get a list of link-layer
2353 types for a live capture device; if the user didn't specify an
2354 interface to use, pick a default. */
2355 ret = capture_opts_default_iface_if_necessary(&global_capture_opts,
2356 ((global_commandline_info.prefs_p->capture_device) && (*global_commandline_info.prefs_p->capture_device != '\0')) ? get_if_name(global_commandline_info.prefs_p->capture_device) : NULL);
2362 if (global_commandline_info.list_link_layer_types) {
2363 /* Get the list of link-layer types for the capture devices. */
2364 if_capabilities_t *caps;
2367 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2369 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2370 if (device.selected) {
2371 gchar* auth_str = NULL;
2372 #ifdef HAVE_PCAP_REMOTE
2373 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
2374 auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
2375 device.remote_opts.remote_host_opts.auth_password);
2378 #if defined(HAVE_PCAP_CREATE)
2379 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
2381 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
2385 cmdarg_err("%s", err_str);
2387 ret = INVALID_CAPABILITY;
2390 if (caps->data_link_types == NULL) {
2391 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2392 ret = INVALID_LINK_TYPE;
2398 #if defined(HAVE_PCAP_CREATE)
2399 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2401 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2406 free_if_capabilities(caps);
2412 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2413 capture_opts_trim_ring_num_files(&global_capture_opts);
2414 #endif /* HAVE_LIBPCAP */
2416 /* Notify all registered modules that have had any of their preferences
2417 changed either from one of the preferences file or from the command
2418 line that their preferences have changed. */
2422 if ((global_capture_opts.num_selected == 0) &&
2423 ((prefs.capture_device != NULL) &&
2424 (global_commandline_info.prefs_p != NULL) &&
2425 (*global_commandline_info.prefs_p->capture_device != '\0'))) {
2428 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2429 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2430 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2431 device.selected = TRUE;
2432 global_capture_opts.num_selected++;
2433 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2434 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2439 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2440 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2441 device.selected = TRUE;
2442 global_capture_opts.num_selected++;
2443 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2444 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2449 * Enabled and disabled protocols and heuristic dissectors as per
2450 * command-line options.
2452 if (!setup_enabled_and_disabled_protocols()) {
2453 ret = INVALID_OPTION;
2457 build_column_format_array(&cfile.cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
2459 /* read in rc file from global and personal configuration paths. */
2460 rc_file = get_datafile_path(RC_FILE);
2461 #if GTK_CHECK_VERSION(3,0,0)
2462 /* XXX resolve later */
2464 gtk_rc_parse(rc_file);
2466 rc_file = get_persconffile_path(RC_FILE, FALSE);
2467 gtk_rc_parse(rc_file);
2477 /* close the splash screen, as we are going to open the main window now */
2478 splash_destroy(splash_win);
2480 /************************************************************************/
2481 /* Everything is prepared now, preferences and command line was read in */
2483 /* Pop up the main window. */
2484 create_main_window(pl_size, tv_size, bv_size, global_commandline_info.prefs_p);
2486 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2487 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
2488 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2489 "Could not open recent file\n\"%s\": %s.",
2490 rf_path, g_strerror(rf_open_errno));
2494 packet_list_enable_color(recent.packet_list_colorize);
2496 /* rearrange all the widgets as we now have all recent settings ready for this */
2497 main_widgets_rearrange();
2499 /* Fill in column titles. This must be done after the top level window
2502 XXX - is that still true, with fixed-width columns? */
2504 menu_recent_read_finished();
2506 main_auto_scroll_live_changed(auto_scroll_live);
2509 switch (user_font_apply()) {
2512 case FA_ZOOMED_TOO_FAR:
2513 /* The zoom level is too big for this font; turn off zooming. */
2514 recent.gui_zoom_level = 0;
2516 case FA_FONT_NOT_AVAILABLE:
2517 /* XXX - did we successfully load the un-zoomed version earlier?
2518 If so, this *probably* means the font is available, but not at
2519 this particular zoom level, but perhaps some other failure
2520 occurred; I'm not sure you can determine which is the case,
2522 /* turn off zooming - zoom level is unavailable */
2524 /* in any other case than FA_SUCCESS, turn off zooming */
2525 recent.gui_zoom_level = 0;
2526 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2530 dnd_init(top_level);
2532 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
2533 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
2537 capture_filter_init();
2540 /* the window can be sized only, if it's not already shown, so do it now! */
2541 main_load_window_geometry(top_level);
2543 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2545 /* this is to keep tap extensions updating once every 3 seconds */
2546 tap_update_timer_id = g_timeout_add(global_commandline_info.prefs_p->tap_update_interval, tap_update_cb, NULL);
2548 /* If we were given the name of a capture file, read it in now;
2549 we defer it until now, so that, if we can't open it, and pop
2550 up an alert box, the alert box is more likely to come up on
2551 top of the main window - but before the preference-file-error
2552 alert box, so, if we get one of those, it's more likely to come
2554 if (global_commandline_info.cf_name) {
2555 show_main_window(TRUE);
2556 check_and_warn_user_startup(global_commandline_info.cf_name);
2557 if (global_commandline_info.rfilter != NULL) {
2558 if (!dfilter_compile(global_commandline_info.rfilter, &rfcode, &err_msg)) {
2559 bad_dfilter_alert_box(top_level, global_commandline_info.rfilter, err_msg);
2561 rfilter_parse_failed = TRUE;
2564 if (ex_opt_count("read_format") > 0) {
2565 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
2567 if (!rfilter_parse_failed) {
2568 if (cf_open(&cfile, global_commandline_info.cf_name, in_file_type, FALSE, &err) == CF_OK) {
2569 /* "cf_open()" succeeded, so it closed the previous
2570 capture file, and thus destroyed any previous read filter
2571 attached to "cf". */
2573 cfile.rfcode = rfcode;
2574 /* Open stat windows; we do so after creating the main window,
2575 to avoid GTK warnings, and after successfully opening the
2576 capture file, so we know we have something to compute stats
2577 on, and after registering all dissectors, so that MATE will
2578 have registered its field array and we can have a tap filter
2579 with one of MATE's late-registered fields as part of the
2581 start_requested_stats();
2583 /* Read the capture file. */
2584 switch (cf_read(&cfile, FALSE)) {
2588 /* Just because we got an error, that doesn't mean we were unable
2589 to read any of the file; we handle what we could get from the
2591 /* if the user told us to jump to a specific packet, do it now */
2592 if(global_commandline_info.go_to_packet != 0) {
2593 /* Jump to the specified frame number, kept for backward
2595 cf_goto_frame(&cfile, global_commandline_info.go_to_packet);
2596 } else if (global_commandline_info.jfilter != NULL) {
2597 /* try to compile given filter */
2598 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
2599 bad_dfilter_alert_box(top_level, global_commandline_info.jfilter, err_msg);
2602 /* Filter ok, jump to the first packet matching the filter
2603 conditions. Default search direction is forward, but if
2604 option d was given, search backwards */
2605 cf_find_packet_dfilter(&cfile, jump_to_filter, global_commandline_info.jump_backwards);
2610 case CF_READ_ABORTED:
2616 /* If the filename is not the absolute path, prepend the current dir. This happens
2617 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
2618 if (!g_path_is_absolute(global_commandline_info.cf_name)) {
2619 char *old_cf_name = global_commandline_info.cf_name;
2620 char *pwd = g_get_current_dir();
2621 global_commandline_info.cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, global_commandline_info.cf_name);
2622 g_free(old_cf_name);
2626 /* Save the name of the containing directory specified in the
2627 path name, if any; we can write over cf_name, which is a
2628 good thing, given that "get_dirname()" does write over its
2630 s = get_dirname(global_commandline_info.cf_name);
2631 set_last_open_dir(s);
2632 g_free(global_commandline_info.cf_name);
2633 global_commandline_info.cf_name = NULL;
2636 dfilter_free(rfcode);
2637 cfile.rfcode = NULL;
2638 show_main_window(FALSE);
2639 /* Don't call check_and_warn_user_startup(): we did it above */
2640 main_set_for_capture_in_progress(FALSE);
2641 set_capture_if_dialog_for_capture_in_progress(FALSE);
2646 if (global_commandline_info.start_capture) {
2647 if (global_capture_opts.save_file != NULL) {
2648 /* Save the directory name for future file dialogs. */
2649 /* (get_dirname overwrites filename) */
2650 s = g_strdup(global_capture_opts.save_file);
2651 set_last_open_dir(get_dirname(s));
2654 /* "-k" was specified; start a capture. */
2655 show_main_window(FALSE);
2656 check_and_warn_user_startup(global_commandline_info.cf_name);
2658 /* If no user interfaces were specified on the command line,
2659 copy the list of selected interfaces to the set of interfaces
2660 to use for this capture. */
2661 if (global_capture_opts.ifaces->len == 0)
2662 collect_ifaces(&global_capture_opts);
2663 if (capture_start(&global_capture_opts, &global_capture_session, &global_info_data,main_window_update)) {
2664 /* The capture started. Open stat windows; we do so after creating
2665 the main window, to avoid GTK warnings, and after successfully
2666 opening the capture file, so we know we have something to compute
2667 stats on, and after registering all dissectors, so that MATE will
2668 have registered its field array and we can have a tap filter with
2669 one of MATE's late-registered fields as part of the filter. */
2670 start_requested_stats();
2673 show_main_window(FALSE);
2674 check_and_warn_user_startup(global_commandline_info.cf_name);
2675 main_set_for_capture_in_progress(FALSE);
2676 set_capture_if_dialog_for_capture_in_progress(FALSE);
2678 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
2679 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
2680 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
2682 #else /* HAVE_LIBPCAP */
2683 show_main_window(FALSE);
2684 check_and_warn_user_startup(global_commandline_info.cf_name);
2685 main_set_for_capture_in_progress(FALSE);
2686 set_capture_if_dialog_for_capture_in_progress(FALSE);
2687 #endif /* HAVE_LIBPCAP */
2690 if (global_commandline_info.dfilter) {
2691 GtkWidget *filter_te;
2692 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
2693 gtk_entry_set_text(GTK_ENTRY(filter_te), global_commandline_info.dfilter);
2695 /* Run the display filter so it goes in effect. */
2696 main_filter_packets(&cfile, global_commandline_info.dfilter, FALSE);
2699 profile_store_persconffiles (FALSE);
2701 #ifdef HAVE_GTKOSXAPPLICATION
2702 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
2703 #ifdef HAVE_GDK_GRESOURCE
2704 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
2706 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
2708 gtkosx_application_ready(theApp);
2711 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
2714 gtk_iface_mon_start();
2717 software_update_init();
2719 /* we'll enter the GTK loop now and hand the control over to GTK ... */
2721 /* ... back from GTK, we're going down now! */
2724 gtk_iface_mon_stop();
2733 AirPDcapDestroyContext(&airpdcap_ctx);
2735 #ifdef HAVE_GTKOSXAPPLICATION
2736 g_object_unref(theApp);
2740 /* hide the (unresponsive) main window, while asking the user to close the console window */
2741 if (G_IS_OBJECT(top_level))
2742 gtk_widget_hide(top_level);
2744 software_update_cleanup();
2746 /* Shutdown windows sockets */
2749 /* For some unknown reason, the "atexit()" call in "create_console()"
2750 doesn't arrange that "destroy_console()" be called when we exit,
2751 so we call it here if a console was created. */
2755 #ifdef HAVE_GDK_GRESOURCE
2756 main_unregister_resource();
2761 capture_opts_cleanup(&global_capture_opts);
2763 col_cleanup(&cfile.cinfo);
2764 free_filter_lists();
2775 /* We build this as a GUI subsystem application on Win32, so
2776 "WinMain()", not "main()", gets called.
2778 Hack shamelessly stolen from the Win32 port of the GIMP. */
2780 #define _stdcall __attribute__((stdcall))
2784 WinMain (struct HINSTANCE__ *hInstance,
2785 struct HINSTANCE__ *hPrevInstance,
2789 INITCOMMONCONTROLSEX comm_ctrl;
2792 * Initialize our DLL search path. MUST be called before LoadLibrary
2795 ws_init_dll_search_path();
2797 /* Initialize our controls. Required for native Windows file dialogs. */
2798 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
2799 comm_ctrl.dwSize = sizeof(comm_ctrl);
2800 /* Includes the animate, header, hot key, list view, progress bar,
2801 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
2804 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
2805 InitCommonControlsEx(&comm_ctrl);
2807 /* RichEd20.DLL is needed for native file dialog filter entries. */
2808 ws_load_library("riched20.dll");
2810 set_has_console(FALSE);
2811 set_console_wait(FALSE);
2812 return main (__argc, __argv);
2821 * Helper for main_widgets_rearrange()
2823 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
2824 gtk_container_remove(GTK_CONTAINER(data), widget);
2827 static GtkWidget *main_widget_layout(gint layout_content)
2829 switch(layout_content) {
2830 case(layout_pane_content_none):
2832 case(layout_pane_content_plist):
2834 case(layout_pane_content_pdetails):
2836 case(layout_pane_content_pbytes):
2837 return byte_nb_ptr_gbl;
2839 g_assert_not_reached();
2845 * Rearrange the main window widgets
2847 void main_widgets_rearrange(void) {
2848 GtkWidget *first_pane_widget1, *first_pane_widget2;
2849 GtkWidget *second_pane_widget1, *second_pane_widget2;
2850 gboolean split_top_left = FALSE;
2852 /* be a bit faster */
2853 gtk_widget_hide(main_vbox);
2855 /* be sure we don't lose a widget while rearranging */
2856 g_object_ref(G_OBJECT(menubar));
2857 g_object_ref(G_OBJECT(main_tb));
2858 g_object_ref(G_OBJECT(filter_tb));
2859 g_object_ref(G_OBJECT(wireless_tb));
2860 g_object_ref(G_OBJECT(pkt_scrollw));
2861 g_object_ref(G_OBJECT(tv_scrollw));
2862 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
2863 g_object_ref(G_OBJECT(statusbar));
2864 g_object_ref(G_OBJECT(main_pane_v1));
2865 g_object_ref(G_OBJECT(main_pane_v2));
2866 g_object_ref(G_OBJECT(main_pane_h1));
2867 g_object_ref(G_OBJECT(main_pane_h2));
2868 g_object_ref(G_OBJECT(welcome_pane));
2870 /* empty all containers participating */
2871 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
2872 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
2873 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
2874 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
2875 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
2877 statusbar_widgets_emptying(statusbar);
2879 /* add the menubar always at the top */
2880 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2883 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
2885 /* filter toolbar in toolbar area */
2886 if (!prefs.filter_toolbar_show_in_statusbar) {
2887 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
2890 /* airpcap toolbar */
2891 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
2893 /* fill the main layout panes */
2894 switch(prefs.gui_layout_type) {
2895 case(layout_type_5):
2896 main_first_pane = main_pane_v1;
2897 main_second_pane = main_pane_v2;
2898 split_top_left = FALSE;
2900 case(layout_type_2):
2901 main_first_pane = main_pane_v1;
2902 main_second_pane = main_pane_h1;
2903 split_top_left = FALSE;
2905 case(layout_type_1):
2906 main_first_pane = main_pane_v1;
2907 main_second_pane = main_pane_h1;
2908 split_top_left = TRUE;
2910 case(layout_type_4):
2911 main_first_pane = main_pane_h1;
2912 main_second_pane = main_pane_v1;
2913 split_top_left = FALSE;
2915 case(layout_type_3):
2916 main_first_pane = main_pane_h1;
2917 main_second_pane = main_pane_v1;
2918 split_top_left = TRUE;
2920 case(layout_type_6):
2921 main_first_pane = main_pane_h1;
2922 main_second_pane = main_pane_h2;
2923 split_top_left = FALSE;
2926 main_first_pane = NULL;
2927 main_second_pane = NULL;
2928 g_assert_not_reached();
2930 if (split_top_left) {
2931 first_pane_widget1 = main_second_pane;
2932 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2933 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
2934 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2936 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2937 first_pane_widget2 = main_second_pane;
2938 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
2939 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2941 if (first_pane_widget1 != NULL)
2942 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
2943 if (first_pane_widget2 != NULL)
2944 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
2945 if (second_pane_widget1 != NULL)
2946 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
2947 if (second_pane_widget2 != NULL)
2948 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
2950 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
2953 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
2956 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
2958 /* filter toolbar in statusbar hbox */
2959 if (prefs.filter_toolbar_show_in_statusbar) {
2960 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
2963 /* statusbar widgets */
2964 statusbar_widgets_pack(statusbar);
2966 /* hide widgets on users recent settings */
2967 main_widgets_show_or_hide();
2969 gtk_widget_show(main_vbox);
2973 is_widget_visible(GtkWidget *widget, gpointer data)
2975 gboolean *is_visible = ( gboolean *)data;
2978 if (gtk_widget_get_visible(widget))
2985 main_widgets_show_or_hide(void)
2987 gboolean main_second_pane_show;
2989 if (recent.main_toolbar_show) {
2990 gtk_widget_show(main_tb);
2992 gtk_widget_hide(main_tb);
2995 statusbar_widgets_show_or_hide(statusbar);
2997 if (recent.filter_toolbar_show) {
2998 gtk_widget_show(filter_tb);
3000 gtk_widget_hide(filter_tb);
3003 if (recent.wireless_toolbar_show) {
3004 gtk_widget_show(wireless_tb);
3006 gtk_widget_hide(wireless_tb);
3009 if (recent.packet_list_show && have_capture_file) {
3010 gtk_widget_show(pkt_scrollw);
3012 gtk_widget_hide(pkt_scrollw);
3015 if (recent.tree_view_show && have_capture_file) {
3016 gtk_widget_show(tv_scrollw);
3018 gtk_widget_hide(tv_scrollw);
3021 if (recent.byte_view_show && have_capture_file) {
3022 gtk_widget_show(byte_nb_ptr_gbl);
3024 gtk_widget_hide(byte_nb_ptr_gbl);
3027 if (have_capture_file) {
3028 gtk_widget_show(main_first_pane);
3030 gtk_widget_hide(main_first_pane);
3034 * Is anything in "main_second_pane" visible?
3035 * If so, show it, otherwise hide it.
3037 main_second_pane_show = FALSE;
3038 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3039 &main_second_pane_show);
3040 if (main_second_pane_show) {
3041 gtk_widget_show(main_second_pane);
3043 gtk_widget_hide(main_second_pane);
3046 if (!have_capture_file) {
3048 gtk_widget_show(welcome_pane);
3051 gtk_widget_hide(welcome_pane);
3056 /* called, when the window state changes (minimized, maximized, ...) */
3058 window_state_event_cb (GtkWidget *widget _U_,
3062 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3064 if( (event->type) == (GDK_WINDOW_STATE)) {
3065 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3066 /* we might have dialogs popped up while we where iconified,
3068 display_queued_messages();
3076 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3078 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3080 if (event->keyval == GDK_F8) {
3083 } else if (event->keyval == GDK_F7) {
3086 } else if (event->state & NO_SHIFT_MOD_MASK) {
3087 return FALSE; /* Skip control, alt, and other modifiers */
3089 * A comment in gdkkeysyms.h says that it's autogenerated from
3090 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3091 * don't explicitly say so, g_ascii_isprint() should work as expected
3094 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3095 /* Forward the keypress on to the display filter entry */
3096 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3097 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3098 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3106 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3107 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3112 GtkAccelGroup *accel;
3115 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3116 set_titlebar_for_capture_file(NULL);
3118 gtk_widget_set_name(top_level, "main window");
3119 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3121 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3122 G_CALLBACK(window_state_event_cb), NULL);
3123 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3124 G_CALLBACK(top_level_key_pressed_cb), NULL );
3126 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3127 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3129 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3130 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3131 gtk_widget_show(main_vbox);
3134 menubar = main_menu_new(&accel);
3136 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3137 /* macOS native menus are created and displayed by main_menu_new() */
3138 if(!prefs_p->gui_macosx_style) {
3140 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3141 gtk_widget_show(menubar);
3142 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3144 gtk_widget_hide(menubar);
3149 main_tb = toolbar_new();
3150 gtk_widget_show (main_tb);
3152 /* Filter toolbar */
3153 filter_tb = filter_toolbar_new();
3156 pkt_scrollw = packet_list_create();
3157 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3158 gtk_widget_show_all(pkt_scrollw);
3161 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3162 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3163 gtk_widget_show(tv_scrollw);
3165 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3166 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3167 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3168 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3169 gtk_widget_show(tree_view_gbl);
3172 byte_nb_ptr_gbl = byte_view_new();
3173 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3174 gtk_widget_show(byte_nb_ptr_gbl);
3176 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3177 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3179 /* Panes for the packet list, tree, and byte view */
3180 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3181 gtk_widget_show(main_pane_v1);
3182 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3183 gtk_widget_show(main_pane_v2);
3184 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3185 gtk_widget_show(main_pane_h1);
3186 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3187 gtk_widget_show(main_pane_h2);
3189 wireless_tb = airpcap_toolbar_new();
3191 wireless_tb = ws80211_toolbar_new();
3193 gtk_widget_show(wireless_tb);
3196 statusbar = statusbar_new();
3197 gtk_widget_show(statusbar);
3199 /* Pane for the welcome screen */
3200 welcome_pane = welcome_new();
3201 gtk_widget_show(welcome_pane);
3205 show_main_window(gboolean doing_work)
3207 main_set_for_capture_file(doing_work);
3209 /*** we have finished all init things, show the main window ***/
3210 gtk_widget_show(top_level);
3212 /* the window can be maximized only, if it's visible, so do it after show! */
3213 main_load_window_geometry(top_level);
3215 /* process all pending GUI events before continue */
3216 while (gtk_events_pending()) gtk_main_iteration();
3218 /* Pop up any queued-up alert boxes. */
3219 display_queued_messages();
3221 /* Move the main window to the front, in case it isn't already there */
3222 gdk_window_raise(gtk_widget_get_window(top_level));
3225 airpcap_toolbar_show(wireless_tb);
3226 #endif /* HAVE_AIRPCAP */
3229 static void copy_global_profile (const gchar *profile_name)
3231 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3233 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3234 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3235 "Can't create directory\n\"%s\":\n%s.",
3236 pf_dir_path, g_strerror(errno));
3238 g_free(pf_dir_path);
3241 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3242 &pf_dir_path, &pf_dir_path2) == -1) {
3243 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3244 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3245 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3247 g_free(pf_filename);
3248 g_free(pf_dir_path);
3249 g_free(pf_dir_path2);
3253 /* Change configuration profile */
3254 void change_configuration_profile (const gchar *profile_name)
3258 gchar* err_msg = NULL;
3260 /* First check if profile exists */
3261 if (!profile_exists(profile_name, FALSE)) {
3262 if (profile_exists(profile_name, TRUE)) {
3263 /* Copy from global profile */
3264 copy_global_profile (profile_name);
3266 /* No personal and no global profile exists */
3271 /* Then check if changing to another profile */
3272 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3276 /* Get the current geometry, before writing it to disk */
3277 main_save_window_geometry(top_level);
3279 if (profile_exists(get_profile_name(), FALSE)) {
3280 /* Write recent file for profile we are leaving, if it still exists */
3281 write_profile_recent();
3284 /* Set profile name and update the status bar */
3285 set_profile_name (profile_name);
3286 profile_bar_update ();
3289 * Reset current preferences and enabled/disabled protocols and
3290 * heuristic dissectors.
3294 proto_reenable_all();
3297 * Read the configuration files for the new profile.
3299 (void) read_configuration_files();
3301 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
3302 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3303 "Could not open common recent file\n\"%s\": %s.",
3304 rf_path, g_strerror(rf_open_errno));
3307 if (recent.gui_fileopen_remembered_dir &&
3308 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3309 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3311 timestamp_set_type (recent.gui_time_format);
3312 timestamp_set_seconds_type (recent.gui_seconds_format);
3313 packet_list_enable_color(recent.packet_list_colorize);
3315 prefs_to_capture_opts();
3318 update_local_interfaces();
3320 macros_post_update();
3322 /* Update window view and redraw the toolbar */
3323 main_titlebar_update();
3324 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3325 toolbar_redraw_all();
3327 /* Reload color filters */
3328 if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3329 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3333 /* Reload list of interfaces on welcome page */
3334 welcome_if_panel_reload();
3336 /* Recreate the packet list according to new preferences */
3337 packet_list_recreate ();
3338 cfile.columns_changed = FALSE; /* Reset value */
3341 /* Update menus with new recent values */
3342 menu_recent_read_finished();
3344 /* Reload pane geometry, must be done after recreating the list */
3345 main_pane_load_window_geometry();
3349 main_fields_changed (void)
3351 gchar* err_msg = NULL;
3353 /* Reload color filters */
3354 if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3355 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3359 /* Syntax check filter */
3360 filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3361 if (cfile.dfilter) {
3362 /* Check if filter is still valid */
3363 dfilter_t *dfp = NULL;
3364 if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
3365 /* Not valid. Enable 'Apply' button and remove dfilter. */
3366 g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3367 g_free(cfile.dfilter);
3368 cfile.dfilter = NULL;
3373 if (have_custom_cols(&cfile.cinfo)) {
3374 /* Recreate packet list according to new/changed/deleted fields */
3375 packet_list_recreate();
3376 } else if (cfile.state != FILE_CLOSED) {
3377 /* Redissect packets if we have any */
3378 redissect_packets();
3380 destroy_packet_wins(); /* TODO: close windows until we can recreate */
3382 proto_free_deregistered_fields();
3385 /** redissect packets and update UI */
3386 void redissect_packets(void)
3388 cf_redissect_packets(&cfile);
3389 status_expert_update();
3392 #ifdef HAVE_SOFTWARE_UPDATE
3393 /** Check to see if Wireshark can shut down safely (e.g. offer to save the
3397 int software_update_can_shutdown_callback(void) {
3401 /** Shut down Wireshark in preparation for an upgrade.
3404 void software_update_shutdown_request_callback(void) {
3414 * indent-tabs-mode: nil
3417 * ex: set shiftwidth=4 tabstop=8 expandtab:
3418 * :indentSize=4:tabSize=8:noTabs=true: