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>
211 #define INIT_FAILED 2
212 #define INVALID_CAPABILITY 2
213 #define INVALID_LINK_TYPE 2
216 * Files under personal and global preferences directories in which
217 * GTK settings for Wireshark are stored.
219 #define RC_FILE "gtkrc"
222 capture_session global_capture_session;
223 info_data_t global_info_data;
228 static gboolean capture_stopping;
230 /* "exported" main widgets */
231 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
233 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
234 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
235 static GtkWidget *main_first_pane, *main_second_pane;
237 /* internally used widgets */
238 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
240 GtkWidget *wireless_tb;
242 int airpcap_dll_ret_val = -1;
245 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
247 static guint tap_update_timer_id;
249 static void create_main_window(gint, gint, gint, e_prefs*);
250 static void show_main_window(gboolean);
251 static void main_save_window_geometry(GtkWidget *widget);
254 /* Match selected byte pattern */
256 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
258 char *cur_filter, *new_filter;
260 if ((!text) || (0 == strlen(text))) {
261 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter.\nTry expanding or choosing another item.");
267 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
269 switch (action&MATCH_SELECTED_MASK) {
271 case MATCH_SELECTED_REPLACE:
272 new_filter = g_strdup(text);
275 case MATCH_SELECTED_AND:
276 if ((!cur_filter) || (0 == strlen(cur_filter)))
277 new_filter = g_strdup(text);
279 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
282 case MATCH_SELECTED_OR:
283 if ((!cur_filter) || (0 == strlen(cur_filter)))
284 new_filter = g_strdup(text);
286 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
289 case MATCH_SELECTED_NOT:
290 new_filter = g_strconcat("!(", text, ")", NULL);
293 case MATCH_SELECTED_AND_NOT:
294 if ((!cur_filter) || (0 == strlen(cur_filter)))
295 new_filter = g_strconcat("!(", text, ")", NULL);
297 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
300 case MATCH_SELECTED_OR_NOT:
301 if ((!cur_filter) || (0 == strlen(cur_filter)))
302 new_filter = g_strconcat("!(", text, ")", NULL);
304 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
308 g_assert_not_reached();
313 /* Free up the copy we got of the old filter text. */
316 /* Don't change the current display filter if we only want to copy the filter */
317 if (action&MATCH_SELECTED_COPY_ONLY) {
318 GString *gtk_text_str = g_string_new("");
319 g_string_append(gtk_text_str, new_filter);
320 copy_to_clipboard(gtk_text_str);
321 g_string_free(gtk_text_str, TRUE);
323 /* create a new one and set the display filter entry accordingly */
324 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
326 /* Run the display filter so it goes in effect. */
327 if (action&MATCH_SELECTED_APPLY_NOW)
328 main_filter_packets(&cfile, new_filter, FALSE);
331 /* Free up the new filter text. */
336 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
340 if (cfile.finfo_selected) {
341 filter = proto_construct_match_selected_string(cfile.finfo_selected,
343 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
344 wmem_free(NULL, filter);
349 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
352 gchar *err_msg = NULL;
354 if (cfile.finfo_selected) {
355 filter = proto_construct_match_selected_string(cfile.finfo_selected,
357 if ((!filter) || (0 == strlen(filter))) {
358 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
359 "Could not acquire information to build a filter.\n"
360 "Try expanding or choosing another item.");
365 color_display_with_filter(filter);
368 if (!color_filters_reset_tmp(&err_msg)) {
369 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
373 if (!color_filters_set_tmp(filt_nr,filter, FALSE, &err_msg)) {
374 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
379 packet_list_colorize_packets();
381 wmem_free(NULL, filter);
386 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
388 gchar *selected_proto_url;
389 gchar *proto_abbrev = (gchar *)data;
394 if (cfile.finfo_selected) {
395 /* open wiki page using the protocol abbreviation */
396 selected_proto_url = g_strdup_printf("https://wiki.wireshark.org/Protocols/%s", proto_abbrev);
397 browser_open_url(selected_proto_url);
398 g_free(selected_proto_url);
401 case(ESD_BTN_CANCEL):
404 g_assert_not_reached();
410 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
413 const gchar *proto_abbrev;
417 if (cfile.finfo_selected) {
418 /* convert selected field to protocol abbreviation */
419 /* XXX - could this conversion be simplified? */
420 field_id = cfile.finfo_selected->hfinfo->id;
421 /* if the selected field isn't a protocol, get its parent */
422 if(!proto_registrar_is_protocol(field_id)) {
423 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
426 proto_abbrev = proto_registrar_get_abbrev(field_id);
428 /* ask the user if the wiki page really should be opened */
429 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
430 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
432 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
434 "The Wireshark Wiki is a collaborative approach to provide information "
435 "about Wireshark in several ways (not limited to protocol specifics).\n"
437 "This Wiki is new, so the page of the selected protocol "
438 "may not exist and/or may not contain valuable information.\n"
440 "As everyone can edit the Wiki and add new content (or extend existing), "
441 "you are encouraged to add information if you can.\n"
443 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first.\n"
445 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
446 "which will save you a lot of editing and will give a consistent look over the pages.",
447 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
448 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
452 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
454 gchar *selected_proto_url;
455 gchar *proto_abbrev = (gchar *)data;
459 if (cfile.finfo_selected) {
460 /* open reference page using the protocol abbreviation */
461 selected_proto_url = g_strdup_printf("https://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
462 browser_open_url(selected_proto_url);
463 g_free(selected_proto_url);
466 case(ESD_BTN_CANCEL):
469 g_assert_not_reached();
474 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
477 const gchar *proto_abbrev;
481 if (cfile.finfo_selected) {
482 /* convert selected field to protocol abbreviation */
483 /* XXX - could this conversion be simplified? */
484 field_id = cfile.finfo_selected->hfinfo->id;
485 /* if the selected field isn't a protocol, get its parent */
486 if(!proto_registrar_is_protocol(field_id)) {
487 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
490 proto_abbrev = proto_registrar_get_abbrev(field_id);
492 /* ask the user if the wiki page really should be opened */
493 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
494 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
496 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
498 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
499 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
504 is_address_column (gint column)
506 if (((cfile.cinfo.columns[column].col_fmt == COL_DEF_SRC) ||
507 (cfile.cinfo.columns[column].col_fmt == COL_RES_SRC) ||
508 (cfile.cinfo.columns[column].col_fmt == COL_DEF_DST) ||
509 (cfile.cinfo.columns[column].col_fmt == COL_RES_DST)) &&
510 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
519 get_ip_address_list_from_packet_list_row(gpointer data)
521 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
522 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
525 GList *addr_list = NULL;
527 fdata = (frame_data *) packet_list_get_row_data(row);
532 if (!cf_read_record(&cfile, fdata))
533 return NULL; /* error reading the frame */
535 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
536 col_custom_prime_edt(&edt, &cfile.cinfo);
538 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
539 frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
540 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
542 /* First check selected column */
543 if (is_address_column (column)) {
544 addr_list = g_list_append (addr_list, g_strdup(cfile.cinfo.col_expr.col_expr_val[column]));
547 for (col = 0; col < cfile.cinfo.num_cols; col++) {
548 /* Then check all columns except the selected */
549 if ((col != column) && (is_address_column (col))) {
550 addr_list = g_list_append (addr_list, g_strdup(cfile.cinfo.col_expr.col_expr_val[col]));
554 epan_dissect_cleanup(&edt);
561 get_filter_from_packet_list_row_and_column(gpointer data)
563 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
564 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
568 fdata = (frame_data *) packet_list_get_row_data(row);
573 if (!cf_read_record(&cfile, fdata))
574 return NULL; /* error reading the record */
575 /* proto tree, visible. We need a proto tree if there's custom columns */
576 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
577 col_custom_prime_edt(&edt, &cfile.cinfo);
579 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
580 frame_tvbuff_new_buffer(fdata, &cfile.buf),
581 fdata, &cfile.cinfo);
582 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
584 if ((cfile.cinfo.columns[column].col_custom_occurrence) ||
585 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
587 /* Only construct the filter when a single occurrence is displayed
588 * otherwise we might end up with a filter like "ip.proto==1,6".
590 * Or do we want to be able to filter on multiple occurrences so that
591 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
594 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
595 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
596 /* leak a little; is there a safe wmem_ scope here? */
597 if (cfile.cinfo.columns[column].col_fmt == COL_CUSTOM) {
598 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.columns[column].col_custom_fields);
599 if (hfi && hfi->parent == -1) {
601 buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
602 } else if (hfi && IS_FT_STRING(hfi->type)) {
603 /* Custom string, add quotes */
604 buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
605 cfile.cinfo.col_expr.col_expr_val[column]);
609 buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
610 cfile.cinfo.col_expr.col_expr_val[column]);
615 epan_dissect_cleanup(&edt);
622 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
626 filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
628 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
634 /* This function allows users to right click in the details window and copy the text
635 * information to the operating systems clipboard.
637 * We first check to see if a string representation is setup in the tree and then
638 * read the string. If not available then we try to grab the value. If all else
639 * fails we display a message to the user to indicate the copy could not be completed.
642 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
644 GString *gtk_text_str = g_string_new("");
645 char labelstring[ITEM_LABEL_LENGTH];
646 char *stringpointer = labelstring;
650 case COPY_SELECTED_DESCRIPTION:
651 if (cfile.finfo_selected->rep &&
652 strlen(cfile.finfo_selected->rep->representation) > 0) {
653 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
656 case COPY_SELECTED_FIELDNAME:
657 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
658 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
661 case COPY_SELECTED_VALUE:
662 if (cfile.edt !=0 ) {
663 gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
664 g_string_append(gtk_text_str, field_str);
672 if (gtk_text_str->len == 0) {
673 /* If no representation then... Try to read the value */
674 proto_item_fill_label(cfile.finfo_selected, stringpointer);
675 g_string_append(gtk_text_str, stringpointer);
678 if (gtk_text_str->len == 0) {
679 /* Could not get item so display error msg */
680 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
682 /* Copy string to clipboard */
683 copy_to_clipboard(gtk_text_str);
685 g_string_free(gtk_text_str, TRUE); /* Free the memory */
689 /* mark as reference time frame */
691 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
695 frame->flags.ref_time=1;
696 cfile.ref_time_count++;
698 frame->flags.ref_time=0;
699 cfile.ref_time_count--;
701 cf_reftime_packets(&cfile);
702 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
703 packet_list_freeze();
704 cfile.displayed_count--;
705 packet_list_recreate_visible_rows();
708 packet_list_queue_draw();
712 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
716 timestamp_set_type(TS_RELATIVE);
717 recent.gui_time_format = TS_RELATIVE;
718 cf_timestamp_auto_precision(&cfile);
719 packet_list_queue_draw();
724 g_assert_not_reached();
727 if (cfile.current_frame) {
728 set_frame_reftime(!cfile.current_frame->flags.ref_time,
729 cfile.current_frame, cfile.current_row);
735 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
737 static GtkWidget *reftime_dialog = NULL;
741 if (cfile.current_frame) {
742 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
743 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
744 "%sSwitch to the appropriate Time Display Format?%s\n\n"
745 "Time References don't work well with the currently selected Time Display Format.\n\n"
746 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
747 simple_dialog_primary_start(), simple_dialog_primary_end());
748 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
750 set_frame_reftime(!cfile.current_frame->flags.ref_time,
751 cfile.current_frame, cfile.current_row);
755 case REFTIME_FIND_NEXT:
756 cf_find_packet_time_reference(&cfile, SD_FORWARD);
758 case REFTIME_FIND_PREV:
759 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
765 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
767 cf_find_packet_marked(&cfile, SD_FORWARD);
771 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
773 cf_find_packet_marked(&cfile, SD_BACKWARD);
777 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
780 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
782 gboolean has_blurb = FALSE;
783 guint length = 0, byte_len;
784 GtkWidget *byte_view;
785 const guint8 *byte_data;
790 /* if nothing is selected */
791 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
794 * Which byte view is displaying the current protocol tree
797 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
798 if (byte_view == NULL)
801 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
802 if (byte_data == NULL)
805 cf_unselect_field(&cfile);
806 packet_hex_print(byte_view, byte_data,
807 cfile.current_frame, NULL, byte_len);
810 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
813 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
815 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
816 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
817 g_assert(byte_data != NULL);
819 cfile.finfo_selected = finfo;
820 set_menus_for_selected_tree_row(&cfile);
823 if (finfo->hfinfo->blurb != NULL &&
824 finfo->hfinfo->blurb[0] != '\0') {
826 length = (guint) strlen(finfo->hfinfo->blurb);
828 length = (guint) strlen(finfo->hfinfo->name);
830 finfo_length = finfo->length + finfo->appendix_length;
832 if (finfo_length == 0) {
834 } else if (finfo_length == 1) {
835 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
837 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
839 statusbar_pop_field_msg(); /* get rid of current help msg */
841 statusbar_push_field_msg(" %s (%s)%s",
842 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
843 finfo->hfinfo->abbrev, len_str);
846 * Don't show anything if the field name is zero-length;
847 * the pseudo-field for text-only items is such
848 * a field, and we don't want "Text (text)" showing up
849 * on the status line if you've selected such a field.
851 * XXX - there are zero-length fields for which we *do*
852 * want to show the field name.
854 * XXX - perhaps the name and abbrev field should be null
855 * pointers rather than null strings for that pseudo-field,
856 * but we'd have to add checks for null pointers in some
857 * places if we did that.
859 * Or perhaps text-only items should have -1 as the field
860 * index, with no pseudo-field being used, but that might
861 * also require special checks for -1 to be added.
863 statusbar_push_field_msg("%s", "");
866 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
870 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
873 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
876 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
879 expand_all_tree(cfile.edt->tree, tree_view_gbl);
882 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
884 if (cfile.finfo_selected) {
885 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
886 cfile.finfo_selected->hfinfo->abbrev,0);
887 /* Recreate the packet list according to new preferences */
888 packet_list_recreate ();
889 if (!prefs.gui_use_pref_save) {
892 cfile.columns_changed = FALSE; /* Reset value */
896 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
900 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
902 /* the mouse position is at an entry, expand that one */
903 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
904 gtk_tree_path_free(path);
908 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
912 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
914 /* the mouse position is at an entry, expand that one */
916 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
917 gtk_tree_path_free(path);
921 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
923 static const e_addr_resolve resolv_flags = {
925 TRUE, /* network_name */
926 TRUE, /* transport_name */
927 TRUE, /* dns_pkt_addr_resolution */
928 TRUE, /* use_external_net_name_resolver */
929 FALSE, /* load_hosts_file_from_profile_only */
930 FALSE, /* vlan_name */
931 FALSE, /* ss7pc_name */
934 if (cfile.edt->tree) {
935 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
939 /* Update main window items based on whether there's a capture in progress. */
941 main_set_for_capture_in_progress(gboolean capture_in_progress)
943 set_menus_for_capture_in_progress(capture_in_progress);
946 set_toolbar_for_capture_in_progress(capture_in_progress);
948 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
952 /* Update main window items based on whether we have a capture file. */
954 main_set_for_capture_file(gboolean have_capture_file_in)
956 have_capture_file = have_capture_file_in;
958 main_widgets_show_or_hide();
961 /* Update main window items based on whether we have captured packets. */
963 main_set_for_captured_packets(gboolean have_captured_packets)
965 set_menus_for_captured_packets(have_captured_packets);
966 set_toolbar_for_captured_packets(have_captured_packets);
969 /* Update main window items based on whether we have a packet history. */
971 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
973 set_menus_for_packet_history(back_history, forward_history);
974 set_toolbar_for_packet_history(back_history, forward_history);
980 /* get the current geometry, before writing it to disk */
981 main_save_window_geometry(top_level);
983 /* write user's recent file to disk
984 * It is no problem to write this file, even if we do not quit */
985 write_profile_recent();
988 /* XXX - should we check whether the capture file is an
989 unsaved temporary file for a live capture and, if so,
990 pop up a "do you want to exit without saving the capture
991 file?" dialog, and then just return, leaving said dialog
992 box to forcibly quit if the user clicks "OK"?
994 If so, note that this should be done in a subroutine that
995 returns TRUE if we do so, and FALSE otherwise, and if it
996 returns TRUE we should return TRUE without nuking anything.
998 Note that, if we do that, we might also want to check if
999 an "Update list of packets in real time" capture is in
1000 progress and, if so, ask whether they want to terminate
1001 the capture and discard it, and return TRUE, before nuking
1002 any child capture, if they say they don't want to do so. */
1005 /* Nuke any child capture in progress. */
1006 capture_kill_child(&global_capture_session);
1009 /* Are we in the middle of reading a capture? */
1010 if (cfile.state == FILE_READ_IN_PROGRESS) {
1011 /* Yes, so we can't just close the file and quit, as
1012 that may yank the rug out from under the read in
1013 progress; instead, just set the state to
1014 "FILE_READ_ABORTED" and return - the code doing the read
1015 will check for that and, if it sees that, will clean
1017 cfile.state = FILE_READ_ABORTED;
1019 /* Say that the window should *not* be deleted;
1020 that'll be done by the code that cleans up. */
1023 /* Close any capture file we have open; on some OSes, you
1024 can't unlink a temporary capture file if you have it
1026 "cf_close()" will unlink it after closing it if
1027 it's a temporary file.
1029 We do this here, rather than after the main loop returns,
1030 as, after the main loop returns, the main window may have
1031 been destroyed (if this is called due to a "destroy"
1032 even on the main window rather than due to the user
1033 selecting a menu item), and there may be a crash
1034 or other problem when "cf_close()" tries to
1035 clean up stuff in the main window.
1037 XXX - is there a better place to put this?
1038 Or should we have a routine that *just* closes the
1039 capture file, and doesn't do anything with the UI,
1040 which we'd call here, and another routine that
1041 calls that routine and also cleans up the UI, which
1042 we'd call elsewhere? */
1045 /* Exit by leaving the main loop, so that any quit functions
1046 we registered get called. */
1049 /* Say that the window should be deleted. */
1055 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1057 /* If we're in the middle of stopping a capture, don't do anything;
1058 the user can try deleting the window after the capture stops. */
1059 if (capture_stopping)
1062 /* If there's unsaved data, let the user save it first.
1063 If they cancel out of it, don't quit. */
1064 if (do_file_close(&cfile, TRUE, " before quitting"))
1065 return main_do_quit();
1067 return TRUE; /* will this keep the window from being deleted? */
1072 main_pane_load_window_geometry(void)
1074 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1075 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1076 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1077 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1083 main_load_window_geometry(GtkWidget *widget)
1085 window_geometry_t geom;
1087 geom.set_pos = prefs.gui_geometry_save_position;
1088 geom.x = recent.gui_gtk_geometry_main_x;
1089 geom.y = recent.gui_gtk_geometry_main_y;
1090 geom.set_size = prefs.gui_geometry_save_size;
1091 geom.set_maximized = FALSE;
1092 if (recent.gui_geometry_main_width > 0 &&
1093 recent.gui_geometry_main_height > 0) {
1094 geom.width = recent.gui_geometry_main_width;
1095 geom.height = recent.gui_geometry_main_height;
1096 geom.set_maximized = prefs.gui_geometry_save_maximized;
1098 /* We assume this means the width and height weren't set in
1099 the "recent" file (or that there is no "recent" file),
1100 and weren't set to a default value, so we don't set the
1101 size. (The "recent" file code rejects non-positive width
1102 and height values.) */
1103 geom.set_size = FALSE;
1105 geom.maximized = recent.gui_geometry_main_maximized;
1107 window_set_geometry(widget, &geom);
1109 main_pane_load_window_geometry();
1110 statusbar_load_window_geometry();
1115 main_save_window_geometry(GtkWidget *widget)
1117 window_geometry_t geom;
1119 window_get_geometry(widget, &geom);
1121 if (prefs.gui_geometry_save_position) {
1122 recent.gui_gtk_geometry_main_x = geom.x;
1123 recent.gui_gtk_geometry_main_y = geom.y;
1126 if (prefs.gui_geometry_save_size) {
1127 recent.gui_geometry_main_width = geom.width;
1128 recent.gui_geometry_main_height = geom.height;
1131 if(prefs.gui_geometry_save_maximized) {
1132 recent.gui_geometry_main_maximized = geom.maximized;
1135 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1136 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1137 statusbar_save_window_geometry();
1141 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1143 /* If there's unsaved data, let the user save it first. */
1144 if (do_file_close(&cfile, TRUE, " before quitting"))
1149 * Report an error in command-line arguments.
1150 * Creates a console on Windows.
1151 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1152 * terminal isn't the standard error?
1155 wireshark_cmdarg_err(const char *fmt, va_list ap)
1160 fprintf(stderr, "wireshark: ");
1161 vfprintf(stderr, fmt, ap);
1162 fprintf(stderr, "\n");
1166 * Report additional information for an error in command-line arguments.
1167 * Creates a console on Windows.
1168 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1169 * terminal isn't the standard error?
1172 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1177 vfprintf(stderr, fmt, ap);
1178 fprintf(stderr, "\n");
1182 Once every 3 seconds we get a callback here which we use to update
1186 tap_update_cb(gpointer data _U_)
1188 draw_tap_listeners(FALSE);
1193 * Periodically process outstanding hostname lookups. If we have new items,
1194 * redraw the packet list and tree view.
1198 resolv_update_cb(gpointer data _U_)
1200 /* Anything new show up? */
1201 if (host_name_lookup_process()) {
1202 if (gtk_widget_get_window(pkt_scrollw))
1203 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1204 if (gtk_widget_get_window(tv_scrollw))
1205 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1208 /* Always check. Even if we don't do async lookups we could still get
1209 passive updates, e.g. from DNS packets. */
1214 /* Update various parts of the main window for a capture file "unsaved
1215 changes" change - update the title to reflect whether there are
1216 unsaved changes or not, and update the menus and toolbar to
1217 enable or disable the "Save" operation. */
1219 main_update_for_unsaved_changes(capture_file *cf)
1221 set_titlebar_for_capture_file(cf);
1222 set_menus_for_capture_file(cf);
1223 set_toolbar_for_capture_file(cf);
1228 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1230 /* Update menubar and toolbar */
1231 menu_auto_scroll_live_changed(auto_scroll_live_in);
1232 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1234 /* change auto scroll state */
1235 auto_scroll_live = auto_scroll_live_in;
1240 main_colorize_changed(gboolean packet_list_colorize)
1242 /* Update menubar and toolbar */
1243 menu_colorize_changed(packet_list_colorize);
1244 toolbar_colorize_changed(packet_list_colorize);
1246 /* change colorization */
1247 if(packet_list_colorize != recent.packet_list_colorize) {
1248 recent.packet_list_colorize = packet_list_colorize;
1249 packet_list_enable_color(packet_list_colorize);
1250 packet_list_colorize_packets();
1254 static GtkWidget *close_dlg = NULL;
1257 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1259 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1264 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1266 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1271 main_cf_cb_file_closing(capture_file *cf)
1273 /* if we have more than 10000 packets, show a splash screen while closing */
1274 /* XXX - don't know a better way to decide whether to show or not,
1275 * as most of the time is spend in various calls that destroy various
1276 * data structures, so it wouldn't be easy to use a progress bar,
1277 * rather than, say, a progress spinner, here! */
1278 if(cf->count > 10000) {
1279 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1280 "%sClosing file.%s\n\nPlease wait ...",
1281 simple_dialog_primary_start(),
1282 simple_dialog_primary_end());
1283 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1285 /* Clear maunally resolved addresses */
1286 manually_resolve_cleanup();
1287 /* Destroy all windows that refer to the
1288 capture file we're closing. */
1289 destroy_packet_wins();
1291 /* Update the titlebar to reflect the lack of a capture file. */
1292 set_titlebar_for_capture_file(NULL);
1294 /* Disable all menu and toolbar items that make sense only if
1295 you have a capture. */
1296 set_menus_for_capture_file(NULL);
1297 set_toolbar_for_capture_file(NULL);
1298 main_set_for_captured_packets(FALSE);
1299 set_menus_for_selected_packet(cf);
1300 main_set_for_capture_in_progress(FALSE);
1301 set_capture_if_dialog_for_capture_in_progress(FALSE);
1302 set_menus_for_selected_tree_row(cf);
1304 /* Set up main window for no capture file. */
1305 main_set_for_capture_file(FALSE);
1307 main_window_update();
1312 main_cf_cb_file_closed(capture_file *cf _U_)
1314 if(close_dlg != NULL) {
1315 splash_destroy(close_dlg);
1322 main_cf_cb_file_read_started(capture_file *cf _U_)
1324 tap_param_dlg_update();
1326 /* Set up main window for a capture file. */
1327 main_set_for_capture_file(TRUE);
1331 main_cf_cb_file_read_finished(capture_file *cf)
1335 if (!cf->is_tempfile && cf->filename) {
1336 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1337 add_menu_recent_capture_file(cf->filename);
1339 /* Remember folder for next Open dialog and save it in recent */
1340 dir_path = g_strdup(cf->filename);
1341 set_last_open_dir(get_dirname(dir_path));
1345 /* Update the appropriate parts of the main window. */
1346 main_update_for_unsaved_changes(cf);
1348 /* Enable menu items that make sense if you have some captured packets. */
1349 main_set_for_captured_packets(TRUE);
1353 main_cf_cb_file_rescan_finished(capture_file *cf)
1357 if (!cf->is_tempfile && cf->filename) {
1358 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1359 add_menu_recent_capture_file(cf->filename);
1361 /* Remember folder for next Open dialog and save it in recent */
1362 dir_path = g_strdup(cf->filename);
1363 set_last_open_dir(get_dirname(dir_path));
1367 /* Update the appropriate parts of the main window. */
1368 main_update_for_unsaved_changes(cf);
1372 static GList *icon_list_create(
1373 #ifdef HAVE_GDK_GRESOURCE
1374 const gchar *icon16_path,
1375 const gchar *icon32_path,
1376 const gchar *icon48_path,
1377 const gchar *icon64_path)
1379 const guint8 *icon16_pb,
1380 const guint8 *icon32_pb,
1381 const guint8 *icon48_pb,
1382 const guint8 *icon64_pb)
1385 GList *icon_list = NULL;
1386 GdkPixbuf *pixbuf16 = NULL;
1387 GdkPixbuf *pixbuf32 = NULL;
1388 GdkPixbuf *pixbuf48 = NULL;
1389 GdkPixbuf *pixbuf64 = NULL;
1391 #ifdef HAVE_GDK_GRESOURCE
1392 if (icon16_path != NULL)
1393 pixbuf16 = ws_gdk_pixbuf_new_from_resource(icon16_path);
1394 if (icon32_path != NULL)
1395 pixbuf32 = ws_gdk_pixbuf_new_from_resource(icon32_path);
1396 if (icon48_path != NULL)
1397 pixbuf48 = ws_gdk_pixbuf_new_from_resource(icon48_path);
1398 if (icon64_path != NULL)
1399 pixbuf64 = ws_gdk_pixbuf_new_from_resource(icon64_path);
1401 if (icon16_pb != NULL)
1402 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1403 if (icon32_pb != NULL)
1404 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1405 if (icon48_pb != NULL)
1406 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1407 if (icon64_pb != NULL)
1408 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1411 if (pixbuf16 != NULL)
1412 icon_list = g_list_append(icon_list, pixbuf16);
1413 if (pixbuf32 != NULL)
1414 icon_list = g_list_append(icon_list, pixbuf32);
1415 if (pixbuf48 != NULL)
1416 icon_list = g_list_append(icon_list, pixbuf48);
1417 if (pixbuf64 != NULL)
1418 icon_list = g_list_append(icon_list, pixbuf64);
1424 main_capture_cb_capture_prepared(capture_session *cap_session)
1426 static GList *icon_list = NULL;
1428 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1430 if(icon_list == NULL) {
1431 #ifdef HAVE_GDK_GRESOURCE
1432 icon_list = icon_list_create("/org/wireshark/image/wsiconcap16.png",
1433 "/org/wireshark/image/wsiconcap32.png",
1434 "/org/wireshark/image/wsiconcap48.png",
1435 "/org/wireshark/image/wsiconcap64.png");
1437 icon_list = icon_list_create(wsiconcap_16_pb_data,
1438 wsiconcap_32_pb_data,
1439 wsiconcap_48_pb_data,
1440 wsiconcap_64_pb_data);
1443 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1445 /* Disable menu items that make no sense if you're currently running
1447 main_set_for_capture_in_progress(TRUE);
1448 set_capture_if_dialog_for_capture_in_progress(TRUE);
1450 /* Don't set up main window for a capture file. */
1451 main_set_for_capture_file(FALSE);
1455 main_capture_cb_capture_update_started(capture_session *cap_session)
1457 /* We've done this in "prepared" above, but it will be cleared while
1458 switching to the next multiple file. */
1459 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1461 main_set_for_capture_in_progress(TRUE);
1462 set_capture_if_dialog_for_capture_in_progress(TRUE);
1464 /* Enable menu items that make sense if you have some captured
1465 packets (yes, I know, we don't have any *yet*). */
1466 main_set_for_captured_packets(TRUE);
1468 /* Set up main window for a capture file. */
1469 main_set_for_capture_file(TRUE);
1473 main_capture_cb_capture_update_finished(capture_session *cap_session)
1475 capture_file *cf = (capture_file *)cap_session->cf;
1476 static GList *icon_list = NULL;
1478 /* The capture isn't stopping any more - it's stopped. */
1479 capture_stopping = FALSE;
1481 if (!cf->is_tempfile && cf->filename) {
1482 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1483 add_menu_recent_capture_file(cf->filename);
1486 /* Enable menu items that make sense if you're not currently running
1488 main_set_for_capture_in_progress(FALSE);
1489 set_capture_if_dialog_for_capture_in_progress(FALSE);
1491 /* Update the main window as appropriate. This has to occur AFTER
1492 * main_set_for_capture_in_progress() or else some of the menus are
1493 * incorrectly disabled (see bug
1494 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1495 main_update_for_unsaved_changes(cf);
1497 /* Set up main window for a capture file. */
1498 main_set_for_capture_file(TRUE);
1500 if(icon_list == NULL) {
1501 #ifdef HAVE_GDK_GRESOURCE
1502 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1503 "/org/wireshark/image/wsicon32.png",
1504 "/org/wireshark/image/wsicon48.png",
1505 "/org/wireshark/image/wsicon64.png");
1507 icon_list = icon_list_create(wsicon_16_pb_data,
1513 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1515 if(global_commandline_info.quit_after_cap) {
1516 /* command line asked us to quit after the capture */
1517 /* don't pop up a dialog to ask for unsaved files etc. */
1523 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1525 /* Don't set up main window for a capture file. */
1526 main_set_for_capture_file(FALSE);
1530 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1533 capture_file *cf = (capture_file *)cap_session->cf;
1535 static GList *icon_list = NULL;
1537 /* The capture isn't stopping any more - it's stopped. */
1538 capture_stopping = FALSE;
1540 /*set_titlebar_for_capture_file(cf);*/
1542 /* Enable menu items that make sense if you're not currently running
1544 main_set_for_capture_in_progress(FALSE);
1545 set_capture_if_dialog_for_capture_in_progress(FALSE);
1547 /* Restore the standard title bar message */
1548 /* (just in case we have trouble opening the capture file). */
1549 set_titlebar_for_capture_file(NULL);
1551 if(icon_list == NULL) {
1552 #ifdef HAVE_GDK_GRESOURCE
1553 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1554 "/org/wireshark/image/wsicon32.png",
1555 "/org/wireshark/image/wsicon48.png",
1556 "/org/wireshark/image/wsicon64.png");
1558 icon_list = icon_list_create(wsicon_16_pb_data,
1564 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1566 /* We don't have loaded the capture file, this will be done later.
1567 * For now we still have simply a blank screen. */
1569 if(global_commandline_info.quit_after_cap) {
1570 /* command line asked us to quit after the capture */
1571 /* don't pop up a dialog to ask for unsaved files etc. */
1577 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1579 capture_stopping = TRUE;
1580 set_menus_for_capture_stopping();
1582 set_toolbar_for_capture_stopping();
1584 set_capture_if_dialog_for_capture_stopping();
1589 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1591 static GList *icon_list = NULL;
1593 /* Capture isn't stopping any more. */
1594 capture_stopping = FALSE;
1596 /* the capture failed before the first packet was captured
1597 reset title, menus and icon */
1598 set_titlebar_for_capture_file(NULL);
1600 main_set_for_capture_in_progress(FALSE);
1601 set_capture_if_dialog_for_capture_in_progress(FALSE);
1603 main_set_for_capture_file(FALSE);
1605 if(icon_list == NULL) {
1606 #ifdef HAVE_GDK_GRESOURCE
1607 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1608 "/org/wireshark/image/wsicon32.png",
1609 "/org/wireshark/image/wsicon48.png",
1610 "/org/wireshark/image/wsicon64.png");
1612 icon_list = icon_list_create(wsicon_16_pb_data,
1618 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1621 if(global_commandline_info.quit_after_cap) {
1622 /* command line asked us to quit after the capture */
1623 /* don't pop up a dialog to ask for unsaved files etc. */
1627 #endif /* HAVE_LIBPCAP */
1630 main_cf_cb_packet_selected(gpointer data)
1632 capture_file *cf = (capture_file *)data;
1634 /* Display the GUI protocol tree and packet bytes.
1635 XXX - why do we dump core if we call "proto_tree_draw()"
1636 before calling "add_byte_views()"? */
1637 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1638 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1640 /* Note: Both string and hex value searches in the packet data produce a non-zero
1641 search_pos if successful */
1642 if(cf->search_in_progress &&
1643 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1644 highlight_field(cf->edt->tvb, cf->search_pos,
1645 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1648 /* A packet is selected. */
1649 set_menus_for_selected_packet(cf);
1653 main_cf_cb_packet_unselected(capture_file *cf)
1655 /* No packet is being displayed; clear the hex dump pane by getting
1656 rid of all the byte views. */
1657 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1658 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1660 /* Add a placeholder byte view so that there's at least something
1661 displayed in the byte view notebook. */
1662 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1664 /* And clear the protocol tree display as well. */
1665 proto_tree_draw(NULL, tree_view_gbl);
1667 /* No packet is selected. */
1668 set_menus_for_selected_packet(cf);
1672 main_cf_cb_field_unselected(capture_file *cf)
1674 set_menus_for_selected_tree_row(cf);
1678 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1680 capture_file *cf = (capture_file *)data;
1682 case(cf_cb_file_opened):
1683 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1684 fileset_file_opened(cf);
1686 case(cf_cb_file_closing):
1687 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1688 main_cf_cb_file_closing(cf);
1690 case(cf_cb_file_closed):
1691 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1692 main_cf_cb_file_closed(cf);
1693 fileset_file_closed();
1695 case(cf_cb_file_read_started):
1696 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1697 main_cf_cb_file_read_started(cf);
1699 case(cf_cb_file_read_finished):
1700 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1701 main_cf_cb_file_read_finished(cf);
1703 case(cf_cb_file_reload_started):
1704 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1705 main_cf_cb_file_read_started(cf);
1707 case(cf_cb_file_reload_finished):
1708 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1709 main_cf_cb_file_read_finished(cf);
1711 case(cf_cb_file_rescan_started):
1712 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1714 case(cf_cb_file_rescan_finished):
1715 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1716 main_cf_cb_file_rescan_finished(cf);
1718 case(cf_cb_file_retap_started):
1719 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap started");
1721 case(cf_cb_file_retap_finished):
1722 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap finished");
1724 case(cf_cb_file_fast_save_finished):
1725 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1726 main_cf_cb_file_rescan_finished(cf);
1728 case(cf_cb_packet_selected):
1729 main_cf_cb_packet_selected(cf);
1731 case(cf_cb_packet_unselected):
1732 main_cf_cb_packet_unselected(cf);
1734 case(cf_cb_field_unselected):
1735 main_cf_cb_field_unselected(cf);
1737 case(cf_cb_file_save_started):
1738 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1740 case(cf_cb_file_save_finished):
1741 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1743 case(cf_cb_file_save_failed):
1744 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1746 case(cf_cb_file_save_stopped):
1747 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1749 case(cf_cb_file_export_specified_packets_started):
1750 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1752 case(cf_cb_file_export_specified_packets_finished):
1753 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1755 case(cf_cb_file_export_specified_packets_failed):
1756 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1758 case(cf_cb_file_export_specified_packets_stopped):
1759 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1762 g_warning("main_cf_callback: event %u unknown", event);
1763 g_assert_not_reached();
1769 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1771 #ifdef HAVE_GTKOSXAPPLICATION
1772 GtkosxApplication *theApp;
1775 case(capture_cb_capture_prepared):
1776 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1777 main_capture_cb_capture_prepared(cap_session);
1779 case(capture_cb_capture_update_started):
1780 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1781 main_capture_cb_capture_update_started(cap_session);
1782 #ifdef HAVE_GTKOSXAPPLICATION
1783 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1784 #ifdef HAVE_GDK_GRESOURCE
1785 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon48.png"));
1787 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_48_pb_data, FALSE, NULL));
1791 case(capture_cb_capture_update_continue):
1792 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1794 case(capture_cb_capture_update_finished):
1795 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1796 main_capture_cb_capture_update_finished(cap_session);
1798 case(capture_cb_capture_fixed_started):
1799 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1800 main_capture_cb_capture_fixed_started(cap_session);
1802 case(capture_cb_capture_fixed_continue):
1803 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1805 case(capture_cb_capture_fixed_finished):
1806 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1807 main_capture_cb_capture_fixed_finished(cap_session);
1809 case(capture_cb_capture_stopping):
1810 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1811 /* Beware: this state won't be called, if the capture child
1812 * closes the capturing on its own! */
1813 #ifdef HAVE_GTKOSXAPPLICATION
1814 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1815 #ifdef HAVE_GDK_GRESOURCE
1816 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
1818 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1821 main_capture_cb_capture_stopping(cap_session);
1823 case(capture_cb_capture_failed):
1824 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1825 main_capture_cb_capture_failed(cap_session);
1828 g_warning("main_capture_callback: event %u unknown", event);
1829 g_assert_not_reached();
1835 get_wireshark_gtk_compiled_info(GString *str)
1837 g_string_append(str, "with ");
1838 g_string_append_printf(str,
1839 #ifdef GTK_MAJOR_VERSION
1840 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1843 "GTK+ (version unknown)");
1847 g_string_append(str, ", with Cairo ");
1848 g_string_append(str, CAIRO_VERSION_STRING);
1851 g_string_append(str, ", with Pango ");
1852 g_string_append(str, PANGO_VERSION_STRING);
1854 /* Capture libraries */
1855 g_string_append(str, ", ");
1856 get_compiled_caplibs_version(str);
1860 get_gui_compiled_info(GString *str)
1862 epan_get_compiled_version_info(str);
1864 g_string_append(str, ", ");
1865 #ifdef HAVE_LIBPORTAUDIO
1866 #ifdef PORTAUDIO_API_1
1867 g_string_append(str, "with PortAudio <= V18");
1868 #else /* PORTAUDIO_API_1 */
1869 g_string_append(str, "with ");
1870 g_string_append(str, Pa_GetVersionText());
1871 #endif /* PORTAUDIO_API_1 */
1872 #else /* HAVE_LIBPORTAUDIO */
1873 g_string_append(str, "without PortAudio");
1874 #endif /* HAVE_LIBPORTAUDIO */
1876 g_string_append(str, ", ");
1878 get_compiled_airpcap_version(str);
1880 g_string_append(str, "without AirPcap");
1883 codec_get_compiled_version_info(str);
1887 get_wireshark_runtime_info(GString *str)
1890 /* Capture libraries */
1891 g_string_append(str, ", ");
1892 get_runtime_caplibs_version(str);
1895 /* stuff used by libwireshark */
1896 epan_get_runtime_version_info(str);
1899 g_string_append(str, ", ");
1900 get_runtime_airpcap_version(str);
1905 read_configuration_files(char **gdp_path, char **dp_path)
1907 int gpf_open_errno, gpf_read_errno;
1908 int cf_open_errno, df_open_errno;
1909 int gdp_open_errno, gdp_read_errno;
1910 int dp_open_errno, dp_read_errno;
1911 char *gpf_path, *pf_path;
1912 char *cf_path, *df_path;
1913 int pf_open_errno, pf_read_errno;
1916 /* load the decode as entries of this profile */
1917 load_decode_as_entries();
1919 /* Read the preference files. */
1920 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1921 &pf_open_errno, &pf_read_errno, &pf_path);
1923 if (gpf_path != NULL) {
1924 if (gpf_open_errno != 0) {
1925 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1926 "Could not open global preferences file\n\"%s\": %s.",
1927 gpf_path, g_strerror(gpf_open_errno));
1929 if (gpf_read_errno != 0) {
1930 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1931 "I/O error reading global preferences file\n\"%s\": %s.",
1932 gpf_path, g_strerror(gpf_read_errno));
1935 if (pf_path != NULL) {
1936 if (pf_open_errno != 0) {
1937 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1938 "Could not open your preferences file\n\"%s\": %s.",
1939 pf_path, g_strerror(pf_open_errno));
1941 if (pf_read_errno != 0) {
1942 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1943 "I/O error reading your preferences file\n\"%s\": %s.",
1944 pf_path, g_strerror(pf_read_errno));
1951 /* if the user wants a console to be always there, well, we should open one for him */
1952 if (prefs_p->gui_console_open == console_open_always) {
1957 /* Read the capture filter file. */
1958 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1959 if (cf_path != NULL) {
1960 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1961 "Could not open your capture filter file\n\"%s\": %s.",
1962 cf_path, g_strerror(cf_open_errno));
1966 /* Read the display filter file. */
1967 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1968 if (df_path != NULL) {
1969 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1970 "Could not open your display filter file\n\"%s\": %s.",
1971 df_path, g_strerror(df_open_errno));
1975 /* Read the disabled protocols file. */
1976 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1977 dp_path, &dp_open_errno, &dp_read_errno);
1978 read_enabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1979 dp_path, &dp_open_errno, &dp_read_errno);
1980 read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1981 dp_path, &dp_open_errno, &dp_read_errno);
1982 if (*gdp_path != NULL) {
1983 if (gdp_open_errno != 0) {
1984 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1985 "Could not open global disabled protocols file\n\"%s\": %s.",
1986 *gdp_path, g_strerror(gdp_open_errno));
1988 if (gdp_read_errno != 0) {
1989 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1990 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1991 *gdp_path, g_strerror(gdp_read_errno));
1996 if (*dp_path != NULL) {
1997 if (dp_open_errno != 0) {
1998 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1999 "Could not open your disabled protocols file\n\"%s\": %s.",
2000 *dp_path, g_strerror(dp_open_errno));
2002 if (dp_read_errno != 0) {
2003 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2004 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2005 *dp_path, g_strerror(dp_read_errno));
2014 /* Check if there's something important to tell the user during startup.
2015 * We want to do this *after* showing the main window so that any windows
2016 * we pop up will be above the main window.
2020 check_and_warn_user_startup(gchar *cf_name)
2022 check_and_warn_user_startup(gchar *cf_name _U_)
2025 gchar *cur_user, *cur_group;
2026 gpointer priv_warning_dialog;
2028 /* Tell the user not to run as root. */
2029 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2030 cur_user = get_cur_username();
2031 cur_group = get_cur_groupname();
2032 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2033 "Running as user \"%s\" and group \"%s\".\n"
2034 "This could be dangerous.\n\n"
2035 "If you're running Wireshark this way in order to perform live capture, "
2036 "you may want to be aware that there is a better way documented at\n"
2037 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2040 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2041 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2045 /* Warn the user if npf.sys isn't loaded. */
2046 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2047 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2048 "The NPF driver isn't running. You may have trouble\n"
2049 "capturing or listing interfaces.");
2050 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2051 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2057 /* And now our feature presentation... [ fade to music ] */
2059 main(int argc, char *argv[])
2061 char *init_progfile_dir_error;
2063 int ret = EXIT_SUCCESS;
2064 extern int info_update_freq; /* Found in about_dlg.c. */
2065 const gchar *filter;
2073 char *gdp_path, *dp_path;
2084 gint pl_size = 280, tv_size = 95, bv_size = 75;
2086 dfilter_t *rfcode = NULL;
2087 gchar *err_msg = NULL;
2088 gboolean rfilter_parse_failed = FALSE;
2089 GtkWidget *splash_win = NULL;
2090 dfilter_t *jump_to_filter = NULL;
2091 unsigned int in_file_type = WTAP_TYPE_AUTO;
2092 #ifdef HAVE_GTKOSXAPPLICATION
2093 GtkosxApplication *theApp;
2095 GString *comp_info_str = NULL;
2096 GString *runtime_info_str = NULL;
2098 #ifdef HAVE_GDK_GRESOURCE
2099 main_register_resource();
2102 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2104 /* Set the current locale according to the program environment.
2105 * We haven't localized anything, but some GTK widgets are localized
2106 * (the file selection dialogue, for example).
2107 * This also sets the C-language locale to the native environment. */
2108 setlocale(LC_ALL, "");
2110 arg_list_utf_16to8(argc, argv);
2111 create_app_running_mutex();
2115 * Get credential information for later use, and drop privileges
2116 * before doing anything else.
2117 * Let the user know if anything happened.
2119 init_process_policies();
2120 relinquish_special_privs_perm();
2123 * Attempt to get the pathname of the directory containing the
2126 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2128 /* initialize the funnel mini-api */
2129 initialize_funnel_ops();
2131 AirPDcapInitContext(&airpdcap_ctx);
2134 /* Load wpcap if possible. Do this before collecting the run-time version information */
2137 /* ... and also load the packet.dll from wpcap */
2138 wpcap_packet_load();
2141 /* Load the airpcap.dll. This must also be done before collecting
2142 * run-time version information. */
2143 airpcap_dll_ret_val = load_airpcap();
2145 switch (airpcap_dll_ret_val) {
2146 case AIRPCAP_DLL_OK:
2147 /* load the airpcap interfaces */
2148 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2150 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
2151 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2152 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2155 airpcap_if_active = NULL;
2159 /* select the first ad default (THIS SHOULD BE CHANGED) */
2160 airpcap_if_active = airpcap_get_default_if(g_airpcap_if_list);
2165 * XXX - Maybe we need to warn the user if one of the following happens???
2167 case AIRPCAP_DLL_OLD:
2168 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2171 case AIRPCAP_DLL_ERROR:
2172 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2175 case AIRPCAP_DLL_NOT_FOUND:
2176 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2180 #endif /* HAVE_AIRPCAP */
2183 /* Get the compile-time version information string */
2184 comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
2185 get_gui_compiled_info);
2187 /* Get the run-time version information string */
2188 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
2190 /* Add it to the information to be reported on a crash. */
2191 ws_add_crash_info("Wireshark %s\n"
2196 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2199 /* Start windows sockets */
2200 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2203 profile_store_persconffiles (TRUE);
2205 /* Read the profile independent recent file. We have to do this here so we can */
2206 /* set the profile before it can be set from the command line parameter */
2207 recent_read_static(&rf_path, &rf_open_errno);
2208 if (rf_path != NULL && rf_open_errno != 0) {
2209 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2210 "Could not open common recent file\n\"%s\": %s.",
2211 rf_path, g_strerror(rf_open_errno));
2214 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
2216 /* Init the "Open file" dialog directory */
2217 /* (do this after the path settings are processed) */
2219 /* Read the profile dependent (static part) of the recent file. */
2220 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2221 /* recent lists which is done in the dynamic part. */
2222 /* We have to do this already here, so command line parameters can overwrite these values. */
2223 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
2224 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2225 "Could not open recent file\n\"%s\": %s.",
2226 rf_path, g_strerror(rf_open_errno));
2230 if (recent.gui_fileopen_remembered_dir &&
2231 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2232 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2234 set_last_open_dir(get_persdatafile_dir());
2237 #if !GLIB_CHECK_VERSION(2,31,0)
2238 g_thread_init(NULL);
2241 /* Disable liboverlay scrollbar which broke Wireshark on Ubuntu */
2242 #if !GTK_CHECK_VERSION(3,16,0)
2243 if (NULL == g_getenv("LIBOVERLAY_SCROLLBAR")) {
2244 g_setenv("LIBOVERLAY_SCROLLBAR", "0", FALSE);
2248 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2249 gtk_init (&argc, &argv);
2251 cf_callback_add(main_cf_callback, NULL);
2253 capture_callback_add(main_capture_callback, NULL);
2256 cf_callback_add(statusbar_cf_callback, NULL);
2258 capture_callback_add(statusbar_capture_callback, NULL);
2261 cf_callback_add(welcome_cf_callback, NULL);
2263 capture_callback_add(welcome_capture_callback, NULL);
2266 set_console_log_handler();
2269 /* Set the initial values in the capture options. This might be overwritten
2270 by preference settings and then again by the command line parameters. */
2271 capture_opts_init(&global_capture_opts);
2273 capture_session_init(&global_capture_session, &cfile);
2276 init_report_err(vfailure_alert_box, open_failure_alert_box,
2277 read_failure_alert_box, write_failure_alert_box);
2279 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2280 filter = get_conn_cfilter();
2281 if ( *filter != '\0' ) {
2282 info_update_freq = 1000; /* Milliseconds */
2285 /* We won't come till here, if we had a "console only" command line parameter. */
2286 splash_win = splash_new("Loading Wireshark ...");
2287 if (init_progfile_dir_error != NULL) {
2288 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2289 "Can't get pathname of directory containing Wireshark: %s.\n"
2290 "It won't be possible to capture traffic.\n"
2291 "Report this to the Wireshark developers.",
2292 init_progfile_dir_error);
2293 g_free(init_progfile_dir_error);
2299 /* Register all the plugin types we have. */
2300 epan_register_plugin_types(); /* Types known to libwireshark */
2301 codec_register_plugin_types(); /* Types known to libwscodecs */
2303 /* Scan for plugins. This does *not* call their registration routines;
2304 that's done later. */
2305 scan_plugins(REPORT_LOAD_FAILURE);
2307 /* Register all libwiretap plugin modules. */
2308 register_all_wiretap_modules();
2311 /* Register all audio codec plugins. */
2312 register_all_codecs();
2314 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2316 /* Register all dissectors; we must do this before checking for the
2317 "-G" flag, as the "-G" flag dumps information registered by the
2318 dissectors, and we must do it before we read the preferences, in
2319 case any dissectors register preferences. */
2320 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
2321 splash_update, (gpointer) splash_win)) {
2326 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2328 /* Register all tap listeners; we do this before we parse the arguments,
2329 as the "-z" argument can specify a registered tap. */
2331 /* we register the plugin taps before the other taps because
2332 stats_tree taps plugins will be registered as tap listeners
2333 by stats_tree_stat.c and need to registered before that */
2336 register_all_plugin_tap_listeners();
2339 register_all_tap_listeners();
2340 conversation_table_set_gui_info(init_conversation_table);
2341 hostlist_table_set_gui_info(init_hostlist_table);
2342 srt_table_iterate_tables(register_service_response_tables, NULL);
2343 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2344 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2347 splash_update(RA_EXTCAP, NULL, (gpointer)splash_win);
2348 extcap_register_preferences();
2351 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2353 global_commandline_info.prefs_p = read_configuration_files (&gdp_path, &dp_path);
2354 /* Removed thread code:
2355 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2358 cap_file_init(&cfile);
2360 /* Fill in capture options with values from the preferences */
2361 prefs_to_capture_opts();
2363 /*#ifdef HAVE_LIBPCAP
2364 fill_in_local_interfaces();
2367 /* Now get our args */
2368 commandline_other_options(argc, argv, TRUE);
2371 splash_update(RA_INTERFACES, NULL, (gpointer)splash_win);
2373 fill_in_local_interfaces(main_window_update);
2375 if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) {
2376 /* We're supposed to do a live capture or get a list of link-layer
2377 types for a live capture device; if the user didn't specify an
2378 interface to use, pick a default. */
2379 ret = capture_opts_default_iface_if_necessary(&global_capture_opts,
2380 ((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);
2386 if (global_commandline_info.list_link_layer_types) {
2387 /* Get the list of link-layer types for the capture devices. */
2388 if_capabilities_t *caps;
2391 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2393 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2394 if (device.selected) {
2395 gchar* auth_str = NULL;
2396 #ifdef HAVE_PCAP_REMOTE
2397 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
2398 auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
2399 device.remote_opts.remote_host_opts.auth_password);
2402 #if defined(HAVE_PCAP_CREATE)
2403 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
2405 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
2409 cmdarg_err("%s", err_str);
2411 ret = INVALID_CAPABILITY;
2414 if (caps->data_link_types == NULL) {
2415 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2416 ret = INVALID_LINK_TYPE;
2422 #if defined(HAVE_PCAP_CREATE)
2423 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2425 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2430 free_if_capabilities(caps);
2436 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2437 capture_opts_trim_ring_num_files(&global_capture_opts);
2438 #endif /* HAVE_LIBPCAP */
2440 /* Notify all registered modules that have had any of their preferences
2441 changed either from one of the preferences file or from the command
2442 line that their preferences have changed. */
2446 if ((global_capture_opts.num_selected == 0) &&
2447 ((prefs.capture_device != NULL) &&
2448 (global_commandline_info.prefs_p != NULL) &&
2449 (*global_commandline_info.prefs_p->capture_device != '\0'))) {
2452 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2453 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2454 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2455 device.selected = TRUE;
2456 global_capture_opts.num_selected++;
2457 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2458 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2463 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2464 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2465 device.selected = TRUE;
2466 global_capture_opts.num_selected++;
2467 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2468 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2472 /* disabled protocols as per configuration file */
2473 if (gdp_path == NULL && dp_path == NULL) {
2474 set_disabled_protos_list();
2475 set_enabled_protos_list();
2476 set_disabled_heur_dissector_list();
2479 if(global_dissect_options.disable_protocol_slist) {
2480 GSList *proto_disable;
2481 for (proto_disable = global_dissect_options.disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
2483 proto_disable_proto_by_name((char*)proto_disable->data);
2487 if(global_dissect_options.enable_protocol_slist) {
2488 GSList *proto_enable;
2489 for (proto_enable = global_dissect_options.enable_protocol_slist; proto_enable != NULL; proto_enable = g_slist_next(proto_enable))
2491 proto_enable_proto_by_name((char*)proto_enable->data);
2495 if(global_dissect_options.disable_heur_slist) {
2496 GSList *heur_enable;
2497 for (heur_enable = global_dissect_options.disable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
2499 proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
2503 if(global_dissect_options.disable_heur_slist) {
2504 GSList *heur_disable;
2505 for (heur_disable = global_dissect_options.disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
2507 proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
2511 build_column_format_array(&cfile.cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
2513 /* read in rc file from global and personal configuration paths. */
2514 rc_file = get_datafile_path(RC_FILE);
2515 #if GTK_CHECK_VERSION(3,0,0)
2516 /* XXX resolve later */
2518 gtk_rc_parse(rc_file);
2520 rc_file = get_persconffile_path(RC_FILE, FALSE);
2521 gtk_rc_parse(rc_file);
2531 /* close the splash screen, as we are going to open the main window now */
2532 splash_destroy(splash_win);
2534 /************************************************************************/
2535 /* Everything is prepared now, preferences and command line was read in */
2537 /* Pop up the main window. */
2538 create_main_window(pl_size, tv_size, bv_size, global_commandline_info.prefs_p);
2540 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2541 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
2542 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2543 "Could not open recent file\n\"%s\": %s.",
2544 rf_path, g_strerror(rf_open_errno));
2548 packet_list_enable_color(recent.packet_list_colorize);
2550 /* rearrange all the widgets as we now have all recent settings ready for this */
2551 main_widgets_rearrange();
2553 /* Fill in column titles. This must be done after the top level window
2556 XXX - is that still true, with fixed-width columns? */
2558 menu_recent_read_finished();
2560 main_auto_scroll_live_changed(auto_scroll_live);
2563 switch (user_font_apply()) {
2566 case FA_ZOOMED_TOO_FAR:
2567 /* The zoom level is too big for this font; turn off zooming. */
2568 recent.gui_zoom_level = 0;
2570 case FA_FONT_NOT_AVAILABLE:
2571 /* XXX - did we successfully load the un-zoomed version earlier?
2572 If so, this *probably* means the font is available, but not at
2573 this particular zoom level, but perhaps some other failure
2574 occurred; I'm not sure you can determine which is the case,
2576 /* turn off zooming - zoom level is unavailable */
2578 /* in any other case than FA_SUCCESS, turn off zooming */
2579 recent.gui_zoom_level = 0;
2580 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2584 dnd_init(top_level);
2586 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
2587 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
2591 capture_filter_init();
2594 /* the window can be sized only, if it's not already shown, so do it now! */
2595 main_load_window_geometry(top_level);
2597 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2599 /* this is to keep tap extensions updating once every 3 seconds */
2600 tap_update_timer_id = g_timeout_add(global_commandline_info.prefs_p->tap_update_interval, tap_update_cb, NULL);
2602 /* If we were given the name of a capture file, read it in now;
2603 we defer it until now, so that, if we can't open it, and pop
2604 up an alert box, the alert box is more likely to come up on
2605 top of the main window - but before the preference-file-error
2606 alert box, so, if we get one of those, it's more likely to come
2608 if (global_commandline_info.cf_name) {
2609 show_main_window(TRUE);
2610 check_and_warn_user_startup(global_commandline_info.cf_name);
2611 if (global_commandline_info.rfilter != NULL) {
2612 if (!dfilter_compile(global_commandline_info.rfilter, &rfcode, &err_msg)) {
2613 bad_dfilter_alert_box(top_level, global_commandline_info.rfilter, err_msg);
2615 rfilter_parse_failed = TRUE;
2618 if (ex_opt_count("read_format") > 0) {
2619 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
2621 if (!rfilter_parse_failed) {
2622 if (cf_open(&cfile, global_commandline_info.cf_name, in_file_type, FALSE, &err) == CF_OK) {
2623 /* "cf_open()" succeeded, so it closed the previous
2624 capture file, and thus destroyed any previous read filter
2625 attached to "cf". */
2627 cfile.rfcode = rfcode;
2628 /* Open stat windows; we do so after creating the main window,
2629 to avoid GTK warnings, and after successfully opening the
2630 capture file, so we know we have something to compute stats
2631 on, and after registering all dissectors, so that MATE will
2632 have registered its field array and we can have a tap filter
2633 with one of MATE's late-registered fields as part of the
2635 start_requested_stats();
2637 /* Read the capture file. */
2638 switch (cf_read(&cfile, FALSE)) {
2642 /* Just because we got an error, that doesn't mean we were unable
2643 to read any of the file; we handle what we could get from the
2645 /* if the user told us to jump to a specific packet, do it now */
2646 if(global_commandline_info.go_to_packet != 0) {
2647 /* Jump to the specified frame number, kept for backward
2649 cf_goto_frame(&cfile, global_commandline_info.go_to_packet);
2650 } else if (global_commandline_info.jfilter != NULL) {
2651 /* try to compile given filter */
2652 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
2653 bad_dfilter_alert_box(top_level, global_commandline_info.jfilter, err_msg);
2656 /* Filter ok, jump to the first packet matching the filter
2657 conditions. Default search direction is forward, but if
2658 option d was given, search backwards */
2659 cf_find_packet_dfilter(&cfile, jump_to_filter, global_commandline_info.jump_backwards);
2664 case CF_READ_ABORTED:
2670 /* If the filename is not the absolute path, prepend the current dir. This happens
2671 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
2672 if (!g_path_is_absolute(global_commandline_info.cf_name)) {
2673 char *old_cf_name = global_commandline_info.cf_name;
2674 char *pwd = g_get_current_dir();
2675 global_commandline_info.cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, global_commandline_info.cf_name);
2676 g_free(old_cf_name);
2680 /* Save the name of the containing directory specified in the
2681 path name, if any; we can write over cf_name, which is a
2682 good thing, given that "get_dirname()" does write over its
2684 s = get_dirname(global_commandline_info.cf_name);
2685 set_last_open_dir(s);
2686 g_free(global_commandline_info.cf_name);
2687 global_commandline_info.cf_name = NULL;
2690 dfilter_free(rfcode);
2691 cfile.rfcode = NULL;
2692 show_main_window(FALSE);
2693 /* Don't call check_and_warn_user_startup(): we did it above */
2694 main_set_for_capture_in_progress(FALSE);
2695 set_capture_if_dialog_for_capture_in_progress(FALSE);
2700 if (global_commandline_info.start_capture) {
2701 if (global_capture_opts.save_file != NULL) {
2702 /* Save the directory name for future file dialogs. */
2703 /* (get_dirname overwrites filename) */
2704 s = g_strdup(global_capture_opts.save_file);
2705 set_last_open_dir(get_dirname(s));
2708 /* "-k" was specified; start a capture. */
2709 show_main_window(FALSE);
2710 check_and_warn_user_startup(global_commandline_info.cf_name);
2712 /* If no user interfaces were specified on the command line,
2713 copy the list of selected interfaces to the set of interfaces
2714 to use for this capture. */
2715 if (global_capture_opts.ifaces->len == 0)
2716 collect_ifaces(&global_capture_opts);
2717 if (capture_start(&global_capture_opts, &global_capture_session, &global_info_data,main_window_update)) {
2718 /* The capture started. Open stat windows; we do so after creating
2719 the main window, to avoid GTK warnings, and after successfully
2720 opening the capture file, so we know we have something to compute
2721 stats on, and after registering all dissectors, so that MATE will
2722 have registered its field array and we can have a tap filter with
2723 one of MATE's late-registered fields as part of the filter. */
2724 start_requested_stats();
2727 show_main_window(FALSE);
2728 check_and_warn_user_startup(global_commandline_info.cf_name);
2729 main_set_for_capture_in_progress(FALSE);
2730 set_capture_if_dialog_for_capture_in_progress(FALSE);
2732 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
2733 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
2734 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
2736 #else /* HAVE_LIBPCAP */
2737 show_main_window(FALSE);
2738 check_and_warn_user_startup(global_commandline_info.cf_name);
2739 main_set_for_capture_in_progress(FALSE);
2740 set_capture_if_dialog_for_capture_in_progress(FALSE);
2741 #endif /* HAVE_LIBPCAP */
2744 if (global_commandline_info.dfilter) {
2745 GtkWidget *filter_te;
2746 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
2747 gtk_entry_set_text(GTK_ENTRY(filter_te), global_commandline_info.dfilter);
2749 /* Run the display filter so it goes in effect. */
2750 main_filter_packets(&cfile, global_commandline_info.dfilter, FALSE);
2753 profile_store_persconffiles (FALSE);
2755 #ifdef HAVE_GTKOSXAPPLICATION
2756 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
2757 #ifdef HAVE_GDK_GRESOURCE
2758 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
2760 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
2762 gtkosx_application_ready(theApp);
2765 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
2768 gtk_iface_mon_start();
2771 software_update_init();
2773 /* we'll enter the GTK loop now and hand the control over to GTK ... */
2775 /* ... back from GTK, we're going down now! */
2778 gtk_iface_mon_stop();
2787 AirPDcapDestroyContext(&airpdcap_ctx);
2789 #ifdef HAVE_GTKOSXAPPLICATION
2790 g_object_unref(theApp);
2794 /* hide the (unresponsive) main window, while asking the user to close the console window */
2795 if (G_IS_OBJECT(top_level))
2796 gtk_widget_hide(top_level);
2798 software_update_cleanup();
2800 /* Shutdown windows sockets */
2803 /* For some unknown reason, the "atexit()" call in "create_console()"
2804 doesn't arrange that "destroy_console()" be called when we exit,
2805 so we call it here if a console was created. */
2809 #ifdef HAVE_GDK_GRESOURCE
2810 main_unregister_resource();
2815 capture_opts_cleanup(&global_capture_opts);
2817 col_cleanup(&cfile.cinfo);
2818 free_filter_lists();
2829 /* We build this as a GUI subsystem application on Win32, so
2830 "WinMain()", not "main()", gets called.
2832 Hack shamelessly stolen from the Win32 port of the GIMP. */
2834 #define _stdcall __attribute__((stdcall))
2838 WinMain (struct HINSTANCE__ *hInstance,
2839 struct HINSTANCE__ *hPrevInstance,
2843 INITCOMMONCONTROLSEX comm_ctrl;
2846 * Initialize our DLL search path. MUST be called before LoadLibrary
2849 ws_init_dll_search_path();
2851 /* Initialize our controls. Required for native Windows file dialogs. */
2852 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
2853 comm_ctrl.dwSize = sizeof(comm_ctrl);
2854 /* Includes the animate, header, hot key, list view, progress bar,
2855 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
2858 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
2859 InitCommonControlsEx(&comm_ctrl);
2861 /* RichEd20.DLL is needed for native file dialog filter entries. */
2862 ws_load_library("riched20.dll");
2864 set_has_console(FALSE);
2865 set_console_wait(FALSE);
2866 return main (__argc, __argv);
2875 * Helper for main_widgets_rearrange()
2877 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
2878 gtk_container_remove(GTK_CONTAINER(data), widget);
2881 static GtkWidget *main_widget_layout(gint layout_content)
2883 switch(layout_content) {
2884 case(layout_pane_content_none):
2886 case(layout_pane_content_plist):
2888 case(layout_pane_content_pdetails):
2890 case(layout_pane_content_pbytes):
2891 return byte_nb_ptr_gbl;
2893 g_assert_not_reached();
2899 * Rearrange the main window widgets
2901 void main_widgets_rearrange(void) {
2902 GtkWidget *first_pane_widget1, *first_pane_widget2;
2903 GtkWidget *second_pane_widget1, *second_pane_widget2;
2904 gboolean split_top_left = FALSE;
2906 /* be a bit faster */
2907 gtk_widget_hide(main_vbox);
2909 /* be sure we don't lose a widget while rearranging */
2910 g_object_ref(G_OBJECT(menubar));
2911 g_object_ref(G_OBJECT(main_tb));
2912 g_object_ref(G_OBJECT(filter_tb));
2913 g_object_ref(G_OBJECT(wireless_tb));
2914 g_object_ref(G_OBJECT(pkt_scrollw));
2915 g_object_ref(G_OBJECT(tv_scrollw));
2916 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
2917 g_object_ref(G_OBJECT(statusbar));
2918 g_object_ref(G_OBJECT(main_pane_v1));
2919 g_object_ref(G_OBJECT(main_pane_v2));
2920 g_object_ref(G_OBJECT(main_pane_h1));
2921 g_object_ref(G_OBJECT(main_pane_h2));
2922 g_object_ref(G_OBJECT(welcome_pane));
2924 /* empty all containers participating */
2925 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
2926 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
2927 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
2928 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
2929 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
2931 statusbar_widgets_emptying(statusbar);
2933 /* add the menubar always at the top */
2934 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2937 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
2939 /* filter toolbar in toolbar area */
2940 if (!prefs.filter_toolbar_show_in_statusbar) {
2941 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
2944 /* airpcap toolbar */
2945 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
2947 /* fill the main layout panes */
2948 switch(prefs.gui_layout_type) {
2949 case(layout_type_5):
2950 main_first_pane = main_pane_v1;
2951 main_second_pane = main_pane_v2;
2952 split_top_left = FALSE;
2954 case(layout_type_2):
2955 main_first_pane = main_pane_v1;
2956 main_second_pane = main_pane_h1;
2957 split_top_left = FALSE;
2959 case(layout_type_1):
2960 main_first_pane = main_pane_v1;
2961 main_second_pane = main_pane_h1;
2962 split_top_left = TRUE;
2964 case(layout_type_4):
2965 main_first_pane = main_pane_h1;
2966 main_second_pane = main_pane_v1;
2967 split_top_left = FALSE;
2969 case(layout_type_3):
2970 main_first_pane = main_pane_h1;
2971 main_second_pane = main_pane_v1;
2972 split_top_left = TRUE;
2974 case(layout_type_6):
2975 main_first_pane = main_pane_h1;
2976 main_second_pane = main_pane_h2;
2977 split_top_left = FALSE;
2980 main_first_pane = NULL;
2981 main_second_pane = NULL;
2982 g_assert_not_reached();
2984 if (split_top_left) {
2985 first_pane_widget1 = main_second_pane;
2986 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2987 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
2988 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2990 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2991 first_pane_widget2 = main_second_pane;
2992 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
2993 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2995 if (first_pane_widget1 != NULL)
2996 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
2997 if (first_pane_widget2 != NULL)
2998 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
2999 if (second_pane_widget1 != NULL)
3000 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3001 if (second_pane_widget2 != NULL)
3002 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3004 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3007 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3010 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3012 /* filter toolbar in statusbar hbox */
3013 if (prefs.filter_toolbar_show_in_statusbar) {
3014 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3017 /* statusbar widgets */
3018 statusbar_widgets_pack(statusbar);
3020 /* hide widgets on users recent settings */
3021 main_widgets_show_or_hide();
3023 gtk_widget_show(main_vbox);
3027 is_widget_visible(GtkWidget *widget, gpointer data)
3029 gboolean *is_visible = ( gboolean *)data;
3032 if (gtk_widget_get_visible(widget))
3039 main_widgets_show_or_hide(void)
3041 gboolean main_second_pane_show;
3043 if (recent.main_toolbar_show) {
3044 gtk_widget_show(main_tb);
3046 gtk_widget_hide(main_tb);
3049 statusbar_widgets_show_or_hide(statusbar);
3051 if (recent.filter_toolbar_show) {
3052 gtk_widget_show(filter_tb);
3054 gtk_widget_hide(filter_tb);
3057 if (recent.wireless_toolbar_show) {
3058 gtk_widget_show(wireless_tb);
3060 gtk_widget_hide(wireless_tb);
3063 if (recent.packet_list_show && have_capture_file) {
3064 gtk_widget_show(pkt_scrollw);
3066 gtk_widget_hide(pkt_scrollw);
3069 if (recent.tree_view_show && have_capture_file) {
3070 gtk_widget_show(tv_scrollw);
3072 gtk_widget_hide(tv_scrollw);
3075 if (recent.byte_view_show && have_capture_file) {
3076 gtk_widget_show(byte_nb_ptr_gbl);
3078 gtk_widget_hide(byte_nb_ptr_gbl);
3081 if (have_capture_file) {
3082 gtk_widget_show(main_first_pane);
3084 gtk_widget_hide(main_first_pane);
3088 * Is anything in "main_second_pane" visible?
3089 * If so, show it, otherwise hide it.
3091 main_second_pane_show = FALSE;
3092 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3093 &main_second_pane_show);
3094 if (main_second_pane_show) {
3095 gtk_widget_show(main_second_pane);
3097 gtk_widget_hide(main_second_pane);
3100 if (!have_capture_file) {
3102 gtk_widget_show(welcome_pane);
3105 gtk_widget_hide(welcome_pane);
3110 /* called, when the window state changes (minimized, maximized, ...) */
3112 window_state_event_cb (GtkWidget *widget _U_,
3116 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3118 if( (event->type) == (GDK_WINDOW_STATE)) {
3119 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3120 /* we might have dialogs popped up while we where iconified,
3122 display_queued_messages();
3130 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3132 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3134 if (event->keyval == GDK_F8) {
3137 } else if (event->keyval == GDK_F7) {
3140 } else if (event->state & NO_SHIFT_MOD_MASK) {
3141 return FALSE; /* Skip control, alt, and other modifiers */
3143 * A comment in gdkkeysyms.h says that it's autogenerated from
3144 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3145 * don't explicitly say so, g_ascii_isprint() should work as expected
3148 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3149 /* Forward the keypress on to the display filter entry */
3150 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3151 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3152 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3160 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3161 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3166 GtkAccelGroup *accel;
3169 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3170 set_titlebar_for_capture_file(NULL);
3172 gtk_widget_set_name(top_level, "main window");
3173 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3175 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3176 G_CALLBACK(window_state_event_cb), NULL);
3177 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3178 G_CALLBACK(top_level_key_pressed_cb), NULL );
3180 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3181 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3183 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3184 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3185 gtk_widget_show(main_vbox);
3188 menubar = main_menu_new(&accel);
3190 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3191 /* Mac OS X native menus are created and displayed by main_menu_new() */
3192 if(!prefs_p->gui_macosx_style) {
3194 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3195 gtk_widget_show(menubar);
3196 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3198 gtk_widget_hide(menubar);
3203 main_tb = toolbar_new();
3204 gtk_widget_show (main_tb);
3206 /* Filter toolbar */
3207 filter_tb = filter_toolbar_new();
3210 pkt_scrollw = packet_list_create();
3211 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3212 gtk_widget_show_all(pkt_scrollw);
3215 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3216 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3217 gtk_widget_show(tv_scrollw);
3219 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3220 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3221 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3222 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3223 gtk_widget_show(tree_view_gbl);
3226 byte_nb_ptr_gbl = byte_view_new();
3227 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3228 gtk_widget_show(byte_nb_ptr_gbl);
3230 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3231 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3233 /* Panes for the packet list, tree, and byte view */
3234 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3235 gtk_widget_show(main_pane_v1);
3236 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3237 gtk_widget_show(main_pane_v2);
3238 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3239 gtk_widget_show(main_pane_h1);
3240 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3241 gtk_widget_show(main_pane_h2);
3243 wireless_tb = airpcap_toolbar_new();
3245 wireless_tb = ws80211_toolbar_new();
3247 gtk_widget_show(wireless_tb);
3250 statusbar = statusbar_new();
3251 gtk_widget_show(statusbar);
3253 /* Pane for the welcome screen */
3254 welcome_pane = welcome_new();
3255 gtk_widget_show(welcome_pane);
3259 show_main_window(gboolean doing_work)
3261 main_set_for_capture_file(doing_work);
3263 /*** we have finished all init things, show the main window ***/
3264 gtk_widget_show(top_level);
3266 /* the window can be maximized only, if it's visible, so do it after show! */
3267 main_load_window_geometry(top_level);
3269 /* process all pending GUI events before continue */
3270 while (gtk_events_pending()) gtk_main_iteration();
3272 /* Pop up any queued-up alert boxes. */
3273 display_queued_messages();
3275 /* Move the main window to the front, in case it isn't already there */
3276 gdk_window_raise(gtk_widget_get_window(top_level));
3279 airpcap_toolbar_show(wireless_tb);
3280 #endif /* HAVE_AIRPCAP */
3283 static void copy_global_profile (const gchar *profile_name)
3285 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3287 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3288 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3289 "Can't create directory\n\"%s\":\n%s.",
3290 pf_dir_path, g_strerror(errno));
3292 g_free(pf_dir_path);
3295 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3296 &pf_dir_path, &pf_dir_path2) == -1) {
3297 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3298 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3299 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3301 g_free(pf_filename);
3302 g_free(pf_dir_path);
3303 g_free(pf_dir_path2);
3307 /* Change configuration profile */
3308 void change_configuration_profile (const gchar *profile_name)
3310 char *gdp_path, *dp_path;
3313 gchar* err_msg = NULL;
3315 /* First check if profile exists */
3316 if (!profile_exists(profile_name, FALSE)) {
3317 if (profile_exists(profile_name, TRUE)) {
3318 /* Copy from global profile */
3319 copy_global_profile (profile_name);
3321 /* No personal and no global profile exists */
3326 /* Then check if changing to another profile */
3327 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3331 /* Get the current geometry, before writing it to disk */
3332 main_save_window_geometry(top_level);
3334 if (profile_exists(get_profile_name(), FALSE)) {
3335 /* Write recent file for profile we are leaving, if it still exists */
3336 write_profile_recent();
3339 /* Set profile name and update the status bar */
3340 set_profile_name (profile_name);
3341 profile_bar_update ();
3343 /* Reset current preferences and apply the new */
3347 (void) read_configuration_files (&gdp_path, &dp_path);
3349 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
3350 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3351 "Could not open common recent file\n\"%s\": %s.",
3352 rf_path, g_strerror(rf_open_errno));
3355 if (recent.gui_fileopen_remembered_dir &&
3356 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3357 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3359 timestamp_set_type (recent.gui_time_format);
3360 timestamp_set_seconds_type (recent.gui_seconds_format);
3361 packet_list_enable_color(recent.packet_list_colorize);
3363 prefs_to_capture_opts();
3366 update_local_interfaces();
3368 macros_post_update();
3370 /* Update window view and redraw the toolbar */
3371 main_titlebar_update();
3372 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3373 toolbar_redraw_all();
3375 /* Enable all protocols and disable from the disabled list */
3377 if (gdp_path == NULL && dp_path == NULL) {
3378 set_disabled_protos_list();
3379 set_enabled_protos_list();
3380 set_disabled_heur_dissector_list();
3383 /* Reload color filters */
3384 if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3385 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3389 /* Reload list of interfaces on welcome page */
3390 welcome_if_panel_reload();
3392 /* Recreate the packet list according to new preferences */
3393 packet_list_recreate ();
3394 cfile.columns_changed = FALSE; /* Reset value */
3397 /* Update menus with new recent values */
3398 menu_recent_read_finished();
3400 /* Reload pane geometry, must be done after recreating the list */
3401 main_pane_load_window_geometry();
3405 main_fields_changed (void)
3407 gchar* err_msg = NULL;
3409 /* Reload color filters */
3410 if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3411 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3415 /* Syntax check filter */
3416 filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3417 if (cfile.dfilter) {
3418 /* Check if filter is still valid */
3419 dfilter_t *dfp = NULL;
3420 if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
3421 /* Not valid. Enable 'Apply' button and remove dfilter. */
3422 g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3423 g_free(cfile.dfilter);
3424 cfile.dfilter = NULL;
3429 if (have_custom_cols(&cfile.cinfo)) {
3430 /* Recreate packet list according to new/changed/deleted fields */
3431 packet_list_recreate();
3432 } else if (cfile.state != FILE_CLOSED) {
3433 /* Redissect packets if we have any */
3434 redissect_packets();
3436 destroy_packet_wins(); /* TODO: close windows until we can recreate */
3438 proto_free_deregistered_fields();
3441 /** redissect packets and update UI */
3442 void redissect_packets(void)
3444 cf_redissect_packets(&cfile);
3445 status_expert_update();
3448 #ifdef HAVE_SOFTWARE_UPDATE
3449 /** Check to see if Wireshark can shut down safely (e.g. offer to save the
3453 int software_update_can_shutdown_callback(void) {
3457 /** Shut down Wireshark in preparation for an upgrade.
3460 void software_update_shutdown_request_callback(void) {
3470 * indent-tabs-mode: nil
3473 * ex: set shiftwidth=4 tabstop=8 expandtab:
3474 * :indentSize=4:tabSize=8:noTabs=true: