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>
43 #ifndef HAVE_GETOPT_LONG
44 #include "wsutil/wsgetopt.h"
48 #include <zlib.h> /* to get the libz version number */
51 #ifdef HAVE_LIBPORTAUDIO
52 #include <portaudio.h>
53 #endif /* HAVE_LIBPORTAUDIO */
55 #include <wsutil/clopts_common.h>
56 #include <wsutil/copyright_info.h>
57 #include <wsutil/crash_info.h>
58 #include <wsutil/filesystem.h>
59 #include <wsutil/file_util.h>
60 #include <wsutil/privileges.h>
61 #include <wsutil/report_err.h>
62 #include <wsutil/u3.h>
63 #include <wsutil/ws_diag_control.h>
64 #include <wsutil/ws_version_info.h>
66 #include <wiretap/merge.h>
68 #include <epan/addr_resolv.h>
69 #include <epan/column.h>
70 #include <epan/disabled_protos.h>
71 #include <epan/epan.h>
72 #include <epan/proto.h>
73 #include <epan/epan_dissect.h>
74 #include <epan/dfilter/dfilter.h>
75 #include <epan/strutil.h>
76 #include <epan/ex-opt.h>
77 #include <epan/funnel.h>
78 #include <epan/expert.h>
79 #include <epan/prefs.h>
80 #include <epan/prefs-int.h>
82 #include <epan/stat_tap_ui.h>
84 #include <epan/print.h>
85 #include <epan/timestamp.h>
86 #include <epan/conversation_table.h>
88 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
89 #include <epan/asn1.h>
90 #include <epan/dissectors/packet-kerberos.h>
93 #include <wsutil/cmdarg_err.h>
94 #include <wsutil/plugins.h>
96 /* general (not GTK specific) */
98 #include "../frame_tvbuff.h"
99 #include "../summary.h"
100 #include "../color.h"
101 #include "../color_filters.h"
102 #include "../register.h"
103 #include "../ringbuffer.h"
106 #include "gtk_iface_monitor.h"
108 #include "ui/alert_box.h"
109 #include "ui/console.h"
110 #include "ui/decode_as_utils.h"
111 #include "ui/filters.h"
112 #include "ui/main_statusbar.h"
113 #include "ui/persfilepath_opt.h"
114 #include "ui/preference_utils.h"
115 #include "ui/recent.h"
116 #include "ui/recent_utils.h"
117 #include "ui/software_update.h"
118 #include "ui/ui_util.h"
122 #include "ui/capture_ui_utils.h"
123 #include "ui/capture_globals.h"
124 #include "ui/iface_lists.h"
127 #include "codecs/codecs.h"
129 #include "caputils/capture-pcap-util.h"
132 #include "caputils/capture_ifinfo.h"
133 #include "ui/capture.h"
134 #include <capchild/capture_sync.h>
138 #include "caputils/capture-wpcap.h"
139 #include "caputils/capture_wpcap_packet.h"
140 #include <tchar.h> /* Needed for Unicode */
141 #include <wsutil/os_version_info.h>
142 #include <wsutil/unicode-utils.h>
143 #include <commctrl.h>
144 #include <shellapi.h>
148 #include "ui/gtk/file_dlg.h"
149 #include "ui/gtk/gtkglobals.h"
150 #include "ui/gtk/color_utils.h"
151 #include "ui/gtk/gui_utils.h"
152 #include "ui/gtk/color_dlg.h"
153 #include "ui/gtk/filter_dlg.h"
154 #include "ui/gtk/fileset_dlg.h"
155 #include "ui/gtk/uat_gui.h"
156 #include "ui/gtk/main.h"
157 #include "ui/gtk/main_80211_toolbar.h"
158 #include "ui/gtk/main_airpcap_toolbar.h"
159 #include "ui/gtk/main_filter_toolbar.h"
160 #include "ui/gtk/main_titlebar.h"
161 #include "ui/gtk/menus.h"
162 #include "ui/gtk/main_menubar_private.h"
163 #include "ui/gtk/macros_dlg.h"
164 #include "ui/gtk/main_statusbar_private.h"
165 #include "ui/gtk/main_toolbar.h"
166 #include "ui/gtk/main_toolbar_private.h"
167 #include "ui/gtk/main_welcome.h"
168 #include "ui/gtk/main_welcome_private.h"
169 #include "ui/gtk/drag_and_drop.h"
170 #include "ui/gtk/capture_file_dlg.h"
171 #include "ui/gtk/packet_panes.h"
172 #include "ui/gtk/keys.h"
173 #include "ui/gtk/packet_win.h"
174 #include "ui/gtk/stock_icons.h"
175 #include "ui/gtk/find_dlg.h"
176 #include "ui/gtk/follow_tcp.h"
177 #include "ui/gtk/font_utils.h"
178 #include "ui/gtk/about_dlg.h"
179 #include "ui/gtk/help_dlg.h"
180 #include "ui/gtk/decode_as_dlg.h"
181 #include "ui/gtk/webbrowser.h"
182 #include "ui/gtk/capture_dlg.h"
183 #include "ui/gtk/capture_if_dlg.h"
184 #include "ui/gtk/tap_param_dlg.h"
185 #include "ui/gtk/prefs_column.h"
186 #include "ui/gtk/prefs_dlg.h"
187 #include "ui/gtk/proto_help.h"
188 #include "ui/gtk/packet_list.h"
189 #include "ui/gtk/filter_expression_save_dlg.h"
190 #include "ui/gtk/conversations_table.h"
191 #include "ui/gtk/hostlist_table.h"
192 #include "ui/gtk/service_response_time_table.h"
193 #include "ui/gtk/response_time_delay_table.h"
194 #include "ui/gtk/simple_stattable.h"
195 #include "simple_dialog.h"
196 #ifdef HAVE_GRESOURCE
197 #include "wireshark-gresources.h"
199 #include "ui/gtk/pixbuf-csource.h"
202 #include "ui/gtk/old-gtk-compat.h"
205 #include <caputils/airpcap.h>
206 #include <caputils/airpcap_loader.h>
207 #include "airpcap_dlg.h"
208 #include "airpcap_gui_utils.h"
211 #include <epan/crypt/airpdcap_ws.h>
214 #ifdef HAVE_GTKOSXAPPLICATION
215 #include <gtkmacintegration/gtkosxapplication.h>
219 * Files under personal and global preferences directories in which
220 * GTK settings for Wireshark are stored.
222 #define RC_FILE "gtkrc"
225 capture_options global_capture_opts;
226 capture_session global_capture_session;
231 static gboolean capture_stopping;
233 /* "exported" main widgets */
234 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
236 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
237 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
238 static GtkWidget *main_first_pane, *main_second_pane;
240 /* internally used widgets */
241 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
243 GtkWidget *wireless_tb;
245 int airpcap_dll_ret_val = -1;
248 GString *comp_info_str, *runtime_info_str;
250 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
252 static guint tap_update_timer_id;
254 static void create_main_window(gint, gint, gint, e_prefs*);
255 static void show_main_window(gboolean);
256 static void main_save_window_geometry(GtkWidget *widget);
259 /* Match selected byte pattern */
261 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
263 char *cur_filter, *new_filter;
265 if ((!text) || (0 == strlen(text))) {
266 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
272 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
274 switch (action&MATCH_SELECTED_MASK) {
276 case MATCH_SELECTED_REPLACE:
277 new_filter = g_strdup(text);
280 case MATCH_SELECTED_AND:
281 if ((!cur_filter) || (0 == strlen(cur_filter)))
282 new_filter = g_strdup(text);
284 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
287 case MATCH_SELECTED_OR:
288 if ((!cur_filter) || (0 == strlen(cur_filter)))
289 new_filter = g_strdup(text);
291 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
294 case MATCH_SELECTED_NOT:
295 new_filter = g_strconcat("!(", text, ")", NULL);
298 case MATCH_SELECTED_AND_NOT:
299 if ((!cur_filter) || (0 == strlen(cur_filter)))
300 new_filter = g_strconcat("!(", text, ")", NULL);
302 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
305 case MATCH_SELECTED_OR_NOT:
306 if ((!cur_filter) || (0 == strlen(cur_filter)))
307 new_filter = g_strconcat("!(", text, ")", NULL);
309 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
313 g_assert_not_reached();
318 /* Free up the copy we got of the old filter text. */
321 /* Don't change the current display filter if we only want to copy the filter */
322 if (action&MATCH_SELECTED_COPY_ONLY) {
323 GString *gtk_text_str = g_string_new("");
324 g_string_append(gtk_text_str, new_filter);
325 copy_to_clipboard(gtk_text_str);
326 g_string_free(gtk_text_str, TRUE);
328 /* create a new one and set the display filter entry accordingly */
329 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
331 /* Run the display filter so it goes in effect. */
332 if (action&MATCH_SELECTED_APPLY_NOW)
333 main_filter_packets(&cfile, new_filter, FALSE);
336 /* Free up the new filter text. */
341 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
345 if (cfile.finfo_selected) {
346 filter = proto_construct_match_selected_string(cfile.finfo_selected,
348 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
349 wmem_free(NULL, filter);
354 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
358 if (cfile.finfo_selected) {
359 filter = proto_construct_match_selected_string(cfile.finfo_selected,
361 if ((!filter) || (0 == strlen(filter))) {
362 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
363 "Could not acquire information to build a filter!\n"
364 "Try expanding or choosing another item.");
369 color_display_with_filter(filter);
372 color_filters_reset_tmp();
374 color_filters_set_tmp(filt_nr,filter, FALSE);
376 packet_list_colorize_packets();
378 wmem_free(NULL, filter);
383 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
385 gchar *selected_proto_url;
386 gchar *proto_abbrev = (gchar *)data;
391 if (cfile.finfo_selected) {
392 /* open wiki page using the protocol abbreviation */
393 selected_proto_url = g_strdup_printf("https://wiki.wireshark.org/Protocols/%s", proto_abbrev);
394 browser_open_url(selected_proto_url);
395 g_free(selected_proto_url);
398 case(ESD_BTN_CANCEL):
401 g_assert_not_reached();
407 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
410 const gchar *proto_abbrev;
414 if (cfile.finfo_selected) {
415 /* convert selected field to protocol abbreviation */
416 /* XXX - could this conversion be simplified? */
417 field_id = cfile.finfo_selected->hfinfo->id;
418 /* if the selected field isn't a protocol, get its parent */
419 if(!proto_registrar_is_protocol(field_id)) {
420 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
423 proto_abbrev = proto_registrar_get_abbrev(field_id);
425 /* ask the user if the wiki page really should be opened */
426 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
427 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
429 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
431 "The Wireshark Wiki is a collaborative approach to provide information "
432 "about Wireshark in several ways (not limited to protocol specifics).\n"
434 "This Wiki is new, so the page of the selected protocol "
435 "may not exist and/or may not contain valuable information.\n"
437 "As everyone can edit the Wiki and add new content (or extend existing), "
438 "you are encouraged to add information if you can.\n"
440 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
442 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
443 "which will save you a lot of editing and will give a consistent look over the pages.",
444 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
445 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
449 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
451 gchar *selected_proto_url;
452 gchar *proto_abbrev = (gchar *)data;
456 if (cfile.finfo_selected) {
457 /* open reference page using the protocol abbreviation */
458 selected_proto_url = g_strdup_printf("https://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
459 browser_open_url(selected_proto_url);
460 g_free(selected_proto_url);
463 case(ESD_BTN_CANCEL):
466 g_assert_not_reached();
471 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
474 const gchar *proto_abbrev;
478 if (cfile.finfo_selected) {
479 /* convert selected field to protocol abbreviation */
480 /* XXX - could this conversion be simplified? */
481 field_id = cfile.finfo_selected->hfinfo->id;
482 /* if the selected field isn't a protocol, get its parent */
483 if(!proto_registrar_is_protocol(field_id)) {
484 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
487 proto_abbrev = proto_registrar_get_abbrev(field_id);
489 /* ask the user if the wiki page really should be opened */
490 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
491 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
493 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
495 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
496 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
501 is_address_column (gint column)
503 if (((cfile.cinfo.columns[column].col_fmt == COL_DEF_SRC) ||
504 (cfile.cinfo.columns[column].col_fmt == COL_RES_SRC) ||
505 (cfile.cinfo.columns[column].col_fmt == COL_DEF_DST) ||
506 (cfile.cinfo.columns[column].col_fmt == COL_RES_DST)) &&
507 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
516 get_ip_address_list_from_packet_list_row(gpointer data)
518 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
519 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
522 GList *addr_list = NULL;
524 fdata = (frame_data *) packet_list_get_row_data(row);
529 if (!cf_read_record(&cfile, fdata))
530 return NULL; /* error reading the frame */
532 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
533 col_custom_prime_edt(&edt, &cfile.cinfo);
535 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
536 frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
537 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
539 /* First check selected column */
540 if (is_address_column (column)) {
541 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
544 for (col = 0; col < cfile.cinfo.num_cols; col++) {
545 /* Then check all columns except the selected */
546 if ((col != column) && (is_address_column (col))) {
547 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
551 epan_dissect_cleanup(&edt);
558 get_filter_from_packet_list_row_and_column(gpointer data)
560 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
561 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
565 fdata = (frame_data *) packet_list_get_row_data(row);
570 if (!cf_read_record(&cfile, fdata))
571 return NULL; /* error reading the record */
572 /* proto tree, visible. We need a proto tree if there's custom columns */
573 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
574 col_custom_prime_edt(&edt, &cfile.cinfo);
576 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
577 frame_tvbuff_new_buffer(fdata, &cfile.buf),
578 fdata, &cfile.cinfo);
579 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
581 if ((cfile.cinfo.columns[column].col_custom_occurrence) ||
582 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
584 /* Only construct the filter when a single occurrence is displayed
585 * otherwise we might end up with a filter like "ip.proto==1,6".
587 * Or do we want to be able to filter on multiple occurrences so that
588 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
591 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
592 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
593 /* leak a little; is there a safe wmem_ scope here? */
594 if (cfile.cinfo.columns[column].col_fmt == COL_CUSTOM) {
595 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.columns[column].col_custom_field);
596 if (hfi && hfi->parent == -1) {
598 buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
599 } else if (hfi && IS_FT_STRING(hfi->type)) {
600 /* Custom string, add quotes */
601 buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
602 cfile.cinfo.col_expr.col_expr_val[column]);
606 buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
607 cfile.cinfo.col_expr.col_expr_val[column]);
612 epan_dissect_cleanup(&edt);
619 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
623 filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
625 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
631 /* This function allows users to right click in the details window and copy the text
632 * information to the operating systems clipboard.
634 * We first check to see if a string representation is setup in the tree and then
635 * read the string. If not available then we try to grab the value. If all else
636 * fails we display a message to the user to indicate the copy could not be completed.
639 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
641 GString *gtk_text_str = g_string_new("");
642 char labelstring[ITEM_LABEL_LENGTH];
643 char *stringpointer = labelstring;
647 case COPY_SELECTED_DESCRIPTION:
648 if (cfile.finfo_selected->rep &&
649 strlen (cfile.finfo_selected->rep->representation) > 0) {
650 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
653 case COPY_SELECTED_FIELDNAME:
654 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
655 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
658 case COPY_SELECTED_VALUE:
659 if (cfile.edt !=0 ) {
660 gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
661 g_string_append(gtk_text_str, field_str);
669 if (gtk_text_str->len == 0) {
670 /* If no representation then... Try to read the value */
671 proto_item_fill_label(cfile.finfo_selected, stringpointer);
672 g_string_append(gtk_text_str, stringpointer);
675 if (gtk_text_str->len == 0) {
676 /* Could not get item so display error msg */
677 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
679 /* Copy string to clipboard */
680 copy_to_clipboard(gtk_text_str);
682 g_string_free(gtk_text_str, TRUE); /* Free the memory */
686 /* mark as reference time frame */
688 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
692 frame->flags.ref_time=1;
693 cfile.ref_time_count++;
695 frame->flags.ref_time=0;
696 cfile.ref_time_count--;
698 cf_reftime_packets(&cfile);
699 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
700 packet_list_freeze();
701 cfile.displayed_count--;
702 packet_list_recreate_visible_rows();
705 packet_list_queue_draw();
709 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
713 timestamp_set_type(TS_RELATIVE);
714 recent.gui_time_format = TS_RELATIVE;
715 cf_timestamp_auto_precision(&cfile);
716 packet_list_queue_draw();
721 g_assert_not_reached();
724 if (cfile.current_frame) {
725 set_frame_reftime(!cfile.current_frame->flags.ref_time,
726 cfile.current_frame, cfile.current_row);
732 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
734 static GtkWidget *reftime_dialog = NULL;
738 if (cfile.current_frame) {
739 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
740 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
741 "%sSwitch to the appropriate Time Display Format?%s\n\n"
742 "Time References don't work well with the currently selected Time Display Format.\n\n"
743 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
744 simple_dialog_primary_start(), simple_dialog_primary_end());
745 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
747 set_frame_reftime(!cfile.current_frame->flags.ref_time,
748 cfile.current_frame, cfile.current_row);
752 case REFTIME_FIND_NEXT:
753 cf_find_packet_time_reference(&cfile, SD_FORWARD);
755 case REFTIME_FIND_PREV:
756 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
762 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
764 cf_find_packet_marked(&cfile, SD_FORWARD);
768 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
770 cf_find_packet_marked(&cfile, SD_BACKWARD);
774 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
777 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
779 gboolean has_blurb = FALSE;
780 guint length = 0, byte_len;
781 GtkWidget *byte_view;
782 const guint8 *byte_data;
787 /* if nothing is selected */
788 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
791 * Which byte view is displaying the current protocol tree
794 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
795 if (byte_view == NULL)
798 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
799 if (byte_data == NULL)
802 cf_unselect_field(&cfile);
803 packet_hex_print(byte_view, byte_data,
804 cfile.current_frame, NULL, byte_len);
805 proto_help_menu_modify(sel, &cfile);
808 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
811 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
813 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
814 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
815 g_assert(byte_data != NULL);
817 cfile.finfo_selected = finfo;
818 set_menus_for_selected_tree_row(&cfile);
821 if (finfo->hfinfo->blurb != NULL &&
822 finfo->hfinfo->blurb[0] != '\0') {
824 length = (guint) strlen(finfo->hfinfo->blurb);
826 length = (guint) strlen(finfo->hfinfo->name);
828 finfo_length = finfo->length + finfo->appendix_length;
830 if (finfo_length == 0) {
832 } else if (finfo_length == 1) {
833 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
835 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
837 statusbar_pop_field_msg(); /* get rid of current help msg */
839 statusbar_push_field_msg(" %s (%s)%s",
840 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
841 finfo->hfinfo->abbrev, len_str);
844 * Don't show anything if the field name is zero-length;
845 * the pseudo-field for text-only items is such
846 * a field, and we don't want "Text (text)" showing up
847 * on the status line if you've selected such a field.
849 * XXX - there are zero-length fields for which we *do*
850 * want to show the field name.
852 * XXX - perhaps the name and abbrev field should be null
853 * pointers rather than null strings for that pseudo-field,
854 * but we'd have to add checks for null pointers in some
855 * places if we did that.
857 * Or perhaps text-only items should have -1 as the field
858 * index, with no pseudo-field being used, but that might
859 * also require special checks for -1 to be added.
861 statusbar_push_field_msg("%s", "");
864 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
866 proto_help_menu_modify(sel, &cfile);
869 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
872 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
875 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
878 expand_all_tree(cfile.edt->tree, tree_view_gbl);
881 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
883 if (cfile.finfo_selected) {
884 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
885 cfile.finfo_selected->hfinfo->abbrev,0);
886 /* Recreate the packet list according to new preferences */
887 packet_list_recreate ();
888 if (!prefs.gui_use_pref_save) {
891 cfile.columns_changed = FALSE; /* Reset value */
895 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
899 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
901 /* the mouse position is at an entry, expand that one */
902 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
903 gtk_tree_path_free(path);
907 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
911 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
913 /* the mouse position is at an entry, expand that one */
915 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
916 gtk_tree_path_free(path);
920 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
922 static const e_addr_resolve resolv_flags = {
924 TRUE, /* network_name */
925 TRUE, /* transport_name */
926 TRUE, /* concurrent_dns */
927 TRUE, /* dns_pkt_addr_resolution */
928 TRUE, /* use_external_net_name_resolver */
929 FALSE /* load_hosts_file_from_profile_only */
932 if (cfile.edt->tree) {
933 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
937 /* Update main window items based on whether there's a capture in progress. */
939 main_set_for_capture_in_progress(gboolean capture_in_progress)
941 set_menus_for_capture_in_progress(capture_in_progress);
944 set_toolbar_for_capture_in_progress(capture_in_progress);
946 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
950 /* Update main window items based on whether we have a capture file. */
952 main_set_for_capture_file(gboolean have_capture_file_in)
954 have_capture_file = have_capture_file_in;
956 main_widgets_show_or_hide();
959 /* Update main window items based on whether we have captured packets. */
961 main_set_for_captured_packets(gboolean have_captured_packets)
963 set_menus_for_captured_packets(have_captured_packets);
964 set_toolbar_for_captured_packets(have_captured_packets);
967 /* Update main window items based on whether we have a packet history. */
969 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
971 set_menus_for_packet_history(back_history, forward_history);
972 set_toolbar_for_packet_history(back_history, forward_history);
978 /* get the current geometry, before writing it to disk */
979 main_save_window_geometry(top_level);
981 /* write user's recent file to disk
982 * It is no problem to write this file, even if we do not quit */
983 write_profile_recent();
986 /* XXX - should we check whether the capture file is an
987 unsaved temporary file for a live capture and, if so,
988 pop up a "do you want to exit without saving the capture
989 file?" dialog, and then just return, leaving said dialog
990 box to forcibly quit if the user clicks "OK"?
992 If so, note that this should be done in a subroutine that
993 returns TRUE if we do so, and FALSE otherwise, and if it
994 returns TRUE we should return TRUE without nuking anything.
996 Note that, if we do that, we might also want to check if
997 an "Update list of packets in real time" capture is in
998 progress and, if so, ask whether they want to terminate
999 the capture and discard it, and return TRUE, before nuking
1000 any child capture, if they say they don't want to do so. */
1003 /* Nuke any child capture in progress. */
1004 capture_kill_child(&global_capture_session);
1007 /* Are we in the middle of reading a capture? */
1008 if (cfile.state == FILE_READ_IN_PROGRESS) {
1009 /* Yes, so we can't just close the file and quit, as
1010 that may yank the rug out from under the read in
1011 progress; instead, just set the state to
1012 "FILE_READ_ABORTED" and return - the code doing the read
1013 will check for that and, if it sees that, will clean
1015 cfile.state = FILE_READ_ABORTED;
1017 /* Say that the window should *not* be deleted;
1018 that'll be done by the code that cleans up. */
1021 /* Close any capture file we have open; on some OSes, you
1022 can't unlink a temporary capture file if you have it
1024 "cf_close()" will unlink it after closing it if
1025 it's a temporary file.
1027 We do this here, rather than after the main loop returns,
1028 as, after the main loop returns, the main window may have
1029 been destroyed (if this is called due to a "destroy"
1030 even on the main window rather than due to the user
1031 selecting a menu item), and there may be a crash
1032 or other problem when "cf_close()" tries to
1033 clean up stuff in the main window.
1035 XXX - is there a better place to put this?
1036 Or should we have a routine that *just* closes the
1037 capture file, and doesn't do anything with the UI,
1038 which we'd call here, and another routine that
1039 calls that routine and also cleans up the UI, which
1040 we'd call elsewhere? */
1043 /* Exit by leaving the main loop, so that any quit functions
1044 we registered get called. */
1047 /* Say that the window should be deleted. */
1053 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1055 /* If we're in the middle of stopping a capture, don't do anything;
1056 the user can try deleting the window after the capture stops. */
1057 if (capture_stopping)
1060 /* If there's unsaved data, let the user save it first.
1061 If they cancel out of it, don't quit. */
1062 if (do_file_close(&cfile, TRUE, " before quitting"))
1063 return main_do_quit();
1065 return TRUE; /* will this keep the window from being deleted? */
1070 main_pane_load_window_geometry(void)
1072 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1073 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1074 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1075 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1081 main_load_window_geometry(GtkWidget *widget)
1083 window_geometry_t geom;
1085 geom.set_pos = prefs.gui_geometry_save_position;
1086 geom.x = recent.gui_geometry_main_x;
1087 geom.y = recent.gui_geometry_main_y;
1088 geom.set_size = prefs.gui_geometry_save_size;
1089 if (recent.gui_geometry_main_width > 0 &&
1090 recent.gui_geometry_main_height > 0) {
1091 geom.width = recent.gui_geometry_main_width;
1092 geom.height = recent.gui_geometry_main_height;
1093 geom.set_maximized = prefs.gui_geometry_save_maximized;
1095 /* We assume this means the width and height weren't set in
1096 the "recent" file (or that there is no "recent" file),
1097 and weren't set to a default value, so we don't set the
1098 size. (The "recent" file code rejects non-positive width
1099 and height values.) */
1100 geom.set_size = FALSE;
1102 geom.maximized = recent.gui_geometry_main_maximized;
1104 window_set_geometry(widget, &geom);
1106 main_pane_load_window_geometry();
1107 statusbar_load_window_geometry();
1112 main_save_window_geometry(GtkWidget *widget)
1114 window_geometry_t geom;
1116 window_get_geometry(widget, &geom);
1118 if (prefs.gui_geometry_save_position) {
1119 recent.gui_geometry_main_x = geom.x;
1120 recent.gui_geometry_main_y = geom.y;
1123 if (prefs.gui_geometry_save_size) {
1124 recent.gui_geometry_main_width = geom.width;
1125 recent.gui_geometry_main_height = geom.height;
1128 if(prefs.gui_geometry_save_maximized) {
1129 recent.gui_geometry_main_maximized = geom.maximized;
1132 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1133 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1134 statusbar_save_window_geometry();
1138 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1140 /* If there's unsaved data, let the user save it first. */
1141 if (do_file_close(&cfile, TRUE, " before quitting"))
1146 print_usage(gboolean for_help_option) {
1154 if (for_help_option) {
1156 fprintf(output, "Wireshark %s\n"
1157 "Interactively dump and analyze network traffic.\n"
1158 "See https://www.wireshark.org for more information.\n",
1159 get_ws_vcs_version_info());
1163 fprintf(output, "\n");
1164 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1165 fprintf(output, "\n");
1168 fprintf(output, "Capture interface:\n");
1169 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1170 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1171 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1172 fprintf(output, " -p don't capture in promiscuous mode\n");
1173 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1174 fprintf(output, " -S update packet display when new packets are captured\n");
1175 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1176 #ifdef HAVE_PCAP_CREATE
1177 fprintf(output, " -I capture in monitor mode, if available\n");
1179 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
1180 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1182 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1183 fprintf(output, " -D print list of interfaces and exit\n");
1184 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1185 fprintf(output, "\n");
1186 fprintf(output, "Capture stop conditions:\n");
1187 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1188 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1189 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1190 fprintf(output, " files:NUM - stop after NUM files\n");
1191 /*fprintf(output, "\n");*/
1192 fprintf(output, "Capture output:\n");
1193 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1194 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1195 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1196 #endif /* HAVE_LIBPCAP */
1197 #ifdef HAVE_PCAP_REMOTE
1198 fprintf(output, "RPCAP options:\n");
1199 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1201 /*fprintf(output, "\n");*/
1202 fprintf(output, "Input file:\n");
1203 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1205 fprintf(output, "\n");
1206 fprintf(output, "Processing:\n");
1207 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1208 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1209 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtCd\"\n");
1210 fprintf(output, " --disable-protocol <proto_name>\n");
1211 fprintf(output, " disable dissection of proto_name\n");
1212 fprintf(output, " --enable-heuristic <short_name>\n");
1213 fprintf(output, " enable dissection of heuristic protocol\n");
1214 fprintf(output, " --disable-heuristic <short_name>\n");
1215 fprintf(output, " disable dissection of heuristic protocol\n");
1217 fprintf(output, "\n");
1218 fprintf(output, "User interface:\n");
1219 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1220 fprintf(output, " -Y <display filter> start with the given display filter\n");
1221 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1222 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1223 fprintf(output, " filter\n");
1224 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1225 fprintf(output, " -m <font> set the font name used for most text\n");
1226 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
1227 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1228 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1229 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1231 fprintf(output, "\n");
1232 fprintf(output, "Output:\n");
1233 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1235 fprintf(output, "\n");
1236 fprintf(output, "Miscellaneous:\n");
1237 fprintf(output, " -h display this help and exit\n");
1238 fprintf(output, " -v display version info and exit\n");
1239 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1240 fprintf(output, " persdata:path - personal data files\n");
1241 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1242 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1244 fprintf(output, " --display=DISPLAY X display to use\n");
1253 * Report an error in command-line arguments.
1254 * Creates a console on Windows.
1255 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1256 * terminal isn't the standard error?
1259 wireshark_cmdarg_err(const char *fmt, va_list ap)
1264 fprintf(stderr, "wireshark: ");
1265 vfprintf(stderr, fmt, ap);
1266 fprintf(stderr, "\n");
1270 * Report additional information for an error in command-line arguments.
1271 * Creates a console on Windows.
1272 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1273 * terminal isn't the standard error?
1276 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1281 vfprintf(stderr, fmt, ap);
1282 fprintf(stderr, "\n");
1286 Once every 3 seconds we get a callback here which we use to update
1290 tap_update_cb(gpointer data _U_)
1292 draw_tap_listeners(FALSE);
1297 * Periodically process outstanding hostname lookups. If we have new items,
1298 * redraw the packet list and tree view.
1302 resolv_update_cb(gpointer data _U_)
1304 /* Anything new show up? */
1305 if (host_name_lookup_process()) {
1306 if (gtk_widget_get_window(pkt_scrollw))
1307 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1308 if (gtk_widget_get_window(tv_scrollw))
1309 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1312 /* Always check. Even if we don't do async lookups we could still get
1313 passive updates, e.g. from DNS packets. */
1318 /* Update various parts of the main window for a capture file "unsaved
1319 changes" change - update the title to reflect whether there are
1320 unsaved changes or not, and update the menus and toolbar to
1321 enable or disable the "Save" operation. */
1323 main_update_for_unsaved_changes(capture_file *cf)
1325 set_titlebar_for_capture_file(cf);
1326 set_menus_for_capture_file(cf);
1327 set_toolbar_for_capture_file(cf);
1332 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1334 /* Update menubar and toolbar */
1335 menu_auto_scroll_live_changed(auto_scroll_live_in);
1336 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1338 /* change auto scroll state */
1339 auto_scroll_live = auto_scroll_live_in;
1344 main_colorize_changed(gboolean packet_list_colorize)
1346 /* Update menubar and toolbar */
1347 menu_colorize_changed(packet_list_colorize);
1348 toolbar_colorize_changed(packet_list_colorize);
1350 /* change colorization */
1351 if(packet_list_colorize != recent.packet_list_colorize) {
1352 recent.packet_list_colorize = packet_list_colorize;
1353 color_filters_enable(packet_list_colorize);
1354 packet_list_colorize_packets();
1358 static GtkWidget *close_dlg = NULL;
1361 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1363 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1368 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1370 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1375 main_cf_cb_file_closing(capture_file *cf)
1377 /* if we have more than 10000 packets, show a splash screen while closing */
1378 /* XXX - don't know a better way to decide whether to show or not,
1379 * as most of the time is spend in various calls that destroy various
1380 * data structures, so it wouldn't be easy to use a progress bar,
1381 * rather than, say, a progress spinner, here! */
1382 if(cf->count > 10000) {
1383 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1384 "%sClosing file!%s\n\nPlease wait ...",
1385 simple_dialog_primary_start(),
1386 simple_dialog_primary_end());
1387 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1389 /* Clear maunally resolved addresses */
1390 manually_resolve_cleanup();
1391 /* Destroy all windows that refer to the
1392 capture file we're closing. */
1393 destroy_packet_wins();
1395 /* Update the titlebar to reflect the lack of a capture file. */
1396 set_titlebar_for_capture_file(NULL);
1398 /* Disable all menu and toolbar items that make sense only if
1399 you have a capture. */
1400 set_menus_for_capture_file(NULL);
1401 set_toolbar_for_capture_file(NULL);
1402 main_set_for_captured_packets(FALSE);
1403 set_menus_for_selected_packet(cf);
1404 main_set_for_capture_in_progress(FALSE);
1405 set_capture_if_dialog_for_capture_in_progress(FALSE);
1406 set_menus_for_selected_tree_row(cf);
1408 /* Set up main window for no capture file. */
1409 main_set_for_capture_file(FALSE);
1411 main_window_update();
1416 main_cf_cb_file_closed(capture_file *cf _U_)
1418 if(close_dlg != NULL) {
1419 splash_destroy(close_dlg);
1426 main_cf_cb_file_read_started(capture_file *cf _U_)
1428 tap_param_dlg_update();
1430 /* Set up main window for a capture file. */
1431 main_set_for_capture_file(TRUE);
1435 main_cf_cb_file_read_finished(capture_file *cf)
1439 if (!cf->is_tempfile && cf->filename) {
1440 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1441 add_menu_recent_capture_file(cf->filename);
1443 /* Remember folder for next Open dialog and save it in recent */
1444 dir_path = get_dirname(g_strdup(cf->filename));
1445 set_last_open_dir(dir_path);
1449 /* Update the appropriate parts of the main window. */
1450 main_update_for_unsaved_changes(cf);
1452 /* Enable menu items that make sense if you have some captured packets. */
1453 main_set_for_captured_packets(TRUE);
1457 main_cf_cb_file_rescan_finished(capture_file *cf)
1461 if (!cf->is_tempfile && cf->filename) {
1462 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1463 add_menu_recent_capture_file(cf->filename);
1465 /* Remember folder for next Open dialog and save it in recent */
1466 dir_path = get_dirname(g_strdup(cf->filename));
1467 set_last_open_dir(dir_path);
1471 /* Update the appropriate parts of the main window. */
1472 main_update_for_unsaved_changes(cf);
1476 static GList *icon_list_create(
1477 #ifdef HAVE_GRESOURCE
1478 const gchar *icon16_path,
1479 const gchar *icon32_path,
1480 const gchar *icon48_path,
1481 const gchar *icon64_path)
1483 const guint8 *icon16_pb,
1484 const guint8 *icon32_pb,
1485 const guint8 *icon48_pb,
1486 const guint8 *icon64_pb)
1489 GList *icon_list = NULL;
1490 GdkPixbuf *pixbuf16 = NULL;
1491 GdkPixbuf *pixbuf32 = NULL;
1492 GdkPixbuf *pixbuf48 = NULL;
1493 GdkPixbuf *pixbuf64 = NULL;
1495 #ifdef HAVE_GRESOURCE
1496 if (icon16_path != NULL)
1497 pixbuf16 = ws_gdk_pixbuf_new_from_resource(icon16_path);
1498 if (icon32_path != NULL)
1499 pixbuf32 = ws_gdk_pixbuf_new_from_resource(icon32_path);
1500 if (icon48_path != NULL)
1501 pixbuf48 = ws_gdk_pixbuf_new_from_resource(icon48_path);
1502 if (icon64_path != NULL)
1503 pixbuf64 = ws_gdk_pixbuf_new_from_resource(icon64_path);
1505 if (icon16_pb != NULL)
1506 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1507 if (icon32_pb != NULL)
1508 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1509 if (icon48_pb != NULL)
1510 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1511 if (icon64_pb != NULL)
1512 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1515 if (pixbuf16 != NULL)
1516 icon_list = g_list_append(icon_list, pixbuf16);
1517 if (pixbuf32 != NULL)
1518 icon_list = g_list_append(icon_list, pixbuf32);
1519 if (pixbuf48 != NULL)
1520 icon_list = g_list_append(icon_list, pixbuf48);
1521 if (pixbuf64 != NULL)
1522 icon_list = g_list_append(icon_list, pixbuf64);
1528 main_capture_cb_capture_prepared(capture_session *cap_session)
1530 static GList *icon_list = NULL;
1532 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1534 if(icon_list == NULL) {
1535 #ifdef HAVE_GRESOURCE
1536 icon_list = icon_list_create("/org/wireshark/image/wsiconcap16.png",
1537 "/org/wireshark/image/wsiconcap32.png",
1538 "/org/wireshark/image/wsiconcap48.png",
1539 "/org/wireshark/image/wsiconcap64.png");
1541 icon_list = icon_list_create(wsiconcap_16_pb_data,
1542 wsiconcap_32_pb_data,
1543 wsiconcap_48_pb_data,
1544 wsiconcap_64_pb_data);
1547 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1549 /* Disable menu items that make no sense if you're currently running
1551 main_set_for_capture_in_progress(TRUE);
1552 set_capture_if_dialog_for_capture_in_progress(TRUE);
1554 /* Don't set up main window for a capture file. */
1555 main_set_for_capture_file(FALSE);
1559 main_capture_cb_capture_update_started(capture_session *cap_session)
1561 /* We've done this in "prepared" above, but it will be cleared while
1562 switching to the next multiple file. */
1563 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1565 main_set_for_capture_in_progress(TRUE);
1566 set_capture_if_dialog_for_capture_in_progress(TRUE);
1568 /* Enable menu items that make sense if you have some captured
1569 packets (yes, I know, we don't have any *yet*). */
1570 main_set_for_captured_packets(TRUE);
1572 /* Set up main window for a capture file. */
1573 main_set_for_capture_file(TRUE);
1577 main_capture_cb_capture_update_finished(capture_session *cap_session)
1579 capture_file *cf = (capture_file *)cap_session->cf;
1580 static GList *icon_list = NULL;
1582 /* The capture isn't stopping any more - it's stopped. */
1583 capture_stopping = FALSE;
1585 if (!cf->is_tempfile && cf->filename) {
1586 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1587 add_menu_recent_capture_file(cf->filename);
1590 /* Enable menu items that make sense if you're not currently running
1592 main_set_for_capture_in_progress(FALSE);
1593 set_capture_if_dialog_for_capture_in_progress(FALSE);
1595 /* Update the main window as appropriate. This has to occur AFTER
1596 * main_set_for_capture_in_progress() or else some of the menus are
1597 * incorrectly disabled (see bug
1598 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1599 main_update_for_unsaved_changes(cf);
1601 /* Set up main window for a capture file. */
1602 main_set_for_capture_file(TRUE);
1604 if(icon_list == NULL) {
1605 #ifdef HAVE_GRESOURCE
1606 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1607 "/org/wireshark/image/wsicon32.png",
1608 "/org/wireshark/image/wsicon48.png",
1609 "/org/wireshark/image/wsicon64.png");
1611 icon_list = icon_list_create(wsicon_16_pb_data,
1617 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1619 if(global_capture_opts.quit_after_cap) {
1620 /* command line asked us to quit after the capture */
1621 /* don't pop up a dialog to ask for unsaved files etc. */
1627 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1629 /* Don't set up main window for a capture file. */
1630 main_set_for_capture_file(FALSE);
1634 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1637 capture_file *cf = (capture_file *)cap_session->cf;
1639 static GList *icon_list = NULL;
1641 /* The capture isn't stopping any more - it's stopped. */
1642 capture_stopping = FALSE;
1644 /*set_titlebar_for_capture_file(cf);*/
1646 /* Enable menu items that make sense if you're not currently running
1648 main_set_for_capture_in_progress(FALSE);
1649 set_capture_if_dialog_for_capture_in_progress(FALSE);
1651 /* Restore the standard title bar message */
1652 /* (just in case we have trouble opening the capture file). */
1653 set_titlebar_for_capture_file(NULL);
1655 if(icon_list == NULL) {
1656 #ifdef HAVE_GRESOURCE
1657 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1658 "/org/wireshark/image/wsicon32.png",
1659 "/org/wireshark/image/wsicon48.png",
1660 "/org/wireshark/image/wsicon64.png");
1662 icon_list = icon_list_create(wsicon_16_pb_data,
1668 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1670 /* We don't have loaded the capture file, this will be done later.
1671 * For now we still have simply a blank screen. */
1673 if(global_capture_opts.quit_after_cap) {
1674 /* command line asked us to quit after the capture */
1675 /* don't pop up a dialog to ask for unsaved files etc. */
1681 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1683 capture_stopping = TRUE;
1684 set_menus_for_capture_stopping();
1686 set_toolbar_for_capture_stopping();
1688 set_capture_if_dialog_for_capture_stopping();
1693 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1695 static GList *icon_list = NULL;
1697 /* Capture isn't stopping any more. */
1698 capture_stopping = FALSE;
1700 /* the capture failed before the first packet was captured
1701 reset title, menus and icon */
1702 set_titlebar_for_capture_file(NULL);
1704 main_set_for_capture_in_progress(FALSE);
1705 set_capture_if_dialog_for_capture_in_progress(FALSE);
1707 main_set_for_capture_file(FALSE);
1709 if(icon_list == NULL) {
1710 #ifdef HAVE_GRESOURCE
1711 icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1712 "/org/wireshark/image/wsicon32.png",
1713 "/org/wireshark/image/wsicon48.png",
1714 "/org/wireshark/image/wsicon64.png");
1716 icon_list = icon_list_create(wsicon_16_pb_data,
1722 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1725 if(global_capture_opts.quit_after_cap) {
1726 /* command line asked us to quit after the capture */
1727 /* don't pop up a dialog to ask for unsaved files etc. */
1731 #endif /* HAVE_LIBPCAP */
1734 main_cf_cb_packet_selected(gpointer data)
1736 capture_file *cf = (capture_file *)data;
1738 /* Display the GUI protocol tree and packet bytes.
1739 XXX - why do we dump core if we call "proto_tree_draw()"
1740 before calling "add_byte_views()"? */
1741 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1742 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1744 /* Note: Both string and hex value searches in the packet data produce a non-zero
1745 search_pos if successful */
1746 if(cf->search_in_progress &&
1747 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1748 highlight_field(cf->edt->tvb, cf->search_pos,
1749 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1752 /* A packet is selected. */
1753 set_menus_for_selected_packet(cf);
1757 main_cf_cb_packet_unselected(capture_file *cf)
1759 /* No packet is being displayed; clear the hex dump pane by getting
1760 rid of all the byte views. */
1761 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1762 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1764 /* Add a placeholder byte view so that there's at least something
1765 displayed in the byte view notebook. */
1766 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1768 /* And clear the protocol tree display as well. */
1769 proto_tree_draw(NULL, tree_view_gbl);
1771 /* No packet is selected. */
1772 set_menus_for_selected_packet(cf);
1776 main_cf_cb_field_unselected(capture_file *cf)
1778 set_menus_for_selected_tree_row(cf);
1782 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1784 capture_file *cf = (capture_file *)data;
1786 case(cf_cb_file_opened):
1787 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1788 fileset_file_opened(cf);
1790 case(cf_cb_file_closing):
1791 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1792 main_cf_cb_file_closing(cf);
1794 case(cf_cb_file_closed):
1795 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1796 main_cf_cb_file_closed(cf);
1797 fileset_file_closed();
1799 case(cf_cb_file_read_started):
1800 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1801 main_cf_cb_file_read_started(cf);
1803 case(cf_cb_file_read_finished):
1804 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1805 main_cf_cb_file_read_finished(cf);
1807 case(cf_cb_file_reload_started):
1808 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1809 main_cf_cb_file_read_started(cf);
1811 case(cf_cb_file_reload_finished):
1812 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1813 main_cf_cb_file_read_finished(cf);
1815 case(cf_cb_file_rescan_started):
1816 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1818 case(cf_cb_file_rescan_finished):
1819 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1820 main_cf_cb_file_rescan_finished(cf);
1822 case(cf_cb_file_retap_started):
1823 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap started");
1825 case(cf_cb_file_retap_finished):
1826 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap finished");
1828 case(cf_cb_file_fast_save_finished):
1829 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1830 main_cf_cb_file_rescan_finished(cf);
1832 case(cf_cb_packet_selected):
1833 main_cf_cb_packet_selected(cf);
1835 case(cf_cb_packet_unselected):
1836 main_cf_cb_packet_unselected(cf);
1838 case(cf_cb_field_unselected):
1839 main_cf_cb_field_unselected(cf);
1841 case(cf_cb_file_save_started):
1842 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1844 case(cf_cb_file_save_finished):
1845 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1847 case(cf_cb_file_save_failed):
1848 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1850 case(cf_cb_file_save_stopped):
1851 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1853 case(cf_cb_file_export_specified_packets_started):
1854 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1856 case(cf_cb_file_export_specified_packets_finished):
1857 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1859 case(cf_cb_file_export_specified_packets_failed):
1860 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1862 case(cf_cb_file_export_specified_packets_stopped):
1863 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1866 g_warning("main_cf_callback: event %u unknown", event);
1867 g_assert_not_reached();
1873 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1875 #ifdef HAVE_GTKOSXAPPLICATION
1876 GtkosxApplication *theApp;
1879 case(capture_cb_capture_prepared):
1880 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1881 main_capture_cb_capture_prepared(cap_session);
1883 case(capture_cb_capture_update_started):
1884 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1885 main_capture_cb_capture_update_started(cap_session);
1886 #ifdef HAVE_GTKOSXAPPLICATION
1887 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1888 #ifdef HAVE_GRESOURCE
1889 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon48.png"));
1891 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_48_pb_data, FALSE, NULL));
1895 case(capture_cb_capture_update_continue):
1896 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1898 case(capture_cb_capture_update_finished):
1899 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1900 main_capture_cb_capture_update_finished(cap_session);
1902 case(capture_cb_capture_fixed_started):
1903 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1904 main_capture_cb_capture_fixed_started(cap_session);
1906 case(capture_cb_capture_fixed_continue):
1907 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1909 case(capture_cb_capture_fixed_finished):
1910 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1911 main_capture_cb_capture_fixed_finished(cap_session);
1913 case(capture_cb_capture_stopping):
1914 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1915 /* Beware: this state won't be called, if the capture child
1916 * closes the capturing on its own! */
1917 #ifdef HAVE_GTKOSXAPPLICATION
1918 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1919 #ifdef HAVE_GRESOURCE
1920 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
1922 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1925 main_capture_cb_capture_stopping(cap_session);
1927 case(capture_cb_capture_failed):
1928 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1929 main_capture_cb_capture_failed(cap_session);
1932 g_warning("main_capture_callback: event %u unknown", event);
1933 g_assert_not_reached();
1939 get_wireshark_gtk_compiled_info(GString *str)
1941 g_string_append(str, "with ");
1942 g_string_append_printf(str,
1943 #ifdef GTK_MAJOR_VERSION
1944 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1947 "GTK+ (version unknown)");
1951 g_string_append(str, ", with Cairo ");
1952 g_string_append(str, CAIRO_VERSION_STRING);
1955 g_string_append(str, ", with Pango ");
1956 g_string_append(str, PANGO_VERSION_STRING);
1958 /* Capture libraries */
1959 g_string_append(str, ", ");
1960 get_compiled_caplibs_version(str);
1963 g_string_append(str, ", ");
1965 g_string_append(str, "with libz ");
1967 g_string_append(str, ZLIB_VERSION);
1968 #else /* ZLIB_VERSION */
1969 g_string_append(str, "(version unknown)");
1970 #endif /* ZLIB_VERSION */
1971 #else /* HAVE_LIBZ */
1972 g_string_append(str, "without libz");
1973 #endif /* HAVE_LIBZ */
1977 get_gui_compiled_info(GString *str)
1979 epan_get_compiled_version_info(str);
1981 g_string_append(str, ", ");
1982 #ifdef HAVE_LIBPORTAUDIO
1983 #ifdef PORTAUDIO_API_1
1984 g_string_append(str, "with PortAudio <= V18");
1985 #else /* PORTAUDIO_API_1 */
1986 g_string_append(str, "with ");
1987 g_string_append(str, Pa_GetVersionText());
1988 #endif /* PORTAUDIO_API_1 */
1989 #else /* HAVE_LIBPORTAUDIO */
1990 g_string_append(str, "without PortAudio");
1991 #endif /* HAVE_LIBPORTAUDIO */
1993 g_string_append(str, ", ");
1995 get_compiled_airpcap_version(str);
1997 g_string_append(str, "without AirPcap");
2002 get_wireshark_runtime_info(GString *str)
2005 /* Capture libraries */
2006 g_string_append(str, ", ");
2007 get_runtime_caplibs_version(str);
2011 #if defined(HAVE_LIBZ) && !defined(_WIN32)
2012 g_string_append_printf(str, ", with libz %s", zlibVersion());
2015 /* stuff used by libwireshark */
2016 epan_get_runtime_version_info(str);
2019 g_string_append(str, ", ");
2020 get_runtime_airpcap_version(str);
2024 g_string_append(str, ", ");
2025 u3_runtime_info(str);
2030 read_configuration_files(char **gdp_path, char **dp_path)
2032 int gpf_open_errno, gpf_read_errno;
2033 int cf_open_errno, df_open_errno;
2034 int gdp_open_errno, gdp_read_errno;
2035 int dp_open_errno, dp_read_errno;
2036 char *gpf_path, *pf_path;
2037 char *cf_path, *df_path;
2038 int pf_open_errno, pf_read_errno;
2041 /* load the decode as entries of this profile */
2042 load_decode_as_entries();
2044 /* Read the preference files. */
2045 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2046 &pf_open_errno, &pf_read_errno, &pf_path);
2048 if (gpf_path != NULL) {
2049 if (gpf_open_errno != 0) {
2050 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2051 "Could not open global preferences file\n\"%s\": %s.",
2052 gpf_path, g_strerror(gpf_open_errno));
2054 if (gpf_read_errno != 0) {
2055 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2056 "I/O error reading global preferences file\n\"%s\": %s.",
2057 gpf_path, g_strerror(gpf_read_errno));
2060 if (pf_path != NULL) {
2061 if (pf_open_errno != 0) {
2062 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2063 "Could not open your preferences file\n\"%s\": %s.",
2064 pf_path, g_strerror(pf_open_errno));
2066 if (pf_read_errno != 0) {
2067 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2068 "I/O error reading your preferences file\n\"%s\": %s.",
2069 pf_path, g_strerror(pf_read_errno));
2076 /* if the user wants a console to be always there, well, we should open one for him */
2077 if (prefs_p->gui_console_open == console_open_always) {
2082 /* Read the capture filter file. */
2083 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2084 if (cf_path != NULL) {
2085 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2086 "Could not open your capture filter file\n\"%s\": %s.",
2087 cf_path, g_strerror(cf_open_errno));
2091 /* Read the display filter file. */
2092 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2093 if (df_path != NULL) {
2094 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2095 "Could not open your display filter file\n\"%s\": %s.",
2096 df_path, g_strerror(df_open_errno));
2100 /* Read the disabled protocols file. */
2101 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2102 dp_path, &dp_open_errno, &dp_read_errno);
2103 read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2104 dp_path, &dp_open_errno, &dp_read_errno);
2105 if (*gdp_path != NULL) {
2106 if (gdp_open_errno != 0) {
2107 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2108 "Could not open global disabled protocols file\n\"%s\": %s.",
2109 *gdp_path, g_strerror(gdp_open_errno));
2111 if (gdp_read_errno != 0) {
2112 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2113 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2114 *gdp_path, g_strerror(gdp_read_errno));
2119 if (*dp_path != NULL) {
2120 if (dp_open_errno != 0) {
2121 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2122 "Could not open your disabled protocols file\n\"%s\": %s.",
2123 *dp_path, g_strerror(dp_open_errno));
2125 if (dp_read_errno != 0) {
2126 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2127 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2128 *dp_path, g_strerror(dp_read_errno));
2137 /* Check if there's something important to tell the user during startup.
2138 * We want to do this *after* showing the main window so that any windows
2139 * we pop up will be above the main window.
2143 check_and_warn_user_startup(gchar *cf_name)
2145 check_and_warn_user_startup(gchar *cf_name _U_)
2148 gchar *cur_user, *cur_group;
2149 gpointer priv_warning_dialog;
2151 /* Tell the user not to run as root. */
2152 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2153 cur_user = get_cur_username();
2154 cur_group = get_cur_groupname();
2155 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2156 "Running as user \"%s\" and group \"%s\".\n"
2157 "This could be dangerous.\n\n"
2158 "If you're running Wireshark this way in order to perform live capture, "
2159 "you may want to be aware that there is a better way documented at\n"
2160 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2163 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2164 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2168 /* Warn the user if npf.sys isn't loaded. */
2169 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2170 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2171 "The NPF driver isn't running. You may have trouble\n"
2172 "capturing or listing interfaces.");
2173 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2174 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2180 /* And now our feature presentation... [ fade to music ] */
2182 main(int argc, char *argv[])
2184 char *init_progfile_dir_error;
2187 gboolean arg_error = FALSE;
2189 extern int info_update_freq; /* Found in about_dlg.c. */
2190 const gchar *filter;
2198 char *gdp_path, *dp_path;
2201 gboolean start_capture = FALSE;
2202 gboolean list_link_layer_types = FALSE;
2207 gboolean capture_option_specified = FALSE;
2214 gint pl_size = 280, tv_size = 95, bv_size = 75;
2215 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2216 dfilter_t *rfcode = NULL;
2218 gboolean rfilter_parse_failed = FALSE;
2221 GtkWidget *splash_win = NULL;
2222 guint go_to_packet = 0;
2223 search_direction jump_backwards = SD_FORWARD;
2224 dfilter_t *jump_to_filter = NULL;
2225 unsigned int in_file_type = WTAP_TYPE_AUTO;
2226 #ifdef HAVE_GTKOSXAPPLICATION
2227 GtkosxApplication *theApp;
2229 GSList *disable_protocol_slist = NULL;
2230 GSList *enable_heur_slist = NULL;
2231 GSList *disable_heur_slist = NULL;
2233 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
2234 static const struct option long_options[] = {
2235 {"help", no_argument, NULL, 'h'},
2236 {"read-file", required_argument, NULL, 'r' },
2237 {"read-filter", required_argument, NULL, 'R' },
2238 {"display-filter", required_argument, NULL, 'Y' },
2239 {"version", no_argument, NULL, 'v'},
2240 LONGOPT_CAPTURE_COMMON
2243 static const char optstring[] = OPTSTRING;
2245 #ifdef HAVE_GRESOURCE
2246 main_register_resource();
2249 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2251 /* Set the C-language locale to the native environment. */
2252 setlocale(LC_ALL, "");
2254 arg_list_utf_16to8(argc, argv);
2255 create_app_running_mutex();
2259 * Get credential information for later use, and drop privileges
2260 * before doing anything else.
2261 * Let the user know if anything happened.
2263 init_process_policies();
2264 relinquish_special_privs_perm();
2267 * Attempt to get the pathname of the executable file.
2269 init_progfile_dir_error = init_progfile_dir(argv[0], (void *)main);
2271 /* initialize the funnel mini-api */
2272 initialize_funnel_ops();
2274 AirPDcapInitContext(&airpdcap_ctx);
2277 /* Load wpcap if possible. Do this before collecting the run-time version information */
2280 /* ... and also load the packet.dll from wpcap */
2281 wpcap_packet_load();
2284 /* Load the airpcap.dll. This must also be done before collecting
2285 * run-time version information. */
2286 airpcap_dll_ret_val = load_airpcap();
2288 switch (airpcap_dll_ret_val) {
2289 case AIRPCAP_DLL_OK:
2290 /* load the airpcap interfaces */
2291 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2293 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
2294 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2295 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2298 airpcap_if_active = NULL;
2302 /* select the first ad default (THIS SHOULD BE CHANGED) */
2303 airpcap_if_active = airpcap_get_default_if(g_airpcap_if_list);
2308 * XXX - Maybe we need to warn the user if one of the following happens???
2310 case AIRPCAP_DLL_OLD:
2311 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2314 case AIRPCAP_DLL_ERROR:
2315 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2318 case AIRPCAP_DLL_NOT_FOUND:
2319 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2323 #endif /* HAVE_AIRPCAP */
2326 /* Get the compile-time version information string */
2327 comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
2328 get_gui_compiled_info);
2330 /* Get the run-time version information string */
2331 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
2333 /* Add it to the information to be reported on a crash. */
2334 ws_add_crash_info("Wireshark %s\n"
2339 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2342 /* Start windows sockets */
2343 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2346 profile_store_persconffiles (TRUE);
2348 /* Read the profile independent recent file. We have to do this here so we can */
2349 /* set the profile before it can be set from the command line parameter */
2350 recent_read_static(&rf_path, &rf_open_errno);
2351 if (rf_path != NULL && rf_open_errno != 0) {
2352 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2353 "Could not open common recent file\n\"%s\": %s.",
2354 rf_path, g_strerror(rf_open_errno));
2358 * In order to have the -X opts assigned before the wslua machine starts
2359 * we need to call getopt_long before epan_init() gets called.
2361 * In addition, we process "console only" parameters (ones where we
2362 * send output to the console and exit) here, so we don't start GTK+
2363 * if we're only showing command-line help or version information.
2365 * XXX - this pre-scan is done before we start GTK+, so we haven't
2366 * run gtk_init() on the arguments. That means that GTK+ arguments
2367 * have not been removed from the argument list; those arguments
2368 * begin with "--", and will be treated as an error by getopt_long().
2370 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
2373 * XXX - should we, instead, first call gtk_parse_args(), without
2374 * calling gtk_init(), and then call this?
2376 * In order to handle, for example, -o options, we also need to call it
2377 * *after* epan_init() gets called, so that the dissectors have had a
2378 * chance to register their preferences, so we have another getopt_long()
2381 * XXX - can we do this all with one getopt_long() call, saving the
2382 * arguments we can't handle until after initializing libwireshark,
2383 * and then process them after initializing libwireshark?
2385 * Note that we don't want to initialize libwireshark until after the
2386 * GUI is up, as that can take a while, and we want a window of some
2387 * sort up to show progress while that's happening.
2391 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
2393 case 'C': /* Configuration Profile */
2394 if (profile_exists (optarg, FALSE)) {
2395 set_profile_name (optarg);
2397 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2401 case 'D': /* Print a list of capture devices and exit */
2403 if_list = capture_interface_list(&err, &err_str, NULL);
2404 if (if_list == NULL) {
2406 cmdarg_err("There are no interfaces on which a capture can be done");
2408 cmdarg_err("%s", err_str);
2416 capture_opts_print_interfaces(if_list);
2417 free_interface_list(if_list);
2422 #else /* HAVE_LIBPCAP */
2423 capture_option_specified = TRUE;
2425 #endif /* HAVE_LIBPCAP */
2427 case 'h': /* Print help and exit */
2433 if (strcmp(optarg, "-") == 0)
2434 set_stdin_capture(TRUE);
2437 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
2438 if (!persfilepath_opt(opt, optarg)) {
2439 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2443 case 'v': /* Show version and exit */
2447 show_version("Wireshark", comp_info_str, runtime_info_str);
2455 * Extension command line options have to be processed before
2456 * we call epan_init() as they are supposed to be used by dissectors
2457 * or taps very early in the registration process.
2461 case '?': /* Ignore errors - the "real" scan will catch them. */
2466 /* Init the "Open file" dialog directory */
2467 /* (do this after the path settings are processed) */
2469 /* Read the profile dependent (static part) of the recent file. */
2470 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2471 /* recent lists which is done in the dynamic part. */
2472 /* We have to do this already here, so command line parameters can overwrite these values. */
2473 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
2474 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2475 "Could not open recent file\n\"%s\": %s.",
2476 rf_path, g_strerror(rf_open_errno));
2480 if (recent.gui_fileopen_remembered_dir &&
2481 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2482 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2484 set_last_open_dir(get_persdatafile_dir());
2487 #if !GLIB_CHECK_VERSION(2,31,0)
2488 g_thread_init(NULL);
2491 /* Set the current locale according to the program environment.
2492 * We haven't localized anything, but some GTK widgets are localized
2493 * (the file selection dialogue, for example).
2494 * This also sets the C-language locale to the native environment. */
2495 setlocale (LC_ALL, "");
2497 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2498 gtk_init (&argc, &argv);
2500 cf_callback_add(main_cf_callback, NULL);
2502 capture_callback_add(main_capture_callback, NULL);
2505 cf_callback_add(statusbar_cf_callback, NULL);
2507 capture_callback_add(statusbar_capture_callback, NULL);
2510 cf_callback_add(welcome_cf_callback, NULL);
2512 capture_callback_add(welcome_capture_callback, NULL);
2515 set_console_log_handler();
2518 /* Set the initial values in the capture options. This might be overwritten
2519 by preference settings and then again by the command line parameters. */
2520 capture_opts_init(&global_capture_opts);
2522 capture_session_init(&global_capture_session, &cfile);
2525 init_report_err(failure_alert_box, open_failure_alert_box,
2526 read_failure_alert_box, write_failure_alert_box);
2528 /* Initialize whatever we need to allocate colors for GTK+ */
2531 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2532 filter = get_conn_cfilter();
2533 if ( *filter != '\0' ) {
2534 info_update_freq = 1000; /* Milliseconds */
2537 /* We won't come till here, if we had a "console only" command line parameter. */
2538 splash_win = splash_new("Loading Wireshark ...");
2539 if (init_progfile_dir_error != NULL) {
2540 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2541 "Can't get pathname of Wireshark: %s.\n"
2542 "It won't be possible to capture traffic.\n"
2543 "Report this to the Wireshark developers.",
2544 init_progfile_dir_error);
2545 g_free(init_progfile_dir_error);
2548 init_open_routines();
2551 /* Register all the plugin types we have. */
2552 epan_register_plugin_types(); /* Types known to libwireshark */
2553 wtap_register_plugin_types(); /* Types known to libwiretap */
2554 codec_register_plugin_types(); /* Types known to libwscodecs */
2556 /* Scan for plugins. This does *not* call their registration routines;
2557 that's done later. */
2560 /* Register all libwiretap plugin modules. */
2561 register_all_wiretap_modules();
2563 /* Register all audio codec plugins. */
2564 register_all_codecs();
2567 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2569 /* Register all dissectors; we must do this before checking for the
2570 "-G" flag, as the "-G" flag dumps information registered by the
2571 dissectors, and we must do it before we read the preferences, in
2572 case any dissectors register preferences. */
2573 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
2574 splash_update, (gpointer) splash_win))
2577 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2579 /* Register all tap listeners; we do this before we parse the arguments,
2580 as the "-z" argument can specify a registered tap. */
2582 /* we register the plugin taps before the other taps because
2583 stats_tree taps plugins will be registered as tap listeners
2584 by stats_tree_stat.c and need to registered before that */
2587 register_all_plugin_tap_listeners();
2590 register_all_tap_listeners();
2591 conversation_table_set_gui_info(init_conversation_table);
2592 hostlist_table_set_gui_info(init_hostlist_table);
2593 srt_table_iterate_tables(register_service_response_tables, NULL);
2594 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2595 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2597 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2599 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2600 /* Removed thread code:
2601 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2604 /* this is to keep tap extensions updating once every 3 seconds */
2605 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2607 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2609 cap_file_init(&cfile);
2611 /* Fill in capture options with values from the preferences */
2612 prefs_to_capture_opts();
2614 /*#ifdef HAVE_LIBPCAP
2615 fill_in_local_interfaces();
2618 * To reset the options parser, set optreset to 1 on platforms that
2619 * have optreset (documented in *BSD and OS X, apparently present but
2620 * not documented in Solaris - the Illumos repository seems to
2621 * suggest that the first Solaris getopt_long(), at least as of 2004,
2622 * was based on the NetBSD one, it had optreset) and set optind to 1,
2623 * and set optind to 0 otherwise (documented as working in the GNU
2624 * getopt_long(). Setting optind to 0 didn't originally work in the
2625 * NetBSD one, but that was added later - we don't want to depend on
2626 * it if we have optreset).
2628 * Also reset opterr to 1, so that error messages are printed by
2631 * XXX - if we want to control all the command-line option errors, so
2632 * that we can display them where we choose (e.g., in a window), we'd
2633 * want to leave opterr as 0, and produce our own messages using optopt.
2634 * We'd have to check the value of optopt to see if it's a valid option
2635 * letter, in which case *presumably* the error is "this option requires
2636 * an argument but none was specified", or not a valid option letter,
2637 * in which case *presumably* the error is "this option isn't valid".
2638 * Some versions of getopt() let you supply a option string beginning
2639 * with ':', which means that getopt() will return ':' rather than '?'
2640 * for "this option requires an argument but none was specified", but
2641 * not all do. But we're now using getopt_long() - what does it do?
2643 #ifdef HAVE_OPTRESET
2651 /* Now get our args */
2652 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
2654 /*** capture option specific ***/
2655 case 'a': /* autostop criteria */
2656 case 'b': /* Ringbuffer option */
2657 case 'c': /* Capture xxx packets */
2658 case 'f': /* capture filter */
2659 case 'k': /* Start capture immediately */
2660 case 'H': /* Hide capture info dialog box */
2661 case 'p': /* Don't capture in promiscuous mode */
2662 case 'i': /* Use interface x */
2663 #ifdef HAVE_PCAP_CREATE
2664 case 'I': /* Capture in monitor mode, if available */
2666 #ifdef HAVE_PCAP_REMOTE
2667 case 'A': /* Authentication */
2669 case 's': /* Set the snapshot (capture) length */
2670 case 'S': /* "Sync" mode: used for following file ala tail -f */
2671 case 'w': /* Write to capture file xxx */
2672 case 'y': /* Set the pcap data link type */
2673 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
2674 case 'B': /* Buffer size */
2677 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2683 capture_option_specified = TRUE;
2688 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2689 case 'K': /* Kerberos keytab file */
2690 read_keytab_file(optarg);
2694 /*** all non capture option specific ***/
2696 /* Configuration profile settings were already processed just ignore them this time*/
2698 case 'j': /* Search backwards for a matching packet from filter in option J */
2699 jump_backwards = SD_BACKWARD;
2701 case 'g': /* Go to packet with the given packet number */
2702 go_to_packet = get_positive_int(optarg, "go to packet");
2704 case 'J': /* Jump to the first packet which matches the filter criteria */
2707 case 'l': /* Automatic scrolling in live capture mode */
2709 auto_scroll_live = TRUE;
2711 capture_option_specified = TRUE;
2715 case 'L': /* Print list of link-layer types and exit */
2717 list_link_layer_types = TRUE;
2719 capture_option_specified = TRUE;
2723 case 'm': /* Fixed-width font for the display */
2724 g_free(prefs_p->gui_gtk2_font_name);
2725 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2727 case 'n': /* No name resolution */
2728 disable_name_resolution();
2730 case 'N': /* Select what types of addresses/port #s to resolve */
2731 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2732 if (badopt != '\0') {
2733 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
2738 case 'o': /* Override preference from command line */
2739 switch (prefs_set_pref(optarg)) {
2742 case PREFS_SET_SYNTAX_ERR:
2743 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2746 case PREFS_SET_NO_SUCH_PREF:
2747 /* not a preference, might be a recent setting */
2748 switch (recent_set_arg(optarg)) {
2751 case PREFS_SET_SYNTAX_ERR:
2752 /* shouldn't happen, checked already above */
2753 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2756 case PREFS_SET_NO_SUCH_PREF:
2757 case PREFS_SET_OBSOLETE:
2758 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2763 g_assert_not_reached();
2766 case PREFS_SET_OBSOLETE:
2767 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2772 g_assert_not_reached();
2776 /* Path settings were already processed just ignore them this time*/
2778 case 'r': /* Read capture file xxx */
2779 /* We may set "last_open_dir" to "cf_name", and if we change
2780 "last_open_dir" later, we free the old value, so we have to
2781 set "cf_name" to something that's been allocated. */
2782 cf_name = g_strdup(optarg);
2784 case 'R': /* Read file filter */
2787 case 't': /* Time stamp type */
2788 if (strcmp(optarg, "r") == 0)
2789 timestamp_set_type(TS_RELATIVE);
2790 else if (strcmp(optarg, "a") == 0)
2791 timestamp_set_type(TS_ABSOLUTE);
2792 else if (strcmp(optarg, "ad") == 0)
2793 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2794 else if (strcmp(optarg, "adoy") == 0)
2795 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
2796 else if (strcmp(optarg, "d") == 0)
2797 timestamp_set_type(TS_DELTA);
2798 else if (strcmp(optarg, "dd") == 0)
2799 timestamp_set_type(TS_DELTA_DIS);
2800 else if (strcmp(optarg, "e") == 0)
2801 timestamp_set_type(TS_EPOCH);
2802 else if (strcmp(optarg, "u") == 0)
2803 timestamp_set_type(TS_UTC);
2804 else if (strcmp(optarg, "ud") == 0)
2805 timestamp_set_type(TS_UTC_WITH_YMD);
2806 else if (strcmp(optarg, "udoy") == 0)
2807 timestamp_set_type(TS_UTC_WITH_YDOY);
2809 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2811 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2813 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2815 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2817 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2819 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2823 case 'u': /* Seconds type */
2824 if (strcmp(optarg, "s") == 0)
2825 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2826 else if (strcmp(optarg, "hms") == 0)
2827 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2829 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2831 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2836 /* ext ops were already processed just ignore them this time*/
2842 /* We won't call the init function for the stat this soon
2843 as it would disallow MATE's fields (which are registered
2844 by the preferences set callback) from being used as
2845 part of a tap filter. Instead, we just add the argument
2846 to a list of stat arguments. */
2847 if (strcmp("help", optarg) == 0) {
2848 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
2849 list_stat_cmd_args();
2852 if (!process_stat_cmd_arg(optarg)) {
2853 cmdarg_err("Invalid -z argument.");
2854 cmdarg_err_cont(" -z argument must be one of :");
2855 list_stat_cmd_args();
2859 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
2860 disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
2862 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
2863 enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
2865 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
2866 disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
2869 case '?': /* Bad flag - print usage message */
2878 if (cf_name != NULL) {
2880 * Input file name specified with "-r" *and* specified as a regular
2881 * command-line argument.
2883 cmdarg_err("File name specified both with -r and regular argument");
2887 * Input file name not specified with "-r", and a command-line argument
2888 * was specified; treat it as the input file name.
2890 * Yes, this is different from tshark, where non-flag command-line
2891 * arguments are a filter, but this works better on GUI desktops
2892 * where a command can be specified to be run to open a particular
2893 * file - yes, you could have "-r" as the last part of the command,
2894 * but that's a bit ugly.
2896 #ifndef HAVE_GTKOSXAPPLICATION
2898 * For GTK+ Mac Integration, file name passed as free argument passed
2899 * through grag-and-drop and opened twice sometimes causing crashes.
2900 * Subject to report to GTK+ MAC.
2902 cf_name = g_strdup(argv[0]);
2911 * Extra command line arguments were specified; complain.
2913 cmdarg_err("Invalid argument: %s", argv[0]);
2919 #ifndef HAVE_LIBPCAP
2920 if (capture_option_specified) {
2921 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2929 fill_in_local_interfaces(main_window_update);
2930 if (start_capture && list_link_layer_types) {
2931 /* Specifying *both* is bogus. */
2932 cmdarg_err("You can't specify both -L and a live capture.");
2936 if (list_link_layer_types) {
2937 /* We're supposed to list the link-layer types for an interface;
2938 did the user also specify a capture file to be read? */
2940 /* Yes - that's bogus. */
2941 cmdarg_err("You can't specify -L and a capture file to be read.");
2944 /* No - did they specify a ring buffer option? */
2945 if (global_capture_opts.multi_files_on) {
2946 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2950 /* We're supposed to do a live capture; did the user also specify
2951 a capture file to be read? */
2952 if (start_capture && cf_name) {
2953 /* Yes - that's bogus. */
2954 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2958 /* No - was the ring buffer option specified and, if so, does it make
2960 if (global_capture_opts.multi_files_on) {
2961 /* Ring buffer works only under certain conditions:
2962 a) ring buffer does not work with temporary files;
2963 b) real_time_mode and multi_files_on are mutually exclusive -
2964 real_time_mode takes precedence;
2965 c) it makes no sense to enable the ring buffer if the maximum
2966 file size is set to "infinite". */
2967 if (global_capture_opts.save_file == NULL) {
2968 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2969 global_capture_opts.multi_files_on = FALSE;
2971 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2972 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2973 /* XXX - this must be redesigned as the conditions changed */
2978 if (start_capture || list_link_layer_types) {
2979 /* We're supposed to do a live capture or get a list of link-layer
2980 types for a live capture device; if the user didn't specify an
2981 interface to use, pick a default. */
2982 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2983 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2989 if (list_link_layer_types) {
2990 /* Get the list of link-layer types for the capture devices. */
2991 if_capabilities_t *caps;
2994 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2996 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2997 if (device.selected) {
2998 gchar* auth_str = NULL;
2999 #ifdef HAVE_PCAP_REMOTE
3000 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
3001 auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
3002 device.remote_opts.remote_host_opts.auth_password);
3005 #if defined(HAVE_PCAP_CREATE)
3006 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
3008 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
3012 cmdarg_err("%s", err_str);
3016 if (caps->data_link_types == NULL) {
3017 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
3023 #if defined(HAVE_PCAP_CREATE)
3024 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
3026 capture_opts_print_if_capabilities(caps, device.name, FALSE);
3031 free_if_capabilities(caps);
3036 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
3037 capture_opts_trim_ring_num_files(&global_capture_opts);
3038 #endif /* HAVE_LIBPCAP */
3040 /* Notify all registered modules that have had any of their preferences
3041 changed either from one of the preferences file or from the command
3042 line that their preferences have changed. */
3046 if ((global_capture_opts.num_selected == 0) &&
3047 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
3050 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3051 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3052 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
3053 device.selected = TRUE;
3054 global_capture_opts.num_selected++;
3055 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
3056 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
3061 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
3062 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
3063 device.selected = TRUE;
3064 global_capture_opts.num_selected++;
3065 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
3066 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
3070 /* disabled protocols as per configuration file */
3071 if (gdp_path == NULL && dp_path == NULL) {
3072 set_disabled_protos_list();
3073 set_disabled_heur_dissector_list();
3076 if(disable_protocol_slist) {
3077 GSList *proto_disable;
3078 for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
3080 proto_disable_proto_by_name((char*)proto_disable->data);
3084 if(enable_heur_slist) {
3085 GSList *heur_enable;
3086 for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
3088 proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
3092 if(disable_heur_slist) {
3093 GSList *heur_disable;
3094 for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
3096 proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
3100 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
3102 /* read in rc file from global and personal configuration paths. */
3103 rc_file = get_datafile_path(RC_FILE);
3104 #if GTK_CHECK_VERSION(3,0,0)
3105 /* XXX resolve later */
3107 gtk_rc_parse(rc_file);
3109 rc_file = get_persconffile_path(RC_FILE, FALSE);
3110 gtk_rc_parse(rc_file);
3120 /* close the splash screen, as we are going to open the main window now */
3121 splash_destroy(splash_win);
3123 /************************************************************************/
3124 /* Everything is prepared now, preferences and command line was read in */
3126 /* Pop up the main window. */
3127 create_main_window(pl_size, tv_size, bv_size, prefs_p);
3129 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3130 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
3131 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3132 "Could not open recent file\n\"%s\": %s.",
3133 rf_path, g_strerror(rf_open_errno));
3137 color_filters_enable(recent.packet_list_colorize);
3139 /* rearrange all the widgets as we now have all recent settings ready for this */
3140 main_widgets_rearrange();
3142 /* Fill in column titles. This must be done after the top level window
3145 XXX - is that still true, with fixed-width columns? */
3147 menu_recent_read_finished();
3149 main_auto_scroll_live_changed(auto_scroll_live);
3152 switch (user_font_apply()) {
3155 case FA_ZOOMED_TOO_FAR:
3156 /* The zoom level is too big for this font; turn off zooming. */
3157 recent.gui_zoom_level = 0;
3159 case FA_FONT_NOT_AVAILABLE:
3160 /* XXX - did we successfully load the un-zoomed version earlier?
3161 If so, this *probably* means the font is available, but not at
3162 this particular zoom level, but perhaps some other failure
3163 occurred; I'm not sure you can determine which is the case,
3165 /* turn off zooming - zoom level is unavailable */
3167 /* in any other case than FA_SUCCESS, turn off zooming */
3168 recent.gui_zoom_level = 0;
3169 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3173 dnd_init(top_level);
3175 color_filters_init();
3177 capture_filter_init();
3180 /* the window can be sized only, if it's not already shown, so do it now! */
3181 main_load_window_geometry(top_level);
3183 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3185 /* If we were given the name of a capture file, read it in now;
3186 we defer it until now, so that, if we can't open it, and pop
3187 up an alert box, the alert box is more likely to come up on
3188 top of the main window - but before the preference-file-error
3189 alert box, so, if we get one of those, it's more likely to come
3192 show_main_window(TRUE);
3193 check_and_warn_user_startup(cf_name);
3194 if (rfilter != NULL) {
3195 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
3196 bad_dfilter_alert_box(top_level, rfilter, err_msg);
3198 rfilter_parse_failed = TRUE;
3201 if (ex_opt_count("read_format") > 0) {
3202 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
3204 if (!rfilter_parse_failed) {
3205 if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
3206 /* "cf_open()" succeeded, so it closed the previous
3207 capture file, and thus destroyed any previous read filter
3208 attached to "cf". */
3210 cfile.rfcode = rfcode;
3211 /* Open stat windows; we do so after creating the main window,
3212 to avoid GTK warnings, and after successfully opening the
3213 capture file, so we know we have something to compute stats
3214 on, and after registering all dissectors, so that MATE will
3215 have registered its field array and we can have a tap filter
3216 with one of MATE's late-registered fields as part of the
3218 start_requested_stats();
3220 /* Read the capture file. */
3221 switch (cf_read(&cfile, FALSE)) {
3225 /* Just because we got an error, that doesn't mean we were unable
3226 to read any of the file; we handle what we could get from the
3228 /* if the user told us to jump to a specific packet, do it now */
3229 if(go_to_packet != 0) {
3230 /* Jump to the specified frame number, kept for backward
3232 cf_goto_frame(&cfile, go_to_packet);
3233 } else if (jfilter != NULL) {
3234 /* try to compile given filter */
3235 if (!dfilter_compile(jfilter, &jump_to_filter, &err_msg)) {
3236 bad_dfilter_alert_box(top_level, jfilter, err_msg);
3239 /* Filter ok, jump to the first packet matching the filter
3240 conditions. Default search direction is forward, but if
3241 option d was given, search backwards */
3242 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3247 case CF_READ_ABORTED:
3253 /* If the filename is not the absolute path, prepend the current dir. This happens
3254 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3255 if (!g_path_is_absolute(cf_name)) {
3256 char *old_cf_name = cf_name;
3257 char *pwd = g_get_current_dir();
3258 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3259 g_free(old_cf_name);
3263 /* Save the name of the containing directory specified in the
3264 path name, if any; we can write over cf_name, which is a
3265 good thing, given that "get_dirname()" does write over its
3267 s = get_dirname(cf_name);
3268 set_last_open_dir(s);
3273 dfilter_free(rfcode);
3274 cfile.rfcode = NULL;
3275 show_main_window(FALSE);
3276 /* Don't call check_and_warn_user_startup(): we did it above */
3277 main_set_for_capture_in_progress(FALSE);
3278 set_capture_if_dialog_for_capture_in_progress(FALSE);
3283 if (start_capture) {
3284 if (global_capture_opts.save_file != NULL) {
3285 /* Save the directory name for future file dialogs. */
3286 /* (get_dirname overwrites filename) */
3287 s = get_dirname(g_strdup(global_capture_opts.save_file));
3288 set_last_open_dir(s);
3291 /* "-k" was specified; start a capture. */
3292 show_main_window(FALSE);
3293 check_and_warn_user_startup(cf_name);
3295 /* If no user interfaces were specified on the command line,
3296 copy the list of selected interfaces to the set of interfaces
3297 to use for this capture. */
3298 if (global_capture_opts.ifaces->len == 0)
3299 collect_ifaces(&global_capture_opts);
3300 if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3301 /* The capture started. Open stat windows; we do so after creating
3302 the main window, to avoid GTK warnings, and after successfully
3303 opening the capture file, so we know we have something to compute
3304 stats on, and after registering all dissectors, so that MATE will
3305 have registered its field array and we can have a tap filter with
3306 one of MATE's late-registered fields as part of the filter. */
3307 start_requested_stats();
3310 show_main_window(FALSE);
3311 check_and_warn_user_startup(cf_name);
3312 main_set_for_capture_in_progress(FALSE);
3313 set_capture_if_dialog_for_capture_in_progress(FALSE);
3315 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3316 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3317 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3319 #else /* HAVE_LIBPCAP */
3320 show_main_window(FALSE);
3321 check_and_warn_user_startup(cf_name);
3322 main_set_for_capture_in_progress(FALSE);
3323 set_capture_if_dialog_for_capture_in_progress(FALSE);
3324 #endif /* HAVE_LIBPCAP */
3328 GtkWidget *filter_te;
3329 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3330 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3332 /* Run the display filter so it goes in effect. */
3333 main_filter_packets(&cfile, dfilter, FALSE);
3337 /* register our pid if we are being run from a U3 device */
3340 profile_store_persconffiles (FALSE);
3342 #ifdef HAVE_GTKOSXAPPLICATION
3343 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3344 #ifdef HAVE_GRESOURCE
3345 gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
3347 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3349 gtkosx_application_ready(theApp);
3352 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3355 gtk_iface_mon_start();
3358 software_update_init();
3360 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3362 /* ... back from GTK, we're going down now! */
3365 gtk_iface_mon_stop();
3368 /* deregister our pid */
3369 u3_deregister_pid();
3373 AirPDcapDestroyContext(&airpdcap_ctx);
3375 #ifdef HAVE_GTKOSXAPPLICATION
3376 g_object_unref(theApp);
3380 /* hide the (unresponsive) main window, while asking the user to close the console window */
3381 if (G_IS_OBJECT(top_level))
3382 gtk_widget_hide(top_level);
3384 software_update_cleanup();
3386 /* Shutdown windows sockets */
3389 /* For some unknown reason, the "atexit()" call in "create_console()"
3390 doesn't arrange that "destroy_console()" be called when we exit,
3391 so we call it here if a console was created. */
3395 #ifdef HAVE_GRESOURCE
3396 main_unregister_resource();
3404 /* We build this as a GUI subsystem application on Win32, so
3405 "WinMain()", not "main()", gets called.
3407 Hack shamelessly stolen from the Win32 port of the GIMP. */
3409 #define _stdcall __attribute__((stdcall))
3413 WinMain (struct HINSTANCE__ *hInstance,
3414 struct HINSTANCE__ *hPrevInstance,
3418 INITCOMMONCONTROLSEX comm_ctrl;
3421 * Initialize our DLL search path. MUST be called before LoadLibrary
3424 ws_init_dll_search_path();
3426 /* Initialize our controls. Required for native Windows file dialogs. */
3427 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3428 comm_ctrl.dwSize = sizeof(comm_ctrl);
3429 /* Includes the animate, header, hot key, list view, progress bar,
3430 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3433 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3434 InitCommonControlsEx(&comm_ctrl);
3436 /* RichEd20.DLL is needed for filter entries. */
3437 ws_load_library("riched20.dll");
3439 set_has_console(FALSE);
3440 set_console_wait(FALSE);
3441 return main (__argc, __argv);
3450 * Helper for main_widgets_rearrange()
3452 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3453 gtk_container_remove(GTK_CONTAINER(data), widget);
3456 static GtkWidget *main_widget_layout(gint layout_content)
3458 switch(layout_content) {
3459 case(layout_pane_content_none):
3461 case(layout_pane_content_plist):
3463 case(layout_pane_content_pdetails):
3465 case(layout_pane_content_pbytes):
3466 return byte_nb_ptr_gbl;
3468 g_assert_not_reached();
3474 * Rearrange the main window widgets
3476 void main_widgets_rearrange(void) {
3477 GtkWidget *first_pane_widget1, *first_pane_widget2;
3478 GtkWidget *second_pane_widget1, *second_pane_widget2;
3479 gboolean split_top_left = FALSE;
3481 /* be a bit faster */
3482 gtk_widget_hide(main_vbox);
3484 /* be sure we don't lose a widget while rearranging */
3485 g_object_ref(G_OBJECT(menubar));
3486 g_object_ref(G_OBJECT(main_tb));
3487 g_object_ref(G_OBJECT(filter_tb));
3488 g_object_ref(G_OBJECT(wireless_tb));
3489 g_object_ref(G_OBJECT(pkt_scrollw));
3490 g_object_ref(G_OBJECT(tv_scrollw));
3491 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3492 g_object_ref(G_OBJECT(statusbar));
3493 g_object_ref(G_OBJECT(main_pane_v1));
3494 g_object_ref(G_OBJECT(main_pane_v2));
3495 g_object_ref(G_OBJECT(main_pane_h1));
3496 g_object_ref(G_OBJECT(main_pane_h2));
3497 g_object_ref(G_OBJECT(welcome_pane));
3499 /* empty all containers participating */
3500 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3501 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3502 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3503 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3504 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3506 statusbar_widgets_emptying(statusbar);
3508 /* add the menubar always at the top */
3509 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3512 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3514 /* filter toolbar in toolbar area */
3515 if (!prefs.filter_toolbar_show_in_statusbar) {
3516 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3519 /* airpcap toolbar */
3520 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3522 /* fill the main layout panes */
3523 switch(prefs.gui_layout_type) {
3524 case(layout_type_5):
3525 main_first_pane = main_pane_v1;
3526 main_second_pane = main_pane_v2;
3527 split_top_left = FALSE;
3529 case(layout_type_2):
3530 main_first_pane = main_pane_v1;
3531 main_second_pane = main_pane_h1;
3532 split_top_left = FALSE;
3534 case(layout_type_1):
3535 main_first_pane = main_pane_v1;
3536 main_second_pane = main_pane_h1;
3537 split_top_left = TRUE;
3539 case(layout_type_4):
3540 main_first_pane = main_pane_h1;
3541 main_second_pane = main_pane_v1;
3542 split_top_left = FALSE;
3544 case(layout_type_3):
3545 main_first_pane = main_pane_h1;
3546 main_second_pane = main_pane_v1;
3547 split_top_left = TRUE;
3549 case(layout_type_6):
3550 main_first_pane = main_pane_h1;
3551 main_second_pane = main_pane_h2;
3552 split_top_left = FALSE;
3555 main_first_pane = NULL;
3556 main_second_pane = NULL;
3557 g_assert_not_reached();
3559 if (split_top_left) {
3560 first_pane_widget1 = main_second_pane;
3561 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3562 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3563 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3565 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3566 first_pane_widget2 = main_second_pane;
3567 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3568 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3570 if (first_pane_widget1 != NULL)
3571 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3572 if (first_pane_widget2 != NULL)
3573 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3574 if (second_pane_widget1 != NULL)
3575 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3576 if (second_pane_widget2 != NULL)
3577 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3579 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3582 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3585 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3587 /* filter toolbar in statusbar hbox */
3588 if (prefs.filter_toolbar_show_in_statusbar) {
3589 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3592 /* statusbar widgets */
3593 statusbar_widgets_pack(statusbar);
3595 /* hide widgets on users recent settings */
3596 main_widgets_show_or_hide();
3598 gtk_widget_show(main_vbox);
3602 is_widget_visible(GtkWidget *widget, gpointer data)
3604 gboolean *is_visible = ( gboolean *)data;
3607 if (gtk_widget_get_visible(widget))
3614 main_widgets_show_or_hide(void)
3616 gboolean main_second_pane_show;
3618 if (recent.main_toolbar_show) {
3619 gtk_widget_show(main_tb);
3621 gtk_widget_hide(main_tb);
3624 statusbar_widgets_show_or_hide(statusbar);
3626 if (recent.filter_toolbar_show) {
3627 gtk_widget_show(filter_tb);
3629 gtk_widget_hide(filter_tb);
3632 if (recent.wireless_toolbar_show) {
3633 gtk_widget_show(wireless_tb);
3635 gtk_widget_hide(wireless_tb);
3638 if (recent.packet_list_show && have_capture_file) {
3639 gtk_widget_show(pkt_scrollw);
3641 gtk_widget_hide(pkt_scrollw);
3644 if (recent.tree_view_show && have_capture_file) {
3645 gtk_widget_show(tv_scrollw);
3647 gtk_widget_hide(tv_scrollw);
3650 if (recent.byte_view_show && have_capture_file) {
3651 gtk_widget_show(byte_nb_ptr_gbl);
3653 gtk_widget_hide(byte_nb_ptr_gbl);
3656 if (have_capture_file) {
3657 gtk_widget_show(main_first_pane);
3659 gtk_widget_hide(main_first_pane);
3663 * Is anything in "main_second_pane" visible?
3664 * If so, show it, otherwise hide it.
3666 main_second_pane_show = FALSE;
3667 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3668 &main_second_pane_show);
3669 if (main_second_pane_show) {
3670 gtk_widget_show(main_second_pane);
3672 gtk_widget_hide(main_second_pane);
3675 if (!have_capture_file) {
3677 gtk_widget_show(welcome_pane);
3680 gtk_widget_hide(welcome_pane);
3685 /* called, when the window state changes (minimized, maximized, ...) */
3687 window_state_event_cb (GtkWidget *widget _U_,
3691 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3693 if( (event->type) == (GDK_WINDOW_STATE)) {
3694 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3695 /* we might have dialogs popped up while we where iconified,
3697 display_queued_messages();
3705 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3707 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3709 if (event->keyval == GDK_F8) {
3712 } else if (event->keyval == GDK_F7) {
3715 } else if (event->state & NO_SHIFT_MOD_MASK) {
3716 return FALSE; /* Skip control, alt, and other modifiers */
3718 * A comment in gdkkeysyms.h says that it's autogenerated from
3719 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3720 * don't explicitly say so, g_ascii_isprint() should work as expected
3723 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3724 /* Forward the keypress on to the display filter entry */
3725 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3726 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3727 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3735 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3736 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3741 GtkAccelGroup *accel;
3744 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3745 set_titlebar_for_capture_file(NULL);
3747 gtk_widget_set_name(top_level, "main window");
3748 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3750 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3751 G_CALLBACK(window_state_event_cb), NULL);
3752 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3753 G_CALLBACK(top_level_key_pressed_cb), NULL );
3755 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3756 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3758 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3759 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3760 gtk_widget_show(main_vbox);
3763 menubar = main_menu_new(&accel);
3765 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3766 /* Mac OS X native menus are created and displayed by main_menu_new() */
3767 if(!prefs_p->gui_macosx_style) {
3769 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3770 gtk_widget_show(menubar);
3771 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3773 gtk_widget_hide(menubar);
3778 main_tb = toolbar_new();
3779 gtk_widget_show (main_tb);
3781 /* Filter toolbar */
3782 filter_tb = filter_toolbar_new();
3785 pkt_scrollw = packet_list_create();
3786 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3787 gtk_widget_show_all(pkt_scrollw);
3790 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3791 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3792 gtk_widget_show(tv_scrollw);
3794 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3795 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3796 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3797 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3798 gtk_widget_show(tree_view_gbl);
3801 byte_nb_ptr_gbl = byte_view_new();
3802 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3803 gtk_widget_show(byte_nb_ptr_gbl);
3805 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3806 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3808 /* Panes for the packet list, tree, and byte view */
3809 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3810 gtk_widget_show(main_pane_v1);
3811 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3812 gtk_widget_show(main_pane_v2);
3813 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3814 gtk_widget_show(main_pane_h1);
3815 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3816 gtk_widget_show(main_pane_h2);
3818 wireless_tb = airpcap_toolbar_new();
3820 wireless_tb = ws80211_toolbar_new();
3822 gtk_widget_show(wireless_tb);
3825 statusbar = statusbar_new();
3826 gtk_widget_show(statusbar);
3828 /* Pane for the welcome screen */
3829 welcome_pane = welcome_new();
3830 gtk_widget_show(welcome_pane);
3834 show_main_window(gboolean doing_work)
3836 main_set_for_capture_file(doing_work);
3838 /*** we have finished all init things, show the main window ***/
3839 gtk_widget_show(top_level);
3841 /* the window can be maximized only, if it's visible, so do it after show! */
3842 main_load_window_geometry(top_level);
3844 /* process all pending GUI events before continue */
3845 while (gtk_events_pending()) gtk_main_iteration();
3847 /* Pop up any queued-up alert boxes. */
3848 display_queued_messages();
3850 /* Move the main window to the front, in case it isn't already there */
3851 gdk_window_raise(gtk_widget_get_window(top_level));
3854 airpcap_toolbar_show(wireless_tb);
3855 #endif /* HAVE_AIRPCAP */
3858 static void copy_global_profile (const gchar *profile_name)
3860 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3862 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3863 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3864 "Can't create directory\n\"%s\":\n%s.",
3865 pf_dir_path, g_strerror(errno));
3867 g_free(pf_dir_path);
3870 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3871 &pf_dir_path, &pf_dir_path2) == -1) {
3872 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3873 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3874 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3876 g_free(pf_filename);
3877 g_free(pf_dir_path);
3878 g_free(pf_dir_path2);
3882 /* Change configuration profile */
3883 void change_configuration_profile (const gchar *profile_name)
3885 char *gdp_path, *dp_path;
3889 /* First check if profile exists */
3890 if (!profile_exists(profile_name, FALSE)) {
3891 if (profile_exists(profile_name, TRUE)) {
3892 /* Copy from global profile */
3893 copy_global_profile (profile_name);
3895 /* No personal and no global profile exists */
3900 /* Then check if changing to another profile */
3901 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3905 /* Get the current geometry, before writing it to disk */
3906 main_save_window_geometry(top_level);
3908 if (profile_exists(get_profile_name(), FALSE)) {
3909 /* Write recent file for profile we are leaving, if it still exists */
3910 write_profile_recent();
3913 /* Set profile name and update the status bar */
3914 set_profile_name (profile_name);
3915 profile_bar_update ();
3917 /* Reset current preferences and apply the new */
3921 (void) read_configuration_files (&gdp_path, &dp_path);
3923 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
3924 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3925 "Could not open common recent file\n\"%s\": %s.",
3926 rf_path, g_strerror(rf_open_errno));
3929 if (recent.gui_fileopen_remembered_dir &&
3930 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3931 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3933 timestamp_set_type (recent.gui_time_format);
3934 timestamp_set_seconds_type (recent.gui_seconds_format);
3935 color_filters_enable(recent.packet_list_colorize);
3937 prefs_to_capture_opts();
3940 update_local_interfaces();
3942 macros_post_update();
3944 /* Update window view and redraw the toolbar */
3945 main_titlebar_update();
3946 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3947 toolbar_redraw_all();
3949 /* Enable all protocols and disable from the disabled list */
3951 if (gdp_path == NULL && dp_path == NULL) {
3952 set_disabled_protos_list();
3953 set_disabled_heur_dissector_list();
3956 /* Reload color filters */
3957 color_filters_reload();
3959 /* Reload list of interfaces on welcome page */
3960 welcome_if_panel_reload();
3962 /* Recreate the packet list according to new preferences */
3963 packet_list_recreate ();
3964 cfile.columns_changed = FALSE; /* Reset value */
3967 /* Update menus with new recent values */
3968 menu_recent_read_finished();
3970 /* Reload pane geometry, must be done after recreating the list */
3971 main_pane_load_window_geometry();
3975 main_fields_changed (void)
3977 /* Reload color filters */
3978 color_filters_reload();
3980 /* Syntax check filter */
3981 filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3982 if (cfile.dfilter) {
3983 /* Check if filter is still valid */
3984 dfilter_t *dfp = NULL;
3985 if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
3986 /* Not valid. Enable 'Apply' button and remove dfilter. */
3987 g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3988 g_free(cfile.dfilter);
3989 cfile.dfilter = NULL;
3994 if (have_custom_cols(&cfile.cinfo)) {
3995 /* Recreate packet list according to new/changed/deleted fields */
3996 packet_list_recreate();
3997 } else if (cfile.state != FILE_CLOSED) {
3998 /* Redissect packets if we have any */
3999 redissect_packets();
4001 destroy_packet_wins(); /* TODO: close windows until we can recreate */
4003 proto_free_deregistered_fields();
4006 /** redissect packets and update UI */
4007 void redissect_packets(void)
4009 cf_redissect_packets(&cfile);
4010 status_expert_update();
4019 * indent-tabs-mode: nil
4022 * ex: set shiftwidth=4 tabstop=8 expandtab:
4023 * :indentSize=4:tabSize=8:noTabs=true: