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>
45 #include "wsutil/wsgetopt.h"
48 #ifdef _WIN32 /* Needed for console I/O */
52 #include <ui/win32/console_win32.h>
55 #ifdef HAVE_LIBPORTAUDIO
56 #include <portaudio.h>
57 #endif /* HAVE_LIBPORTAUDIO */
59 #include <wsutil/crash_info.h>
60 #include <wsutil/filesystem.h>
61 #include <wsutil/file_util.h>
62 #include <wsutil/privileges.h>
63 #include <wsutil/report_err.h>
64 #include <wsutil/u3.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/epan_dissect.h>
73 #include <epan/dfilter/dfilter.h>
74 #include <epan/strutil.h>
75 #include <epan/emem.h>
76 #include <epan/ex-opt.h>
77 #include <epan/funnel.h>
78 #include <epan/expert.h>
79 #include <epan/frequency-utils.h>
80 #include <epan/prefs.h>
81 #include <epan/prefs-int.h>
83 #include <epan/stat_cmd_args.h>
85 #include <epan/print.h>
86 #include <epan/timestamp.h>
88 #include <wsutil/plugins.h>
90 /* general (not GTK specific) */
92 #include "../frame_tvbuff.h"
93 #include "../summary.h"
94 #include "../filters.h"
96 #include "../color_filters.h"
97 #include "../register.h"
98 #include "../ringbuffer.h"
100 #include "../clopts_common.h"
101 #include "../cmdarg_err.h"
102 #include "../version_info.h"
105 #include "gtk_iface_monitor.h"
107 #include "ui/alert_box.h"
108 #include "ui/decode_as_utils.h"
109 #include "ui/main_statusbar.h"
110 #include "ui/persfilepath_opt.h"
111 #include "ui/preference_utils.h"
112 #include "ui/recent.h"
113 #include "ui/recent_utils.h"
114 #include "ui/software_update.h"
115 #include "ui/simple_dialog.h"
116 #include "ui/ui_util.h"
119 #include "ui/capture_globals.h"
120 #include "ui/iface_lists.h"
123 #include "codecs/codecs.h"
126 #include "capture_ui_utils.h"
127 #include "capture-pcap-util.h"
128 #include "capture_ifinfo.h"
130 #include "capture_sync.h"
134 #include "capture-wpcap.h"
135 #include "capture_wpcap_packet.h"
136 #include <tchar.h> /* Needed for Unicode */
137 #include <wsutil/unicode-utils.h>
138 #include <commctrl.h>
139 #include <shellapi.h>
143 #include "ui/gtk/file_dlg.h"
144 #include "ui/gtk/gtkglobals.h"
145 #include "ui/gtk/color_utils.h"
146 #include "ui/gtk/gui_utils.h"
147 #include "ui/gtk/color_dlg.h"
148 #include "ui/gtk/filter_dlg.h"
149 #include "ui/gtk/fileset_dlg.h"
150 #include "ui/gtk/uat_gui.h"
151 #include "ui/gtk/main.h"
152 #include "ui/gtk/main_80211_toolbar.h"
153 #include "ui/gtk/main_airpcap_toolbar.h"
154 #include "ui/gtk/main_filter_toolbar.h"
155 #include "ui/gtk/main_titlebar.h"
156 #include "ui/gtk/menus.h"
157 #include "ui/gtk/main_menubar_private.h"
158 #include "ui/gtk/macros_dlg.h"
159 #include "ui/gtk/main_statusbar_private.h"
160 #include "ui/gtk/main_toolbar.h"
161 #include "ui/gtk/main_toolbar_private.h"
162 #include "ui/gtk/main_welcome.h"
163 #include "ui/gtk/drag_and_drop.h"
164 #include "ui/gtk/capture_file_dlg.h"
165 #include "ui/gtk/packet_panes.h"
166 #include "ui/gtk/keys.h"
167 #include "ui/gtk/packet_win.h"
168 #include "ui/gtk/stock_icons.h"
169 #include "ui/gtk/find_dlg.h"
170 #include "ui/gtk/follow_tcp.h"
171 #include "ui/gtk/font_utils.h"
172 #include "ui/gtk/about_dlg.h"
173 #include "ui/gtk/help_dlg.h"
174 #include "ui/gtk/decode_as_dlg.h"
175 #include "ui/gtk/webbrowser.h"
176 #include "ui/gtk/capture_dlg.h"
177 #include "ui/gtk/capture_if_dlg.h"
178 #include "ui/gtk/tap_param_dlg.h"
179 #include "ui/gtk/prefs_column.h"
180 #include "ui/gtk/prefs_dlg.h"
181 #include "ui/gtk/proto_help.h"
182 #include "ui/gtk/packet_list.h"
183 #include "ui/gtk/filter_expression_save_dlg.h"
185 #include "ui/gtk/old-gtk-compat.h"
189 #include "wsiconcap.h"
194 #include "airpcap_loader.h"
195 #include "airpcap_dlg.h"
196 #include "airpcap_gui_utils.h"
199 #include <epan/crypt/airpdcap_ws.h>
202 #ifdef HAVE_GTKOSXAPPLICATION
203 #include <gtkmacintegration/gtkosxapplication.h>
207 * Files under personal and global preferences directories in which
208 * GTK settings for Wireshark are stored.
210 #define RC_FILE "gtkrc"
213 capture_options global_capture_opts;
214 capture_session global_capture_session;
219 static gboolean capture_stopping;
221 /* "exported" main widgets */
222 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
224 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
225 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
226 static GtkWidget *main_first_pane, *main_second_pane;
228 /* internally used widgets */
229 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
231 GtkWidget *wireless_tb;
233 int airpcap_dll_ret_val = -1;
236 GString *comp_info_str, *runtime_info_str;
238 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
240 static guint tap_update_timer_id;
242 static void console_log_handler(const char *log_domain,
243 GLogLevelFlags log_level, const char *message, gpointer user_data);
245 static void create_main_window(gint, gint, gint, e_prefs*);
246 static void show_main_window(gboolean);
247 static void main_save_window_geometry(GtkWidget *widget);
250 /* Match selected byte pattern */
252 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
254 char *cur_filter, *new_filter;
256 if ((!text) || (0 == strlen(text))) {
257 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
263 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
265 switch (action&MATCH_SELECTED_MASK) {
267 case MATCH_SELECTED_REPLACE:
268 new_filter = g_strdup(text);
271 case MATCH_SELECTED_AND:
272 if ((!cur_filter) || (0 == strlen(cur_filter)))
273 new_filter = g_strdup(text);
275 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
278 case MATCH_SELECTED_OR:
279 if ((!cur_filter) || (0 == strlen(cur_filter)))
280 new_filter = g_strdup(text);
282 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
285 case MATCH_SELECTED_NOT:
286 new_filter = g_strconcat("!(", text, ")", NULL);
289 case MATCH_SELECTED_AND_NOT:
290 if ((!cur_filter) || (0 == strlen(cur_filter)))
291 new_filter = g_strconcat("!(", text, ")", NULL);
293 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
296 case MATCH_SELECTED_OR_NOT:
297 if ((!cur_filter) || (0 == strlen(cur_filter)))
298 new_filter = g_strconcat("!(", text, ")", NULL);
300 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
304 g_assert_not_reached();
309 /* Free up the copy we got of the old filter text. */
312 /* Don't change the current display filter if we only want to copy the filter */
313 if (action&MATCH_SELECTED_COPY_ONLY) {
314 GString *gtk_text_str = g_string_new("");
315 g_string_append(gtk_text_str, new_filter);
316 copy_to_clipboard(gtk_text_str);
317 g_string_free(gtk_text_str, TRUE);
319 /* create a new one and set the display filter entry accordingly */
320 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
322 /* Run the display filter so it goes in effect. */
323 if (action&MATCH_SELECTED_APPLY_NOW)
324 main_filter_packets(&cfile, new_filter, FALSE);
327 /* Free up the new filter text. */
332 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
336 if (cfile.finfo_selected) {
337 filter = proto_construct_match_selected_string(cfile.finfo_selected,
339 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
344 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
348 if (cfile.finfo_selected) {
349 filter = proto_construct_match_selected_string(cfile.finfo_selected,
351 if ((!filter) || (0 == strlen(filter))) {
352 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
353 "Could not acquire information to build a filter!\n"
354 "Try expanding or choosing another item.");
359 color_display_with_filter(filter);
362 color_filters_reset_tmp();
364 color_filters_set_tmp(filt_nr,filter, FALSE);
366 packet_list_colorize_packets();
372 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
374 gchar *selected_proto_url;
375 gchar *proto_abbrev = (gchar *)data;
380 if (cfile.finfo_selected) {
381 /* open wiki page using the protocol abbreviation */
382 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
383 browser_open_url(selected_proto_url);
384 g_free(selected_proto_url);
387 case(ESD_BTN_CANCEL):
390 g_assert_not_reached();
396 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
399 const gchar *proto_abbrev;
403 if (cfile.finfo_selected) {
404 /* convert selected field to protocol abbreviation */
405 /* XXX - could this conversion be simplified? */
406 field_id = cfile.finfo_selected->hfinfo->id;
407 /* if the selected field isn't a protocol, get its parent */
408 if(!proto_registrar_is_protocol(field_id)) {
409 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
412 proto_abbrev = proto_registrar_get_abbrev(field_id);
414 if (!proto_is_private(field_id)) {
415 /* ask the user if the wiki page really should be opened */
416 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
417 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
419 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
421 "The Wireshark Wiki is a collaborative approach to provide information "
422 "about Wireshark in several ways (not limited to protocol specifics).\n"
424 "This Wiki is new, so the page of the selected protocol "
425 "may not exist and/or may not contain valuable information.\n"
427 "As everyone can edit the Wiki and add new content (or extend existing), "
428 "you are encouraged to add information if you can.\n"
430 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
432 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
433 "which will save you a lot of editing and will give a consistent look over the pages.",
434 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
435 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
437 /* appologize to the user that the wiki page cannot be opened */
438 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
439 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
441 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
443 "Since this is a private protocol, such information is not available in "
444 "a public wiki. Therefore this wiki entry is blocked.\n"
446 "Sorry for the inconvenience.\n",
447 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
452 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
454 gchar *selected_proto_url;
455 gchar *proto_abbrev = (gchar *)data;
459 if (cfile.finfo_selected) {
460 /* open reference page using the protocol abbreviation */
461 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
462 browser_open_url(selected_proto_url);
463 g_free(selected_proto_url);
466 case(ESD_BTN_CANCEL):
469 g_assert_not_reached();
474 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
477 const gchar *proto_abbrev;
481 if (cfile.finfo_selected) {
482 /* convert selected field to protocol abbreviation */
483 /* XXX - could this conversion be simplified? */
484 field_id = cfile.finfo_selected->hfinfo->id;
485 /* if the selected field isn't a protocol, get its parent */
486 if(!proto_registrar_is_protocol(field_id)) {
487 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
490 proto_abbrev = proto_registrar_get_abbrev(field_id);
492 if (!proto_is_private(field_id)) {
493 /* ask the user if the wiki page really should be opened */
494 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
495 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
497 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
499 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
500 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
502 /* appologize to the user that the wiki page cannot be opened */
503 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
504 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
506 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
508 "Since this is a private protocol, such information is not available on "
509 "a public website. Therefore this filter entry is blocked.\n"
511 "Sorry for the inconvenience.\n",
512 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
518 is_address_column (gint column)
520 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
521 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
522 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
523 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
524 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
533 get_ip_address_list_from_packet_list_row(gpointer data)
535 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
536 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
539 GList *addr_list = NULL;
541 fdata = (frame_data *) packet_list_get_row_data(row);
546 if (!cf_read_frame (&cfile, fdata))
547 return NULL; /* error reading the frame */
549 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
550 col_custom_prime_edt(&edt, &cfile.cinfo);
552 epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
553 fdata, &cfile.cinfo);
554 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
556 /* First check selected column */
557 if (is_address_column (column)) {
558 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
561 for (col = 0; col < cfile.cinfo.num_cols; col++) {
562 /* Then check all columns except the selected */
563 if ((col != column) && (is_address_column (col))) {
564 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
568 epan_dissect_cleanup(&edt);
575 get_filter_from_packet_list_row_and_column(gpointer data)
577 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
578 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
582 fdata = (frame_data *) packet_list_get_row_data(row);
587 if (!cf_read_frame(&cfile, fdata))
588 return NULL; /* error reading the frame */
589 /* proto tree, visible. We need a proto tree if there's custom columns */
590 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
591 col_custom_prime_edt(&edt, &cfile.cinfo);
593 epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
594 fdata, &cfile.cinfo);
595 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
597 if ((cfile.cinfo.col_custom_occurrence[column]) ||
598 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
600 /* Only construct the filter when a single occurrence is displayed
601 * otherwise we might end up with a filter like "ip.proto==1,6".
603 * Or do we want to be able to filter on multiple occurrences so that
604 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
607 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
608 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
609 /* leak a little but safer than ep_ here */
610 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
611 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
612 if (hfi && hfi->parent == -1) {
614 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
615 } else if (hfi && IS_FT_STRING(hfi->type)) {
616 /* Custom string, add quotes */
617 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
618 cfile.cinfo.col_expr.col_expr_val[column]);
622 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
623 cfile.cinfo.col_expr.col_expr_val[column]);
628 epan_dissect_cleanup(&edt);
635 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
637 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
639 get_filter_from_packet_list_row_and_column((GtkWidget *)data));
642 /* This function allows users to right click in the details window and copy the text
643 * information to the operating systems clipboard.
645 * We first check to see if a string representation is setup in the tree and then
646 * read the string. If not available then we try to grab the value. If all else
647 * fails we display a message to the user to indicate the copy could not be completed.
650 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
652 GString *gtk_text_str = g_string_new("");
653 char labelstring[ITEM_LABEL_LENGTH];
654 char *stringpointer = labelstring;
658 case COPY_SELECTED_DESCRIPTION:
659 if (cfile.finfo_selected->rep &&
660 strlen (cfile.finfo_selected->rep->representation) > 0) {
661 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
664 case COPY_SELECTED_FIELDNAME:
665 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
666 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
669 case COPY_SELECTED_VALUE:
670 if (cfile.edt !=0 ) {
671 g_string_append(gtk_text_str,
672 get_node_field_value(cfile.finfo_selected, cfile.edt));
679 if (gtk_text_str->len == 0) {
680 /* If no representation then... Try to read the value */
681 proto_item_fill_label(cfile.finfo_selected, stringpointer);
682 g_string_append(gtk_text_str, stringpointer);
685 if (gtk_text_str->len == 0) {
686 /* Could not get item so display error msg */
687 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
689 /* Copy string to clipboard */
690 copy_to_clipboard(gtk_text_str);
692 g_string_free(gtk_text_str, TRUE); /* Free the memory */
696 /* mark as reference time frame */
698 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
702 frame->flags.ref_time=1;
703 cfile.ref_time_count++;
705 frame->flags.ref_time=0;
706 cfile.ref_time_count--;
708 cf_reftime_packets(&cfile);
709 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
710 packet_list_freeze();
711 cfile.displayed_count--;
712 packet_list_recreate_visible_rows();
715 packet_list_queue_draw();
719 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
723 timestamp_set_type(TS_RELATIVE);
724 recent.gui_time_format = TS_RELATIVE;
725 cf_timestamp_auto_precision(&cfile);
726 packet_list_queue_draw();
731 g_assert_not_reached();
734 if (cfile.current_frame) {
735 set_frame_reftime(!cfile.current_frame->flags.ref_time,
736 cfile.current_frame, cfile.current_row);
742 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
744 static GtkWidget *reftime_dialog = NULL;
748 if (cfile.current_frame) {
749 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
750 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
751 "%sSwitch to the appropriate Time Display Format?%s\n\n"
752 "Time References don't work well with the currently selected Time Display Format.\n\n"
753 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
754 simple_dialog_primary_start(), simple_dialog_primary_end());
755 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
757 set_frame_reftime(!cfile.current_frame->flags.ref_time,
758 cfile.current_frame, cfile.current_row);
762 case REFTIME_FIND_NEXT:
763 cf_find_packet_time_reference(&cfile, SD_FORWARD);
765 case REFTIME_FIND_PREV:
766 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
772 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
774 cf_find_packet_marked(&cfile, SD_FORWARD);
778 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
780 cf_find_packet_marked(&cfile, SD_BACKWARD);
784 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
787 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
789 gboolean has_blurb = FALSE;
790 guint length = 0, byte_len;
791 GtkWidget *byte_view;
792 const guint8 *byte_data;
797 /* if nothing is selected */
798 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
801 * Which byte view is displaying the current protocol tree
804 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
805 if (byte_view == NULL)
808 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
809 if (byte_data == NULL)
812 cf_unselect_field(&cfile);
813 packet_hex_print(byte_view, byte_data,
814 cfile.current_frame, NULL, byte_len);
815 proto_help_menu_modify(sel, &cfile);
818 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
821 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
823 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
824 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
825 g_assert(byte_data != NULL);
827 cfile.finfo_selected = finfo;
828 set_menus_for_selected_tree_row(&cfile);
831 if (finfo->hfinfo->blurb != NULL &&
832 finfo->hfinfo->blurb[0] != '\0') {
834 length = (guint) strlen(finfo->hfinfo->blurb);
836 length = (guint) strlen(finfo->hfinfo->name);
838 finfo_length = finfo->length + finfo->appendix_length;
840 if (finfo_length == 0) {
842 } else if (finfo_length == 1) {
843 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
845 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
847 statusbar_pop_field_msg(); /* get rid of current help msg */
849 statusbar_push_field_msg(" %s (%s)%s",
850 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
851 finfo->hfinfo->abbrev, len_str);
854 * Don't show anything if the field name is zero-length;
855 * the pseudo-field for "proto_tree_add_text()" is such
856 * a field, and we don't want "Text (text)" showing up
857 * on the status line if you've selected such a field.
859 * XXX - there are zero-length fields for which we *do*
860 * want to show the field name.
862 * XXX - perhaps the name and abbrev field should be null
863 * pointers rather than null strings for that pseudo-field,
864 * but we'd have to add checks for null pointers in some
865 * places if we did that.
867 * Or perhaps protocol tree items added with
868 * "proto_tree_add_text()" should have -1 as the field index,
869 * with no pseudo-field being used, but that might also
870 * require special checks for -1 to be added.
872 statusbar_push_field_msg("%s", "");
875 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
877 proto_help_menu_modify(sel, &cfile);
880 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
883 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
886 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
889 expand_all_tree(cfile.edt->tree, tree_view_gbl);
892 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
894 if (cfile.finfo_selected) {
895 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
896 cfile.finfo_selected->hfinfo->abbrev,0);
897 /* Recreate the packet list according to new preferences */
898 packet_list_recreate ();
899 if (!prefs.gui_use_pref_save) {
902 cfile.columns_changed = FALSE; /* Reset value */
906 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
910 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
912 /* the mouse position is at an entry, expand that one */
913 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
914 gtk_tree_path_free(path);
918 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
922 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
924 /* the mouse position is at an entry, expand that one */
926 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
927 gtk_tree_path_free(path);
931 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
933 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
935 if (cfile.edt->tree) {
936 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
940 /* Update main window items based on whether there's a capture in progress. */
942 main_set_for_capture_in_progress(gboolean capture_in_progress)
944 set_menus_for_capture_in_progress(capture_in_progress);
947 set_toolbar_for_capture_in_progress(capture_in_progress);
949 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
953 /* Update main window items based on whether we have a capture file. */
955 main_set_for_capture_file(gboolean have_capture_file_in)
957 have_capture_file = have_capture_file_in;
959 main_widgets_show_or_hide();
962 /* Update main window items based on whether we have captured packets. */
964 main_set_for_captured_packets(gboolean have_captured_packets)
966 set_menus_for_captured_packets(have_captured_packets);
967 set_toolbar_for_captured_packets(have_captured_packets);
970 /* Update main window items based on whether we have a packet history. */
972 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
974 set_menus_for_packet_history(back_history, forward_history);
975 set_toolbar_for_packet_history(back_history, forward_history);
981 /* get the current geometry, before writing it to disk */
982 main_save_window_geometry(top_level);
984 /* write user's recent file to disk
985 * It is no problem to write this file, even if we do not quit */
986 write_profile_recent();
989 /* XXX - should we check whether the capture file is an
990 unsaved temporary file for a live capture and, if so,
991 pop up a "do you want to exit without saving the capture
992 file?" dialog, and then just return, leaving said dialog
993 box to forcibly quit if the user clicks "OK"?
995 If so, note that this should be done in a subroutine that
996 returns TRUE if we do so, and FALSE otherwise, and if it
997 returns TRUE we should return TRUE without nuking anything.
999 Note that, if we do that, we might also want to check if
1000 an "Update list of packets in real time" capture is in
1001 progress and, if so, ask whether they want to terminate
1002 the capture and discard it, and return TRUE, before nuking
1003 any child capture, if they say they don't want to do so. */
1006 /* Nuke any child capture in progress. */
1007 capture_kill_child(&global_capture_session);
1010 /* Are we in the middle of reading a capture? */
1011 if (cfile.state == FILE_READ_IN_PROGRESS) {
1012 /* Yes, so we can't just close the file and quit, as
1013 that may yank the rug out from under the read in
1014 progress; instead, just set the state to
1015 "FILE_READ_ABORTED" and return - the code doing the read
1016 will check for that and, if it sees that, will clean
1018 cfile.state = FILE_READ_ABORTED;
1020 /* Say that the window should *not* be deleted;
1021 that'll be done by the code that cleans up. */
1024 /* Close any capture file we have open; on some OSes, you
1025 can't unlink a temporary capture file if you have it
1027 "cf_close()" will unlink it after closing it if
1028 it's a temporary file.
1030 We do this here, rather than after the main loop returns,
1031 as, after the main loop returns, the main window may have
1032 been destroyed (if this is called due to a "destroy"
1033 even on the main window rather than due to the user
1034 selecting a menu item), and there may be a crash
1035 or other problem when "cf_close()" tries to
1036 clean up stuff in the main window.
1038 XXX - is there a better place to put this?
1039 Or should we have a routine that *just* closes the
1040 capture file, and doesn't do anything with the UI,
1041 which we'd call here, and another routine that
1042 calls that routine and also cleans up the UI, which
1043 we'd call elsewhere? */
1046 /* Exit by leaving the main loop, so that any quit functions
1047 we registered get called. */
1050 /* Say that the window should be deleted. */
1056 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1058 /* If we're in the middle of stopping a capture, don't do anything;
1059 the user can try deleting the window after the capture stops. */
1060 if (capture_stopping)
1063 /* If there's unsaved data, let the user save it first.
1064 If they cancel out of it, don't quit. */
1065 if (do_file_close(&cfile, TRUE, " before quitting"))
1066 return main_do_quit();
1068 return TRUE; /* will this keep the window from being deleted? */
1073 main_pane_load_window_geometry(void)
1075 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1076 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1077 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1078 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1084 main_load_window_geometry(GtkWidget *widget)
1086 window_geometry_t geom;
1088 geom.set_pos = prefs.gui_geometry_save_position;
1089 geom.x = recent.gui_geometry_main_x;
1090 geom.y = recent.gui_geometry_main_y;
1091 geom.set_size = prefs.gui_geometry_save_size;
1092 if (recent.gui_geometry_main_width > 0 &&
1093 recent.gui_geometry_main_height > 0) {
1094 geom.width = recent.gui_geometry_main_width;
1095 geom.height = recent.gui_geometry_main_height;
1096 geom.set_maximized = prefs.gui_geometry_save_maximized;
1098 /* We assume this means the width and height weren't set in
1099 the "recent" file (or that there is no "recent" file),
1100 and weren't set to a default value, so we don't set the
1101 size. (The "recent" file code rejects non-positive width
1102 and height values.) */
1103 geom.set_size = FALSE;
1105 geom.maximized = recent.gui_geometry_main_maximized;
1107 window_set_geometry(widget, &geom);
1109 main_pane_load_window_geometry();
1110 statusbar_load_window_geometry();
1115 main_save_window_geometry(GtkWidget *widget)
1117 window_geometry_t geom;
1119 window_get_geometry(widget, &geom);
1121 if (prefs.gui_geometry_save_position) {
1122 recent.gui_geometry_main_x = geom.x;
1123 recent.gui_geometry_main_y = geom.y;
1126 if (prefs.gui_geometry_save_size) {
1127 recent.gui_geometry_main_width = geom.width;
1128 recent.gui_geometry_main_height = geom.height;
1131 if(prefs.gui_geometry_save_maximized) {
1132 recent.gui_geometry_main_maximized = geom.maximized;
1135 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1136 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1137 statusbar_save_window_geometry();
1141 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1143 /* If there's unsaved data, let the user save it first. */
1144 if (do_file_close(&cfile, TRUE, " before quitting"))
1149 print_usage(gboolean print_ver) {
1159 fprintf(output, "Wireshark " VERSION "%s\n"
1160 "Interactively dump and analyze network traffic.\n"
1161 "See http://www.wireshark.org for more information.\n"
1164 wireshark_gitversion, get_copyright_info());
1168 fprintf(output, "\n");
1169 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1170 fprintf(output, "\n");
1173 fprintf(output, "Capture interface:\n");
1174 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1175 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1176 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1177 fprintf(output, " -p don't capture in promiscuous mode\n");
1178 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1179 fprintf(output, " -S update packet display when new packets are captured\n");
1180 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1181 #ifdef HAVE_PCAP_CREATE
1182 fprintf(output, " -I capture in monitor mode, if available\n");
1184 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1185 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1187 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1188 fprintf(output, " -D print list of interfaces and exit\n");
1189 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1190 fprintf(output, "\n");
1191 fprintf(output, "Capture stop conditions:\n");
1192 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1193 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1194 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1195 fprintf(output, " files:NUM - stop after NUM files\n");
1196 /*fprintf(output, "\n");*/
1197 fprintf(output, "Capture output:\n");
1198 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1199 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1200 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1201 #endif /* HAVE_LIBPCAP */
1202 #ifdef HAVE_PCAP_REMOTE
1203 fprintf(output, "RPCAP options:\n");
1204 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1206 /*fprintf(output, "\n");*/
1207 fprintf(output, "Input file:\n");
1208 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1210 fprintf(output, "\n");
1211 fprintf(output, "Processing:\n");
1212 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1213 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1214 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1216 fprintf(output, "\n");
1217 fprintf(output, "User interface:\n");
1218 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1219 fprintf(output, " -Y <display filter> start with the given display filter\n");
1220 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1221 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1222 fprintf(output, " filter\n");
1223 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1224 fprintf(output, " -m <font> set the font name used for most text\n");
1225 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
1226 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1227 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1228 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1230 fprintf(output, "\n");
1231 fprintf(output, "Output:\n");
1232 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1234 fprintf(output, "\n");
1235 fprintf(output, "Miscellaneous:\n");
1236 fprintf(output, " -h display this help and exit\n");
1237 fprintf(output, " -v display version info and exit\n");
1238 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1239 fprintf(output, " persdata:path - personal data files\n");
1240 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1241 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1243 fprintf(output, " --display=DISPLAY X display to use\n");
1254 printf(PACKAGE " " VERSION "%s\n"
1261 wireshark_gitversion, get_copyright_info(), comp_info_str->str,
1262 runtime_info_str->str);
1266 * Report an error in command-line arguments.
1267 * Creates a console on Windows.
1270 cmdarg_err(const char *fmt, ...)
1277 fprintf(stderr, "wireshark: ");
1279 vfprintf(stderr, fmt, ap);
1281 fprintf(stderr, "\n");
1285 * Report additional information for an error in command-line arguments.
1286 * Creates a console on Windows.
1287 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1288 * terminal isn't the standard error?
1291 cmdarg_err_cont(const char *fmt, ...)
1299 vfprintf(stderr, fmt, ap);
1300 fprintf(stderr, "\n");
1305 Once every 3 seconds we get a callback here which we use to update
1309 tap_update_cb(gpointer data _U_)
1311 draw_tap_listeners(FALSE);
1316 * Periodically process outstanding hostname lookups. If we have new items,
1317 * redraw the packet list and tree view.
1321 resolv_update_cb(gpointer data _U_)
1323 /* Anything new show up? */
1324 if (host_name_lookup_process()) {
1325 if (gtk_widget_get_window(pkt_scrollw))
1326 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1327 if (gtk_widget_get_window(tv_scrollw))
1328 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1331 /* Always check. Even if we don't do async lookups we could still get
1332 passive updates, e.g. from DNS packets. */
1337 /* Update various parts of the main window for a capture file "unsaved
1338 changes" change - update the title to reflect whether there are
1339 unsaved changes or not, and update the menus and toolbar to
1340 enable or disable the "Save" operation. */
1342 main_update_for_unsaved_changes(capture_file *cf)
1344 set_titlebar_for_capture_file(cf);
1345 set_menus_for_capture_file(cf);
1346 set_toolbar_for_capture_file(cf);
1351 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1353 /* Update menubar and toolbar */
1354 menu_auto_scroll_live_changed(auto_scroll_live_in);
1355 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1357 /* change auto scroll state */
1358 auto_scroll_live = auto_scroll_live_in;
1363 main_colorize_changed(gboolean packet_list_colorize)
1365 /* Update menubar and toolbar */
1366 menu_colorize_changed(packet_list_colorize);
1367 toolbar_colorize_changed(packet_list_colorize);
1369 /* change colorization */
1370 if(packet_list_colorize != recent.packet_list_colorize) {
1371 recent.packet_list_colorize = packet_list_colorize;
1372 color_filters_enable(packet_list_colorize);
1373 packet_list_colorize_packets();
1377 static GtkWidget *close_dlg = NULL;
1380 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1382 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1387 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1389 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1394 main_cf_cb_file_closing(capture_file *cf)
1396 /* if we have more than 10000 packets, show a splash screen while closing */
1397 /* XXX - don't know a better way to decide whether to show or not,
1398 * as most of the time is spend in various calls that destroy various
1399 * data structures, so it wouldn't be easy to use a progress bar,
1400 * rather than, say, a progress spinner, here! */
1401 if(cf->count > 10000) {
1402 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1403 "%sClosing file!%s\n\nPlease wait ...",
1404 simple_dialog_primary_start(),
1405 simple_dialog_primary_end());
1406 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1408 /* Clear maunally resolved addresses */
1409 manually_resolve_cleanup();
1410 /* Destroy all windows that refer to the
1411 capture file we're closing. */
1412 destroy_packet_wins();
1414 /* Update the titlebar to reflect the lack of a capture file. */
1415 set_titlebar_for_capture_file(NULL);
1417 /* Disable all menu and toolbar items that make sense only if
1418 you have a capture. */
1419 set_menus_for_capture_file(NULL);
1420 set_toolbar_for_capture_file(NULL);
1421 main_set_for_captured_packets(FALSE);
1422 set_menus_for_selected_packet(cf);
1423 main_set_for_capture_in_progress(FALSE);
1424 set_capture_if_dialog_for_capture_in_progress(FALSE);
1425 set_menus_for_selected_tree_row(cf);
1427 /* Set up main window for no capture file. */
1428 main_set_for_capture_file(FALSE);
1430 main_window_update();
1435 main_cf_cb_file_closed(capture_file *cf _U_)
1437 if(close_dlg != NULL) {
1438 splash_destroy(close_dlg);
1445 main_cf_cb_file_read_started(capture_file *cf _U_)
1447 tap_param_dlg_update();
1449 /* Set up main window for a capture file. */
1450 main_set_for_capture_file(TRUE);
1454 main_cf_cb_file_read_finished(capture_file *cf)
1458 if (!cf->is_tempfile && cf->filename) {
1459 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1460 add_menu_recent_capture_file(cf->filename);
1462 /* Remember folder for next Open dialog and save it in recent */
1463 dir_path = get_dirname(g_strdup(cf->filename));
1464 set_last_open_dir(dir_path);
1468 /* Update the appropriate parts of the main window. */
1469 main_update_for_unsaved_changes(cf);
1471 /* Enable menu items that make sense if you have some captured packets. */
1472 main_set_for_captured_packets(TRUE);
1476 main_cf_cb_file_rescan_finished(capture_file *cf)
1480 if (!cf->is_tempfile && cf->filename) {
1481 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1482 add_menu_recent_capture_file(cf->filename);
1484 /* Remember folder for next Open dialog and save it in recent */
1485 dir_path = get_dirname(g_strdup(cf->filename));
1486 set_last_open_dir(dir_path);
1490 /* Update the appropriate parts of the main window. */
1491 main_update_for_unsaved_changes(cf);
1495 static GList *icon_list_create(
1496 const guint8 *icon16_pb,
1497 const guint8 *icon32_pb,
1498 const guint8 *icon48_pb,
1499 const guint8 *icon64_pb)
1501 GList *icon_list = NULL;
1502 GdkPixbuf * pixbuf16;
1503 GdkPixbuf * pixbuf32;
1504 GdkPixbuf * pixbuf48;
1505 GdkPixbuf * pixbuf64;
1508 if(icon16_pb != NULL) {
1509 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1511 icon_list = g_list_append(icon_list, pixbuf16);
1514 if(icon32_pb != NULL) {
1515 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1517 icon_list = g_list_append(icon_list, pixbuf32);
1520 if(icon48_pb != NULL) {
1521 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1523 icon_list = g_list_append(icon_list, pixbuf48);
1526 if(icon64_pb != NULL) {
1527 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1529 icon_list = g_list_append(icon_list, pixbuf64);
1536 main_capture_cb_capture_prepared(capture_session *cap_session)
1538 static GList *icon_list = NULL;
1540 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1542 if(icon_list == NULL) {
1543 icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1545 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1547 /* Disable menu items that make no sense if you're currently running
1549 main_set_for_capture_in_progress(TRUE);
1550 set_capture_if_dialog_for_capture_in_progress(TRUE);
1552 /* Don't set up main window for a capture file. */
1553 main_set_for_capture_file(FALSE);
1557 main_capture_cb_capture_update_started(capture_session *cap_session)
1559 /* We've done this in "prepared" above, but it will be cleared while
1560 switching to the next multiple file. */
1561 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1563 main_set_for_capture_in_progress(TRUE);
1564 set_capture_if_dialog_for_capture_in_progress(TRUE);
1566 /* Enable menu items that make sense if you have some captured
1567 packets (yes, I know, we don't have any *yet*). */
1568 main_set_for_captured_packets(TRUE);
1570 /* Set up main window for a capture file. */
1571 main_set_for_capture_file(TRUE);
1575 main_capture_cb_capture_update_finished(capture_session *cap_session)
1577 capture_file *cf = (capture_file *)cap_session->cf;
1578 static GList *icon_list = NULL;
1580 /* The capture isn't stopping any more - it's stopped. */
1581 capture_stopping = FALSE;
1583 if (!cf->is_tempfile && cf->filename) {
1584 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1585 add_menu_recent_capture_file(cf->filename);
1588 /* Enable menu items that make sense if you're not currently running
1590 main_set_for_capture_in_progress(FALSE);
1591 set_capture_if_dialog_for_capture_in_progress(FALSE);
1593 /* Update the main window as appropriate. This has to occur AFTER
1594 * main_set_for_capture_in_progress() or else some of the menus are
1595 * incorrectly disabled (see bug
1596 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1597 main_update_for_unsaved_changes(cf);
1599 /* Set up main window for a capture file. */
1600 main_set_for_capture_file(TRUE);
1602 if(icon_list == NULL) {
1603 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1605 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1607 if(global_capture_opts.quit_after_cap) {
1608 /* command line asked us to quit after the capture */
1609 /* don't pop up a dialog to ask for unsaved files etc. */
1615 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1617 /* Don't set up main window for a capture file. */
1618 main_set_for_capture_file(FALSE);
1622 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1625 capture_file *cf = (capture_file *)cap_session->cf;
1627 static GList *icon_list = NULL;
1629 /* The capture isn't stopping any more - it's stopped. */
1630 capture_stopping = FALSE;
1632 /*set_titlebar_for_capture_file(cf);*/
1634 /* Enable menu items that make sense if you're not currently running
1636 main_set_for_capture_in_progress(FALSE);
1637 set_capture_if_dialog_for_capture_in_progress(FALSE);
1639 /* Restore the standard title bar message */
1640 /* (just in case we have trouble opening the capture file). */
1641 set_titlebar_for_capture_file(NULL);
1643 if(icon_list == NULL) {
1644 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1646 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1648 /* We don't have loaded the capture file, this will be done later.
1649 * For now we still have simply a blank screen. */
1651 if(global_capture_opts.quit_after_cap) {
1652 /* command line asked us to quit after the capture */
1653 /* don't pop up a dialog to ask for unsaved files etc. */
1659 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1661 capture_stopping = TRUE;
1662 set_menus_for_capture_stopping();
1664 set_toolbar_for_capture_stopping();
1666 set_capture_if_dialog_for_capture_stopping();
1671 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1673 static GList *icon_list = NULL;
1675 /* Capture isn't stopping any more. */
1676 capture_stopping = FALSE;
1678 /* the capture failed before the first packet was captured
1679 reset title, menus and icon */
1680 set_titlebar_for_capture_file(NULL);
1682 main_set_for_capture_in_progress(FALSE);
1683 set_capture_if_dialog_for_capture_in_progress(FALSE);
1685 main_set_for_capture_file(FALSE);
1687 if(icon_list == NULL) {
1688 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1690 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1693 if(global_capture_opts.quit_after_cap) {
1694 /* command line asked us to quit after the capture */
1695 /* don't pop up a dialog to ask for unsaved files etc. */
1699 #endif /* HAVE_LIBPCAP */
1702 main_cf_cb_packet_selected(gpointer data)
1704 capture_file *cf = (capture_file *)data;
1706 /* Display the GUI protocol tree and packet bytes.
1707 XXX - why do we dump core if we call "proto_tree_draw()"
1708 before calling "add_byte_views()"? */
1709 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1710 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1712 /* Note: Both string and hex value searches in the packet data produce a non-zero
1713 search_pos if successful */
1714 if(cf->search_in_progress &&
1715 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1716 highlight_field(cf->edt->tvb, cf->search_pos,
1717 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1720 /* A packet is selected. */
1721 set_menus_for_selected_packet(cf);
1725 main_cf_cb_packet_unselected(capture_file *cf)
1727 /* No packet is being displayed; clear the hex dump pane by getting
1728 rid of all the byte views. */
1729 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1730 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1732 /* Add a placeholder byte view so that there's at least something
1733 displayed in the byte view notebook. */
1734 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1736 /* And clear the protocol tree display as well. */
1737 proto_tree_draw(NULL, tree_view_gbl);
1739 /* No packet is selected. */
1740 set_menus_for_selected_packet(cf);
1744 main_cf_cb_field_unselected(capture_file *cf)
1746 set_menus_for_selected_tree_row(cf);
1750 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1752 capture_file *cf = (capture_file *)data;
1754 case(cf_cb_file_opened):
1755 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1756 fileset_file_opened(cf);
1758 case(cf_cb_file_closing):
1759 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1760 main_cf_cb_file_closing(cf);
1762 case(cf_cb_file_closed):
1763 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1764 main_cf_cb_file_closed(cf);
1765 fileset_file_closed();
1767 case(cf_cb_file_read_started):
1768 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1769 main_cf_cb_file_read_started(cf);
1771 case(cf_cb_file_read_finished):
1772 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1773 main_cf_cb_file_read_finished(cf);
1775 case(cf_cb_file_reload_started):
1776 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1777 main_cf_cb_file_read_started(cf);
1779 case(cf_cb_file_reload_finished):
1780 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1781 main_cf_cb_file_read_finished(cf);
1783 case(cf_cb_file_rescan_started):
1784 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1786 case(cf_cb_file_rescan_finished):
1787 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1788 main_cf_cb_file_rescan_finished(cf);
1790 case(cf_cb_file_fast_save_finished):
1791 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1792 main_cf_cb_file_rescan_finished(cf);
1794 case(cf_cb_packet_selected):
1795 main_cf_cb_packet_selected(cf);
1797 case(cf_cb_packet_unselected):
1798 main_cf_cb_packet_unselected(cf);
1800 case(cf_cb_field_unselected):
1801 main_cf_cb_field_unselected(cf);
1803 case(cf_cb_file_save_started):
1804 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1806 case(cf_cb_file_save_finished):
1807 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1809 case(cf_cb_file_save_failed):
1810 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1812 case(cf_cb_file_save_stopped):
1813 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1815 case(cf_cb_file_export_specified_packets_started):
1816 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1818 case(cf_cb_file_export_specified_packets_finished):
1819 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1821 case(cf_cb_file_export_specified_packets_failed):
1822 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1824 case(cf_cb_file_export_specified_packets_stopped):
1825 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1828 g_warning("main_cf_callback: event %u unknown", event);
1829 g_assert_not_reached();
1835 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1837 #ifdef HAVE_GTKOSXAPPLICATION
1838 GtkosxApplication *theApp;
1841 case(capture_cb_capture_prepared):
1842 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1843 main_capture_cb_capture_prepared(cap_session);
1845 case(capture_cb_capture_update_started):
1846 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1847 main_capture_cb_capture_update_started(cap_session);
1848 #ifdef HAVE_GTKOSXAPPLICATION
1849 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1850 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1853 case(capture_cb_capture_update_continue):
1854 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1856 case(capture_cb_capture_update_finished):
1857 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1858 main_capture_cb_capture_update_finished(cap_session);
1860 case(capture_cb_capture_fixed_started):
1861 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1862 main_capture_cb_capture_fixed_started(cap_session);
1864 case(capture_cb_capture_fixed_continue):
1865 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1867 case(capture_cb_capture_fixed_finished):
1868 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1869 main_capture_cb_capture_fixed_finished(cap_session);
1871 case(capture_cb_capture_stopping):
1872 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1873 /* Beware: this state won't be called, if the capture child
1874 * closes the capturing on its own! */
1875 #ifdef HAVE_GTKOSXAPPLICATION
1876 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1877 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1879 main_capture_cb_capture_stopping(cap_session);
1881 case(capture_cb_capture_failed):
1882 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1883 main_capture_cb_capture_failed(cap_session);
1886 g_warning("main_capture_callback: event %u unknown", event);
1887 g_assert_not_reached();
1893 get_gtk_compiled_info(GString *str)
1895 g_string_append(str, "with ");
1896 g_string_append_printf(str,
1897 #ifdef GTK_MAJOR_VERSION
1898 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1901 "GTK+ (version unknown)");
1903 g_string_append(str, ", ");
1905 g_string_append(str, "with Cairo ");
1906 g_string_append(str, CAIRO_VERSION_STRING);
1907 g_string_append(str, ", ");
1910 g_string_append(str, "with Pango ");
1911 g_string_append(str, PANGO_VERSION_STRING);
1912 g_string_append(str, ", ");
1917 get_gui_compiled_info(GString *str)
1919 epan_get_compiled_version_info(str);
1921 g_string_append(str, ", ");
1922 #ifdef HAVE_LIBPORTAUDIO
1923 #ifdef PORTAUDIO_API_1
1924 g_string_append(str, "with PortAudio <= V18");
1925 #else /* PORTAUDIO_API_1 */
1926 g_string_append(str, "with ");
1927 g_string_append(str, Pa_GetVersionText());
1928 #endif /* PORTAUDIO_API_1 */
1929 #else /* HAVE_LIBPORTAUDIO */
1930 g_string_append(str, "without PortAudio");
1931 #endif /* HAVE_LIBPORTAUDIO */
1933 g_string_append(str, ", ");
1935 get_compiled_airpcap_version(str);
1937 g_string_append(str, "without AirPcap");
1942 get_gui_runtime_info(GString *str)
1944 epan_get_runtime_version_info(str);
1947 g_string_append(str, ", ");
1948 get_runtime_airpcap_version(str);
1952 g_string_append(str, ", ");
1953 u3_runtime_info(str);
1958 read_configuration_files(char **gdp_path, char **dp_path)
1960 int gpf_open_errno, gpf_read_errno;
1961 int cf_open_errno, df_open_errno;
1962 int gdp_open_errno, gdp_read_errno;
1963 int dp_open_errno, dp_read_errno;
1964 char *gpf_path, *pf_path;
1965 char *cf_path, *df_path;
1966 int pf_open_errno, pf_read_errno;
1969 /* load the decode as entries of this profile */
1970 load_decode_as_entries();
1972 /* Read the preference files. */
1973 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1974 &pf_open_errno, &pf_read_errno, &pf_path);
1976 if (gpf_path != NULL) {
1977 if (gpf_open_errno != 0) {
1978 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1979 "Could not open global preferences file\n\"%s\": %s.",
1980 gpf_path, g_strerror(gpf_open_errno));
1982 if (gpf_read_errno != 0) {
1983 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1984 "I/O error reading global preferences file\n\"%s\": %s.",
1985 gpf_path, g_strerror(gpf_read_errno));
1988 if (pf_path != NULL) {
1989 if (pf_open_errno != 0) {
1990 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1991 "Could not open your preferences file\n\"%s\": %s.",
1992 pf_path, g_strerror(pf_open_errno));
1994 if (pf_read_errno != 0) {
1995 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1996 "I/O error reading your preferences file\n\"%s\": %s.",
1997 pf_path, g_strerror(pf_read_errno));
2004 /* if the user wants a console to be always there, well, we should open one for him */
2005 if (prefs_p->gui_console_open == console_open_always) {
2010 /* Read the capture filter file. */
2011 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2012 if (cf_path != NULL) {
2013 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2014 "Could not open your capture filter file\n\"%s\": %s.",
2015 cf_path, g_strerror(cf_open_errno));
2019 /* Read the display filter file. */
2020 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2021 if (df_path != NULL) {
2022 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2023 "Could not open your display filter file\n\"%s\": %s.",
2024 df_path, g_strerror(df_open_errno));
2028 /* Read the disabled protocols file. */
2029 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2030 dp_path, &dp_open_errno, &dp_read_errno);
2031 if (*gdp_path != NULL) {
2032 if (gdp_open_errno != 0) {
2033 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2034 "Could not open global disabled protocols file\n\"%s\": %s.",
2035 *gdp_path, g_strerror(gdp_open_errno));
2037 if (gdp_read_errno != 0) {
2038 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2039 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2040 *gdp_path, g_strerror(gdp_read_errno));
2045 if (*dp_path != NULL) {
2046 if (dp_open_errno != 0) {
2047 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2048 "Could not open your disabled protocols file\n\"%s\": %s.",
2049 *dp_path, g_strerror(dp_open_errno));
2051 if (dp_read_errno != 0) {
2052 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2053 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2054 *dp_path, g_strerror(dp_read_errno));
2063 /* Check if there's something important to tell the user during startup.
2064 * We want to do this *after* showing the main window so that any windows
2065 * we pop up will be above the main window.
2069 check_and_warn_user_startup(gchar *cf_name)
2071 check_and_warn_user_startup(gchar *cf_name _U_)
2074 gchar *cur_user, *cur_group;
2075 gpointer priv_warning_dialog;
2077 /* Tell the user not to run as root. */
2078 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2079 cur_user = get_cur_username();
2080 cur_group = get_cur_groupname();
2081 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2082 "Running as user \"%s\" and group \"%s\".\n"
2083 "This could be dangerous.\n\n"
2084 "If you're running Wireshark this way in order to perform live capture, "
2085 "you may want to be aware that there is a better way documented at\n"
2086 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2089 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2090 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2094 /* Warn the user if npf.sys isn't loaded. */
2095 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2096 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2097 "The NPF driver isn't running. You may have trouble\n"
2098 "capturing or listing interfaces.");
2099 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2100 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2106 /* And now our feature presentation... [ fade to music ] */
2108 main(int argc, char *argv[])
2110 char *init_progfile_dir_error;
2113 gboolean arg_error = FALSE;
2115 extern int info_update_freq; /* Found in about_dlg.c. */
2116 const gchar *filter;
2124 char *gdp_path, *dp_path;
2127 gboolean start_capture = FALSE;
2128 gboolean list_link_layer_types = FALSE;
2133 gboolean capture_option_specified = FALSE;
2140 gint pl_size = 280, tv_size = 95, bv_size = 75;
2141 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2142 dfilter_t *rfcode = NULL;
2143 gboolean rfilter_parse_failed = FALSE;
2146 GtkWidget *splash_win = NULL;
2147 GLogLevelFlags log_flags;
2148 guint go_to_packet = 0;
2149 search_direction jump_backwards = SD_FORWARD;
2150 dfilter_t *jump_to_filter = NULL;
2152 unsigned int in_file_type = WTAP_TYPE_AUTO;
2153 #ifdef HAVE_GTKOSXAPPLICATION
2154 GtkosxApplication *theApp;
2158 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2159 #define OPTSTRING_B "B:"
2161 #define OPTSTRING_B ""
2162 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2163 #else /* HAVE_LIBPCAP */
2164 #define OPTSTRING_B ""
2165 #endif /* HAVE_LIBPCAP */
2166 #ifdef HAVE_PCAP_REMOTE
2167 #define OPTSTRING_A "A:"
2169 #define OPTSTRING_A ""
2171 #ifdef HAVE_PCAP_CREATE
2172 #define OPTSTRING_I "I"
2174 #define OPTSTRING_I ""
2177 #define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:Y:z:"
2179 static const char optstring[] = OPTSTRING;
2182 /* Set the C-language locale to the native environment. */
2183 setlocale(LC_ALL, "");
2185 arg_list_utf_16to8(argc, argv);
2186 create_app_running_mutex();
2190 * Get credential information for later use, and drop privileges
2191 * before doing anything else.
2192 * Let the user know if anything happened.
2194 init_process_policies();
2195 relinquish_special_privs_perm();
2198 * Attempt to get the pathname of the executable file.
2200 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2202 /* initialize the funnel mini-api */
2203 initialize_funnel_ops();
2205 AirPDcapInitContext(&airpdcap_ctx);
2208 /* Load wpcap if possible. Do this before collecting the run-time version information */
2211 /* ... and also load the packet.dll from wpcap */
2212 wpcap_packet_load();
2215 /* Load the airpcap.dll. This must also be done before collecting
2216 * run-time version information. */
2217 airpcap_dll_ret_val = load_airpcap();
2219 switch (airpcap_dll_ret_val) {
2220 case AIRPCAP_DLL_OK:
2221 /* load the airpcap interfaces */
2222 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2224 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2225 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2226 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2229 airpcap_if_active = NULL;
2233 /* select the first ad default (THIS SHOULD BE CHANGED) */
2234 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2239 * XXX - Maybe we need to warn the user if one of the following happens???
2241 case AIRPCAP_DLL_OLD:
2242 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2245 case AIRPCAP_DLL_ERROR:
2246 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2249 case AIRPCAP_DLL_NOT_FOUND:
2250 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2254 #endif /* HAVE_AIRPCAP */
2257 /* Assemble the compile-time version information string */
2258 comp_info_str = g_string_new("Compiled ");
2260 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2262 /* Assemble the run-time version information string */
2263 runtime_info_str = g_string_new("Running ");
2264 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2267 ws_add_crash_info(PACKAGE " " VERSION "%s\n"
2272 wireshark_gitversion, comp_info_str->str, runtime_info_str->str);
2274 /* Start windows sockets */
2275 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2278 profile_store_persconffiles (TRUE);
2280 /* Read the profile independent recent file. We have to do this here so we can */
2281 /* set the profile before it can be set from the command line parameter */
2282 recent_read_static(&rf_path, &rf_open_errno);
2283 if (rf_path != NULL && rf_open_errno != 0) {
2284 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2285 "Could not open common recent file\n\"%s\": %s.",
2286 rf_path, g_strerror(rf_open_errno));
2289 /* "pre-scan" the command line parameters, if we have "console only"
2290 parameters. We do this so we don't start GTK+ if we're only showing
2291 command-line help or version information.
2293 XXX - this pre-scan is done before we start GTK+, so we haven't
2294 run gtk_init() on the arguments. That means that GTK+ arguments
2295 have not been removed from the argument list; those arguments
2296 begin with "--", and will be treated as an error by getopt().
2298 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2301 optind_initial = optind;
2302 while ((opt = getopt(argc, argv, optstring)) != -1) {
2304 case 'C': /* Configuration Profile */
2305 if (profile_exists (optarg, FALSE)) {
2306 set_profile_name (optarg);
2308 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2312 case 'D': /* Print a list of capture devices and exit */
2314 if_list = capture_interface_list(&err, &err_str,main_window_update);
2315 if (if_list == NULL) {
2317 case CANT_GET_INTERFACE_LIST:
2318 case DONT_HAVE_PCAP:
2319 cmdarg_err("%s", err_str);
2323 case NO_INTERFACES_FOUND:
2324 cmdarg_err("There are no interfaces on which a capture can be done");
2332 capture_opts_print_interfaces(if_list);
2333 free_interface_list(if_list);
2338 #else /* HAVE_LIBPCAP */
2339 capture_option_specified = TRUE;
2341 #endif /* HAVE_LIBPCAP */
2343 case 'h': /* Print help and exit */
2349 if (strcmp(optarg, "-") == 0)
2350 set_stdin_capture(TRUE);
2353 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
2354 if (!persfilepath_opt(opt, optarg)) {
2355 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2359 case 'v': /* Show version and exit */
2371 * Extension command line options have to be processed before
2372 * we call epan_init() as they are supposed to be used by dissectors
2373 * or taps very early in the registration process.
2377 case '?': /* Ignore errors - the "real" scan will catch them. */
2382 /* Init the "Open file" dialog directory */
2383 /* (do this after the path settings are processed) */
2385 /* Read the profile dependent (static part) of the recent file. */
2386 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2387 /* recent lists which is done in the dynamic part. */
2388 /* We have to do this already here, so command line parameters can overwrite these values. */
2389 recent_read_profile_static(&rf_path, &rf_open_errno);
2390 if (rf_path != NULL && rf_open_errno != 0) {
2391 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2392 "Could not open recent file\n\"%s\": %s.",
2393 rf_path, g_strerror(rf_open_errno));
2396 if (recent.gui_fileopen_remembered_dir &&
2397 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2398 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2400 set_last_open_dir(get_persdatafile_dir());
2403 /* Set getopt index back to initial value, so it will start with the
2404 first command line parameter again. Also reset opterr to 1, so that
2405 error messages are printed by getopt().
2407 XXX - this seems to work on most platforms, but time will tell.
2408 The Single UNIX Specification says "The getopt() function need
2409 not be reentrant", so this isn't guaranteed to work. The Mac
2410 OS X 10.4[.x] getopt() man page says
2412 In order to use getopt() to evaluate multiple sets of arguments, or to
2413 evaluate a single set of arguments multiple times, the variable optreset
2414 must be set to 1 before the second and each additional set of calls to
2415 getopt(), and the variable optind must be reinitialized.
2419 The optreset variable was added to make it possible to call the getopt()
2420 function multiple times. This is an extension to the IEEE Std 1003.2
2421 (``POSIX.2'') specification.
2423 which I think comes from one of the other BSDs.
2425 XXX - if we want to control all the command-line option errors, so
2426 that we can display them where we choose (e.g., in a window), we'd
2427 want to leave opterr as 0, and produce our own messages using optopt.
2428 We'd have to check the value of optopt to see if it's a valid option
2429 letter, in which case *presumably* the error is "this option requires
2430 an argument but none was specified", or not a valid option letter,
2431 in which case *presumably* the error is "this option isn't valid".
2432 Some versions of getopt() let you supply a option string beginning
2433 with ':', which means that getopt() will return ':' rather than '?'
2434 for "this option requires an argument but none was specified", but
2436 optind = optind_initial;
2439 #if !GLIB_CHECK_VERSION(2,31,0)
2440 g_thread_init(NULL);
2443 /* Set the current locale according to the program environment.
2444 * We haven't localized anything, but some GTK widgets are localized
2445 * (the file selection dialogue, for example).
2446 * This also sets the C-language locale to the native environment. */
2447 setlocale (LC_ALL, "");
2449 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2450 gtk_init (&argc, &argv);
2452 cf_callback_add(main_cf_callback, NULL);
2454 capture_callback_add(main_capture_callback, NULL);
2456 cf_callback_add(statusbar_cf_callback, NULL);
2458 capture_callback_add(statusbar_capture_callback, NULL);
2461 /* Arrange that if we have no console window, and a GLib message logging
2462 routine is called to log a message, we pop up a console window.
2464 We do that by inserting our own handler for all messages logged
2465 to the default domain; that handler pops up a console if necessary,
2466 and then calls the default handler. */
2468 /* We might want to have component specific log levels later ... */
2470 log_flags = (GLogLevelFlags)
2472 G_LOG_LEVEL_CRITICAL|
2473 G_LOG_LEVEL_WARNING|
2474 G_LOG_LEVEL_MESSAGE|
2478 G_LOG_FLAG_RECURSION);
2480 g_log_set_handler(NULL,
2482 console_log_handler, NULL /* user_data */);
2483 g_log_set_handler(LOG_DOMAIN_MAIN,
2485 console_log_handler, NULL /* user_data */);
2488 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2490 console_log_handler, NULL /* user_data */);
2491 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2493 console_log_handler, NULL /* user_data */);
2495 /* Set the initial values in the capture options. This might be overwritten
2496 by preference settings and then again by the command line parameters. */
2497 capture_opts_init(&global_capture_opts);
2499 capture_session_init(&global_capture_session, (void *)&cfile);
2502 init_report_err(failure_alert_box, open_failure_alert_box,
2503 read_failure_alert_box, write_failure_alert_box);
2505 /* Initialize whatever we need to allocate colors for GTK+ */
2508 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2509 filter = get_conn_cfilter();
2510 if ( *filter != '\0' ) {
2511 info_update_freq = 1000; /* Milliseconds */
2514 /* We won't come till here, if we had a "console only" command line parameter. */
2515 splash_win = splash_new("Loading Wireshark ...");
2516 if (init_progfile_dir_error != NULL) {
2517 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2518 "Can't get pathname of Wireshark: %s.\n"
2519 "It won't be possible to capture traffic.\n"
2520 "Report this to the Wireshark developers.",
2521 init_progfile_dir_error);
2522 g_free(init_progfile_dir_error);
2525 init_open_routines();
2528 /* Register all the plugin types we have. */
2529 epan_register_plugin_types(); /* Types known to libwireshark */
2530 wtap_register_plugin_types(); /* Types known to libwiretap */
2531 codec_register_plugin_types(); /* Types known to libcodec */
2533 /* Scan for plugins. This does *not* call their registration routines;
2534 that's done later. */
2537 /* Register all libwiretap plugin modules. */
2538 register_all_wiretap_modules();
2540 /* Register all audio codec plugins. */
2541 register_all_codecs();
2544 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2546 /* Register all dissectors; we must do this before checking for the
2547 "-G" flag, as the "-G" flag dumps information registered by the
2548 dissectors, and we must do it before we read the preferences, in
2549 case any dissectors register preferences. */
2550 epan_init(register_all_protocols,register_all_protocol_handoffs,
2551 splash_update, (gpointer) splash_win);
2553 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2555 /* Register all tap listeners; we do this before we parse the arguments,
2556 as the "-z" argument can specify a registered tap. */
2558 /* we register the plugin taps before the other taps because
2559 stats_tree taps plugins will be registered as tap listeners
2560 by stats_tree_stat.c and need to registered before that */
2563 register_all_plugin_tap_listeners();
2566 register_all_tap_listeners();
2568 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2570 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2571 /* Removed thread code:
2572 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2575 /* this is to keep tap extensions updating once every 3 seconds */
2576 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2578 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2580 cap_file_init(&cfile);
2582 /* Fill in capture options with values from the preferences */
2583 prefs_to_capture_opts();
2585 /*#ifdef HAVE_LIBPCAP
2586 fill_in_local_interfaces();
2588 /* Now get our args */
2589 while ((opt = getopt(argc, argv, optstring)) != -1) {
2591 /*** capture option specific ***/
2592 case 'a': /* autostop criteria */
2593 case 'b': /* Ringbuffer option */
2594 case 'c': /* Capture xxx packets */
2595 case 'f': /* capture filter */
2596 case 'k': /* Start capture immediately */
2597 case 'H': /* Hide capture info dialog box */
2598 case 'p': /* Don't capture in promiscuous mode */
2599 case 'i': /* Use interface x */
2600 #ifdef HAVE_PCAP_CREATE
2601 case 'I': /* Capture in monitor mode, if available */
2603 #ifdef HAVE_PCAP_REMOTE
2604 case 'A': /* Authentication */
2606 case 's': /* Set the snapshot (capture) length */
2607 case 'S': /* "Sync" mode: used for following file ala tail -f */
2608 case 'w': /* Write to capture file xxx */
2609 case 'y': /* Set the pcap data link type */
2610 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2611 case 'B': /* Buffer size */
2612 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2614 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2620 capture_option_specified = TRUE;
2625 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2626 case 'K': /* Kerberos keytab file */
2627 read_keytab_file(optarg);
2631 /*** all non capture option specific ***/
2633 /* Configuration profile settings were already processed just ignore them this time*/
2635 case 'j': /* Search backwards for a matching packet from filter in option J */
2636 jump_backwards = SD_BACKWARD;
2638 case 'g': /* Go to packet with the given packet number */
2639 go_to_packet = get_positive_int(optarg, "go to packet");
2641 case 'J': /* Jump to the first packet which matches the filter criteria */
2644 case 'l': /* Automatic scrolling in live capture mode */
2646 auto_scroll_live = TRUE;
2648 capture_option_specified = TRUE;
2652 case 'L': /* Print list of link-layer types and exit */
2654 list_link_layer_types = TRUE;
2656 capture_option_specified = TRUE;
2660 case 'm': /* Fixed-width font for the display */
2661 g_free(prefs_p->gui_gtk2_font_name);
2662 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2664 case 'n': /* No name resolution */
2665 gbl_resolv_flags.mac_name = FALSE;
2666 gbl_resolv_flags.network_name = FALSE;
2667 gbl_resolv_flags.transport_name = FALSE;
2668 gbl_resolv_flags.concurrent_dns = FALSE;
2670 case 'N': /* Select what types of addresses/port #s to resolve */
2671 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2672 if (badopt != '\0') {
2673 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2678 case 'o': /* Override preference from command line */
2679 switch (prefs_set_pref(optarg)) {
2682 case PREFS_SET_SYNTAX_ERR:
2683 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2686 case PREFS_SET_NO_SUCH_PREF:
2687 /* not a preference, might be a recent setting */
2688 switch (recent_set_arg(optarg)) {
2691 case PREFS_SET_SYNTAX_ERR:
2692 /* shouldn't happen, checked already above */
2693 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2696 case PREFS_SET_NO_SUCH_PREF:
2697 case PREFS_SET_OBSOLETE:
2698 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2703 g_assert_not_reached();
2706 case PREFS_SET_OBSOLETE:
2707 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2712 g_assert_not_reached();
2716 /* Path settings were already processed just ignore them this time*/
2718 case 'r': /* Read capture file xxx */
2719 /* We may set "last_open_dir" to "cf_name", and if we change
2720 "last_open_dir" later, we free the old value, so we have to
2721 set "cf_name" to something that's been allocated. */
2722 cf_name = g_strdup(optarg);
2724 case 'R': /* Read file filter */
2727 case 't': /* Time stamp type */
2728 if (strcmp(optarg, "r") == 0)
2729 timestamp_set_type(TS_RELATIVE);
2730 else if (strcmp(optarg, "a") == 0)
2731 timestamp_set_type(TS_ABSOLUTE);
2732 else if (strcmp(optarg, "ad") == 0)
2733 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2734 else if (strcmp(optarg, "adoy") == 0)
2735 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
2736 else if (strcmp(optarg, "d") == 0)
2737 timestamp_set_type(TS_DELTA);
2738 else if (strcmp(optarg, "dd") == 0)
2739 timestamp_set_type(TS_DELTA_DIS);
2740 else if (strcmp(optarg, "e") == 0)
2741 timestamp_set_type(TS_EPOCH);
2742 else if (strcmp(optarg, "u") == 0)
2743 timestamp_set_type(TS_UTC);
2744 else if (strcmp(optarg, "ud") == 0)
2745 timestamp_set_type(TS_UTC_WITH_YMD);
2746 else if (strcmp(optarg, "udoy") == 0)
2747 timestamp_set_type(TS_UTC_WITH_YDOY);
2749 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2751 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2753 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2755 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2757 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2759 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2763 case 'u': /* Seconds type */
2764 if (strcmp(optarg, "s") == 0)
2765 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2766 else if (strcmp(optarg, "hms") == 0)
2767 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2769 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2771 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2776 /* ext ops were already processed just ignore them this time*/
2782 /* We won't call the init function for the stat this soon
2783 as it would disallow MATE's fields (which are registered
2784 by the preferences set callback) from being used as
2785 part of a tap filter. Instead, we just add the argument
2786 to a list of stat arguments. */
2787 if (!process_stat_cmd_arg(optarg)) {
2788 cmdarg_err("Invalid -z argument.");
2789 cmdarg_err_cont(" -z argument must be one of :");
2790 list_stat_cmd_args();
2795 case '?': /* Bad flag - print usage message */
2804 if (cf_name != NULL) {
2806 * Input file name specified with "-r" *and* specified as a regular
2807 * command-line argument.
2809 cmdarg_err("File name specified both with -r and regular argument");
2813 * Input file name not specified with "-r", and a command-line argument
2814 * was specified; treat it as the input file name.
2816 * Yes, this is different from tshark, where non-flag command-line
2817 * arguments are a filter, but this works better on GUI desktops
2818 * where a command can be specified to be run to open a particular
2819 * file - yes, you could have "-r" as the last part of the command,
2820 * but that's a bit ugly.
2822 #ifndef HAVE_GTKOSXAPPLICATION
2824 * For GTK+ Mac Integration, file name passed as free argument passed
2825 * through grag-and-drop and opened twice sometimes causing crashes.
2826 * Subject to report to GTK+ MAC.
2828 cf_name = g_strdup(argv[0]);
2837 * Extra command line arguments were specified; complain.
2839 cmdarg_err("Invalid argument: %s", argv[0]);
2845 #ifndef HAVE_LIBPCAP
2846 if (capture_option_specified) {
2847 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2855 fill_in_local_interfaces(main_window_update);
2856 if (start_capture && list_link_layer_types) {
2857 /* Specifying *both* is bogus. */
2858 cmdarg_err("You can't specify both -L and a live capture.");
2862 if (list_link_layer_types) {
2863 /* We're supposed to list the link-layer types for an interface;
2864 did the user also specify a capture file to be read? */
2866 /* Yes - that's bogus. */
2867 cmdarg_err("You can't specify -L and a capture file to be read.");
2870 /* No - did they specify a ring buffer option? */
2871 if (global_capture_opts.multi_files_on) {
2872 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2876 /* We're supposed to do a live capture; did the user also specify
2877 a capture file to be read? */
2878 if (start_capture && cf_name) {
2879 /* Yes - that's bogus. */
2880 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2884 /* No - was the ring buffer option specified and, if so, does it make
2886 if (global_capture_opts.multi_files_on) {
2887 /* Ring buffer works only under certain conditions:
2888 a) ring buffer does not work with temporary files;
2889 b) real_time_mode and multi_files_on are mutually exclusive -
2890 real_time_mode takes precedence;
2891 c) it makes no sense to enable the ring buffer if the maximum
2892 file size is set to "infinite". */
2893 if (global_capture_opts.save_file == NULL) {
2894 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2895 global_capture_opts.multi_files_on = FALSE;
2897 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2898 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2899 /* XXX - this must be redesigned as the conditions changed */
2904 if (start_capture || list_link_layer_types) {
2905 /* We're supposed to do a live capture or get a list of link-layer
2906 types for a live capture device; if the user didn't specify an
2907 interface to use, pick a default. */
2908 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2909 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2915 if (list_link_layer_types) {
2916 /* Get the list of link-layer types for the capture devices. */
2917 if_capabilities_t *caps;
2920 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2922 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2923 if (device.selected) {
2924 #if defined(HAVE_PCAP_CREATE)
2925 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str, main_window_update);
2927 caps = capture_get_if_capabilities(device.name, FALSE, &err_str,main_window_update);
2930 cmdarg_err("%s", err_str);
2934 if (caps->data_link_types == NULL) {
2935 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2941 #if defined(HAVE_PCAP_CREATE)
2942 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2944 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2949 free_if_capabilities(caps);
2954 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2955 capture_opts_trim_ring_num_files(&global_capture_opts);
2956 #endif /* HAVE_LIBPCAP */
2958 /* Notify all registered modules that have had any of their preferences
2959 changed either from one of the preferences file or from the command
2960 line that their preferences have changed. */
2964 if ((global_capture_opts.num_selected == 0) &&
2965 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2968 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2969 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2970 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2971 device.selected = TRUE;
2972 global_capture_opts.num_selected++;
2973 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2974 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2979 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2980 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2981 device.selected = TRUE;
2982 global_capture_opts.num_selected++;
2983 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2984 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2988 /* disabled protocols as per configuration file */
2989 if (gdp_path == NULL && dp_path == NULL) {
2990 set_disabled_protos_list();
2993 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2995 /* read in rc file from global and personal configuration paths. */
2996 rc_file = get_datafile_path(RC_FILE);
2997 #if GTK_CHECK_VERSION(3,0,0)
2998 /* XXX resolve later */
3000 gtk_rc_parse(rc_file);
3002 rc_file = get_persconffile_path(RC_FILE, FALSE);
3003 gtk_rc_parse(rc_file);
3013 /* close the splash screen, as we are going to open the main window now */
3014 splash_destroy(splash_win);
3016 /************************************************************************/
3017 /* Everything is prepared now, preferences and command line was read in */
3019 /* Pop up the main window. */
3020 create_main_window(pl_size, tv_size, bv_size, prefs_p);
3022 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3023 recent_read_dynamic(&rf_path, &rf_open_errno);
3024 if (rf_path != NULL && rf_open_errno != 0) {
3025 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3026 "Could not open recent file\n\"%s\": %s.",
3027 rf_path, g_strerror(rf_open_errno));
3030 color_filters_enable(recent.packet_list_colorize);
3032 /* rearrange all the widgets as we now have all recent settings ready for this */
3033 main_widgets_rearrange();
3035 /* Fill in column titles. This must be done after the top level window
3038 XXX - is that still true, with fixed-width columns? */
3040 menu_recent_read_finished();
3042 main_auto_scroll_live_changed(auto_scroll_live);
3045 switch (user_font_apply()) {
3048 case FA_FONT_NOT_RESIZEABLE:
3049 /* "user_font_apply()" popped up an alert box. */
3050 /* turn off zooming - font can't be resized */
3051 case FA_FONT_NOT_AVAILABLE:
3052 /* XXX - did we successfully load the un-zoomed version earlier?
3053 If so, this *probably* means the font is available, but not at
3054 this particular zoom level, but perhaps some other failure
3055 occurred; I'm not sure you can determine which is the case,
3057 /* turn off zooming - zoom level is unavailable */
3059 /* in any other case than FA_SUCCESS, turn off zooming */
3060 recent.gui_zoom_level = 0;
3061 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3064 dnd_init(top_level);
3066 color_filters_init();
3068 capture_filter_init();
3071 /* the window can be sized only, if it's not already shown, so do it now! */
3072 main_load_window_geometry(top_level);
3074 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3076 /* If we were given the name of a capture file, read it in now;
3077 we defer it until now, so that, if we can't open it, and pop
3078 up an alert box, the alert box is more likely to come up on
3079 top of the main window - but before the preference-file-error
3080 alert box, so, if we get one of those, it's more likely to come
3083 show_main_window(TRUE);
3084 check_and_warn_user_startup(cf_name);
3085 if (rfilter != NULL) {
3086 if (!dfilter_compile(rfilter, &rfcode)) {
3087 bad_dfilter_alert_box(top_level, rfilter);
3088 rfilter_parse_failed = TRUE;
3091 if (ex_opt_count("read_format") > 0) {
3092 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
3094 if (!rfilter_parse_failed) {
3095 if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
3096 /* "cf_open()" succeeded, so it closed the previous
3097 capture file, and thus destroyed any previous read filter
3098 attached to "cf". */
3100 cfile.rfcode = rfcode;
3101 /* Open stat windows; we do so after creating the main window,
3102 to avoid GTK warnings, and after successfully opening the
3103 capture file, so we know we have something to compute stats
3104 on, and after registering all dissectors, so that MATE will
3105 have registered its field array and we can have a tap filter
3106 with one of MATE's late-registered fields as part of the
3108 start_requested_stats();
3110 /* Read the capture file. */
3111 switch (cf_read(&cfile, FALSE)) {
3115 /* Just because we got an error, that doesn't mean we were unable
3116 to read any of the file; we handle what we could get from the
3118 /* if the user told us to jump to a specific packet, do it now */
3119 if(go_to_packet != 0) {
3120 /* Jump to the specified frame number, kept for backward
3122 cf_goto_frame(&cfile, go_to_packet);
3123 } else if (jfilter != NULL) {
3124 /* try to compile given filter */
3125 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3126 bad_dfilter_alert_box(top_level, jfilter);
3128 /* Filter ok, jump to the first packet matching the filter
3129 conditions. Default search direction is forward, but if
3130 option d was given, search backwards */
3131 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3136 case CF_READ_ABORTED:
3142 /* If the filename is not the absolute path, prepend the current dir. This happens
3143 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3144 if (!g_path_is_absolute(cf_name)) {
3145 char *old_cf_name = cf_name;
3146 char *pwd = g_get_current_dir();
3147 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3148 g_free(old_cf_name);
3152 /* Save the name of the containing directory specified in the
3153 path name, if any; we can write over cf_name, which is a
3154 good thing, given that "get_dirname()" does write over its
3156 s = get_dirname(cf_name);
3157 set_last_open_dir(s);
3162 dfilter_free(rfcode);
3163 cfile.rfcode = NULL;
3164 show_main_window(FALSE);
3165 /* Don't call check_and_warn_user_startup(): we did it above */
3166 main_set_for_capture_in_progress(FALSE);
3167 set_capture_if_dialog_for_capture_in_progress(FALSE);
3172 if (start_capture) {
3173 if (global_capture_opts.save_file != NULL) {
3174 /* Save the directory name for future file dialogs. */
3175 /* (get_dirname overwrites filename) */
3176 s = get_dirname(g_strdup(global_capture_opts.save_file));
3177 set_last_open_dir(s);
3180 /* "-k" was specified; start a capture. */
3181 show_main_window(FALSE);
3182 check_and_warn_user_startup(cf_name);
3184 /* If no user interfaces were specified on the command line,
3185 copy the list of selected interfaces to the set of interfaces
3186 to use for this capture. */
3187 if (global_capture_opts.ifaces->len == 0)
3188 collect_ifaces(&global_capture_opts);
3189 if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3190 /* The capture started. Open stat windows; we do so after creating
3191 the main window, to avoid GTK warnings, and after successfully
3192 opening the capture file, so we know we have something to compute
3193 stats on, and after registering all dissectors, so that MATE will
3194 have registered its field array and we can have a tap filter with
3195 one of MATE's late-registered fields as part of the filter. */
3196 start_requested_stats();
3199 show_main_window(FALSE);
3200 check_and_warn_user_startup(cf_name);
3201 main_set_for_capture_in_progress(FALSE);
3202 set_capture_if_dialog_for_capture_in_progress(FALSE);
3204 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3205 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3206 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3208 #else /* HAVE_LIBPCAP */
3209 show_main_window(FALSE);
3210 check_and_warn_user_startup(cf_name);
3211 main_set_for_capture_in_progress(FALSE);
3212 set_capture_if_dialog_for_capture_in_progress(FALSE);
3213 #endif /* HAVE_LIBPCAP */
3217 GtkWidget *filter_te;
3218 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3219 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3221 /* Run the display filter so it goes in effect. */
3222 main_filter_packets(&cfile, dfilter, FALSE);
3226 /* register our pid if we are being run from a U3 device */
3229 profile_store_persconffiles (FALSE);
3231 #ifdef HAVE_GTKOSXAPPLICATION
3232 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3233 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3234 gtkosx_application_ready(theApp);
3237 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3240 gtk_iface_mon_start();
3243 software_update_init();
3245 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3247 /* ... back from GTK, we're going down now! */
3250 gtk_iface_mon_stop();
3253 /* deregister our pid */
3254 u3_deregister_pid();
3258 AirPDcapDestroyContext(&airpdcap_ctx);
3260 #ifdef HAVE_GTKOSXAPPLICATION
3261 g_object_unref(theApp);
3265 /* hide the (unresponsive) main window, while asking the user to close the console window */
3266 gtk_widget_hide(top_level);
3268 software_update_cleanup();
3270 /* Shutdown windows sockets */
3273 /* For some unknown reason, the "atexit()" call in "create_console()"
3274 doesn't arrange that "destroy_console()" be called when we exit,
3275 so we call it here if a console was created. */
3284 /* We build this as a GUI subsystem application on Win32, so
3285 "WinMain()", not "main()", gets called.
3287 Hack shamelessly stolen from the Win32 port of the GIMP. */
3289 #define _stdcall __attribute__((stdcall))
3293 WinMain (struct HINSTANCE__ *hInstance,
3294 struct HINSTANCE__ *hPrevInstance,
3298 INITCOMMONCONTROLSEX comm_ctrl;
3301 * Initialize our DLL search path. MUST be called before LoadLibrary
3304 ws_init_dll_search_path();
3306 /* Initialize our controls. Required for native Windows file dialogs. */
3307 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3308 comm_ctrl.dwSize = sizeof(comm_ctrl);
3309 /* Includes the animate, header, hot key, list view, progress bar,
3310 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3313 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3314 InitCommonControlsEx(&comm_ctrl);
3316 /* RichEd20.DLL is needed for filter entries. */
3317 ws_load_library("riched20.dll");
3319 set_has_console(FALSE);
3320 set_console_wait(FALSE);
3321 return main (__argc, __argv);
3328 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3329 const char *message, gpointer user_data _U_)
3336 /* ignore log message, if log_level isn't interesting based
3337 upon the console log preferences.
3338 If the preferences haven't been loaded loaded yet, display the
3341 The default console_log_level preference value is such that only
3342 ERROR, CRITICAL and WARNING level messages are processed;
3343 MESSAGE, INFO and DEBUG level messages are ignored. */
3344 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3345 prefs.console_log_level != 0) {
3350 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3351 /* the user wants a console or the application will terminate immediately */
3354 if (get_has_console()) {
3355 /* For some unknown reason, the above doesn't appear to actually cause
3356 anything to be sent to the standard output, so we'll just splat the
3357 message out directly, just to make sure it gets out. */
3359 switch(log_level & G_LOG_LEVEL_MASK) {
3360 case G_LOG_LEVEL_ERROR:
3363 case G_LOG_LEVEL_CRITICAL:
3366 case G_LOG_LEVEL_WARNING:
3369 case G_LOG_LEVEL_MESSAGE:
3372 case G_LOG_LEVEL_INFO:
3375 case G_LOG_LEVEL_DEBUG:
3379 fprintf(stderr, "unknown log_level %u\n", log_level);
3381 g_assert_not_reached();
3384 /* create a "timestamp" */
3386 today = localtime(&curr);
3388 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3389 today->tm_hour, today->tm_min, today->tm_sec,
3390 log_domain != NULL ? log_domain : "",
3393 if(log_level & G_LOG_LEVEL_ERROR) {
3394 /* wait for a key press before the following error handler will terminate the program
3395 this way the user at least can read the error message */
3396 printf("\n\nPress any key to exit\n");
3400 /* XXX - on UN*X, should we just use g_log_default_handler()?
3401 We want the error messages to go to the standard output;
3402 on Mac OS X, that will cause them to show up in various
3403 per-user logs accessible through Console (details depend
3404 on whether you're running 10.0 through 10.4 or running
3405 10.5 and later), and, on other UN*X desktop environments,
3406 if they don't show up in some form of console log, that's
3407 a deficiency in that desktop environment. (Too bad
3408 Windows doesn't set the standard output and error for
3409 GUI apps to something that shows up in such a log.) */
3410 g_log_default_handler(log_domain, log_level, message, user_data);
3417 * Helper for main_widgets_rearrange()
3419 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3420 gtk_container_remove(GTK_CONTAINER(data), widget);
3423 static GtkWidget *main_widget_layout(gint layout_content)
3425 switch(layout_content) {
3426 case(layout_pane_content_none):
3428 case(layout_pane_content_plist):
3430 case(layout_pane_content_pdetails):
3432 case(layout_pane_content_pbytes):
3433 return byte_nb_ptr_gbl;
3435 g_assert_not_reached();
3442 * Rearrange the main window widgets
3444 void main_widgets_rearrange(void) {
3445 GtkWidget *first_pane_widget1, *first_pane_widget2;
3446 GtkWidget *second_pane_widget1, *second_pane_widget2;
3447 gboolean split_top_left = FALSE;
3449 /* be a bit faster */
3450 gtk_widget_hide(main_vbox);
3452 /* be sure we don't lose a widget while rearranging */
3453 g_object_ref(G_OBJECT(menubar));
3454 g_object_ref(G_OBJECT(main_tb));
3455 g_object_ref(G_OBJECT(filter_tb));
3456 g_object_ref(G_OBJECT(wireless_tb));
3457 g_object_ref(G_OBJECT(pkt_scrollw));
3458 g_object_ref(G_OBJECT(tv_scrollw));
3459 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3460 g_object_ref(G_OBJECT(statusbar));
3461 g_object_ref(G_OBJECT(main_pane_v1));
3462 g_object_ref(G_OBJECT(main_pane_v2));
3463 g_object_ref(G_OBJECT(main_pane_h1));
3464 g_object_ref(G_OBJECT(main_pane_h2));
3465 g_object_ref(G_OBJECT(welcome_pane));
3467 /* empty all containers participating */
3468 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3469 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3470 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3471 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3472 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3474 statusbar_widgets_emptying(statusbar);
3476 /* add the menubar always at the top */
3477 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3480 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3482 /* filter toolbar in toolbar area */
3483 if (!prefs.filter_toolbar_show_in_statusbar) {
3484 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3487 /* airpcap toolbar */
3488 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3490 /* fill the main layout panes */
3491 switch(prefs.gui_layout_type) {
3492 case(layout_type_5):
3493 main_first_pane = main_pane_v1;
3494 main_second_pane = main_pane_v2;
3495 split_top_left = FALSE;
3497 case(layout_type_2):
3498 main_first_pane = main_pane_v1;
3499 main_second_pane = main_pane_h1;
3500 split_top_left = FALSE;
3502 case(layout_type_1):
3503 main_first_pane = main_pane_v1;
3504 main_second_pane = main_pane_h1;
3505 split_top_left = TRUE;
3507 case(layout_type_4):
3508 main_first_pane = main_pane_h1;
3509 main_second_pane = main_pane_v1;
3510 split_top_left = FALSE;
3512 case(layout_type_3):
3513 main_first_pane = main_pane_h1;
3514 main_second_pane = main_pane_v1;
3515 split_top_left = TRUE;
3517 case(layout_type_6):
3518 main_first_pane = main_pane_h1;
3519 main_second_pane = main_pane_h2;
3520 split_top_left = FALSE;
3523 main_first_pane = NULL;
3524 main_second_pane = NULL;
3525 g_assert_not_reached();
3527 if (split_top_left) {
3528 first_pane_widget1 = main_second_pane;
3529 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3530 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3531 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3533 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3534 first_pane_widget2 = main_second_pane;
3535 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3536 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3538 if (first_pane_widget1 != NULL)
3539 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3540 if (first_pane_widget2 != NULL)
3541 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3542 if (second_pane_widget1 != NULL)
3543 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3544 if (second_pane_widget2 != NULL)
3545 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3547 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3550 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3553 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3555 /* filter toolbar in statusbar hbox */
3556 if (prefs.filter_toolbar_show_in_statusbar) {
3557 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3560 /* statusbar widgets */
3561 statusbar_widgets_pack(statusbar);
3563 /* hide widgets on users recent settings */
3564 main_widgets_show_or_hide();
3566 gtk_widget_show(main_vbox);
3570 is_widget_visible(GtkWidget *widget, gpointer data)
3572 gboolean *is_visible = ( gboolean *)data;
3575 if (gtk_widget_get_visible(widget))
3582 main_widgets_show_or_hide(void)
3584 gboolean main_second_pane_show;
3586 if (recent.main_toolbar_show) {
3587 gtk_widget_show(main_tb);
3589 gtk_widget_hide(main_tb);
3592 statusbar_widgets_show_or_hide(statusbar);
3594 if (recent.filter_toolbar_show) {
3595 gtk_widget_show(filter_tb);
3597 gtk_widget_hide(filter_tb);
3600 if (recent.wireless_toolbar_show) {
3601 gtk_widget_show(wireless_tb);
3603 gtk_widget_hide(wireless_tb);
3606 if (recent.packet_list_show && have_capture_file) {
3607 gtk_widget_show(pkt_scrollw);
3609 gtk_widget_hide(pkt_scrollw);
3612 if (recent.tree_view_show && have_capture_file) {
3613 gtk_widget_show(tv_scrollw);
3615 gtk_widget_hide(tv_scrollw);
3618 if (recent.byte_view_show && have_capture_file) {
3619 gtk_widget_show(byte_nb_ptr_gbl);
3621 gtk_widget_hide(byte_nb_ptr_gbl);
3624 if (have_capture_file) {
3625 gtk_widget_show(main_first_pane);
3627 gtk_widget_hide(main_first_pane);
3631 * Is anything in "main_second_pane" visible?
3632 * If so, show it, otherwise hide it.
3634 main_second_pane_show = FALSE;
3635 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3636 &main_second_pane_show);
3637 if (main_second_pane_show) {
3638 gtk_widget_show(main_second_pane);
3640 gtk_widget_hide(main_second_pane);
3643 if (!have_capture_file) {
3645 gtk_widget_show(welcome_pane);
3648 gtk_widget_hide(welcome_pane);
3653 /* called, when the window state changes (minimized, maximized, ...) */
3655 window_state_event_cb (GtkWidget *widget _U_,
3659 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3661 if( (event->type) == (GDK_WINDOW_STATE)) {
3662 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3663 /* we might have dialogs popped up while we where iconified,
3665 display_queued_messages();
3673 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3675 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3677 if (event->keyval == GDK_F8) {
3680 } else if (event->keyval == GDK_F7) {
3683 } else if (event->state & NO_SHIFT_MOD_MASK) {
3684 return FALSE; /* Skip control, alt, and other modifiers */
3686 * A comment in gdkkeysyms.h says that it's autogenerated from
3687 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3688 * don't explicitly say so, g_ascii_isprint() should work as expected
3691 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3692 /* Forward the keypress on to the display filter entry */
3693 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3694 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3695 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3703 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3704 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3709 GtkAccelGroup *accel;
3712 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3713 set_titlebar_for_capture_file(NULL);
3715 gtk_widget_set_name(top_level, "main window");
3716 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3718 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3719 G_CALLBACK(window_state_event_cb), NULL);
3720 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3721 G_CALLBACK(top_level_key_pressed_cb), NULL );
3723 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3724 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3726 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3727 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3728 gtk_widget_show(main_vbox);
3731 menubar = main_menu_new(&accel);
3733 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3734 /* Mac OS X native menus are created and displayed by main_menu_new() */
3735 if(!prefs_p->gui_macosx_style) {
3737 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3738 gtk_widget_show(menubar);
3739 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3741 gtk_widget_hide(menubar);
3746 main_tb = toolbar_new();
3747 gtk_widget_show (main_tb);
3749 /* Filter toolbar */
3750 filter_tb = filter_toolbar_new();
3753 pkt_scrollw = packet_list_create();
3754 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3755 gtk_widget_show_all(pkt_scrollw);
3758 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3759 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3760 gtk_widget_show(tv_scrollw);
3762 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3763 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3764 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3765 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3766 gtk_widget_show(tree_view_gbl);
3769 byte_nb_ptr_gbl = byte_view_new();
3770 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3771 gtk_widget_show(byte_nb_ptr_gbl);
3773 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3774 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3776 /* Panes for the packet list, tree, and byte view */
3777 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3778 gtk_widget_show(main_pane_v1);
3779 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3780 gtk_widget_show(main_pane_v2);
3781 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3782 gtk_widget_show(main_pane_h1);
3783 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3784 gtk_widget_show(main_pane_h2);
3786 wireless_tb = airpcap_toolbar_new();
3788 wireless_tb = ws80211_toolbar_new();
3790 gtk_widget_show(wireless_tb);
3793 statusbar = statusbar_new();
3794 gtk_widget_show(statusbar);
3796 /* Pane for the welcome screen */
3797 welcome_pane = welcome_new();
3798 gtk_widget_show(welcome_pane);
3802 show_main_window(gboolean doing_work)
3804 main_set_for_capture_file(doing_work);
3806 /*** we have finished all init things, show the main window ***/
3807 gtk_widget_show(top_level);
3809 /* the window can be maximized only, if it's visible, so do it after show! */
3810 main_load_window_geometry(top_level);
3812 /* process all pending GUI events before continue */
3813 while (gtk_events_pending()) gtk_main_iteration();
3815 /* Pop up any queued-up alert boxes. */
3816 display_queued_messages();
3818 /* Move the main window to the front, in case it isn't already there */
3819 gdk_window_raise(gtk_widget_get_window(top_level));
3822 airpcap_toolbar_show(wireless_tb);
3823 #endif /* HAVE_AIRPCAP */
3826 static void copy_global_profile (const gchar *profile_name)
3828 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3830 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3831 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3832 "Can't create directory\n\"%s\":\n%s.",
3833 pf_dir_path, g_strerror(errno));
3835 g_free(pf_dir_path);
3838 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3839 &pf_dir_path, &pf_dir_path2) == -1) {
3840 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3841 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3842 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3844 g_free(pf_filename);
3845 g_free(pf_dir_path);
3846 g_free(pf_dir_path2);
3850 /* Change configuration profile */
3851 void change_configuration_profile (const gchar *profile_name)
3853 char *gdp_path, *dp_path;
3857 /* First check if profile exists */
3858 if (!profile_exists(profile_name, FALSE)) {
3859 if (profile_exists(profile_name, TRUE)) {
3860 /* Copy from global profile */
3861 copy_global_profile (profile_name);
3863 /* No personal and no global profile exists */
3868 /* Then check if changing to another profile */
3869 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3873 /* Get the current geometry, before writing it to disk */
3874 main_save_window_geometry(top_level);
3876 if (profile_exists(get_profile_name(), FALSE)) {
3877 /* Write recent file for profile we are leaving, if it still exists */
3878 write_profile_recent();
3881 /* Set profile name and update the status bar */
3882 set_profile_name (profile_name);
3883 profile_bar_update ();
3884 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3886 /* Reset current preferences and apply the new */
3890 (void) read_configuration_files (&gdp_path, &dp_path);
3892 recent_read_profile_static(&rf_path, &rf_open_errno);
3893 if (rf_path != NULL && rf_open_errno != 0) {
3894 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3895 "Could not open common recent file\n\"%s\": %s.",
3896 rf_path, g_strerror(rf_open_errno));
3898 if (recent.gui_fileopen_remembered_dir &&
3899 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3900 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3902 timestamp_set_type (recent.gui_time_format);
3903 timestamp_set_seconds_type (recent.gui_seconds_format);
3904 color_filters_enable(recent.packet_list_colorize);
3906 prefs_to_capture_opts();
3908 macros_post_update();
3910 /* Update window view and redraw the toolbar */
3911 main_titlebar_update();
3912 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3913 toolbar_redraw_all();
3915 /* Enable all protocols and disable from the disabled list */
3917 if (gdp_path == NULL && dp_path == NULL) {
3918 set_disabled_protos_list();
3921 /* Reload color filters */
3922 color_filters_reload();
3924 /* Reload list of interfaces on welcome page */
3925 welcome_if_panel_reload();
3927 /* Recreate the packet list according to new preferences */
3928 packet_list_recreate ();
3929 cfile.columns_changed = FALSE; /* Reset value */
3932 /* Update menus with new recent values */
3933 menu_recent_read_finished();
3935 /* Reload pane geometry, must be done after recreating the list */
3936 main_pane_load_window_geometry();
3939 /** redissect packets and update UI */
3940 void redissect_packets(void)
3942 cf_redissect_packets(&cfile);
3943 status_expert_update();
3952 * indent-tabs-mode: nil
3955 * ex: set shiftwidth=4 tabstop=8 expandtab:
3956 * :indentSize=4:tabSize=8:noTabs=true: