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_err.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>
212 * Files under personal and global preferences directories in which
213 * GTK settings for Wireshark are stored.
215 #define RC_FILE "gtkrc"
218 capture_session global_capture_session;
219 info_data_t global_info_data;
224 static gboolean capture_stopping;
226 /* "exported" main widgets */
227 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
229 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
230 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
231 static GtkWidget *main_first_pane, *main_second_pane;
233 /* internally used widgets */
234 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
236 GtkWidget *wireless_tb;
238 int airpcap_dll_ret_val = -1;
241 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
243 static guint tap_update_timer_id;
245 static void create_main_window(gint, gint, gint, e_prefs*);
246 static void show_main_window(gboolean);
247 static void main_save_window_geometry(GtkWidget *widget);
250 /* Match selected byte pattern */
252 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
254 char *cur_filter, *new_filter;
256 if ((!text) || (0 == strlen(text))) {
257 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
263 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
265 switch (action&MATCH_SELECTED_MASK) {
267 case MATCH_SELECTED_REPLACE:
268 new_filter = g_strdup(text);
271 case MATCH_SELECTED_AND:
272 if ((!cur_filter) || (0 == strlen(cur_filter)))
273 new_filter = g_strdup(text);
275 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
278 case MATCH_SELECTED_OR:
279 if ((!cur_filter) || (0 == strlen(cur_filter)))
280 new_filter = g_strdup(text);
282 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
285 case MATCH_SELECTED_NOT:
286 new_filter = g_strconcat("!(", text, ")", NULL);
289 case MATCH_SELECTED_AND_NOT:
290 if ((!cur_filter) || (0 == strlen(cur_filter)))
291 new_filter = g_strconcat("!(", text, ")", NULL);
293 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
296 case MATCH_SELECTED_OR_NOT:
297 if ((!cur_filter) || (0 == strlen(cur_filter)))
298 new_filter = g_strconcat("!(", text, ")", NULL);
300 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
304 g_assert_not_reached();
309 /* Free up the copy we got of the old filter text. */
312 /* Don't change the current display filter if we only want to copy the filter */
313 if (action&MATCH_SELECTED_COPY_ONLY) {
314 GString *gtk_text_str = g_string_new("");
315 g_string_append(gtk_text_str, new_filter);
316 copy_to_clipboard(gtk_text_str);
317 g_string_free(gtk_text_str, TRUE);
319 /* create a new one and set the display filter entry accordingly */
320 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
322 /* Run the display filter so it goes in effect. */
323 if (action&MATCH_SELECTED_APPLY_NOW)
324 main_filter_packets(&cfile, new_filter, FALSE);
327 /* Free up the new filter text. */
332 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
336 if (cfile.finfo_selected) {
337 filter = proto_construct_match_selected_string(cfile.finfo_selected,
339 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
340 wmem_free(NULL, filter);
345 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
348 gchar *err_msg = NULL;
350 if (cfile.finfo_selected) {
351 filter = proto_construct_match_selected_string(cfile.finfo_selected,
353 if ((!filter) || (0 == strlen(filter))) {
354 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
355 "Could not acquire information to build a filter!\n"
356 "Try expanding or choosing another item.");
361 color_display_with_filter(filter);
364 if (!color_filters_reset_tmp(&err_msg)) {
365 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
369 if (!color_filters_set_tmp(filt_nr,filter, FALSE, &err_msg)) {
370 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
375 packet_list_colorize_packets();
377 wmem_free(NULL, filter);
382 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
384 gchar *selected_proto_url;
385 gchar *proto_abbrev = (gchar *)data;
390 if (cfile.finfo_selected) {
391 /* open wiki page using the protocol abbreviation */
392 selected_proto_url = g_strdup_printf("https://wiki.wireshark.org/Protocols/%s", proto_abbrev);
393 browser_open_url(selected_proto_url);
394 g_free(selected_proto_url);
397 case(ESD_BTN_CANCEL):
400 g_assert_not_reached();
406 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
409 const gchar *proto_abbrev;
413 if (cfile.finfo_selected) {
414 /* convert selected field to protocol abbreviation */
415 /* XXX - could this conversion be simplified? */
416 field_id = cfile.finfo_selected->hfinfo->id;
417 /* if the selected field isn't a protocol, get its parent */
418 if(!proto_registrar_is_protocol(field_id)) {
419 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
422 proto_abbrev = proto_registrar_get_abbrev(field_id);
424 /* ask the user if the wiki page really should be opened */
425 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
426 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
428 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
430 "The Wireshark Wiki is a collaborative approach to provide information "
431 "about Wireshark in several ways (not limited to protocol specifics).\n"
433 "This Wiki is new, so the page of the selected protocol "
434 "may not exist and/or may not contain valuable information.\n"
436 "As everyone can edit the Wiki and add new content (or extend existing), "
437 "you are encouraged to add information if you can.\n"
439 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
441 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
442 "which will save you a lot of editing and will give a consistent look over the pages.",
443 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
444 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
448 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
450 gchar *selected_proto_url;
451 gchar *proto_abbrev = (gchar *)data;
455 if (cfile.finfo_selected) {
456 /* open reference page using the protocol abbreviation */
457 selected_proto_url = g_strdup_printf("https://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
458 browser_open_url(selected_proto_url);
459 g_free(selected_proto_url);
462 case(ESD_BTN_CANCEL):
465 g_assert_not_reached();
470 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
473 const gchar *proto_abbrev;
477 if (cfile.finfo_selected) {
478 /* convert selected field to protocol abbreviation */
479 /* XXX - could this conversion be simplified? */
480 field_id = cfile.finfo_selected->hfinfo->id;
481 /* if the selected field isn't a protocol, get its parent */
482 if(!proto_registrar_is_protocol(field_id)) {
483 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
486 proto_abbrev = proto_registrar_get_abbrev(field_id);
488 /* ask the user if the wiki page really should be opened */
489 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
490 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
492 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
494 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
495 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
500 is_address_column (gint column)
502 if (((cfile.cinfo.columns[column].col_fmt == COL_DEF_SRC) ||
503 (cfile.cinfo.columns[column].col_fmt == COL_RES_SRC) ||
504 (cfile.cinfo.columns[column].col_fmt == COL_DEF_DST) ||
505 (cfile.cinfo.columns[column].col_fmt == COL_RES_DST)) &&
506 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
515 get_ip_address_list_from_packet_list_row(gpointer data)
517 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
518 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
521 GList *addr_list = NULL;
523 fdata = (frame_data *) packet_list_get_row_data(row);
528 if (!cf_read_record(&cfile, fdata))
529 return NULL; /* error reading the frame */
531 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
532 col_custom_prime_edt(&edt, &cfile.cinfo);
534 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
535 frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
536 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
538 /* First check selected column */
539 if (is_address_column (column)) {
540 addr_list = g_list_append (addr_list, g_strdup(cfile.cinfo.col_expr.col_expr_val[column]));
543 for (col = 0; col < cfile.cinfo.num_cols; col++) {
544 /* Then check all columns except the selected */
545 if ((col != column) && (is_address_column (col))) {
546 addr_list = g_list_append (addr_list, g_strdup(cfile.cinfo.col_expr.col_expr_val[col]));
550 epan_dissect_cleanup(&edt);
557 get_filter_from_packet_list_row_and_column(gpointer data)
559 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
560 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
564 fdata = (frame_data *) packet_list_get_row_data(row);
569 if (!cf_read_record(&cfile, fdata))
570 return NULL; /* error reading the record */
571 /* proto tree, visible. We need a proto tree if there's custom columns */
572 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
573 col_custom_prime_edt(&edt, &cfile.cinfo);
575 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
576 frame_tvbuff_new_buffer(fdata, &cfile.buf),
577 fdata, &cfile.cinfo);
578 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
580 if ((cfile.cinfo.columns[column].col_custom_occurrence) ||
581 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
583 /* Only construct the filter when a single occurrence is displayed
584 * otherwise we might end up with a filter like "ip.proto==1,6".
586 * Or do we want to be able to filter on multiple occurrences so that
587 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
590 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
591 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
592 /* leak a little; is there a safe wmem_ scope here? */
593 if (cfile.cinfo.columns[column].col_fmt == COL_CUSTOM) {
594 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.columns[column].col_custom_fields);
595 if (hfi && hfi->parent == -1) {
597 buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
598 } else if (hfi && IS_FT_STRING(hfi->type)) {
599 /* Custom string, add quotes */
600 buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
601 cfile.cinfo.col_expr.col_expr_val[column]);
605 buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
606 cfile.cinfo.col_expr.col_expr_val[column]);
611 epan_dissect_cleanup(&edt);
618 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
622 filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
624 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
630 /* This function allows users to right click in the details window and copy the text
631 * information to the operating systems clipboard.
633 * We first check to see if a string representation is setup in the tree and then
634 * read the string. If not available then we try to grab the value. If all else
635 * fails we display a message to the user to indicate the copy could not be completed.
638 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
640 GString *gtk_text_str = g_string_new("");
641 char labelstring[ITEM_LABEL_LENGTH];
642 char *stringpointer = labelstring;
646 case COPY_SELECTED_DESCRIPTION:
647 if (cfile.finfo_selected->rep &&
648 strlen(cfile.finfo_selected->rep->representation) > 0) {
649 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
652 case COPY_SELECTED_FIELDNAME:
653 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
654 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
657 case COPY_SELECTED_VALUE:
658 if (cfile.edt !=0 ) {
659 gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
660 g_string_append(gtk_text_str, field_str);
668 if (gtk_text_str->len == 0) {
669 /* If no representation then... Try to read the value */
670 proto_item_fill_label(cfile.finfo_selected, stringpointer);
671 g_string_append(gtk_text_str, stringpointer);
674 if (gtk_text_str->len == 0) {
675 /* Could not get item so display error msg */
676 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
678 /* Copy string to clipboard */
679 copy_to_clipboard(gtk_text_str);
681 g_string_free(gtk_text_str, TRUE); /* Free the memory */
685 /* mark as reference time frame */
687 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
691 frame->flags.ref_time=1;
692 cfile.ref_time_count++;
694 frame->flags.ref_time=0;
695 cfile.ref_time_count--;
697 cf_reftime_packets(&cfile);
698 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
699 packet_list_freeze();
700 cfile.displayed_count--;
701 packet_list_recreate_visible_rows();
704 packet_list_queue_draw();
708 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
712 timestamp_set_type(TS_RELATIVE);
713 recent.gui_time_format = TS_RELATIVE;
714 cf_timestamp_auto_precision(&cfile);
715 packet_list_queue_draw();
720 g_assert_not_reached();
723 if (cfile.current_frame) {
724 set_frame_reftime(!cfile.current_frame->flags.ref_time,
725 cfile.current_frame, cfile.current_row);
731 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
733 static GtkWidget *reftime_dialog = NULL;
737 if (cfile.current_frame) {
738 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
739 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
740 "%sSwitch to the appropriate Time Display Format?%s\n\n"
741 "Time References don't work well with the currently selected Time Display Format.\n\n"
742 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
743 simple_dialog_primary_start(), simple_dialog_primary_end());
744 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
746 set_frame_reftime(!cfile.current_frame->flags.ref_time,
747 cfile.current_frame, cfile.current_row);
751 case REFTIME_FIND_NEXT:
752 cf_find_packet_time_reference(&cfile, SD_FORWARD);
754 case REFTIME_FIND_PREV:
755 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
761 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
763 cf_find_packet_marked(&cfile, SD_FORWARD);
767 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
769 cf_find_packet_marked(&cfile, SD_BACKWARD);
773 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
776 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
778 gboolean has_blurb = FALSE;
779 guint length = 0, byte_len;
780 GtkWidget *byte_view;
781 const guint8 *byte_data;
786 /* if nothing is selected */
787 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
790 * Which byte view is displaying the current protocol tree
793 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
794 if (byte_view == NULL)
797 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
798 if (byte_data == NULL)
801 cf_unselect_field(&cfile);
802 packet_hex_print(byte_view, byte_data,
803 cfile.current_frame, NULL, byte_len);
806 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
809 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
811 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
812 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
813 g_assert(byte_data != NULL);
815 cfile.finfo_selected = finfo;
816 set_menus_for_selected_tree_row(&cfile);
819 if (finfo->hfinfo->blurb != NULL &&
820 finfo->hfinfo->blurb[0] != '\0') {
822 length = (guint) strlen(finfo->hfinfo->blurb);
824 length = (guint) strlen(finfo->hfinfo->name);
826 finfo_length = finfo->length + finfo->appendix_length;
828 if (finfo_length == 0) {
830 } else if (finfo_length == 1) {
831 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
833 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
835 statusbar_pop_field_msg(); /* get rid of current help msg */
837 statusbar_push_field_msg(" %s (%s)%s",
838 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
839 finfo->hfinfo->abbrev, len_str);
842 * Don't show anything if the field name is zero-length;
843 * the pseudo-field for text-only items is such
844 * a field, and we don't want "Text (text)" showing up
845 * on the status line if you've selected such a field.
847 * XXX - there are zero-length fields for which we *do*
848 * want to show the field name.
850 * XXX - perhaps the name and abbrev field should be null
851 * pointers rather than null strings for that pseudo-field,
852 * but we'd have to add checks for null pointers in some
853 * places if we did that.
855 * Or perhaps text-only items should have -1 as the field
856 * index, with no pseudo-field being used, but that might
857 * also require special checks for -1 to be added.
859 statusbar_push_field_msg("%s", "");
862 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
866 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
869 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
872 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
875 expand_all_tree(cfile.edt->tree, tree_view_gbl);
878 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
880 if (cfile.finfo_selected) {
881 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
882 cfile.finfo_selected->hfinfo->abbrev,0);
883 /* Recreate the packet list according to new preferences */
884 packet_list_recreate ();
885 if (!prefs.gui_use_pref_save) {
888 cfile.columns_changed = FALSE; /* Reset value */
892 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
896 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
898 /* the mouse position is at an entry, expand that one */
899 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
900 gtk_tree_path_free(path);
904 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
908 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
910 /* the mouse position is at an entry, expand that one */
912 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
913 gtk_tree_path_free(path);
917 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
919 static const e_addr_resolve resolv_flags = {
921 TRUE, /* network_name */
922 TRUE, /* transport_name */
923 TRUE, /* dns_pkt_addr_resolution */
924 TRUE, /* use_external_net_name_resolver */
925 FALSE, /* load_hosts_file_from_profile_only */
926 FALSE, /* vlan_name */
927 FALSE, /* ss7pc_name */
930 if (cfile.edt->tree) {
931 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
935 /* Update main window items based on whether there's a capture in progress. */
937 main_set_for_capture_in_progress(gboolean capture_in_progress)
939 set_menus_for_capture_in_progress(capture_in_progress);
942 set_toolbar_for_capture_in_progress(capture_in_progress);
944 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
948 /* Update main window items based on whether we have a capture file. */
950 main_set_for_capture_file(gboolean have_capture_file_in)
952 have_capture_file = have_capture_file_in;
954 main_widgets_show_or_hide();
957 /* Update main window items based on whether we have captured packets. */
959 main_set_for_captured_packets(gboolean have_captured_packets)
961 set_menus_for_captured_packets(have_captured_packets);
962 set_toolbar_for_captured_packets(have_captured_packets);
965 /* Update main window items based on whether we have a packet history. */
967 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
969 set_menus_for_packet_history(back_history, forward_history);
970 set_toolbar_for_packet_history(back_history, forward_history);
976 /* get the current geometry, before writing it to disk */
977 main_save_window_geometry(top_level);
979 /* write user's recent file to disk
980 * It is no problem to write this file, even if we do not quit */
981 write_profile_recent();
984 /* XXX - should we check whether the capture file is an
985 unsaved temporary file for a live capture and, if so,
986 pop up a "do you want to exit without saving the capture
987 file?" dialog, and then just return, leaving said dialog
988 box to forcibly quit if the user clicks "OK"?
990 If so, note that this should be done in a subroutine that
991 returns TRUE if we do so, and FALSE otherwise, and if it
992 returns TRUE we should return TRUE without nuking anything.
994 Note that, if we do that, we might also want to check if
995 an "Update list of packets in real time" capture is in
996 progress and, if so, ask whether they want to terminate
997 the capture and discard it, and return TRUE, before nuking
998 any child capture, if they say they don't want to do so. */
1001 /* Nuke any child capture in progress. */
1002 capture_kill_child(&global_capture_session);
1005 /* Are we in the middle of reading a capture? */
1006 if (cfile.state == FILE_READ_IN_PROGRESS) {
1007 /* Yes, so we can't just close the file and quit, as
1008 that may yank the rug out from under the read in
1009 progress; instead, just set the state to
1010 "FILE_READ_ABORTED" and return - the code doing the read
1011 will check for that and, if it sees that, will clean
1013 cfile.state = FILE_READ_ABORTED;
1015 /* Say that the window should *not* be deleted;
1016 that'll be done by the code that cleans up. */
1019 /* Close any capture file we have open; on some OSes, you
1020 can't unlink a temporary capture file if you have it
1022 "cf_close()" will unlink it after closing it if
1023 it's a temporary file.
1025 We do this here, rather than after the main loop returns,
1026 as, after the main loop returns, the main window may have
1027 been destroyed (if this is called due to a "destroy"
1028 even on the main window rather than due to the user
1029 selecting a menu item), and there may be a crash
1030 or other problem when "cf_close()" tries to
1031 clean up stuff in the main window.
1033 XXX - is there a better place to put this?
1034 Or should we have a routine that *just* closes the
1035 capture file, and doesn't do anything with the UI,
1036 which we'd call here, and another routine that
1037 calls that routine and also cleans up the UI, which
1038 we'd call elsewhere? */
1041 /* Exit by leaving the main loop, so that any quit functions
1042 we registered get called. */
1045 /* Say that the window should be deleted. */
1051 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1053 /* If we're in the middle of stopping a capture, don't do anything;
1054 the user can try deleting the window after the capture stops. */
1055 if (capture_stopping)
1058 /* If there's unsaved data, let the user save it first.
1059 If they cancel out of it, don't quit. */
1060 if (do_file_close(&cfile, TRUE, " before quitting"))
1061 return main_do_quit();
1063 return TRUE; /* will this keep the window from being deleted? */
1068 main_pane_load_window_geometry(void)
1070 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1071 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1072 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1073 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1079 main_load_window_geometry(GtkWidget *widget)
1081 window_geometry_t geom;
1083 geom.set_pos = prefs.gui_geometry_save_position;
1084 geom.x = recent.gui_gtk_geometry_main_x;
1085 geom.y = recent.gui_gtk_geometry_main_y;
1086 geom.set_size = prefs.gui_geometry_save_size;
1087 geom.set_maximized = FALSE;
1088 if (recent.gui_geometry_main_width > 0 &&
1089 recent.gui_geometry_main_height > 0) {
1090 geom.width = recent.gui_geometry_main_width;
1091 geom.height = recent.gui_geometry_main_height;
1092 geom.set_maximized = prefs.gui_geometry_save_maximized;
1094 /* We assume this means the width and height weren't set in
1095 the "recent" file (or that there is no "recent" file),
1096 and weren't set to a default value, so we don't set the
1097 size. (The "recent" file code rejects non-positive width
1098 and height values.) */
1099 geom.set_size = FALSE;
1101 geom.maximized = recent.gui_geometry_main_maximized;
1103 window_set_geometry(widget, &geom);
1105 main_pane_load_window_geometry();
1106 statusbar_load_window_geometry();
1111 main_save_window_geometry(GtkWidget *widget)
1113 window_geometry_t geom;
1115 window_get_geometry(widget, &geom);
1117 if (prefs.gui_geometry_save_position) {
1118 recent.gui_gtk_geometry_main_x = geom.x;
1119 recent.gui_gtk_geometry_main_y = geom.y;
1122 if (prefs.gui_geometry_save_size) {
1123 recent.gui_geometry_main_width = geom.width;
1124 recent.gui_geometry_main_height = geom.height;
1127 if(prefs.gui_geometry_save_maximized) {
1128 recent.gui_geometry_main_maximized = geom.maximized;
1131 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1132 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1133 statusbar_save_window_geometry();
1137 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1139 /* If there's unsaved data, let the user save it first. */
1140 if (do_file_close(&cfile, TRUE, " before quitting"))
1145 * Report an error in command-line arguments.
1146 * Creates a console on Windows.
1147 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1148 * terminal isn't the standard error?
1151 wireshark_cmdarg_err(const char *fmt, va_list ap)
1156 fprintf(stderr, "wireshark: ");
1157 vfprintf(stderr, fmt, ap);
1158 fprintf(stderr, "\n");
1162 * Report additional information for an error in command-line arguments.
1163 * Creates a console on Windows.
1164 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1165 * terminal isn't the standard error?
1168 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1173 vfprintf(stderr, fmt, ap);
1174 fprintf(stderr, "\n");
1178 Once every 3 seconds we get a callback here which we use to update
1182 tap_update_cb(gpointer data _U_)
1184 draw_tap_listeners(FALSE);
1189 * Periodically process outstanding hostname lookups. If we have new items,
1190 * redraw the packet list and tree view.
1194 resolv_update_cb(gpointer data _U_)
1196 /* Anything new show up? */
1197 if (host_name_lookup_process()) {
1198 if (gtk_widget_get_window(pkt_scrollw))
1199 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1200 if (gtk_widget_get_window(tv_scrollw))
1201 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1204 /* Always check. Even if we don't do async lookups we could still get
1205 passive updates, e.g. from DNS packets. */
1210 /* Update various parts of the main window for a capture file "unsaved
1211 changes" change - update the title to reflect whether there are
1212 unsaved changes or not, and update the menus and toolbar to
1213 enable or disable the "Save" operation. */
1215 main_update_for_unsaved_changes(capture_file *cf)
1217 set_titlebar_for_capture_file(cf);
1218 set_menus_for_capture_file(cf);
1219 set_toolbar_for_capture_file(cf);
1224 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1226 /* Update menubar and toolbar */
1227 menu_auto_scroll_live_changed(auto_scroll_live_in);
1228 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1230 /* change auto scroll state */
1231 auto_scroll_live = auto_scroll_live_in;
1236 main_colorize_changed(gboolean packet_list_colorize)
1238 /* Update menubar and toolbar */
1239 menu_colorize_changed(packet_list_colorize);
1240 toolbar_colorize_changed(packet_list_colorize);
1242 /* change colorization */
1243 if(packet_list_colorize != recent.packet_list_colorize) {
1244 recent.packet_list_colorize = packet_list_colorize;
1245 packet_list_enable_color(packet_list_colorize);
1246 packet_list_colorize_packets();
1250 static GtkWidget *close_dlg = NULL;
1253 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1255 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1260 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1262 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1267 main_cf_cb_file_closing(capture_file *cf)
1269 /* if we have more than 10000 packets, show a splash screen while closing */
1270 /* XXX - don't know a better way to decide whether to show or not,
1271 * as most of the time is spend in various calls that destroy various
1272 * data structures, so it wouldn't be easy to use a progress bar,
1273 * rather than, say, a progress spinner, here! */
1274 if(cf->count > 10000) {
1275 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1276 "%sClosing file!%s\n\nPlease wait ...",
1277 simple_dialog_primary_start(),
1278 simple_dialog_primary_end());
1279 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1281 /* Clear maunally resolved addresses */
1282 manually_resolve_cleanup();
1283 /* Destroy all windows that refer to the
1284 capture file we're closing. */
1285 destroy_packet_wins();
1287 /* Update the titlebar to reflect the lack of a capture file. */
1288 set_titlebar_for_capture_file(NULL);
1290 /* Disable all menu and toolbar items that make sense only if
1291 you have a capture. */
1292 set_menus_for_capture_file(NULL);
1293 set_toolbar_for_capture_file(NULL);
1294 main_set_for_captured_packets(FALSE);
1295 set_menus_for_selected_packet(cf);
1296 main_set_for_capture_in_progress(FALSE);
1297 set_capture_if_dialog_for_capture_in_progress(FALSE);
1298 set_menus_for_selected_tree_row(cf);
1300 /* Set up main window for no capture file. */
1301 main_set_for_capture_file(FALSE);
1303 main_window_update();
1308 main_cf_cb_file_closed(capture_file *cf _U_)
1310 if(close_dlg != NULL) {
1311 splash_destroy(close_dlg);
1318 main_cf_cb_file_read_started(capture_file *cf _U_)
1320 tap_param_dlg_update();
1322 /* Set up main window for a capture file. */
1323 main_set_for_capture_file(TRUE);
1327 main_cf_cb_file_read_finished(capture_file *cf)
1331 if (!cf->is_tempfile && cf->filename) {
1332 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1333 add_menu_recent_capture_file(cf->filename);
1335 /* Remember folder for next Open dialog and save it in recent */
1336 dir_path = g_strdup(cf->filename);
1337 set_last_open_dir(get_dirname(dir_path));
1341 /* Update the appropriate parts of the main window. */
1342 main_update_for_unsaved_changes(cf);
1344 /* Enable menu items that make sense if you have some captured packets. */
1345 main_set_for_captured_packets(TRUE);
1349 main_cf_cb_file_rescan_finished(capture_file *cf)
1353 if (!cf->is_tempfile && cf->filename) {
1354 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1355 add_menu_recent_capture_file(cf->filename);
1357 /* Remember folder for next Open dialog and save it in recent */
1358 dir_path = g_strdup(cf->filename);
1359 set_last_open_dir(get_dirname(dir_path));
1363 /* Update the appropriate parts of the main window. */
1364 main_update_for_unsaved_changes(cf);
1368 static GList *icon_list_create(
1369 #ifdef HAVE_GDK_GRESOURCE
1370 const gchar *icon16_path,
1371 const gchar *icon32_path,
1372 const gchar *icon48_path,
1373 const gchar *icon64_path)
1375 const guint8 *icon16_pb,
1376 const guint8 *icon32_pb,
1377 const guint8 *icon48_pb,
1378 const guint8 *icon64_pb)
1381 GList *icon_list = NULL;
1382 GdkPixbuf *pixbuf16 = NULL;
1383 GdkPixbuf *pixbuf32 = NULL;
1384 GdkPixbuf *pixbuf48 = NULL;
1385 GdkPixbuf *pixbuf64 = NULL;
1387 #ifdef HAVE_GDK_GRESOURCE
1388 if (icon16_path != NULL)
1389 pixbuf16 = ws_gdk_pixbuf_new_from_resource(icon16_path);
1390 if (icon32_path != NULL)
1391 pixbuf32 = ws_gdk_pixbuf_new_from_resource(icon32_path);
1392 if (icon48_path != NULL)
1393 pixbuf48 = ws_gdk_pixbuf_new_from_resource(icon48_path);
1394 if (icon64_path != NULL)
1395 pixbuf64 = ws_gdk_pixbuf_new_from_resource(icon64_path);
1397 if (icon16_pb != NULL)
1398 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1399 if (icon32_pb != NULL)
1400 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1401 if (icon48_pb != NULL)
1402 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1403 if (icon64_pb != NULL)
1404 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1407 if (pixbuf16 != NULL)
1408 icon_list = g_list_append(icon_list, pixbuf16);
1409 if (pixbuf32 != NULL)
1410 icon_list = g_list_append(icon_list, pixbuf32);
1411 if (pixbuf48 != NULL)
1412 icon_list = g_list_append(icon_list, pixbuf48);
1413 if (pixbuf64 != NULL)
1414 icon_list = g_list_append(icon_list, pixbuf64);
1420 main_capture_cb_capture_prepared(capture_session *cap_session)
1422 static GList *icon_list = NULL;
1424 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1426 if(icon_list == NULL) {
1427 #ifdef HAVE_GDK_GRESOURCE
1428 icon_list = icon_list_create("/org/wireshark/image/wsiconcap16.png",
1429 "/org/wireshark/image/wsiconcap32.png",
1430 "/org/wireshark/image/wsiconcap48.png",
1431 "/org/wireshark/image/wsiconcap64.png");
1433 icon_list = icon_list_create(wsiconcap_16_pb_data,
1434 wsiconcap_32_pb_data,
1435 wsiconcap_48_pb_data,
1436 wsiconcap_64_pb_data);
1439 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1441 /* Disable menu items that make no sense if you're currently running
1443 main_set_for_capture_in_progress(TRUE);
1444 set_capture_if_dialog_for_capture_in_progress(TRUE);
1446 /* Don't set up main window for a capture file. */
1447 main_set_for_capture_file(FALSE);
1451 main_capture_cb_capture_update_started(capture_session *cap_session)
1453 /* We've done this in "prepared" above, but it will be cleared while
1454 switching to the next multiple file. */
1455 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1457 main_set_for_capture_in_progress(TRUE);
1458 set_capture_if_dialog_for_capture_in_progress(TRUE);
1460 /* Enable menu items that make sense if you have some captured
1461 packets (yes, I know, we don't have any *yet*). */
1462 main_set_for_captured_packets(TRUE);
1464 /* Set up main window for a capture file. */
1465 main_set_for_capture_file(TRUE);
1469 main_capture_cb_capture_update_finished(capture_session *cap_session)
1471 capture_file *cf = (capture_file *)cap_session->cf;
1472 static GList *icon_list = NULL;
1474 /* The capture isn't stopping any more - it's stopped. */
1475 capture_stopping = FALSE;
1477 if (!cf->is_tempfile && cf->filename) {
1478 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1479 add_menu_recent_capture_file(cf->filename);
1482 /* Enable menu items that make sense if you're not currently running
1484 main_set_for_capture_in_progress(FALSE);
1485 set_capture_if_dialog_for_capture_in_progress(FALSE);
1487 /* Update the main window as appropriate. This has to occur AFTER
1488 * main_set_for_capture_in_progress() or else some of the menus are
1489 * incorrectly disabled (see bug
1490 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1491 main_update_for_unsaved_changes(cf);
1493 /* Set up main window for a capture file. */
1494 main_set_for_capture_file(TRUE);
1496 if(icon_list == NULL) {
1497 #ifdef HAVE_GDK_GRESOURCE
1498 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1499 "/org/wireshark/image/wsicon32.png",
1500 "/org/wireshark/image/wsicon48.png",
1501 "/org/wireshark/image/wsicon64.png");
1503 icon_list = icon_list_create(wsicon_16_pb_data,
1509 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1511 if(global_commandline_info.quit_after_cap) {
1512 /* command line asked us to quit after the capture */
1513 /* don't pop up a dialog to ask for unsaved files etc. */
1519 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1521 /* Don't set up main window for a capture file. */
1522 main_set_for_capture_file(FALSE);
1526 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1529 capture_file *cf = (capture_file *)cap_session->cf;
1531 static GList *icon_list = NULL;
1533 /* The capture isn't stopping any more - it's stopped. */
1534 capture_stopping = FALSE;
1536 /*set_titlebar_for_capture_file(cf);*/
1538 /* Enable menu items that make sense if you're not currently running
1540 main_set_for_capture_in_progress(FALSE);
1541 set_capture_if_dialog_for_capture_in_progress(FALSE);
1543 /* Restore the standard title bar message */
1544 /* (just in case we have trouble opening the capture file). */
1545 set_titlebar_for_capture_file(NULL);
1547 if(icon_list == NULL) {
1548 #ifdef HAVE_GDK_GRESOURCE
1549 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1550 "/org/wireshark/image/wsicon32.png",
1551 "/org/wireshark/image/wsicon48.png",
1552 "/org/wireshark/image/wsicon64.png");
1554 icon_list = icon_list_create(wsicon_16_pb_data,
1560 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1562 /* We don't have loaded the capture file, this will be done later.
1563 * For now we still have simply a blank screen. */
1565 if(global_commandline_info.quit_after_cap) {
1566 /* command line asked us to quit after the capture */
1567 /* don't pop up a dialog to ask for unsaved files etc. */
1573 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1575 capture_stopping = TRUE;
1576 set_menus_for_capture_stopping();
1578 set_toolbar_for_capture_stopping();
1580 set_capture_if_dialog_for_capture_stopping();
1585 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1587 static GList *icon_list = NULL;
1589 /* Capture isn't stopping any more. */
1590 capture_stopping = FALSE;
1592 /* the capture failed before the first packet was captured
1593 reset title, menus and icon */
1594 set_titlebar_for_capture_file(NULL);
1596 main_set_for_capture_in_progress(FALSE);
1597 set_capture_if_dialog_for_capture_in_progress(FALSE);
1599 main_set_for_capture_file(FALSE);
1601 if(icon_list == NULL) {
1602 #ifdef HAVE_GDK_GRESOURCE
1603 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1604 "/org/wireshark/image/wsicon32.png",
1605 "/org/wireshark/image/wsicon48.png",
1606 "/org/wireshark/image/wsicon64.png");
1608 icon_list = icon_list_create(wsicon_16_pb_data,
1614 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1617 if(global_commandline_info.quit_after_cap) {
1618 /* command line asked us to quit after the capture */
1619 /* don't pop up a dialog to ask for unsaved files etc. */
1623 #endif /* HAVE_LIBPCAP */
1626 main_cf_cb_packet_selected(gpointer data)
1628 capture_file *cf = (capture_file *)data;
1630 /* Display the GUI protocol tree and packet bytes.
1631 XXX - why do we dump core if we call "proto_tree_draw()"
1632 before calling "add_byte_views()"? */
1633 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1634 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1636 /* Note: Both string and hex value searches in the packet data produce a non-zero
1637 search_pos if successful */
1638 if(cf->search_in_progress &&
1639 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1640 highlight_field(cf->edt->tvb, cf->search_pos,
1641 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1644 /* A packet is selected. */
1645 set_menus_for_selected_packet(cf);
1649 main_cf_cb_packet_unselected(capture_file *cf)
1651 /* No packet is being displayed; clear the hex dump pane by getting
1652 rid of all the byte views. */
1653 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1654 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1656 /* Add a placeholder byte view so that there's at least something
1657 displayed in the byte view notebook. */
1658 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1660 /* And clear the protocol tree display as well. */
1661 proto_tree_draw(NULL, tree_view_gbl);
1663 /* No packet is selected. */
1664 set_menus_for_selected_packet(cf);
1668 main_cf_cb_field_unselected(capture_file *cf)
1670 set_menus_for_selected_tree_row(cf);
1674 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1676 capture_file *cf = (capture_file *)data;
1678 case(cf_cb_file_opened):
1679 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1680 fileset_file_opened(cf);
1682 case(cf_cb_file_closing):
1683 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1684 main_cf_cb_file_closing(cf);
1686 case(cf_cb_file_closed):
1687 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1688 main_cf_cb_file_closed(cf);
1689 fileset_file_closed();
1691 case(cf_cb_file_read_started):
1692 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1693 main_cf_cb_file_read_started(cf);
1695 case(cf_cb_file_read_finished):
1696 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1697 main_cf_cb_file_read_finished(cf);
1699 case(cf_cb_file_reload_started):
1700 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1701 main_cf_cb_file_read_started(cf);
1703 case(cf_cb_file_reload_finished):
1704 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1705 main_cf_cb_file_read_finished(cf);
1707 case(cf_cb_file_rescan_started):
1708 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1710 case(cf_cb_file_rescan_finished):
1711 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1712 main_cf_cb_file_rescan_finished(cf);
1714 case(cf_cb_file_retap_started):
1715 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap started");
1717 case(cf_cb_file_retap_finished):
1718 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap finished");
1720 case(cf_cb_file_fast_save_finished):
1721 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1722 main_cf_cb_file_rescan_finished(cf);
1724 case(cf_cb_packet_selected):
1725 main_cf_cb_packet_selected(cf);
1727 case(cf_cb_packet_unselected):
1728 main_cf_cb_packet_unselected(cf);
1730 case(cf_cb_field_unselected):
1731 main_cf_cb_field_unselected(cf);
1733 case(cf_cb_file_save_started):
1734 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1736 case(cf_cb_file_save_finished):
1737 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1739 case(cf_cb_file_save_failed):
1740 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1742 case(cf_cb_file_save_stopped):
1743 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1745 case(cf_cb_file_export_specified_packets_started):
1746 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1748 case(cf_cb_file_export_specified_packets_finished):
1749 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1751 case(cf_cb_file_export_specified_packets_failed):
1752 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1754 case(cf_cb_file_export_specified_packets_stopped):
1755 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1758 g_warning("main_cf_callback: event %u unknown", event);
1759 g_assert_not_reached();
1765 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1767 #ifdef HAVE_GTKOSXAPPLICATION
1768 GtkosxApplication *theApp;
1771 case(capture_cb_capture_prepared):
1772 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1773 main_capture_cb_capture_prepared(cap_session);
1775 case(capture_cb_capture_update_started):
1776 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1777 main_capture_cb_capture_update_started(cap_session);
1778 #ifdef HAVE_GTKOSXAPPLICATION
1779 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1780 #ifdef HAVE_GDK_GRESOURCE
1781 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon48.png"));
1783 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_48_pb_data, FALSE, NULL));
1787 case(capture_cb_capture_update_continue):
1788 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1790 case(capture_cb_capture_update_finished):
1791 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1792 main_capture_cb_capture_update_finished(cap_session);
1794 case(capture_cb_capture_fixed_started):
1795 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1796 main_capture_cb_capture_fixed_started(cap_session);
1798 case(capture_cb_capture_fixed_continue):
1799 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1801 case(capture_cb_capture_fixed_finished):
1802 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1803 main_capture_cb_capture_fixed_finished(cap_session);
1805 case(capture_cb_capture_stopping):
1806 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1807 /* Beware: this state won't be called, if the capture child
1808 * closes the capturing on its own! */
1809 #ifdef HAVE_GTKOSXAPPLICATION
1810 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1811 #ifdef HAVE_GDK_GRESOURCE
1812 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
1814 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1817 main_capture_cb_capture_stopping(cap_session);
1819 case(capture_cb_capture_failed):
1820 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1821 main_capture_cb_capture_failed(cap_session);
1824 g_warning("main_capture_callback: event %u unknown", event);
1825 g_assert_not_reached();
1831 get_wireshark_gtk_compiled_info(GString *str)
1833 g_string_append(str, "with ");
1834 g_string_append_printf(str,
1835 #ifdef GTK_MAJOR_VERSION
1836 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1839 "GTK+ (version unknown)");
1843 g_string_append(str, ", with Cairo ");
1844 g_string_append(str, CAIRO_VERSION_STRING);
1847 g_string_append(str, ", with Pango ");
1848 g_string_append(str, PANGO_VERSION_STRING);
1850 /* Capture libraries */
1851 g_string_append(str, ", ");
1852 get_compiled_caplibs_version(str);
1856 get_gui_compiled_info(GString *str)
1858 epan_get_compiled_version_info(str);
1860 g_string_append(str, ", ");
1861 #ifdef HAVE_LIBPORTAUDIO
1862 #ifdef PORTAUDIO_API_1
1863 g_string_append(str, "with PortAudio <= V18");
1864 #else /* PORTAUDIO_API_1 */
1865 g_string_append(str, "with ");
1866 g_string_append(str, Pa_GetVersionText());
1867 #endif /* PORTAUDIO_API_1 */
1868 #else /* HAVE_LIBPORTAUDIO */
1869 g_string_append(str, "without PortAudio");
1870 #endif /* HAVE_LIBPORTAUDIO */
1872 g_string_append(str, ", ");
1874 get_compiled_airpcap_version(str);
1876 g_string_append(str, "without AirPcap");
1879 codec_get_compiled_version_info(str);
1883 get_wireshark_runtime_info(GString *str)
1886 /* Capture libraries */
1887 g_string_append(str, ", ");
1888 get_runtime_caplibs_version(str);
1891 /* stuff used by libwireshark */
1892 epan_get_runtime_version_info(str);
1895 g_string_append(str, ", ");
1896 get_runtime_airpcap_version(str);
1901 read_configuration_files(char **gdp_path, char **dp_path)
1903 int gpf_open_errno, gpf_read_errno;
1904 int cf_open_errno, df_open_errno;
1905 int gdp_open_errno, gdp_read_errno;
1906 int dp_open_errno, dp_read_errno;
1907 char *gpf_path, *pf_path;
1908 char *cf_path, *df_path;
1909 int pf_open_errno, pf_read_errno;
1912 /* load the decode as entries of this profile */
1913 load_decode_as_entries();
1915 /* Read the preference files. */
1916 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1917 &pf_open_errno, &pf_read_errno, &pf_path);
1919 if (gpf_path != NULL) {
1920 if (gpf_open_errno != 0) {
1921 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1922 "Could not open global preferences file\n\"%s\": %s.",
1923 gpf_path, g_strerror(gpf_open_errno));
1925 if (gpf_read_errno != 0) {
1926 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1927 "I/O error reading global preferences file\n\"%s\": %s.",
1928 gpf_path, g_strerror(gpf_read_errno));
1931 if (pf_path != NULL) {
1932 if (pf_open_errno != 0) {
1933 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1934 "Could not open your preferences file\n\"%s\": %s.",
1935 pf_path, g_strerror(pf_open_errno));
1937 if (pf_read_errno != 0) {
1938 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1939 "I/O error reading your preferences file\n\"%s\": %s.",
1940 pf_path, g_strerror(pf_read_errno));
1947 /* if the user wants a console to be always there, well, we should open one for him */
1948 if (prefs_p->gui_console_open == console_open_always) {
1953 /* Read the capture filter file. */
1954 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1955 if (cf_path != NULL) {
1956 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1957 "Could not open your capture filter file\n\"%s\": %s.",
1958 cf_path, g_strerror(cf_open_errno));
1962 /* Read the display filter file. */
1963 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1964 if (df_path != NULL) {
1965 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1966 "Could not open your display filter file\n\"%s\": %s.",
1967 df_path, g_strerror(df_open_errno));
1971 /* Read the disabled protocols file. */
1972 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1973 dp_path, &dp_open_errno, &dp_read_errno);
1974 read_enabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1975 dp_path, &dp_open_errno, &dp_read_errno);
1976 read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1977 dp_path, &dp_open_errno, &dp_read_errno);
1978 if (*gdp_path != NULL) {
1979 if (gdp_open_errno != 0) {
1980 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1981 "Could not open global disabled protocols file\n\"%s\": %s.",
1982 *gdp_path, g_strerror(gdp_open_errno));
1984 if (gdp_read_errno != 0) {
1985 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1986 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1987 *gdp_path, g_strerror(gdp_read_errno));
1992 if (*dp_path != NULL) {
1993 if (dp_open_errno != 0) {
1994 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1995 "Could not open your disabled protocols file\n\"%s\": %s.",
1996 *dp_path, g_strerror(dp_open_errno));
1998 if (dp_read_errno != 0) {
1999 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2000 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2001 *dp_path, g_strerror(dp_read_errno));
2010 /* Check if there's something important to tell the user during startup.
2011 * We want to do this *after* showing the main window so that any windows
2012 * we pop up will be above the main window.
2016 check_and_warn_user_startup(gchar *cf_name)
2018 check_and_warn_user_startup(gchar *cf_name _U_)
2021 gchar *cur_user, *cur_group;
2022 gpointer priv_warning_dialog;
2024 /* Tell the user not to run as root. */
2025 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2026 cur_user = get_cur_username();
2027 cur_group = get_cur_groupname();
2028 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2029 "Running as user \"%s\" and group \"%s\".\n"
2030 "This could be dangerous.\n\n"
2031 "If you're running Wireshark this way in order to perform live capture, "
2032 "you may want to be aware that there is a better way documented at\n"
2033 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2036 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2037 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2041 /* Warn the user if npf.sys isn't loaded. */
2042 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2043 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2044 "The NPF driver isn't running. You may have trouble\n"
2045 "capturing or listing interfaces.");
2046 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2047 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2053 /* And now our feature presentation... [ fade to music ] */
2055 main(int argc, char *argv[])
2057 char *init_progfile_dir_error;
2060 extern int info_update_freq; /* Found in about_dlg.c. */
2061 const gchar *filter;
2069 char *gdp_path, *dp_path;
2081 gint pl_size = 280, tv_size = 95, bv_size = 75;
2083 dfilter_t *rfcode = NULL;
2084 gchar *err_msg = NULL;
2085 gboolean rfilter_parse_failed = FALSE;
2086 GtkWidget *splash_win = NULL;
2087 dfilter_t *jump_to_filter = NULL;
2088 unsigned int in_file_type = WTAP_TYPE_AUTO;
2089 #ifdef HAVE_GTKOSXAPPLICATION
2090 GtkosxApplication *theApp;
2092 GString *comp_info_str = NULL;
2093 GString *runtime_info_str = NULL;
2095 #ifdef HAVE_GDK_GRESOURCE
2096 main_register_resource();
2099 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2101 /* Set the current locale according to the program environment.
2102 * We haven't localized anything, but some GTK widgets are localized
2103 * (the file selection dialogue, for example).
2104 * This also sets the C-language locale to the native environment. */
2105 setlocale(LC_ALL, "");
2107 arg_list_utf_16to8(argc, argv);
2108 create_app_running_mutex();
2112 * Get credential information for later use, and drop privileges
2113 * before doing anything else.
2114 * Let the user know if anything happened.
2116 init_process_policies();
2117 relinquish_special_privs_perm();
2120 * Attempt to get the pathname of the directory containing the
2123 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2125 /* initialize the funnel mini-api */
2126 initialize_funnel_ops();
2128 AirPDcapInitContext(&airpdcap_ctx);
2131 /* Load wpcap if possible. Do this before collecting the run-time version information */
2134 /* ... and also load the packet.dll from wpcap */
2135 wpcap_packet_load();
2138 /* Load the airpcap.dll. This must also be done before collecting
2139 * run-time version information. */
2140 airpcap_dll_ret_val = load_airpcap();
2142 switch (airpcap_dll_ret_val) {
2143 case AIRPCAP_DLL_OK:
2144 /* load the airpcap interfaces */
2145 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2147 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
2148 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2149 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2152 airpcap_if_active = NULL;
2156 /* select the first ad default (THIS SHOULD BE CHANGED) */
2157 airpcap_if_active = airpcap_get_default_if(g_airpcap_if_list);
2162 * XXX - Maybe we need to warn the user if one of the following happens???
2164 case AIRPCAP_DLL_OLD:
2165 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2168 case AIRPCAP_DLL_ERROR:
2169 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2172 case AIRPCAP_DLL_NOT_FOUND:
2173 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2177 #endif /* HAVE_AIRPCAP */
2180 /* Get the compile-time version information string */
2181 comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
2182 get_gui_compiled_info);
2184 /* Get the run-time version information string */
2185 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
2187 /* Add it to the information to be reported on a crash. */
2188 ws_add_crash_info("Wireshark %s\n"
2193 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2196 /* Start windows sockets */
2197 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2200 profile_store_persconffiles (TRUE);
2202 /* Read the profile independent recent file. We have to do this here so we can */
2203 /* set the profile before it can be set from the command line parameter */
2204 recent_read_static(&rf_path, &rf_open_errno);
2205 if (rf_path != NULL && rf_open_errno != 0) {
2206 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2207 "Could not open common recent file\n\"%s\": %s.",
2208 rf_path, g_strerror(rf_open_errno));
2211 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
2213 /* Init the "Open file" dialog directory */
2214 /* (do this after the path settings are processed) */
2216 /* Read the profile dependent (static part) of the recent file. */
2217 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2218 /* recent lists which is done in the dynamic part. */
2219 /* We have to do this already here, so command line parameters can overwrite these values. */
2220 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
2221 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2222 "Could not open recent file\n\"%s\": %s.",
2223 rf_path, g_strerror(rf_open_errno));
2227 if (recent.gui_fileopen_remembered_dir &&
2228 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2229 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2231 set_last_open_dir(get_persdatafile_dir());
2234 #if !GLIB_CHECK_VERSION(2,31,0)
2235 g_thread_init(NULL);
2238 /* Disable liboverlay scrollbar which broke Wireshark on Ubuntu */
2239 #if !GTK_CHECK_VERSION(3,16,0)
2240 if (NULL == g_getenv("LIBOVERLAY_SCROLLBAR")) {
2241 g_setenv("LIBOVERLAY_SCROLLBAR", "0", FALSE);
2245 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2246 gtk_init (&argc, &argv);
2248 cf_callback_add(main_cf_callback, NULL);
2250 capture_callback_add(main_capture_callback, NULL);
2253 cf_callback_add(statusbar_cf_callback, NULL);
2255 capture_callback_add(statusbar_capture_callback, NULL);
2258 cf_callback_add(welcome_cf_callback, NULL);
2260 capture_callback_add(welcome_capture_callback, NULL);
2263 set_console_log_handler();
2266 /* Set the initial values in the capture options. This might be overwritten
2267 by preference settings and then again by the command line parameters. */
2268 capture_opts_init(&global_capture_opts);
2270 capture_session_init(&global_capture_session, &cfile);
2273 init_report_err(vfailure_alert_box, open_failure_alert_box,
2274 read_failure_alert_box, write_failure_alert_box);
2276 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2277 filter = get_conn_cfilter();
2278 if ( *filter != '\0' ) {
2279 info_update_freq = 1000; /* Milliseconds */
2282 /* We won't come till here, if we had a "console only" command line parameter. */
2283 splash_win = splash_new("Loading Wireshark ...");
2284 if (init_progfile_dir_error != NULL) {
2285 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2286 "Can't get pathname of directory containing Wireshark: %s.\n"
2287 "It won't be possible to capture traffic.\n"
2288 "Report this to the Wireshark developers.",
2289 init_progfile_dir_error);
2290 g_free(init_progfile_dir_error);
2296 /* Register all the plugin types we have. */
2297 epan_register_plugin_types(); /* Types known to libwireshark */
2298 codec_register_plugin_types(); /* Types known to libwscodecs */
2300 /* Scan for plugins. This does *not* call their registration routines;
2301 that's done later. */
2302 scan_plugins(REPORT_LOAD_FAILURE);
2304 /* Register all libwiretap plugin modules. */
2305 register_all_wiretap_modules();
2308 /* Register all audio codec plugins. */
2309 register_all_codecs();
2311 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2313 /* Register all dissectors; we must do this before checking for the
2314 "-G" flag, as the "-G" flag dumps information registered by the
2315 dissectors, and we must do it before we read the preferences, in
2316 case any dissectors register preferences. */
2317 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
2318 splash_update, (gpointer) splash_win))
2321 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2323 /* Register all tap listeners; we do this before we parse the arguments,
2324 as the "-z" argument can specify a registered tap. */
2326 /* we register the plugin taps before the other taps because
2327 stats_tree taps plugins will be registered as tap listeners
2328 by stats_tree_stat.c and need to registered before that */
2331 register_all_plugin_tap_listeners();
2334 register_all_tap_listeners();
2335 conversation_table_set_gui_info(init_conversation_table);
2336 hostlist_table_set_gui_info(init_hostlist_table);
2337 srt_table_iterate_tables(register_service_response_tables, NULL);
2338 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2339 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2342 splash_update(RA_EXTCAP, NULL, (gpointer)splash_win);
2343 extcap_register_preferences();
2346 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2348 global_commandline_info.prefs_p = read_configuration_files (&gdp_path, &dp_path);
2349 /* Removed thread code:
2350 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2353 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2354 cap_file_init(&cfile);
2356 /* Fill in capture options with values from the preferences */
2357 prefs_to_capture_opts();
2359 /*#ifdef HAVE_LIBPCAP
2360 fill_in_local_interfaces();
2363 /* Now get our args */
2364 commandline_other_options(argc, argv, TRUE);
2367 splash_update(RA_INTERFACES, NULL, (gpointer)splash_win);
2369 fill_in_local_interfaces(main_window_update);
2371 if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) {
2372 /* We're supposed to do a live capture or get a list of link-layer
2373 types for a live capture device; if the user didn't specify an
2374 interface to use, pick a default. */
2375 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2376 ((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);
2382 if (global_commandline_info.list_link_layer_types) {
2383 /* Get the list of link-layer types for the capture devices. */
2384 if_capabilities_t *caps;
2387 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2389 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2390 if (device.selected) {
2391 gchar* auth_str = NULL;
2392 #ifdef HAVE_PCAP_REMOTE
2393 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
2394 auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
2395 device.remote_opts.remote_host_opts.auth_password);
2398 #if defined(HAVE_PCAP_CREATE)
2399 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
2401 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
2405 cmdarg_err("%s", err_str);
2409 if (caps->data_link_types == NULL) {
2410 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2416 #if defined(HAVE_PCAP_CREATE)
2417 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2419 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2424 free_if_capabilities(caps);
2429 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2430 capture_opts_trim_ring_num_files(&global_capture_opts);
2431 #endif /* HAVE_LIBPCAP */
2433 /* Notify all registered modules that have had any of their preferences
2434 changed either from one of the preferences file or from the command
2435 line that their preferences have changed. */
2439 if ((global_capture_opts.num_selected == 0) &&
2440 ((prefs.capture_device != NULL) &&
2441 (global_commandline_info.prefs_p != NULL) &&
2442 (*global_commandline_info.prefs_p->capture_device != '\0'))) {
2445 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2446 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2447 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2448 device.selected = TRUE;
2449 global_capture_opts.num_selected++;
2450 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2451 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2456 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2457 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2458 device.selected = TRUE;
2459 global_capture_opts.num_selected++;
2460 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2461 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2465 /* disabled protocols as per configuration file */
2466 if (gdp_path == NULL && dp_path == NULL) {
2467 set_disabled_protos_list();
2468 set_enabled_protos_list();
2469 set_disabled_heur_dissector_list();
2472 if(global_dissect_options.disable_protocol_slist) {
2473 GSList *proto_disable;
2474 for (proto_disable = global_dissect_options.disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
2476 proto_disable_proto_by_name((char*)proto_disable->data);
2480 if(global_dissect_options.enable_protocol_slist) {
2481 GSList *proto_enable;
2482 for (proto_enable = global_dissect_options.enable_protocol_slist; proto_enable != NULL; proto_enable = g_slist_next(proto_enable))
2484 proto_enable_proto_by_name((char*)proto_enable->data);
2488 if(global_dissect_options.disable_heur_slist) {
2489 GSList *heur_enable;
2490 for (heur_enable = global_dissect_options.disable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
2492 proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
2496 if(global_dissect_options.disable_heur_slist) {
2497 GSList *heur_disable;
2498 for (heur_disable = global_dissect_options.disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
2500 proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
2504 build_column_format_array(&cfile.cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
2506 /* read in rc file from global and personal configuration paths. */
2507 rc_file = get_datafile_path(RC_FILE);
2508 #if GTK_CHECK_VERSION(3,0,0)
2509 /* XXX resolve later */
2511 gtk_rc_parse(rc_file);
2513 rc_file = get_persconffile_path(RC_FILE, FALSE);
2514 gtk_rc_parse(rc_file);
2524 /* close the splash screen, as we are going to open the main window now */
2525 splash_destroy(splash_win);
2527 /************************************************************************/
2528 /* Everything is prepared now, preferences and command line was read in */
2530 /* Pop up the main window. */
2531 create_main_window(pl_size, tv_size, bv_size, global_commandline_info.prefs_p);
2533 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2534 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
2535 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2536 "Could not open recent file\n\"%s\": %s.",
2537 rf_path, g_strerror(rf_open_errno));
2541 packet_list_enable_color(recent.packet_list_colorize);
2543 /* rearrange all the widgets as we now have all recent settings ready for this */
2544 main_widgets_rearrange();
2546 /* Fill in column titles. This must be done after the top level window
2549 XXX - is that still true, with fixed-width columns? */
2551 menu_recent_read_finished();
2553 main_auto_scroll_live_changed(auto_scroll_live);
2556 switch (user_font_apply()) {
2559 case FA_ZOOMED_TOO_FAR:
2560 /* The zoom level is too big for this font; turn off zooming. */
2561 recent.gui_zoom_level = 0;
2563 case FA_FONT_NOT_AVAILABLE:
2564 /* XXX - did we successfully load the un-zoomed version earlier?
2565 If so, this *probably* means the font is available, but not at
2566 this particular zoom level, but perhaps some other failure
2567 occurred; I'm not sure you can determine which is the case,
2569 /* turn off zooming - zoom level is unavailable */
2571 /* in any other case than FA_SUCCESS, turn off zooming */
2572 recent.gui_zoom_level = 0;
2573 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2577 dnd_init(top_level);
2579 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
2580 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
2584 capture_filter_init();
2587 /* the window can be sized only, if it's not already shown, so do it now! */
2588 main_load_window_geometry(top_level);
2590 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2592 /* this is to keep tap extensions updating once every 3 seconds */
2593 tap_update_timer_id = g_timeout_add(global_commandline_info.prefs_p->tap_update_interval, tap_update_cb, NULL);
2595 /* If we were given the name of a capture file, read it in now;
2596 we defer it until now, so that, if we can't open it, and pop
2597 up an alert box, the alert box is more likely to come up on
2598 top of the main window - but before the preference-file-error
2599 alert box, so, if we get one of those, it's more likely to come
2601 if (global_commandline_info.cf_name) {
2602 show_main_window(TRUE);
2603 check_and_warn_user_startup(global_commandline_info.cf_name);
2604 if (global_commandline_info.rfilter != NULL) {
2605 if (!dfilter_compile(global_commandline_info.rfilter, &rfcode, &err_msg)) {
2606 bad_dfilter_alert_box(top_level, global_commandline_info.rfilter, err_msg);
2608 rfilter_parse_failed = TRUE;
2611 if (ex_opt_count("read_format") > 0) {
2612 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
2614 if (!rfilter_parse_failed) {
2615 if (cf_open(&cfile, global_commandline_info.cf_name, in_file_type, FALSE, &err) == CF_OK) {
2616 /* "cf_open()" succeeded, so it closed the previous
2617 capture file, and thus destroyed any previous read filter
2618 attached to "cf". */
2620 cfile.rfcode = rfcode;
2621 /* Open stat windows; we do so after creating the main window,
2622 to avoid GTK warnings, and after successfully opening the
2623 capture file, so we know we have something to compute stats
2624 on, and after registering all dissectors, so that MATE will
2625 have registered its field array and we can have a tap filter
2626 with one of MATE's late-registered fields as part of the
2628 start_requested_stats();
2630 /* Read the capture file. */
2631 switch (cf_read(&cfile, FALSE)) {
2635 /* Just because we got an error, that doesn't mean we were unable
2636 to read any of the file; we handle what we could get from the
2638 /* if the user told us to jump to a specific packet, do it now */
2639 if(global_commandline_info.go_to_packet != 0) {
2640 /* Jump to the specified frame number, kept for backward
2642 cf_goto_frame(&cfile, global_commandline_info.go_to_packet);
2643 } else if (global_commandline_info.jfilter != NULL) {
2644 /* try to compile given filter */
2645 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
2646 bad_dfilter_alert_box(top_level, global_commandline_info.jfilter, err_msg);
2649 /* Filter ok, jump to the first packet matching the filter
2650 conditions. Default search direction is forward, but if
2651 option d was given, search backwards */
2652 cf_find_packet_dfilter(&cfile, jump_to_filter, global_commandline_info.jump_backwards);
2657 case CF_READ_ABORTED:
2663 /* If the filename is not the absolute path, prepend the current dir. This happens
2664 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
2665 if (!g_path_is_absolute(global_commandline_info.cf_name)) {
2666 char *old_cf_name = global_commandline_info.cf_name;
2667 char *pwd = g_get_current_dir();
2668 global_commandline_info.cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, global_commandline_info.cf_name);
2669 g_free(old_cf_name);
2673 /* Save the name of the containing directory specified in the
2674 path name, if any; we can write over cf_name, which is a
2675 good thing, given that "get_dirname()" does write over its
2677 s = get_dirname(global_commandline_info.cf_name);
2678 set_last_open_dir(s);
2679 g_free(global_commandline_info.cf_name);
2680 global_commandline_info.cf_name = NULL;
2683 dfilter_free(rfcode);
2684 cfile.rfcode = NULL;
2685 show_main_window(FALSE);
2686 /* Don't call check_and_warn_user_startup(): we did it above */
2687 main_set_for_capture_in_progress(FALSE);
2688 set_capture_if_dialog_for_capture_in_progress(FALSE);
2693 if (global_commandline_info.start_capture) {
2694 if (global_capture_opts.save_file != NULL) {
2695 /* Save the directory name for future file dialogs. */
2696 /* (get_dirname overwrites filename) */
2697 s = g_strdup(global_capture_opts.save_file);
2698 set_last_open_dir(get_dirname(s));
2701 /* "-k" was specified; start a capture. */
2702 show_main_window(FALSE);
2703 check_and_warn_user_startup(global_commandline_info.cf_name);
2705 /* If no user interfaces were specified on the command line,
2706 copy the list of selected interfaces to the set of interfaces
2707 to use for this capture. */
2708 if (global_capture_opts.ifaces->len == 0)
2709 collect_ifaces(&global_capture_opts);
2710 if (capture_start(&global_capture_opts, &global_capture_session, &global_info_data,main_window_update)) {
2711 /* The capture started. Open stat windows; we do so after creating
2712 the main window, to avoid GTK warnings, and after successfully
2713 opening the capture file, so we know we have something to compute
2714 stats on, and after registering all dissectors, so that MATE will
2715 have registered its field array and we can have a tap filter with
2716 one of MATE's late-registered fields as part of the filter. */
2717 start_requested_stats();
2720 show_main_window(FALSE);
2721 check_and_warn_user_startup(global_commandline_info.cf_name);
2722 main_set_for_capture_in_progress(FALSE);
2723 set_capture_if_dialog_for_capture_in_progress(FALSE);
2725 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
2726 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
2727 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
2729 #else /* HAVE_LIBPCAP */
2730 show_main_window(FALSE);
2731 check_and_warn_user_startup(global_commandline_info.cf_name);
2732 main_set_for_capture_in_progress(FALSE);
2733 set_capture_if_dialog_for_capture_in_progress(FALSE);
2734 #endif /* HAVE_LIBPCAP */
2737 if (global_commandline_info.dfilter) {
2738 GtkWidget *filter_te;
2739 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
2740 gtk_entry_set_text(GTK_ENTRY(filter_te), global_commandline_info.dfilter);
2742 /* Run the display filter so it goes in effect. */
2743 main_filter_packets(&cfile, global_commandline_info.dfilter, FALSE);
2746 profile_store_persconffiles (FALSE);
2748 #ifdef HAVE_GTKOSXAPPLICATION
2749 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
2750 #ifdef HAVE_GDK_GRESOURCE
2751 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
2753 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
2755 gtkosx_application_ready(theApp);
2758 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
2761 gtk_iface_mon_start();
2764 software_update_init();
2766 /* we'll enter the GTK loop now and hand the control over to GTK ... */
2768 /* ... back from GTK, we're going down now! */
2771 gtk_iface_mon_stop();
2780 AirPDcapDestroyContext(&airpdcap_ctx);
2782 #ifdef HAVE_GTKOSXAPPLICATION
2783 g_object_unref(theApp);
2787 /* hide the (unresponsive) main window, while asking the user to close the console window */
2788 if (G_IS_OBJECT(top_level))
2789 gtk_widget_hide(top_level);
2791 software_update_cleanup();
2793 /* Shutdown windows sockets */
2796 /* For some unknown reason, the "atexit()" call in "create_console()"
2797 doesn't arrange that "destroy_console()" be called when we exit,
2798 so we call it here if a console was created. */
2802 #ifdef HAVE_GDK_GRESOURCE
2803 main_unregister_resource();
2811 /* We build this as a GUI subsystem application on Win32, so
2812 "WinMain()", not "main()", gets called.
2814 Hack shamelessly stolen from the Win32 port of the GIMP. */
2816 #define _stdcall __attribute__((stdcall))
2820 WinMain (struct HINSTANCE__ *hInstance,
2821 struct HINSTANCE__ *hPrevInstance,
2825 INITCOMMONCONTROLSEX comm_ctrl;
2828 * Initialize our DLL search path. MUST be called before LoadLibrary
2831 ws_init_dll_search_path();
2833 /* Initialize our controls. Required for native Windows file dialogs. */
2834 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
2835 comm_ctrl.dwSize = sizeof(comm_ctrl);
2836 /* Includes the animate, header, hot key, list view, progress bar,
2837 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
2840 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
2841 InitCommonControlsEx(&comm_ctrl);
2843 /* RichEd20.DLL is needed for native file dialog filter entries. */
2844 ws_load_library("riched20.dll");
2846 set_has_console(FALSE);
2847 set_console_wait(FALSE);
2848 return main (__argc, __argv);
2857 * Helper for main_widgets_rearrange()
2859 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
2860 gtk_container_remove(GTK_CONTAINER(data), widget);
2863 static GtkWidget *main_widget_layout(gint layout_content)
2865 switch(layout_content) {
2866 case(layout_pane_content_none):
2868 case(layout_pane_content_plist):
2870 case(layout_pane_content_pdetails):
2872 case(layout_pane_content_pbytes):
2873 return byte_nb_ptr_gbl;
2875 g_assert_not_reached();
2881 * Rearrange the main window widgets
2883 void main_widgets_rearrange(void) {
2884 GtkWidget *first_pane_widget1, *first_pane_widget2;
2885 GtkWidget *second_pane_widget1, *second_pane_widget2;
2886 gboolean split_top_left = FALSE;
2888 /* be a bit faster */
2889 gtk_widget_hide(main_vbox);
2891 /* be sure we don't lose a widget while rearranging */
2892 g_object_ref(G_OBJECT(menubar));
2893 g_object_ref(G_OBJECT(main_tb));
2894 g_object_ref(G_OBJECT(filter_tb));
2895 g_object_ref(G_OBJECT(wireless_tb));
2896 g_object_ref(G_OBJECT(pkt_scrollw));
2897 g_object_ref(G_OBJECT(tv_scrollw));
2898 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
2899 g_object_ref(G_OBJECT(statusbar));
2900 g_object_ref(G_OBJECT(main_pane_v1));
2901 g_object_ref(G_OBJECT(main_pane_v2));
2902 g_object_ref(G_OBJECT(main_pane_h1));
2903 g_object_ref(G_OBJECT(main_pane_h2));
2904 g_object_ref(G_OBJECT(welcome_pane));
2906 /* empty all containers participating */
2907 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
2908 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
2909 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
2910 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
2911 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
2913 statusbar_widgets_emptying(statusbar);
2915 /* add the menubar always at the top */
2916 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2919 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
2921 /* filter toolbar in toolbar area */
2922 if (!prefs.filter_toolbar_show_in_statusbar) {
2923 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
2926 /* airpcap toolbar */
2927 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
2929 /* fill the main layout panes */
2930 switch(prefs.gui_layout_type) {
2931 case(layout_type_5):
2932 main_first_pane = main_pane_v1;
2933 main_second_pane = main_pane_v2;
2934 split_top_left = FALSE;
2936 case(layout_type_2):
2937 main_first_pane = main_pane_v1;
2938 main_second_pane = main_pane_h1;
2939 split_top_left = FALSE;
2941 case(layout_type_1):
2942 main_first_pane = main_pane_v1;
2943 main_second_pane = main_pane_h1;
2944 split_top_left = TRUE;
2946 case(layout_type_4):
2947 main_first_pane = main_pane_h1;
2948 main_second_pane = main_pane_v1;
2949 split_top_left = FALSE;
2951 case(layout_type_3):
2952 main_first_pane = main_pane_h1;
2953 main_second_pane = main_pane_v1;
2954 split_top_left = TRUE;
2956 case(layout_type_6):
2957 main_first_pane = main_pane_h1;
2958 main_second_pane = main_pane_h2;
2959 split_top_left = FALSE;
2962 main_first_pane = NULL;
2963 main_second_pane = NULL;
2964 g_assert_not_reached();
2966 if (split_top_left) {
2967 first_pane_widget1 = main_second_pane;
2968 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2969 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
2970 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2972 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2973 first_pane_widget2 = main_second_pane;
2974 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
2975 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2977 if (first_pane_widget1 != NULL)
2978 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
2979 if (first_pane_widget2 != NULL)
2980 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
2981 if (second_pane_widget1 != NULL)
2982 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
2983 if (second_pane_widget2 != NULL)
2984 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
2986 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
2989 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
2992 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
2994 /* filter toolbar in statusbar hbox */
2995 if (prefs.filter_toolbar_show_in_statusbar) {
2996 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
2999 /* statusbar widgets */
3000 statusbar_widgets_pack(statusbar);
3002 /* hide widgets on users recent settings */
3003 main_widgets_show_or_hide();
3005 gtk_widget_show(main_vbox);
3009 is_widget_visible(GtkWidget *widget, gpointer data)
3011 gboolean *is_visible = ( gboolean *)data;
3014 if (gtk_widget_get_visible(widget))
3021 main_widgets_show_or_hide(void)
3023 gboolean main_second_pane_show;
3025 if (recent.main_toolbar_show) {
3026 gtk_widget_show(main_tb);
3028 gtk_widget_hide(main_tb);
3031 statusbar_widgets_show_or_hide(statusbar);
3033 if (recent.filter_toolbar_show) {
3034 gtk_widget_show(filter_tb);
3036 gtk_widget_hide(filter_tb);
3039 if (recent.wireless_toolbar_show) {
3040 gtk_widget_show(wireless_tb);
3042 gtk_widget_hide(wireless_tb);
3045 if (recent.packet_list_show && have_capture_file) {
3046 gtk_widget_show(pkt_scrollw);
3048 gtk_widget_hide(pkt_scrollw);
3051 if (recent.tree_view_show && have_capture_file) {
3052 gtk_widget_show(tv_scrollw);
3054 gtk_widget_hide(tv_scrollw);
3057 if (recent.byte_view_show && have_capture_file) {
3058 gtk_widget_show(byte_nb_ptr_gbl);
3060 gtk_widget_hide(byte_nb_ptr_gbl);
3063 if (have_capture_file) {
3064 gtk_widget_show(main_first_pane);
3066 gtk_widget_hide(main_first_pane);
3070 * Is anything in "main_second_pane" visible?
3071 * If so, show it, otherwise hide it.
3073 main_second_pane_show = FALSE;
3074 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3075 &main_second_pane_show);
3076 if (main_second_pane_show) {
3077 gtk_widget_show(main_second_pane);
3079 gtk_widget_hide(main_second_pane);
3082 if (!have_capture_file) {
3084 gtk_widget_show(welcome_pane);
3087 gtk_widget_hide(welcome_pane);
3092 /* called, when the window state changes (minimized, maximized, ...) */
3094 window_state_event_cb (GtkWidget *widget _U_,
3098 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3100 if( (event->type) == (GDK_WINDOW_STATE)) {
3101 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3102 /* we might have dialogs popped up while we where iconified,
3104 display_queued_messages();
3112 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3114 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3116 if (event->keyval == GDK_F8) {
3119 } else if (event->keyval == GDK_F7) {
3122 } else if (event->state & NO_SHIFT_MOD_MASK) {
3123 return FALSE; /* Skip control, alt, and other modifiers */
3125 * A comment in gdkkeysyms.h says that it's autogenerated from
3126 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3127 * don't explicitly say so, g_ascii_isprint() should work as expected
3130 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3131 /* Forward the keypress on to the display filter entry */
3132 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3133 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3134 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3142 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3143 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3148 GtkAccelGroup *accel;
3151 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3152 set_titlebar_for_capture_file(NULL);
3154 gtk_widget_set_name(top_level, "main window");
3155 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3157 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3158 G_CALLBACK(window_state_event_cb), NULL);
3159 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3160 G_CALLBACK(top_level_key_pressed_cb), NULL );
3162 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3163 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3165 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3166 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3167 gtk_widget_show(main_vbox);
3170 menubar = main_menu_new(&accel);
3172 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3173 /* Mac OS X native menus are created and displayed by main_menu_new() */
3174 if(!prefs_p->gui_macosx_style) {
3176 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3177 gtk_widget_show(menubar);
3178 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3180 gtk_widget_hide(menubar);
3185 main_tb = toolbar_new();
3186 gtk_widget_show (main_tb);
3188 /* Filter toolbar */
3189 filter_tb = filter_toolbar_new();
3192 pkt_scrollw = packet_list_create();
3193 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3194 gtk_widget_show_all(pkt_scrollw);
3197 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3198 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3199 gtk_widget_show(tv_scrollw);
3201 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3202 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3203 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3204 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3205 gtk_widget_show(tree_view_gbl);
3208 byte_nb_ptr_gbl = byte_view_new();
3209 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3210 gtk_widget_show(byte_nb_ptr_gbl);
3212 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3213 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3215 /* Panes for the packet list, tree, and byte view */
3216 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3217 gtk_widget_show(main_pane_v1);
3218 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3219 gtk_widget_show(main_pane_v2);
3220 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3221 gtk_widget_show(main_pane_h1);
3222 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3223 gtk_widget_show(main_pane_h2);
3225 wireless_tb = airpcap_toolbar_new();
3227 wireless_tb = ws80211_toolbar_new();
3229 gtk_widget_show(wireless_tb);
3232 statusbar = statusbar_new();
3233 gtk_widget_show(statusbar);
3235 /* Pane for the welcome screen */
3236 welcome_pane = welcome_new();
3237 gtk_widget_show(welcome_pane);
3241 show_main_window(gboolean doing_work)
3243 main_set_for_capture_file(doing_work);
3245 /*** we have finished all init things, show the main window ***/
3246 gtk_widget_show(top_level);
3248 /* the window can be maximized only, if it's visible, so do it after show! */
3249 main_load_window_geometry(top_level);
3251 /* process all pending GUI events before continue */
3252 while (gtk_events_pending()) gtk_main_iteration();
3254 /* Pop up any queued-up alert boxes. */
3255 display_queued_messages();
3257 /* Move the main window to the front, in case it isn't already there */
3258 gdk_window_raise(gtk_widget_get_window(top_level));
3261 airpcap_toolbar_show(wireless_tb);
3262 #endif /* HAVE_AIRPCAP */
3265 static void copy_global_profile (const gchar *profile_name)
3267 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3269 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3270 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3271 "Can't create directory\n\"%s\":\n%s.",
3272 pf_dir_path, g_strerror(errno));
3274 g_free(pf_dir_path);
3277 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3278 &pf_dir_path, &pf_dir_path2) == -1) {
3279 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3280 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3281 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3283 g_free(pf_filename);
3284 g_free(pf_dir_path);
3285 g_free(pf_dir_path2);
3289 /* Change configuration profile */
3290 void change_configuration_profile (const gchar *profile_name)
3292 char *gdp_path, *dp_path;
3295 gchar* err_msg = NULL;
3297 /* First check if profile exists */
3298 if (!profile_exists(profile_name, FALSE)) {
3299 if (profile_exists(profile_name, TRUE)) {
3300 /* Copy from global profile */
3301 copy_global_profile (profile_name);
3303 /* No personal and no global profile exists */
3308 /* Then check if changing to another profile */
3309 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3313 /* Get the current geometry, before writing it to disk */
3314 main_save_window_geometry(top_level);
3316 if (profile_exists(get_profile_name(), FALSE)) {
3317 /* Write recent file for profile we are leaving, if it still exists */
3318 write_profile_recent();
3321 /* Set profile name and update the status bar */
3322 set_profile_name (profile_name);
3323 profile_bar_update ();
3325 /* Reset current preferences and apply the new */
3329 (void) read_configuration_files (&gdp_path, &dp_path);
3331 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
3332 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3333 "Could not open common recent file\n\"%s\": %s.",
3334 rf_path, g_strerror(rf_open_errno));
3337 if (recent.gui_fileopen_remembered_dir &&
3338 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3339 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3341 timestamp_set_type (recent.gui_time_format);
3342 timestamp_set_seconds_type (recent.gui_seconds_format);
3343 packet_list_enable_color(recent.packet_list_colorize);
3345 prefs_to_capture_opts();
3348 update_local_interfaces();
3350 macros_post_update();
3352 /* Update window view and redraw the toolbar */
3353 main_titlebar_update();
3354 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3355 toolbar_redraw_all();
3357 /* Enable all protocols and disable from the disabled list */
3359 if (gdp_path == NULL && dp_path == NULL) {
3360 set_disabled_protos_list();
3361 set_enabled_protos_list();
3362 set_disabled_heur_dissector_list();
3365 /* Reload color filters */
3366 if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3367 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3371 /* Reload list of interfaces on welcome page */
3372 welcome_if_panel_reload();
3374 /* Recreate the packet list according to new preferences */
3375 packet_list_recreate ();
3376 cfile.columns_changed = FALSE; /* Reset value */
3379 /* Update menus with new recent values */
3380 menu_recent_read_finished();
3382 /* Reload pane geometry, must be done after recreating the list */
3383 main_pane_load_window_geometry();
3387 main_fields_changed (void)
3389 gchar* err_msg = NULL;
3391 /* Reload color filters */
3392 if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3393 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3397 /* Syntax check filter */
3398 filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3399 if (cfile.dfilter) {
3400 /* Check if filter is still valid */
3401 dfilter_t *dfp = NULL;
3402 if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
3403 /* Not valid. Enable 'Apply' button and remove dfilter. */
3404 g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3405 g_free(cfile.dfilter);
3406 cfile.dfilter = NULL;
3411 if (have_custom_cols(&cfile.cinfo)) {
3412 /* Recreate packet list according to new/changed/deleted fields */
3413 packet_list_recreate();
3414 } else if (cfile.state != FILE_CLOSED) {
3415 /* Redissect packets if we have any */
3416 redissect_packets();
3418 destroy_packet_wins(); /* TODO: close windows until we can recreate */
3420 proto_free_deregistered_fields();
3423 /** redissect packets and update UI */
3424 void redissect_packets(void)
3426 cf_redissect_packets(&cfile);
3427 status_expert_update();
3430 #ifdef HAVE_SOFTWARE_UPDATE
3431 /** Check to see if Wireshark can shut down safely (e.g. offer to save the
3435 int software_update_can_shutdown_callback(void) {
3439 /** Shut down Wireshark in preparation for an upgrade.
3442 void software_update_shutdown_request_callback(void) {
3452 * indent-tabs-mode: nil
3455 * ex: set shiftwidth=4 tabstop=8 expandtab:
3456 * :indentSize=4:tabSize=8:noTabs=true: