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"
49 #include <zlib.h> /* to get the libz version number */
52 #ifdef _WIN32 /* Needed for console I/O */
56 #include <ui/win32/console_win32.h>
59 #ifdef HAVE_LIBPORTAUDIO
60 #include <portaudio.h>
61 #endif /* HAVE_LIBPORTAUDIO */
63 #include <wsutil/clopts_common.h>
64 #include <wsutil/crash_info.h>
65 #include <wsutil/filesystem.h>
66 #include <wsutil/file_util.h>
67 #include <wsutil/privileges.h>
68 #include <wsutil/report_err.h>
69 #include <wsutil/u3.h>
70 #include <wsutil/copyright_info.h>
71 #include <wsutil/os_version_info.h>
72 #include <wsutil/ws_version_info.h>
74 #include <wiretap/merge.h>
76 #include <epan/addr_resolv.h>
77 #include <epan/column.h>
78 #include <epan/disabled_protos.h>
79 #include <epan/epan.h>
80 #include <epan/epan_dissect.h>
81 #include <epan/dfilter/dfilter.h>
82 #include <epan/strutil.h>
83 #include <epan/emem.h>
84 #include <epan/ex-opt.h>
85 #include <epan/funnel.h>
86 #include <epan/expert.h>
87 #include <epan/frequency-utils.h>
88 #include <epan/prefs.h>
89 #include <epan/prefs-int.h>
91 #include <epan/stat_cmd_args.h>
93 #include <epan/print.h>
94 #include <epan/timestamp.h>
95 #include <epan/conversation_table.h>
97 #include <wsutil/cmdarg_err.h>
98 #include <wsutil/plugins.h>
100 /* general (not GTK specific) */
102 #include "../frame_tvbuff.h"
103 #include "../summary.h"
104 #include "../color.h"
105 #include "../color_filters.h"
106 #include "../register.h"
107 #include "../ringbuffer.h"
108 #include "../version_info.h"
111 #include "gtk_iface_monitor.h"
113 #include "ui/alert_box.h"
114 #include "ui/decode_as_utils.h"
115 #include "ui/filters.h"
116 #include "ui/main_statusbar.h"
117 #include "ui/persfilepath_opt.h"
118 #include "ui/preference_utils.h"
119 #include "ui/recent.h"
120 #include "ui/recent_utils.h"
121 #include "ui/software_update.h"
122 #include "ui/simple_dialog.h"
123 #include "ui/ui_util.h"
127 #include "ui/capture_ui_utils.h"
128 #include "ui/capture_globals.h"
129 #include "ui/iface_lists.h"
132 #include "codecs/codecs.h"
134 #include "caputils/capture-pcap-util.h"
137 #include "caputils/capture_ifinfo.h"
138 #include "ui/capture.h"
139 #include <capchild/capture_sync.h>
143 #include "caputils/capture-wpcap.h"
144 #include "caputils/capture_wpcap_packet.h"
145 #include <tchar.h> /* Needed for Unicode */
146 #include <wsutil/unicode-utils.h>
147 #include <commctrl.h>
148 #include <shellapi.h>
152 #include "ui/gtk/file_dlg.h"
153 #include "ui/gtk/gtkglobals.h"
154 #include "ui/gtk/color_utils.h"
155 #include "ui/gtk/gui_utils.h"
156 #include "ui/gtk/color_dlg.h"
157 #include "ui/gtk/filter_dlg.h"
158 #include "ui/gtk/fileset_dlg.h"
159 #include "ui/gtk/uat_gui.h"
160 #include "ui/gtk/main.h"
161 #include "ui/gtk/main_80211_toolbar.h"
162 #include "ui/gtk/main_airpcap_toolbar.h"
163 #include "ui/gtk/main_filter_toolbar.h"
164 #include "ui/gtk/main_titlebar.h"
165 #include "ui/gtk/menus.h"
166 #include "ui/gtk/main_menubar_private.h"
167 #include "ui/gtk/macros_dlg.h"
168 #include "ui/gtk/main_statusbar_private.h"
169 #include "ui/gtk/main_toolbar.h"
170 #include "ui/gtk/main_toolbar_private.h"
171 #include "ui/gtk/main_welcome.h"
172 #include "ui/gtk/drag_and_drop.h"
173 #include "ui/gtk/capture_file_dlg.h"
174 #include "ui/gtk/packet_panes.h"
175 #include "ui/gtk/keys.h"
176 #include "ui/gtk/packet_win.h"
177 #include "ui/gtk/stock_icons.h"
178 #include "ui/gtk/find_dlg.h"
179 #include "ui/gtk/follow_tcp.h"
180 #include "ui/gtk/font_utils.h"
181 #include "ui/gtk/about_dlg.h"
182 #include "ui/gtk/help_dlg.h"
183 #include "ui/gtk/decode_as_dlg.h"
184 #include "ui/gtk/webbrowser.h"
185 #include "ui/gtk/capture_dlg.h"
186 #include "ui/gtk/capture_if_dlg.h"
187 #include "ui/gtk/tap_param_dlg.h"
188 #include "ui/gtk/prefs_column.h"
189 #include "ui/gtk/prefs_dlg.h"
190 #include "ui/gtk/proto_help.h"
191 #include "ui/gtk/packet_list.h"
192 #include "ui/gtk/filter_expression_save_dlg.h"
193 #include "ui/gtk/conversations_table.h"
195 #include "ui/gtk/old-gtk-compat.h"
199 #include "wsiconcap.h"
203 #include <caputils/airpcap.h>
204 #include <caputils/airpcap_loader.h>
205 #include "airpcap_dlg.h"
206 #include "airpcap_gui_utils.h"
209 #include <epan/crypt/airpdcap_ws.h>
212 #ifdef HAVE_GTKOSXAPPLICATION
213 #include <gtkmacintegration/gtkosxapplication.h>
217 * Files under personal and global preferences directories in which
218 * GTK settings for Wireshark are stored.
220 #define RC_FILE "gtkrc"
223 capture_options global_capture_opts;
224 capture_session global_capture_session;
229 static gboolean capture_stopping;
231 /* "exported" main widgets */
232 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
234 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
235 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
236 static GtkWidget *main_first_pane, *main_second_pane;
238 /* internally used widgets */
239 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
241 GtkWidget *wireless_tb;
243 int airpcap_dll_ret_val = -1;
246 GString *comp_info_str, *runtime_info_str;
248 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
250 static guint tap_update_timer_id;
252 static void console_log_handler(const char *log_domain,
253 GLogLevelFlags log_level, const char *message, gpointer user_data);
255 static void create_main_window(gint, gint, gint, e_prefs*);
256 static void show_main_window(gboolean);
257 static void main_save_window_geometry(GtkWidget *widget);
260 /* Match selected byte pattern */
262 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
264 char *cur_filter, *new_filter;
266 if ((!text) || (0 == strlen(text))) {
267 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
273 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
275 switch (action&MATCH_SELECTED_MASK) {
277 case MATCH_SELECTED_REPLACE:
278 new_filter = g_strdup(text);
281 case MATCH_SELECTED_AND:
282 if ((!cur_filter) || (0 == strlen(cur_filter)))
283 new_filter = g_strdup(text);
285 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
288 case MATCH_SELECTED_OR:
289 if ((!cur_filter) || (0 == strlen(cur_filter)))
290 new_filter = g_strdup(text);
292 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
295 case MATCH_SELECTED_NOT:
296 new_filter = g_strconcat("!(", text, ")", NULL);
299 case MATCH_SELECTED_AND_NOT:
300 if ((!cur_filter) || (0 == strlen(cur_filter)))
301 new_filter = g_strconcat("!(", text, ")", NULL);
303 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
306 case MATCH_SELECTED_OR_NOT:
307 if ((!cur_filter) || (0 == strlen(cur_filter)))
308 new_filter = g_strconcat("!(", text, ")", NULL);
310 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
314 g_assert_not_reached();
319 /* Free up the copy we got of the old filter text. */
322 /* Don't change the current display filter if we only want to copy the filter */
323 if (action&MATCH_SELECTED_COPY_ONLY) {
324 GString *gtk_text_str = g_string_new("");
325 g_string_append(gtk_text_str, new_filter);
326 copy_to_clipboard(gtk_text_str);
327 g_string_free(gtk_text_str, TRUE);
329 /* create a new one and set the display filter entry accordingly */
330 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
332 /* Run the display filter so it goes in effect. */
333 if (action&MATCH_SELECTED_APPLY_NOW)
334 main_filter_packets(&cfile, new_filter, FALSE);
337 /* Free up the new filter text. */
342 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
346 if (cfile.finfo_selected) {
347 filter = proto_construct_match_selected_string(cfile.finfo_selected,
349 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
354 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
358 if (cfile.finfo_selected) {
359 filter = proto_construct_match_selected_string(cfile.finfo_selected,
361 if ((!filter) || (0 == strlen(filter))) {
362 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
363 "Could not acquire information to build a filter!\n"
364 "Try expanding or choosing another item.");
369 color_display_with_filter(filter);
372 color_filters_reset_tmp();
374 color_filters_set_tmp(filt_nr,filter, FALSE);
376 packet_list_colorize_packets();
382 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
384 gchar *selected_proto_url;
385 gchar *proto_abbrev = (gchar *)data;
390 if (cfile.finfo_selected) {
391 /* open wiki page using the protocol abbreviation */
392 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
393 browser_open_url(selected_proto_url);
394 g_free(selected_proto_url);
397 case(ESD_BTN_CANCEL):
400 g_assert_not_reached();
406 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
409 const gchar *proto_abbrev;
413 if (cfile.finfo_selected) {
414 /* convert selected field to protocol abbreviation */
415 /* XXX - could this conversion be simplified? */
416 field_id = cfile.finfo_selected->hfinfo->id;
417 /* if the selected field isn't a protocol, get its parent */
418 if(!proto_registrar_is_protocol(field_id)) {
419 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
422 proto_abbrev = proto_registrar_get_abbrev(field_id);
424 if (!proto_is_private(field_id)) {
425 /* ask the user if the wiki page really should be opened */
426 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
427 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
429 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
431 "The Wireshark Wiki is a collaborative approach to provide information "
432 "about Wireshark in several ways (not limited to protocol specifics).\n"
434 "This Wiki is new, so the page of the selected protocol "
435 "may not exist and/or may not contain valuable information.\n"
437 "As everyone can edit the Wiki and add new content (or extend existing), "
438 "you are encouraged to add information if you can.\n"
440 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
442 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
443 "which will save you a lot of editing and will give a consistent look over the pages.",
444 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
445 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
447 /* appologize to the user that the wiki page cannot be opened */
448 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
449 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
451 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
453 "Since this is a private protocol, such information is not available in "
454 "a public wiki. Therefore this wiki entry is blocked.\n"
456 "Sorry for the inconvenience.\n",
457 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
462 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
464 gchar *selected_proto_url;
465 gchar *proto_abbrev = (gchar *)data;
469 if (cfile.finfo_selected) {
470 /* open reference page using the protocol abbreviation */
471 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
472 browser_open_url(selected_proto_url);
473 g_free(selected_proto_url);
476 case(ESD_BTN_CANCEL):
479 g_assert_not_reached();
484 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
487 const gchar *proto_abbrev;
491 if (cfile.finfo_selected) {
492 /* convert selected field to protocol abbreviation */
493 /* XXX - could this conversion be simplified? */
494 field_id = cfile.finfo_selected->hfinfo->id;
495 /* if the selected field isn't a protocol, get its parent */
496 if(!proto_registrar_is_protocol(field_id)) {
497 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
500 proto_abbrev = proto_registrar_get_abbrev(field_id);
502 if (!proto_is_private(field_id)) {
503 /* ask the user if the wiki page really should be opened */
504 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
505 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
507 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
509 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
510 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
512 /* appologize to the user that the wiki page cannot be opened */
513 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
514 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
516 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
518 "Since this is a private protocol, such information is not available on "
519 "a public website. Therefore this filter entry is blocked.\n"
521 "Sorry for the inconvenience.\n",
522 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
528 is_address_column (gint column)
530 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
531 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
532 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
533 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
534 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
543 get_ip_address_list_from_packet_list_row(gpointer data)
545 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
546 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
549 GList *addr_list = NULL;
551 fdata = (frame_data *) packet_list_get_row_data(row);
556 if (!cf_read_record(&cfile, fdata))
557 return NULL; /* error reading the frame */
559 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
560 col_custom_prime_edt(&edt, &cfile.cinfo);
562 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
563 frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
564 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
566 /* First check selected column */
567 if (is_address_column (column)) {
568 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
571 for (col = 0; col < cfile.cinfo.num_cols; col++) {
572 /* Then check all columns except the selected */
573 if ((col != column) && (is_address_column (col))) {
574 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
578 epan_dissect_cleanup(&edt);
585 get_filter_from_packet_list_row_and_column(gpointer data)
587 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
588 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
592 fdata = (frame_data *) packet_list_get_row_data(row);
597 if (!cf_read_record(&cfile, fdata))
598 return NULL; /* error reading the record */
599 /* proto tree, visible. We need a proto tree if there's custom columns */
600 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
601 col_custom_prime_edt(&edt, &cfile.cinfo);
603 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
604 frame_tvbuff_new_buffer(fdata, &cfile.buf),
605 fdata, &cfile.cinfo);
606 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
608 if ((cfile.cinfo.col_custom_occurrence[column]) ||
609 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
611 /* Only construct the filter when a single occurrence is displayed
612 * otherwise we might end up with a filter like "ip.proto==1,6".
614 * Or do we want to be able to filter on multiple occurrences so that
615 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
618 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
619 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
620 /* leak a little but safer than ep_ here */
621 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
622 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
623 if (hfi && hfi->parent == -1) {
625 buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
626 } else if (hfi && IS_FT_STRING(hfi->type)) {
627 /* Custom string, add quotes */
628 buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
629 cfile.cinfo.col_expr.col_expr_val[column]);
633 buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
634 cfile.cinfo.col_expr.col_expr_val[column]);
639 epan_dissect_cleanup(&edt);
646 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
650 filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
652 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
658 /* This function allows users to right click in the details window and copy the text
659 * information to the operating systems clipboard.
661 * We first check to see if a string representation is setup in the tree and then
662 * read the string. If not available then we try to grab the value. If all else
663 * fails we display a message to the user to indicate the copy could not be completed.
666 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
668 GString *gtk_text_str = g_string_new("");
669 char labelstring[ITEM_LABEL_LENGTH];
670 char *stringpointer = labelstring;
674 case COPY_SELECTED_DESCRIPTION:
675 if (cfile.finfo_selected->rep &&
676 strlen (cfile.finfo_selected->rep->representation) > 0) {
677 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
680 case COPY_SELECTED_FIELDNAME:
681 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
682 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
685 case COPY_SELECTED_VALUE:
686 if (cfile.edt !=0 ) {
687 gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
688 g_string_append(gtk_text_str, field_str);
696 if (gtk_text_str->len == 0) {
697 /* If no representation then... Try to read the value */
698 proto_item_fill_label(cfile.finfo_selected, stringpointer);
699 g_string_append(gtk_text_str, stringpointer);
702 if (gtk_text_str->len == 0) {
703 /* Could not get item so display error msg */
704 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
706 /* Copy string to clipboard */
707 copy_to_clipboard(gtk_text_str);
709 g_string_free(gtk_text_str, TRUE); /* Free the memory */
713 /* mark as reference time frame */
715 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
719 frame->flags.ref_time=1;
720 cfile.ref_time_count++;
722 frame->flags.ref_time=0;
723 cfile.ref_time_count--;
725 cf_reftime_packets(&cfile);
726 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
727 packet_list_freeze();
728 cfile.displayed_count--;
729 packet_list_recreate_visible_rows();
732 packet_list_queue_draw();
736 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
740 timestamp_set_type(TS_RELATIVE);
741 recent.gui_time_format = TS_RELATIVE;
742 cf_timestamp_auto_precision(&cfile);
743 packet_list_queue_draw();
748 g_assert_not_reached();
751 if (cfile.current_frame) {
752 set_frame_reftime(!cfile.current_frame->flags.ref_time,
753 cfile.current_frame, cfile.current_row);
759 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
761 static GtkWidget *reftime_dialog = NULL;
765 if (cfile.current_frame) {
766 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
767 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
768 "%sSwitch to the appropriate Time Display Format?%s\n\n"
769 "Time References don't work well with the currently selected Time Display Format.\n\n"
770 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
771 simple_dialog_primary_start(), simple_dialog_primary_end());
772 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
774 set_frame_reftime(!cfile.current_frame->flags.ref_time,
775 cfile.current_frame, cfile.current_row);
779 case REFTIME_FIND_NEXT:
780 cf_find_packet_time_reference(&cfile, SD_FORWARD);
782 case REFTIME_FIND_PREV:
783 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
789 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
791 cf_find_packet_marked(&cfile, SD_FORWARD);
795 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
797 cf_find_packet_marked(&cfile, SD_BACKWARD);
801 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
804 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
806 gboolean has_blurb = FALSE;
807 guint length = 0, byte_len;
808 GtkWidget *byte_view;
809 const guint8 *byte_data;
814 /* if nothing is selected */
815 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
818 * Which byte view is displaying the current protocol tree
821 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
822 if (byte_view == NULL)
825 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
826 if (byte_data == NULL)
829 cf_unselect_field(&cfile);
830 packet_hex_print(byte_view, byte_data,
831 cfile.current_frame, NULL, byte_len);
832 proto_help_menu_modify(sel, &cfile);
835 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
838 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
840 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
841 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
842 g_assert(byte_data != NULL);
844 cfile.finfo_selected = finfo;
845 set_menus_for_selected_tree_row(&cfile);
848 if (finfo->hfinfo->blurb != NULL &&
849 finfo->hfinfo->blurb[0] != '\0') {
851 length = (guint) strlen(finfo->hfinfo->blurb);
853 length = (guint) strlen(finfo->hfinfo->name);
855 finfo_length = finfo->length + finfo->appendix_length;
857 if (finfo_length == 0) {
859 } else if (finfo_length == 1) {
860 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
862 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
864 statusbar_pop_field_msg(); /* get rid of current help msg */
866 statusbar_push_field_msg(" %s (%s)%s",
867 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
868 finfo->hfinfo->abbrev, len_str);
871 * Don't show anything if the field name is zero-length;
872 * the pseudo-field for "proto_tree_add_text()" is such
873 * a field, and we don't want "Text (text)" showing up
874 * on the status line if you've selected such a field.
876 * XXX - there are zero-length fields for which we *do*
877 * want to show the field name.
879 * XXX - perhaps the name and abbrev field should be null
880 * pointers rather than null strings for that pseudo-field,
881 * but we'd have to add checks for null pointers in some
882 * places if we did that.
884 * Or perhaps protocol tree items added with
885 * "proto_tree_add_text()" should have -1 as the field index,
886 * with no pseudo-field being used, but that might also
887 * require special checks for -1 to be added.
889 statusbar_push_field_msg("%s", "");
892 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
894 proto_help_menu_modify(sel, &cfile);
897 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
900 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
903 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
906 expand_all_tree(cfile.edt->tree, tree_view_gbl);
909 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
911 if (cfile.finfo_selected) {
912 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
913 cfile.finfo_selected->hfinfo->abbrev,0);
914 /* Recreate the packet list according to new preferences */
915 packet_list_recreate ();
916 if (!prefs.gui_use_pref_save) {
919 cfile.columns_changed = FALSE; /* Reset value */
923 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
927 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
929 /* the mouse position is at an entry, expand that one */
930 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
931 gtk_tree_path_free(path);
935 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
939 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
941 /* the mouse position is at an entry, expand that one */
943 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
944 gtk_tree_path_free(path);
948 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
950 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
952 if (cfile.edt->tree) {
953 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
957 /* Update main window items based on whether there's a capture in progress. */
959 main_set_for_capture_in_progress(gboolean capture_in_progress)
961 set_menus_for_capture_in_progress(capture_in_progress);
964 set_toolbar_for_capture_in_progress(capture_in_progress);
966 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
970 /* Update main window items based on whether we have a capture file. */
972 main_set_for_capture_file(gboolean have_capture_file_in)
974 have_capture_file = have_capture_file_in;
976 main_widgets_show_or_hide();
979 /* Update main window items based on whether we have captured packets. */
981 main_set_for_captured_packets(gboolean have_captured_packets)
983 set_menus_for_captured_packets(have_captured_packets);
984 set_toolbar_for_captured_packets(have_captured_packets);
987 /* Update main window items based on whether we have a packet history. */
989 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
991 set_menus_for_packet_history(back_history, forward_history);
992 set_toolbar_for_packet_history(back_history, forward_history);
998 /* get the current geometry, before writing it to disk */
999 main_save_window_geometry(top_level);
1001 /* write user's recent file to disk
1002 * It is no problem to write this file, even if we do not quit */
1003 write_profile_recent();
1006 /* XXX - should we check whether the capture file is an
1007 unsaved temporary file for a live capture and, if so,
1008 pop up a "do you want to exit without saving the capture
1009 file?" dialog, and then just return, leaving said dialog
1010 box to forcibly quit if the user clicks "OK"?
1012 If so, note that this should be done in a subroutine that
1013 returns TRUE if we do so, and FALSE otherwise, and if it
1014 returns TRUE we should return TRUE without nuking anything.
1016 Note that, if we do that, we might also want to check if
1017 an "Update list of packets in real time" capture is in
1018 progress and, if so, ask whether they want to terminate
1019 the capture and discard it, and return TRUE, before nuking
1020 any child capture, if they say they don't want to do so. */
1023 /* Nuke any child capture in progress. */
1024 capture_kill_child(&global_capture_session);
1027 /* Are we in the middle of reading a capture? */
1028 if (cfile.state == FILE_READ_IN_PROGRESS) {
1029 /* Yes, so we can't just close the file and quit, as
1030 that may yank the rug out from under the read in
1031 progress; instead, just set the state to
1032 "FILE_READ_ABORTED" and return - the code doing the read
1033 will check for that and, if it sees that, will clean
1035 cfile.state = FILE_READ_ABORTED;
1037 /* Say that the window should *not* be deleted;
1038 that'll be done by the code that cleans up. */
1041 /* Close any capture file we have open; on some OSes, you
1042 can't unlink a temporary capture file if you have it
1044 "cf_close()" will unlink it after closing it if
1045 it's a temporary file.
1047 We do this here, rather than after the main loop returns,
1048 as, after the main loop returns, the main window may have
1049 been destroyed (if this is called due to a "destroy"
1050 even on the main window rather than due to the user
1051 selecting a menu item), and there may be a crash
1052 or other problem when "cf_close()" tries to
1053 clean up stuff in the main window.
1055 XXX - is there a better place to put this?
1056 Or should we have a routine that *just* closes the
1057 capture file, and doesn't do anything with the UI,
1058 which we'd call here, and another routine that
1059 calls that routine and also cleans up the UI, which
1060 we'd call elsewhere? */
1063 /* Exit by leaving the main loop, so that any quit functions
1064 we registered get called. */
1067 /* Say that the window should be deleted. */
1073 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1075 /* If we're in the middle of stopping a capture, don't do anything;
1076 the user can try deleting the window after the capture stops. */
1077 if (capture_stopping)
1080 /* If there's unsaved data, let the user save it first.
1081 If they cancel out of it, don't quit. */
1082 if (do_file_close(&cfile, TRUE, " before quitting"))
1083 return main_do_quit();
1085 return TRUE; /* will this keep the window from being deleted? */
1090 main_pane_load_window_geometry(void)
1092 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1093 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1094 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1095 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1101 main_load_window_geometry(GtkWidget *widget)
1103 window_geometry_t geom;
1105 geom.set_pos = prefs.gui_geometry_save_position;
1106 geom.x = recent.gui_geometry_main_x;
1107 geom.y = recent.gui_geometry_main_y;
1108 geom.set_size = prefs.gui_geometry_save_size;
1109 if (recent.gui_geometry_main_width > 0 &&
1110 recent.gui_geometry_main_height > 0) {
1111 geom.width = recent.gui_geometry_main_width;
1112 geom.height = recent.gui_geometry_main_height;
1113 geom.set_maximized = prefs.gui_geometry_save_maximized;
1115 /* We assume this means the width and height weren't set in
1116 the "recent" file (or that there is no "recent" file),
1117 and weren't set to a default value, so we don't set the
1118 size. (The "recent" file code rejects non-positive width
1119 and height values.) */
1120 geom.set_size = FALSE;
1122 geom.maximized = recent.gui_geometry_main_maximized;
1124 window_set_geometry(widget, &geom);
1126 main_pane_load_window_geometry();
1127 statusbar_load_window_geometry();
1132 main_save_window_geometry(GtkWidget *widget)
1134 window_geometry_t geom;
1136 window_get_geometry(widget, &geom);
1138 if (prefs.gui_geometry_save_position) {
1139 recent.gui_geometry_main_x = geom.x;
1140 recent.gui_geometry_main_y = geom.y;
1143 if (prefs.gui_geometry_save_size) {
1144 recent.gui_geometry_main_width = geom.width;
1145 recent.gui_geometry_main_height = geom.height;
1148 if(prefs.gui_geometry_save_maximized) {
1149 recent.gui_geometry_main_maximized = geom.maximized;
1152 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1153 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1154 statusbar_save_window_geometry();
1158 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1160 /* If there's unsaved data, let the user save it first. */
1161 if (do_file_close(&cfile, TRUE, " before quitting"))
1166 print_usage(gboolean for_help_option) {
1174 if (for_help_option) {
1176 fprintf(output, "Wireshark %s\n"
1177 "Interactively dump and analyze network traffic.\n"
1178 "See http://www.wireshark.org for more information.\n",
1179 get_ws_vcs_version_info());
1183 fprintf(output, "\n");
1184 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1185 fprintf(output, "\n");
1188 fprintf(output, "Capture interface:\n");
1189 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1190 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1191 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1192 fprintf(output, " -p don't capture in promiscuous mode\n");
1193 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1194 fprintf(output, " -S update packet display when new packets are captured\n");
1195 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1196 #ifdef HAVE_PCAP_CREATE
1197 fprintf(output, " -I capture in monitor mode, if available\n");
1199 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1200 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1202 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1203 fprintf(output, " -D print list of interfaces and exit\n");
1204 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1205 fprintf(output, "\n");
1206 fprintf(output, "Capture stop conditions:\n");
1207 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1208 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1209 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1210 fprintf(output, " files:NUM - stop after NUM files\n");
1211 /*fprintf(output, "\n");*/
1212 fprintf(output, "Capture output:\n");
1213 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1214 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1215 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1216 #endif /* HAVE_LIBPCAP */
1217 #ifdef HAVE_PCAP_REMOTE
1218 fprintf(output, "RPCAP options:\n");
1219 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1221 /*fprintf(output, "\n");*/
1222 fprintf(output, "Input file:\n");
1223 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1225 fprintf(output, "\n");
1226 fprintf(output, "Processing:\n");
1227 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1228 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1229 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1231 fprintf(output, "\n");
1232 fprintf(output, "User interface:\n");
1233 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1234 fprintf(output, " -Y <display filter> start with the given display filter\n");
1235 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1236 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1237 fprintf(output, " filter\n");
1238 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1239 fprintf(output, " -m <font> set the font name used for most text\n");
1240 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
1241 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1242 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1243 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1245 fprintf(output, "\n");
1246 fprintf(output, "Output:\n");
1247 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1249 fprintf(output, "\n");
1250 fprintf(output, "Miscellaneous:\n");
1251 fprintf(output, " -h display this help and exit\n");
1252 fprintf(output, " -v display version info and exit\n");
1253 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1254 fprintf(output, " persdata:path - personal data files\n");
1255 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1256 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1258 fprintf(output, " --display=DISPLAY X display to use\n");
1269 printf("Wireshark %s\n"
1276 get_ws_vcs_version_info(), get_copyright_info(), comp_info_str->str,
1277 runtime_info_str->str);
1281 * Report an error in command-line arguments.
1282 * Creates a console on Windows.
1283 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1284 * terminal isn't the standard error?
1287 wireshark_cmdarg_err(const char *fmt, va_list ap)
1292 fprintf(stderr, "wireshark: ");
1293 vfprintf(stderr, fmt, ap);
1294 fprintf(stderr, "\n");
1298 * Report additional information for an error in command-line arguments.
1299 * Creates a console on Windows.
1300 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1301 * terminal isn't the standard error?
1304 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1309 vfprintf(stderr, fmt, ap);
1310 fprintf(stderr, "\n");
1314 Once every 3 seconds we get a callback here which we use to update
1318 tap_update_cb(gpointer data _U_)
1320 draw_tap_listeners(FALSE);
1325 * Periodically process outstanding hostname lookups. If we have new items,
1326 * redraw the packet list and tree view.
1330 resolv_update_cb(gpointer data _U_)
1332 /* Anything new show up? */
1333 if (host_name_lookup_process()) {
1334 if (gtk_widget_get_window(pkt_scrollw))
1335 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1336 if (gtk_widget_get_window(tv_scrollw))
1337 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1340 /* Always check. Even if we don't do async lookups we could still get
1341 passive updates, e.g. from DNS packets. */
1346 /* Update various parts of the main window for a capture file "unsaved
1347 changes" change - update the title to reflect whether there are
1348 unsaved changes or not, and update the menus and toolbar to
1349 enable or disable the "Save" operation. */
1351 main_update_for_unsaved_changes(capture_file *cf)
1353 set_titlebar_for_capture_file(cf);
1354 set_menus_for_capture_file(cf);
1355 set_toolbar_for_capture_file(cf);
1360 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1362 /* Update menubar and toolbar */
1363 menu_auto_scroll_live_changed(auto_scroll_live_in);
1364 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1366 /* change auto scroll state */
1367 auto_scroll_live = auto_scroll_live_in;
1372 main_colorize_changed(gboolean packet_list_colorize)
1374 /* Update menubar and toolbar */
1375 menu_colorize_changed(packet_list_colorize);
1376 toolbar_colorize_changed(packet_list_colorize);
1378 /* change colorization */
1379 if(packet_list_colorize != recent.packet_list_colorize) {
1380 recent.packet_list_colorize = packet_list_colorize;
1381 color_filters_enable(packet_list_colorize);
1382 packet_list_colorize_packets();
1386 static GtkWidget *close_dlg = NULL;
1389 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1391 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1396 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1398 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1403 main_cf_cb_file_closing(capture_file *cf)
1405 /* if we have more than 10000 packets, show a splash screen while closing */
1406 /* XXX - don't know a better way to decide whether to show or not,
1407 * as most of the time is spend in various calls that destroy various
1408 * data structures, so it wouldn't be easy to use a progress bar,
1409 * rather than, say, a progress spinner, here! */
1410 if(cf->count > 10000) {
1411 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1412 "%sClosing file!%s\n\nPlease wait ...",
1413 simple_dialog_primary_start(),
1414 simple_dialog_primary_end());
1415 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1417 /* Clear maunally resolved addresses */
1418 manually_resolve_cleanup();
1419 /* Destroy all windows that refer to the
1420 capture file we're closing. */
1421 destroy_packet_wins();
1423 /* Update the titlebar to reflect the lack of a capture file. */
1424 set_titlebar_for_capture_file(NULL);
1426 /* Disable all menu and toolbar items that make sense only if
1427 you have a capture. */
1428 set_menus_for_capture_file(NULL);
1429 set_toolbar_for_capture_file(NULL);
1430 main_set_for_captured_packets(FALSE);
1431 set_menus_for_selected_packet(cf);
1432 main_set_for_capture_in_progress(FALSE);
1433 set_capture_if_dialog_for_capture_in_progress(FALSE);
1434 set_menus_for_selected_tree_row(cf);
1436 /* Set up main window for no capture file. */
1437 main_set_for_capture_file(FALSE);
1439 main_window_update();
1444 main_cf_cb_file_closed(capture_file *cf _U_)
1446 if(close_dlg != NULL) {
1447 splash_destroy(close_dlg);
1454 main_cf_cb_file_read_started(capture_file *cf _U_)
1456 tap_param_dlg_update();
1458 /* Set up main window for a capture file. */
1459 main_set_for_capture_file(TRUE);
1463 main_cf_cb_file_read_finished(capture_file *cf)
1467 if (!cf->is_tempfile && cf->filename) {
1468 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1469 add_menu_recent_capture_file(cf->filename);
1471 /* Remember folder for next Open dialog and save it in recent */
1472 dir_path = get_dirname(g_strdup(cf->filename));
1473 set_last_open_dir(dir_path);
1477 /* Update the appropriate parts of the main window. */
1478 main_update_for_unsaved_changes(cf);
1480 /* Enable menu items that make sense if you have some captured packets. */
1481 main_set_for_captured_packets(TRUE);
1485 main_cf_cb_file_rescan_finished(capture_file *cf)
1489 if (!cf->is_tempfile && cf->filename) {
1490 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1491 add_menu_recent_capture_file(cf->filename);
1493 /* Remember folder for next Open dialog and save it in recent */
1494 dir_path = get_dirname(g_strdup(cf->filename));
1495 set_last_open_dir(dir_path);
1499 /* Update the appropriate parts of the main window. */
1500 main_update_for_unsaved_changes(cf);
1504 static GList *icon_list_create(
1505 const guint8 *icon16_pb,
1506 const guint8 *icon32_pb,
1507 const guint8 *icon48_pb,
1508 const guint8 *icon64_pb)
1510 GList *icon_list = NULL;
1511 GdkPixbuf * pixbuf16;
1512 GdkPixbuf * pixbuf32;
1513 GdkPixbuf * pixbuf48;
1514 GdkPixbuf * pixbuf64;
1517 if(icon16_pb != NULL) {
1518 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1520 icon_list = g_list_append(icon_list, pixbuf16);
1523 if(icon32_pb != NULL) {
1524 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1526 icon_list = g_list_append(icon_list, pixbuf32);
1529 if(icon48_pb != NULL) {
1530 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1532 icon_list = g_list_append(icon_list, pixbuf48);
1535 if(icon64_pb != NULL) {
1536 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1538 icon_list = g_list_append(icon_list, pixbuf64);
1545 main_capture_cb_capture_prepared(capture_session *cap_session)
1547 static GList *icon_list = NULL;
1549 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1551 if(icon_list == NULL) {
1552 icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1554 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1556 /* Disable menu items that make no sense if you're currently running
1558 main_set_for_capture_in_progress(TRUE);
1559 set_capture_if_dialog_for_capture_in_progress(TRUE);
1561 /* Don't set up main window for a capture file. */
1562 main_set_for_capture_file(FALSE);
1566 main_capture_cb_capture_update_started(capture_session *cap_session)
1568 /* We've done this in "prepared" above, but it will be cleared while
1569 switching to the next multiple file. */
1570 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1572 main_set_for_capture_in_progress(TRUE);
1573 set_capture_if_dialog_for_capture_in_progress(TRUE);
1575 /* Enable menu items that make sense if you have some captured
1576 packets (yes, I know, we don't have any *yet*). */
1577 main_set_for_captured_packets(TRUE);
1579 /* Set up main window for a capture file. */
1580 main_set_for_capture_file(TRUE);
1584 main_capture_cb_capture_update_finished(capture_session *cap_session)
1586 capture_file *cf = (capture_file *)cap_session->cf;
1587 static GList *icon_list = NULL;
1589 /* The capture isn't stopping any more - it's stopped. */
1590 capture_stopping = FALSE;
1592 if (!cf->is_tempfile && cf->filename) {
1593 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1594 add_menu_recent_capture_file(cf->filename);
1597 /* Enable menu items that make sense if you're not currently running
1599 main_set_for_capture_in_progress(FALSE);
1600 set_capture_if_dialog_for_capture_in_progress(FALSE);
1602 /* Update the main window as appropriate. This has to occur AFTER
1603 * main_set_for_capture_in_progress() or else some of the menus are
1604 * incorrectly disabled (see bug
1605 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1606 main_update_for_unsaved_changes(cf);
1608 /* Set up main window for a capture file. */
1609 main_set_for_capture_file(TRUE);
1611 if(icon_list == NULL) {
1612 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1614 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1616 if(global_capture_opts.quit_after_cap) {
1617 /* command line asked us to quit after the capture */
1618 /* don't pop up a dialog to ask for unsaved files etc. */
1624 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1626 /* Don't set up main window for a capture file. */
1627 main_set_for_capture_file(FALSE);
1631 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1634 capture_file *cf = (capture_file *)cap_session->cf;
1636 static GList *icon_list = NULL;
1638 /* The capture isn't stopping any more - it's stopped. */
1639 capture_stopping = FALSE;
1641 /*set_titlebar_for_capture_file(cf);*/
1643 /* Enable menu items that make sense if you're not currently running
1645 main_set_for_capture_in_progress(FALSE);
1646 set_capture_if_dialog_for_capture_in_progress(FALSE);
1648 /* Restore the standard title bar message */
1649 /* (just in case we have trouble opening the capture file). */
1650 set_titlebar_for_capture_file(NULL);
1652 if(icon_list == NULL) {
1653 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1655 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1657 /* We don't have loaded the capture file, this will be done later.
1658 * For now we still have simply a blank screen. */
1660 if(global_capture_opts.quit_after_cap) {
1661 /* command line asked us to quit after the capture */
1662 /* don't pop up a dialog to ask for unsaved files etc. */
1668 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1670 capture_stopping = TRUE;
1671 set_menus_for_capture_stopping();
1673 set_toolbar_for_capture_stopping();
1675 set_capture_if_dialog_for_capture_stopping();
1680 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1682 static GList *icon_list = NULL;
1684 /* Capture isn't stopping any more. */
1685 capture_stopping = FALSE;
1687 /* the capture failed before the first packet was captured
1688 reset title, menus and icon */
1689 set_titlebar_for_capture_file(NULL);
1691 main_set_for_capture_in_progress(FALSE);
1692 set_capture_if_dialog_for_capture_in_progress(FALSE);
1694 main_set_for_capture_file(FALSE);
1696 if(icon_list == NULL) {
1697 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1699 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1702 if(global_capture_opts.quit_after_cap) {
1703 /* command line asked us to quit after the capture */
1704 /* don't pop up a dialog to ask for unsaved files etc. */
1708 #endif /* HAVE_LIBPCAP */
1711 main_cf_cb_packet_selected(gpointer data)
1713 capture_file *cf = (capture_file *)data;
1715 /* Display the GUI protocol tree and packet bytes.
1716 XXX - why do we dump core if we call "proto_tree_draw()"
1717 before calling "add_byte_views()"? */
1718 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1719 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1721 /* Note: Both string and hex value searches in the packet data produce a non-zero
1722 search_pos if successful */
1723 if(cf->search_in_progress &&
1724 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1725 highlight_field(cf->edt->tvb, cf->search_pos,
1726 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1729 /* A packet is selected. */
1730 set_menus_for_selected_packet(cf);
1734 main_cf_cb_packet_unselected(capture_file *cf)
1736 /* No packet is being displayed; clear the hex dump pane by getting
1737 rid of all the byte views. */
1738 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1739 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1741 /* Add a placeholder byte view so that there's at least something
1742 displayed in the byte view notebook. */
1743 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1745 /* And clear the protocol tree display as well. */
1746 proto_tree_draw(NULL, tree_view_gbl);
1748 /* No packet is selected. */
1749 set_menus_for_selected_packet(cf);
1753 main_cf_cb_field_unselected(capture_file *cf)
1755 set_menus_for_selected_tree_row(cf);
1759 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1761 capture_file *cf = (capture_file *)data;
1763 case(cf_cb_file_opened):
1764 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1765 fileset_file_opened(cf);
1767 case(cf_cb_file_closing):
1768 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1769 main_cf_cb_file_closing(cf);
1771 case(cf_cb_file_closed):
1772 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1773 main_cf_cb_file_closed(cf);
1774 fileset_file_closed();
1776 case(cf_cb_file_read_started):
1777 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1778 main_cf_cb_file_read_started(cf);
1780 case(cf_cb_file_read_finished):
1781 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1782 main_cf_cb_file_read_finished(cf);
1784 case(cf_cb_file_reload_started):
1785 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1786 main_cf_cb_file_read_started(cf);
1788 case(cf_cb_file_reload_finished):
1789 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1790 main_cf_cb_file_read_finished(cf);
1792 case(cf_cb_file_rescan_started):
1793 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1795 case(cf_cb_file_rescan_finished):
1796 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1797 main_cf_cb_file_rescan_finished(cf);
1799 case(cf_cb_file_fast_save_finished):
1800 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1801 main_cf_cb_file_rescan_finished(cf);
1803 case(cf_cb_packet_selected):
1804 main_cf_cb_packet_selected(cf);
1806 case(cf_cb_packet_unselected):
1807 main_cf_cb_packet_unselected(cf);
1809 case(cf_cb_field_unselected):
1810 main_cf_cb_field_unselected(cf);
1812 case(cf_cb_file_save_started):
1813 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1815 case(cf_cb_file_save_finished):
1816 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1818 case(cf_cb_file_save_failed):
1819 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1821 case(cf_cb_file_save_stopped):
1822 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1824 case(cf_cb_file_export_specified_packets_started):
1825 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1827 case(cf_cb_file_export_specified_packets_finished):
1828 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1830 case(cf_cb_file_export_specified_packets_failed):
1831 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1833 case(cf_cb_file_export_specified_packets_stopped):
1834 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1837 g_warning("main_cf_callback: event %u unknown", event);
1838 g_assert_not_reached();
1844 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1846 #ifdef HAVE_GTKOSXAPPLICATION
1847 GtkosxApplication *theApp;
1850 case(capture_cb_capture_prepared):
1851 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1852 main_capture_cb_capture_prepared(cap_session);
1854 case(capture_cb_capture_update_started):
1855 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1856 main_capture_cb_capture_update_started(cap_session);
1857 #ifdef HAVE_GTKOSXAPPLICATION
1858 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1859 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1862 case(capture_cb_capture_update_continue):
1863 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1865 case(capture_cb_capture_update_finished):
1866 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1867 main_capture_cb_capture_update_finished(cap_session);
1869 case(capture_cb_capture_fixed_started):
1870 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1871 main_capture_cb_capture_fixed_started(cap_session);
1873 case(capture_cb_capture_fixed_continue):
1874 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1876 case(capture_cb_capture_fixed_finished):
1877 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1878 main_capture_cb_capture_fixed_finished(cap_session);
1880 case(capture_cb_capture_stopping):
1881 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1882 /* Beware: this state won't be called, if the capture child
1883 * closes the capturing on its own! */
1884 #ifdef HAVE_GTKOSXAPPLICATION
1885 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1886 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1888 main_capture_cb_capture_stopping(cap_session);
1890 case(capture_cb_capture_failed):
1891 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1892 main_capture_cb_capture_failed(cap_session);
1895 g_warning("main_capture_callback: event %u unknown", event);
1896 g_assert_not_reached();
1902 get_wireshark_gtk_compiled_info(GString *str)
1904 g_string_append(str, "with ");
1905 g_string_append_printf(str,
1906 #ifdef GTK_MAJOR_VERSION
1907 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1910 "GTK+ (version unknown)");
1914 g_string_append(str, ", with Cairo ");
1915 g_string_append(str, CAIRO_VERSION_STRING);
1918 g_string_append(str, ", with Pango ");
1919 g_string_append(str, PANGO_VERSION_STRING);
1921 /* Capture libraries */
1922 g_string_append(str, ", ");
1923 get_compiled_caplibs_version(str);
1926 g_string_append(str, ", ");
1928 g_string_append(str, "with libz ");
1930 g_string_append(str, ZLIB_VERSION);
1931 #else /* ZLIB_VERSION */
1932 g_string_append(str, "(version unknown)");
1933 #endif /* ZLIB_VERSION */
1934 #else /* HAVE_LIBZ */
1935 g_string_append(str, "without libz");
1936 #endif /* HAVE_LIBZ */
1940 get_gui_compiled_info(GString *str)
1942 epan_get_compiled_version_info(str);
1944 g_string_append(str, ", ");
1945 #ifdef HAVE_LIBPORTAUDIO
1946 #ifdef PORTAUDIO_API_1
1947 g_string_append(str, "with PortAudio <= V18");
1948 #else /* PORTAUDIO_API_1 */
1949 g_string_append(str, "with ");
1950 g_string_append(str, Pa_GetVersionText());
1951 #endif /* PORTAUDIO_API_1 */
1952 #else /* HAVE_LIBPORTAUDIO */
1953 g_string_append(str, "without PortAudio");
1954 #endif /* HAVE_LIBPORTAUDIO */
1956 g_string_append(str, ", ");
1958 get_compiled_airpcap_version(str);
1960 g_string_append(str, "without AirPcap");
1965 get_wireshark_runtime_info(GString *str)
1968 /* Capture libraries */
1969 g_string_append(str, ", ");
1970 get_runtime_caplibs_version(str);
1974 #if defined(HAVE_LIBZ) && !defined(_WIN32)
1975 g_string_append_printf(str, ", with libz %s", zlibVersion());
1978 /* stuff used by libwireshark */
1979 epan_get_runtime_version_info(str);
1982 g_string_append(str, ", ");
1983 get_runtime_airpcap_version(str);
1987 g_string_append(str, ", ");
1988 u3_runtime_info(str);
1993 read_configuration_files(char **gdp_path, char **dp_path)
1995 int gpf_open_errno, gpf_read_errno;
1996 int cf_open_errno, df_open_errno;
1997 int gdp_open_errno, gdp_read_errno;
1998 int dp_open_errno, dp_read_errno;
1999 char *gpf_path, *pf_path;
2000 char *cf_path, *df_path;
2001 int pf_open_errno, pf_read_errno;
2004 /* load the decode as entries of this profile */
2005 load_decode_as_entries();
2007 /* Read the preference files. */
2008 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2009 &pf_open_errno, &pf_read_errno, &pf_path);
2011 if (gpf_path != NULL) {
2012 if (gpf_open_errno != 0) {
2013 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2014 "Could not open global preferences file\n\"%s\": %s.",
2015 gpf_path, g_strerror(gpf_open_errno));
2017 if (gpf_read_errno != 0) {
2018 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2019 "I/O error reading global preferences file\n\"%s\": %s.",
2020 gpf_path, g_strerror(gpf_read_errno));
2023 if (pf_path != NULL) {
2024 if (pf_open_errno != 0) {
2025 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2026 "Could not open your preferences file\n\"%s\": %s.",
2027 pf_path, g_strerror(pf_open_errno));
2029 if (pf_read_errno != 0) {
2030 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2031 "I/O error reading your preferences file\n\"%s\": %s.",
2032 pf_path, g_strerror(pf_read_errno));
2039 /* if the user wants a console to be always there, well, we should open one for him */
2040 if (prefs_p->gui_console_open == console_open_always) {
2045 /* Read the capture filter file. */
2046 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2047 if (cf_path != NULL) {
2048 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2049 "Could not open your capture filter file\n\"%s\": %s.",
2050 cf_path, g_strerror(cf_open_errno));
2054 /* Read the display filter file. */
2055 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2056 if (df_path != NULL) {
2057 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2058 "Could not open your display filter file\n\"%s\": %s.",
2059 df_path, g_strerror(df_open_errno));
2063 /* Read the disabled protocols file. */
2064 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2065 dp_path, &dp_open_errno, &dp_read_errno);
2066 if (*gdp_path != NULL) {
2067 if (gdp_open_errno != 0) {
2068 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2069 "Could not open global disabled protocols file\n\"%s\": %s.",
2070 *gdp_path, g_strerror(gdp_open_errno));
2072 if (gdp_read_errno != 0) {
2073 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2074 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2075 *gdp_path, g_strerror(gdp_read_errno));
2080 if (*dp_path != NULL) {
2081 if (dp_open_errno != 0) {
2082 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2083 "Could not open your disabled protocols file\n\"%s\": %s.",
2084 *dp_path, g_strerror(dp_open_errno));
2086 if (dp_read_errno != 0) {
2087 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2088 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2089 *dp_path, g_strerror(dp_read_errno));
2098 /* Check if there's something important to tell the user during startup.
2099 * We want to do this *after* showing the main window so that any windows
2100 * we pop up will be above the main window.
2104 check_and_warn_user_startup(gchar *cf_name)
2106 check_and_warn_user_startup(gchar *cf_name _U_)
2109 gchar *cur_user, *cur_group;
2110 gpointer priv_warning_dialog;
2112 /* Tell the user not to run as root. */
2113 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2114 cur_user = get_cur_username();
2115 cur_group = get_cur_groupname();
2116 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2117 "Running as user \"%s\" and group \"%s\".\n"
2118 "This could be dangerous.\n\n"
2119 "If you're running Wireshark this way in order to perform live capture, "
2120 "you may want to be aware that there is a better way documented at\n"
2121 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2124 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2125 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2129 /* Warn the user if npf.sys isn't loaded. */
2130 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2131 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2132 "The NPF driver isn't running. You may have trouble\n"
2133 "capturing or listing interfaces.");
2134 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2135 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2141 /* And now our feature presentation... [ fade to music ] */
2143 main(int argc, char *argv[])
2145 char *init_progfile_dir_error;
2148 gboolean arg_error = FALSE;
2150 extern int info_update_freq; /* Found in about_dlg.c. */
2151 const gchar *filter;
2159 char *gdp_path, *dp_path;
2162 gboolean start_capture = FALSE;
2163 gboolean list_link_layer_types = FALSE;
2168 gboolean capture_option_specified = FALSE;
2175 gint pl_size = 280, tv_size = 95, bv_size = 75;
2176 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2177 dfilter_t *rfcode = NULL;
2178 gboolean rfilter_parse_failed = FALSE;
2181 GtkWidget *splash_win = NULL;
2182 GLogLevelFlags log_flags;
2183 guint go_to_packet = 0;
2184 search_direction jump_backwards = SD_FORWARD;
2185 dfilter_t *jump_to_filter = NULL;
2187 unsigned int in_file_type = WTAP_TYPE_AUTO;
2188 #ifdef HAVE_GTKOSXAPPLICATION
2189 GtkosxApplication *theApp;
2192 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
2194 static const char optstring[] = OPTSTRING;
2196 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2198 /* Set the C-language locale to the native environment. */
2199 setlocale(LC_ALL, "");
2201 arg_list_utf_16to8(argc, argv);
2202 create_app_running_mutex();
2206 * Get credential information for later use, and drop privileges
2207 * before doing anything else.
2208 * Let the user know if anything happened.
2210 init_process_policies();
2211 relinquish_special_privs_perm();
2214 * Attempt to get the pathname of the executable file.
2216 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2218 /* initialize the funnel mini-api */
2219 initialize_funnel_ops();
2221 AirPDcapInitContext(&airpdcap_ctx);
2224 /* Load wpcap if possible. Do this before collecting the run-time version information */
2227 /* ... and also load the packet.dll from wpcap */
2228 wpcap_packet_load();
2231 /* Load the airpcap.dll. This must also be done before collecting
2232 * run-time version information. */
2233 airpcap_dll_ret_val = load_airpcap();
2235 switch (airpcap_dll_ret_val) {
2236 case AIRPCAP_DLL_OK:
2237 /* load the airpcap interfaces */
2238 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2240 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2241 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2242 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2245 airpcap_if_active = NULL;
2249 /* select the first ad default (THIS SHOULD BE CHANGED) */
2250 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2255 * XXX - Maybe we need to warn the user if one of the following happens???
2257 case AIRPCAP_DLL_OLD:
2258 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2261 case AIRPCAP_DLL_ERROR:
2262 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2265 case AIRPCAP_DLL_NOT_FOUND:
2266 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2270 #endif /* HAVE_AIRPCAP */
2273 /* Assemble the compile-time version information string */
2274 comp_info_str = g_string_new("Compiled ");
2276 get_compiled_version_info(comp_info_str, get_wireshark_gtk_compiled_info,
2277 get_gui_compiled_info);
2279 /* Assemble the run-time version information string */
2280 runtime_info_str = g_string_new("Running ");
2281 get_runtime_version_info(runtime_info_str, get_wireshark_runtime_info);
2283 /* Add it to the information to be reported on a crash. */
2284 ws_add_crash_info("Wireshark %s\n"
2289 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2292 /* Start windows sockets */
2293 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2296 profile_store_persconffiles (TRUE);
2298 /* Read the profile independent recent file. We have to do this here so we can */
2299 /* set the profile before it can be set from the command line parameter */
2300 recent_read_static(&rf_path, &rf_open_errno);
2301 if (rf_path != NULL && rf_open_errno != 0) {
2302 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2303 "Could not open common recent file\n\"%s\": %s.",
2304 rf_path, g_strerror(rf_open_errno));
2307 /* "pre-scan" the command line parameters, if we have "console only"
2308 parameters. We do this so we don't start GTK+ if we're only showing
2309 command-line help or version information.
2311 XXX - this pre-scan is done before we start GTK+, so we haven't
2312 run gtk_init() on the arguments. That means that GTK+ arguments
2313 have not been removed from the argument list; those arguments
2314 begin with "--", and will be treated as an error by getopt().
2316 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2319 optind_initial = optind;
2320 while ((opt = getopt(argc, argv, optstring)) != -1) {
2322 case 'C': /* Configuration Profile */
2323 if (profile_exists (optarg, FALSE)) {
2324 set_profile_name (optarg);
2326 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2330 case 'D': /* Print a list of capture devices and exit */
2332 if_list = capture_interface_list(&err, &err_str,main_window_update);
2333 if (if_list == NULL) {
2335 cmdarg_err("There are no interfaces on which a capture can be done");
2337 cmdarg_err("%s", err_str);
2345 capture_opts_print_interfaces(if_list);
2346 free_interface_list(if_list);
2351 #else /* HAVE_LIBPCAP */
2352 capture_option_specified = TRUE;
2354 #endif /* HAVE_LIBPCAP */
2356 case 'h': /* Print help and exit */
2362 if (strcmp(optarg, "-") == 0)
2363 set_stdin_capture(TRUE);
2366 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
2367 if (!persfilepath_opt(opt, optarg)) {
2368 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2372 case 'v': /* Show version and exit */
2384 * Extension command line options have to be processed before
2385 * we call epan_init() as they are supposed to be used by dissectors
2386 * or taps very early in the registration process.
2390 case '?': /* Ignore errors - the "real" scan will catch them. */
2395 /* Init the "Open file" dialog directory */
2396 /* (do this after the path settings are processed) */
2398 /* Read the profile dependent (static part) of the recent file. */
2399 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2400 /* recent lists which is done in the dynamic part. */
2401 /* We have to do this already here, so command line parameters can overwrite these values. */
2402 recent_read_profile_static(&rf_path, &rf_open_errno);
2403 if (rf_path != NULL && rf_open_errno != 0) {
2404 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2405 "Could not open recent file\n\"%s\": %s.",
2406 rf_path, g_strerror(rf_open_errno));
2409 if (recent.gui_fileopen_remembered_dir &&
2410 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2411 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2413 set_last_open_dir(get_persdatafile_dir());
2416 /* Set getopt index back to initial value, so it will start with the
2417 first command line parameter again. Also reset opterr to 1, so that
2418 error messages are printed by getopt().
2420 XXX - this seems to work on most platforms, but time will tell.
2421 The Single UNIX Specification says "The getopt() function need
2422 not be reentrant", so this isn't guaranteed to work. The Mac
2423 OS X 10.4[.x] getopt() man page says
2425 In order to use getopt() to evaluate multiple sets of arguments, or to
2426 evaluate a single set of arguments multiple times, the variable optreset
2427 must be set to 1 before the second and each additional set of calls to
2428 getopt(), and the variable optind must be reinitialized.
2432 The optreset variable was added to make it possible to call the getopt()
2433 function multiple times. This is an extension to the IEEE Std 1003.2
2434 (``POSIX.2'') specification.
2436 which I think comes from one of the other BSDs.
2438 XXX - if we want to control all the command-line option errors, so
2439 that we can display them where we choose (e.g., in a window), we'd
2440 want to leave opterr as 0, and produce our own messages using optopt.
2441 We'd have to check the value of optopt to see if it's a valid option
2442 letter, in which case *presumably* the error is "this option requires
2443 an argument but none was specified", or not a valid option letter,
2444 in which case *presumably* the error is "this option isn't valid".
2445 Some versions of getopt() let you supply a option string beginning
2446 with ':', which means that getopt() will return ':' rather than '?'
2447 for "this option requires an argument but none was specified", but
2449 optind = optind_initial;
2452 #if !GLIB_CHECK_VERSION(2,31,0)
2453 g_thread_init(NULL);
2456 /* Set the current locale according to the program environment.
2457 * We haven't localized anything, but some GTK widgets are localized
2458 * (the file selection dialogue, for example).
2459 * This also sets the C-language locale to the native environment. */
2460 setlocale (LC_ALL, "");
2462 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2463 gtk_init (&argc, &argv);
2465 cf_callback_add(main_cf_callback, NULL);
2467 capture_callback_add(main_capture_callback, NULL);
2469 cf_callback_add(statusbar_cf_callback, NULL);
2471 capture_callback_add(statusbar_capture_callback, NULL);
2474 /* Arrange that if we have no console window, and a GLib message logging
2475 routine is called to log a message, we pop up a console window.
2477 We do that by inserting our own handler for all messages logged
2478 to the default domain; that handler pops up a console if necessary,
2479 and then calls the default handler. */
2481 /* We might want to have component specific log levels later ... */
2483 log_flags = (GLogLevelFlags)
2485 G_LOG_LEVEL_CRITICAL|
2486 G_LOG_LEVEL_WARNING|
2487 G_LOG_LEVEL_MESSAGE|
2491 G_LOG_FLAG_RECURSION);
2493 g_log_set_handler(NULL,
2495 console_log_handler, NULL /* user_data */);
2496 g_log_set_handler(LOG_DOMAIN_MAIN,
2498 console_log_handler, NULL /* user_data */);
2501 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2503 console_log_handler, NULL /* user_data */);
2504 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2506 console_log_handler, NULL /* user_data */);
2508 /* Set the initial values in the capture options. This might be overwritten
2509 by preference settings and then again by the command line parameters. */
2510 capture_opts_init(&global_capture_opts);
2512 capture_session_init(&global_capture_session, (void *)&cfile);
2515 init_report_err(failure_alert_box, open_failure_alert_box,
2516 read_failure_alert_box, write_failure_alert_box);
2518 /* Initialize whatever we need to allocate colors for GTK+ */
2521 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2522 filter = get_conn_cfilter();
2523 if ( *filter != '\0' ) {
2524 info_update_freq = 1000; /* Milliseconds */
2527 /* We won't come till here, if we had a "console only" command line parameter. */
2528 splash_win = splash_new("Loading Wireshark ...");
2529 if (init_progfile_dir_error != NULL) {
2530 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2531 "Can't get pathname of Wireshark: %s.\n"
2532 "It won't be possible to capture traffic.\n"
2533 "Report this to the Wireshark developers.",
2534 init_progfile_dir_error);
2535 g_free(init_progfile_dir_error);
2538 init_open_routines();
2541 /* Register all the plugin types we have. */
2542 epan_register_plugin_types(); /* Types known to libwireshark */
2543 wtap_register_plugin_types(); /* Types known to libwiretap */
2544 codec_register_plugin_types(); /* Types known to libcodec */
2546 /* Scan for plugins. This does *not* call their registration routines;
2547 that's done later. */
2550 /* Register all libwiretap plugin modules. */
2551 register_all_wiretap_modules();
2553 /* Register all audio codec plugins. */
2554 register_all_codecs();
2557 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2559 /* Register all dissectors; we must do this before checking for the
2560 "-G" flag, as the "-G" flag dumps information registered by the
2561 dissectors, and we must do it before we read the preferences, in
2562 case any dissectors register preferences. */
2563 epan_init(register_all_protocols,register_all_protocol_handoffs,
2564 splash_update, (gpointer) splash_win);
2566 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2568 /* Register all tap listeners; we do this before we parse the arguments,
2569 as the "-z" argument can specify a registered tap. */
2571 /* we register the plugin taps before the other taps because
2572 stats_tree taps plugins will be registered as tap listeners
2573 by stats_tree_stat.c and need to registered before that */
2576 register_all_plugin_tap_listeners();
2579 register_all_tap_listeners();
2580 conversation_table_set_gui_info(init_conversation_table);
2582 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2584 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2585 /* Removed thread code:
2586 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2589 /* this is to keep tap extensions updating once every 3 seconds */
2590 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2592 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2594 cap_file_init(&cfile);
2596 /* Fill in capture options with values from the preferences */
2597 prefs_to_capture_opts();
2599 /*#ifdef HAVE_LIBPCAP
2600 fill_in_local_interfaces();
2602 /* Now get our args */
2603 while ((opt = getopt(argc, argv, optstring)) != -1) {
2605 /*** capture option specific ***/
2606 case 'a': /* autostop criteria */
2607 case 'b': /* Ringbuffer option */
2608 case 'c': /* Capture xxx packets */
2609 case 'f': /* capture filter */
2610 case 'k': /* Start capture immediately */
2611 case 'H': /* Hide capture info dialog box */
2612 case 'p': /* Don't capture in promiscuous mode */
2613 case 'i': /* Use interface x */
2614 #ifdef HAVE_PCAP_CREATE
2615 case 'I': /* Capture in monitor mode, if available */
2617 #ifdef HAVE_PCAP_REMOTE
2618 case 'A': /* Authentication */
2620 case 's': /* Set the snapshot (capture) length */
2621 case 'S': /* "Sync" mode: used for following file ala tail -f */
2622 case 'w': /* Write to capture file xxx */
2623 case 'y': /* Set the pcap data link type */
2624 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2625 case 'B': /* Buffer size */
2626 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2628 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2634 capture_option_specified = TRUE;
2639 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2640 case 'K': /* Kerberos keytab file */
2641 read_keytab_file(optarg);
2645 /*** all non capture option specific ***/
2647 /* Configuration profile settings were already processed just ignore them this time*/
2649 case 'j': /* Search backwards for a matching packet from filter in option J */
2650 jump_backwards = SD_BACKWARD;
2652 case 'g': /* Go to packet with the given packet number */
2653 go_to_packet = get_positive_int(optarg, "go to packet");
2655 case 'J': /* Jump to the first packet which matches the filter criteria */
2658 case 'l': /* Automatic scrolling in live capture mode */
2660 auto_scroll_live = TRUE;
2662 capture_option_specified = TRUE;
2666 case 'L': /* Print list of link-layer types and exit */
2668 list_link_layer_types = TRUE;
2670 capture_option_specified = TRUE;
2674 case 'm': /* Fixed-width font for the display */
2675 g_free(prefs_p->gui_gtk2_font_name);
2676 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2678 case 'n': /* No name resolution */
2679 gbl_resolv_flags.mac_name = FALSE;
2680 gbl_resolv_flags.network_name = FALSE;
2681 gbl_resolv_flags.transport_name = FALSE;
2682 gbl_resolv_flags.concurrent_dns = FALSE;
2684 case 'N': /* Select what types of addresses/port #s to resolve */
2685 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2686 if (badopt != '\0') {
2687 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2692 case 'o': /* Override preference from command line */
2693 switch (prefs_set_pref(optarg)) {
2696 case PREFS_SET_SYNTAX_ERR:
2697 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2700 case PREFS_SET_NO_SUCH_PREF:
2701 /* not a preference, might be a recent setting */
2702 switch (recent_set_arg(optarg)) {
2705 case PREFS_SET_SYNTAX_ERR:
2706 /* shouldn't happen, checked already above */
2707 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2710 case PREFS_SET_NO_SUCH_PREF:
2711 case PREFS_SET_OBSOLETE:
2712 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2717 g_assert_not_reached();
2720 case PREFS_SET_OBSOLETE:
2721 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2726 g_assert_not_reached();
2730 /* Path settings were already processed just ignore them this time*/
2732 case 'r': /* Read capture file xxx */
2733 /* We may set "last_open_dir" to "cf_name", and if we change
2734 "last_open_dir" later, we free the old value, so we have to
2735 set "cf_name" to something that's been allocated. */
2736 cf_name = g_strdup(optarg);
2738 case 'R': /* Read file filter */
2741 case 't': /* Time stamp type */
2742 if (strcmp(optarg, "r") == 0)
2743 timestamp_set_type(TS_RELATIVE);
2744 else if (strcmp(optarg, "a") == 0)
2745 timestamp_set_type(TS_ABSOLUTE);
2746 else if (strcmp(optarg, "ad") == 0)
2747 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2748 else if (strcmp(optarg, "adoy") == 0)
2749 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
2750 else if (strcmp(optarg, "d") == 0)
2751 timestamp_set_type(TS_DELTA);
2752 else if (strcmp(optarg, "dd") == 0)
2753 timestamp_set_type(TS_DELTA_DIS);
2754 else if (strcmp(optarg, "e") == 0)
2755 timestamp_set_type(TS_EPOCH);
2756 else if (strcmp(optarg, "u") == 0)
2757 timestamp_set_type(TS_UTC);
2758 else if (strcmp(optarg, "ud") == 0)
2759 timestamp_set_type(TS_UTC_WITH_YMD);
2760 else if (strcmp(optarg, "udoy") == 0)
2761 timestamp_set_type(TS_UTC_WITH_YDOY);
2763 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2765 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2767 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2769 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2771 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2773 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2777 case 'u': /* Seconds type */
2778 if (strcmp(optarg, "s") == 0)
2779 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2780 else if (strcmp(optarg, "hms") == 0)
2781 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2783 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2785 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2790 /* ext ops were already processed just ignore them this time*/
2796 /* We won't call the init function for the stat this soon
2797 as it would disallow MATE's fields (which are registered
2798 by the preferences set callback) from being used as
2799 part of a tap filter. Instead, we just add the argument
2800 to a list of stat arguments. */
2801 if (!process_stat_cmd_arg(optarg)) {
2802 cmdarg_err("Invalid -z argument.");
2803 cmdarg_err_cont(" -z argument must be one of :");
2804 list_stat_cmd_args();
2809 case '?': /* Bad flag - print usage message */
2818 if (cf_name != NULL) {
2820 * Input file name specified with "-r" *and* specified as a regular
2821 * command-line argument.
2823 cmdarg_err("File name specified both with -r and regular argument");
2827 * Input file name not specified with "-r", and a command-line argument
2828 * was specified; treat it as the input file name.
2830 * Yes, this is different from tshark, where non-flag command-line
2831 * arguments are a filter, but this works better on GUI desktops
2832 * where a command can be specified to be run to open a particular
2833 * file - yes, you could have "-r" as the last part of the command,
2834 * but that's a bit ugly.
2836 #ifndef HAVE_GTKOSXAPPLICATION
2838 * For GTK+ Mac Integration, file name passed as free argument passed
2839 * through grag-and-drop and opened twice sometimes causing crashes.
2840 * Subject to report to GTK+ MAC.
2842 cf_name = g_strdup(argv[0]);
2851 * Extra command line arguments were specified; complain.
2853 cmdarg_err("Invalid argument: %s", argv[0]);
2859 #ifndef HAVE_LIBPCAP
2860 if (capture_option_specified) {
2861 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2869 fill_in_local_interfaces(main_window_update);
2870 if (start_capture && list_link_layer_types) {
2871 /* Specifying *both* is bogus. */
2872 cmdarg_err("You can't specify both -L and a live capture.");
2876 if (list_link_layer_types) {
2877 /* We're supposed to list the link-layer types for an interface;
2878 did the user also specify a capture file to be read? */
2880 /* Yes - that's bogus. */
2881 cmdarg_err("You can't specify -L and a capture file to be read.");
2884 /* No - did they specify a ring buffer option? */
2885 if (global_capture_opts.multi_files_on) {
2886 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2890 /* We're supposed to do a live capture; did the user also specify
2891 a capture file to be read? */
2892 if (start_capture && cf_name) {
2893 /* Yes - that's bogus. */
2894 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2898 /* No - was the ring buffer option specified and, if so, does it make
2900 if (global_capture_opts.multi_files_on) {
2901 /* Ring buffer works only under certain conditions:
2902 a) ring buffer does not work with temporary files;
2903 b) real_time_mode and multi_files_on are mutually exclusive -
2904 real_time_mode takes precedence;
2905 c) it makes no sense to enable the ring buffer if the maximum
2906 file size is set to "infinite". */
2907 if (global_capture_opts.save_file == NULL) {
2908 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2909 global_capture_opts.multi_files_on = FALSE;
2911 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2912 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2913 /* XXX - this must be redesigned as the conditions changed */
2918 if (start_capture || list_link_layer_types) {
2919 /* We're supposed to do a live capture or get a list of link-layer
2920 types for a live capture device; if the user didn't specify an
2921 interface to use, pick a default. */
2922 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2923 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2929 if (list_link_layer_types) {
2930 /* Get the list of link-layer types for the capture devices. */
2931 if_capabilities_t *caps;
2934 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2936 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2937 if (device.selected) {
2938 #if defined(HAVE_PCAP_CREATE)
2939 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str, main_window_update);
2941 caps = capture_get_if_capabilities(device.name, FALSE, &err_str,main_window_update);
2944 cmdarg_err("%s", err_str);
2948 if (caps->data_link_types == NULL) {
2949 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2955 #if defined(HAVE_PCAP_CREATE)
2956 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2958 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2963 free_if_capabilities(caps);
2968 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2969 capture_opts_trim_ring_num_files(&global_capture_opts);
2970 #endif /* HAVE_LIBPCAP */
2972 /* Notify all registered modules that have had any of their preferences
2973 changed either from one of the preferences file or from the command
2974 line that their preferences have changed. */
2978 if ((global_capture_opts.num_selected == 0) &&
2979 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2982 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2983 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2984 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2985 device.selected = TRUE;
2986 global_capture_opts.num_selected++;
2987 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2988 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2993 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2994 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2995 device.selected = TRUE;
2996 global_capture_opts.num_selected++;
2997 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2998 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
3002 /* disabled protocols as per configuration file */
3003 if (gdp_path == NULL && dp_path == NULL) {
3004 set_disabled_protos_list();
3007 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
3009 /* read in rc file from global and personal configuration paths. */
3010 rc_file = get_datafile_path(RC_FILE);
3011 #if GTK_CHECK_VERSION(3,0,0)
3012 /* XXX resolve later */
3014 gtk_rc_parse(rc_file);
3016 rc_file = get_persconffile_path(RC_FILE, FALSE);
3017 gtk_rc_parse(rc_file);
3027 /* close the splash screen, as we are going to open the main window now */
3028 splash_destroy(splash_win);
3030 /************************************************************************/
3031 /* Everything is prepared now, preferences and command line was read in */
3033 /* Pop up the main window. */
3034 create_main_window(pl_size, tv_size, bv_size, prefs_p);
3036 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3037 recent_read_dynamic(&rf_path, &rf_open_errno);
3038 if (rf_path != NULL && rf_open_errno != 0) {
3039 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3040 "Could not open recent file\n\"%s\": %s.",
3041 rf_path, g_strerror(rf_open_errno));
3044 color_filters_enable(recent.packet_list_colorize);
3046 /* rearrange all the widgets as we now have all recent settings ready for this */
3047 main_widgets_rearrange();
3049 /* Fill in column titles. This must be done after the top level window
3052 XXX - is that still true, with fixed-width columns? */
3054 menu_recent_read_finished();
3056 main_auto_scroll_live_changed(auto_scroll_live);
3059 switch (user_font_apply()) {
3062 case FA_FONT_NOT_RESIZEABLE:
3063 /* "user_font_apply()" popped up an alert box. */
3064 /* turn off zooming - font can't be resized */
3065 case FA_FONT_NOT_AVAILABLE:
3066 /* XXX - did we successfully load the un-zoomed version earlier?
3067 If so, this *probably* means the font is available, but not at
3068 this particular zoom level, but perhaps some other failure
3069 occurred; I'm not sure you can determine which is the case,
3071 /* turn off zooming - zoom level is unavailable */
3073 /* in any other case than FA_SUCCESS, turn off zooming */
3074 recent.gui_zoom_level = 0;
3075 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3078 dnd_init(top_level);
3080 color_filters_init();
3082 capture_filter_init();
3085 /* the window can be sized only, if it's not already shown, so do it now! */
3086 main_load_window_geometry(top_level);
3088 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3090 /* If we were given the name of a capture file, read it in now;
3091 we defer it until now, so that, if we can't open it, and pop
3092 up an alert box, the alert box is more likely to come up on
3093 top of the main window - but before the preference-file-error
3094 alert box, so, if we get one of those, it's more likely to come
3097 show_main_window(TRUE);
3098 check_and_warn_user_startup(cf_name);
3099 if (rfilter != NULL) {
3100 if (!dfilter_compile(rfilter, &rfcode)) {
3101 bad_dfilter_alert_box(top_level, rfilter);
3102 rfilter_parse_failed = TRUE;
3105 if (ex_opt_count("read_format") > 0) {
3106 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
3108 if (!rfilter_parse_failed) {
3109 if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
3110 /* "cf_open()" succeeded, so it closed the previous
3111 capture file, and thus destroyed any previous read filter
3112 attached to "cf". */
3114 cfile.rfcode = rfcode;
3115 /* Open stat windows; we do so after creating the main window,
3116 to avoid GTK warnings, and after successfully opening the
3117 capture file, so we know we have something to compute stats
3118 on, and after registering all dissectors, so that MATE will
3119 have registered its field array and we can have a tap filter
3120 with one of MATE's late-registered fields as part of the
3122 start_requested_stats();
3124 /* Read the capture file. */
3125 switch (cf_read(&cfile, FALSE)) {
3129 /* Just because we got an error, that doesn't mean we were unable
3130 to read any of the file; we handle what we could get from the
3132 /* if the user told us to jump to a specific packet, do it now */
3133 if(go_to_packet != 0) {
3134 /* Jump to the specified frame number, kept for backward
3136 cf_goto_frame(&cfile, go_to_packet);
3137 } else if (jfilter != NULL) {
3138 /* try to compile given filter */
3139 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3140 bad_dfilter_alert_box(top_level, jfilter);
3142 /* Filter ok, jump to the first packet matching the filter
3143 conditions. Default search direction is forward, but if
3144 option d was given, search backwards */
3145 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3150 case CF_READ_ABORTED:
3156 /* If the filename is not the absolute path, prepend the current dir. This happens
3157 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3158 if (!g_path_is_absolute(cf_name)) {
3159 char *old_cf_name = cf_name;
3160 char *pwd = g_get_current_dir();
3161 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3162 g_free(old_cf_name);
3166 /* Save the name of the containing directory specified in the
3167 path name, if any; we can write over cf_name, which is a
3168 good thing, given that "get_dirname()" does write over its
3170 s = get_dirname(cf_name);
3171 set_last_open_dir(s);
3176 dfilter_free(rfcode);
3177 cfile.rfcode = NULL;
3178 show_main_window(FALSE);
3179 /* Don't call check_and_warn_user_startup(): we did it above */
3180 main_set_for_capture_in_progress(FALSE);
3181 set_capture_if_dialog_for_capture_in_progress(FALSE);
3186 if (start_capture) {
3187 if (global_capture_opts.save_file != NULL) {
3188 /* Save the directory name for future file dialogs. */
3189 /* (get_dirname overwrites filename) */
3190 s = get_dirname(g_strdup(global_capture_opts.save_file));
3191 set_last_open_dir(s);
3194 /* "-k" was specified; start a capture. */
3195 show_main_window(FALSE);
3196 check_and_warn_user_startup(cf_name);
3198 /* If no user interfaces were specified on the command line,
3199 copy the list of selected interfaces to the set of interfaces
3200 to use for this capture. */
3201 if (global_capture_opts.ifaces->len == 0)
3202 collect_ifaces(&global_capture_opts);
3203 if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3204 /* The capture started. Open stat windows; we do so after creating
3205 the main window, to avoid GTK warnings, and after successfully
3206 opening the capture file, so we know we have something to compute
3207 stats on, and after registering all dissectors, so that MATE will
3208 have registered its field array and we can have a tap filter with
3209 one of MATE's late-registered fields as part of the filter. */
3210 start_requested_stats();
3213 show_main_window(FALSE);
3214 check_and_warn_user_startup(cf_name);
3215 main_set_for_capture_in_progress(FALSE);
3216 set_capture_if_dialog_for_capture_in_progress(FALSE);
3218 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3219 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3220 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3222 #else /* HAVE_LIBPCAP */
3223 show_main_window(FALSE);
3224 check_and_warn_user_startup(cf_name);
3225 main_set_for_capture_in_progress(FALSE);
3226 set_capture_if_dialog_for_capture_in_progress(FALSE);
3227 #endif /* HAVE_LIBPCAP */
3231 GtkWidget *filter_te;
3232 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3233 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3235 /* Run the display filter so it goes in effect. */
3236 main_filter_packets(&cfile, dfilter, FALSE);
3240 /* register our pid if we are being run from a U3 device */
3243 profile_store_persconffiles (FALSE);
3245 #ifdef HAVE_GTKOSXAPPLICATION
3246 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3247 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3248 gtkosx_application_ready(theApp);
3251 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3254 gtk_iface_mon_start();
3257 software_update_init();
3259 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3261 /* ... back from GTK, we're going down now! */
3264 gtk_iface_mon_stop();
3267 /* deregister our pid */
3268 u3_deregister_pid();
3272 AirPDcapDestroyContext(&airpdcap_ctx);
3274 #ifdef HAVE_GTKOSXAPPLICATION
3275 g_object_unref(theApp);
3279 /* hide the (unresponsive) main window, while asking the user to close the console window */
3280 if (G_IS_OBJECT(top_level))
3281 gtk_widget_hide(top_level);
3283 software_update_cleanup();
3285 /* Shutdown windows sockets */
3288 /* For some unknown reason, the "atexit()" call in "create_console()"
3289 doesn't arrange that "destroy_console()" be called when we exit,
3290 so we call it here if a console was created. */
3299 /* We build this as a GUI subsystem application on Win32, so
3300 "WinMain()", not "main()", gets called.
3302 Hack shamelessly stolen from the Win32 port of the GIMP. */
3304 #define _stdcall __attribute__((stdcall))
3308 WinMain (struct HINSTANCE__ *hInstance,
3309 struct HINSTANCE__ *hPrevInstance,
3313 INITCOMMONCONTROLSEX comm_ctrl;
3316 * Initialize our DLL search path. MUST be called before LoadLibrary
3319 ws_init_dll_search_path();
3321 /* Initialize our controls. Required for native Windows file dialogs. */
3322 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3323 comm_ctrl.dwSize = sizeof(comm_ctrl);
3324 /* Includes the animate, header, hot key, list view, progress bar,
3325 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3328 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3329 InitCommonControlsEx(&comm_ctrl);
3331 /* RichEd20.DLL is needed for filter entries. */
3332 ws_load_library("riched20.dll");
3334 set_has_console(FALSE);
3335 set_console_wait(FALSE);
3336 return main (__argc, __argv);
3343 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3344 const char *message, gpointer user_data _U_)
3351 /* ignore log message, if log_level isn't interesting based
3352 upon the console log preferences.
3353 If the preferences haven't been loaded loaded yet, display the
3356 The default console_log_level preference value is such that only
3357 ERROR, CRITICAL and WARNING level messages are processed;
3358 MESSAGE, INFO and DEBUG level messages are ignored. */
3359 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3360 prefs.console_log_level != 0) {
3365 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3366 /* the user wants a console or the application will terminate immediately */
3369 if (get_has_console()) {
3370 /* For some unknown reason, the above doesn't appear to actually cause
3371 anything to be sent to the standard output, so we'll just splat the
3372 message out directly, just to make sure it gets out. */
3374 switch(log_level & G_LOG_LEVEL_MASK) {
3375 case G_LOG_LEVEL_ERROR:
3378 case G_LOG_LEVEL_CRITICAL:
3381 case G_LOG_LEVEL_WARNING:
3384 case G_LOG_LEVEL_MESSAGE:
3387 case G_LOG_LEVEL_INFO:
3390 case G_LOG_LEVEL_DEBUG:
3394 fprintf(stderr, "unknown log_level %u\n", log_level);
3396 g_assert_not_reached();
3399 /* create a "timestamp" */
3401 today = localtime(&curr);
3403 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3404 today->tm_hour, today->tm_min, today->tm_sec,
3405 log_domain != NULL ? log_domain : "",
3408 if(log_level & G_LOG_LEVEL_ERROR) {
3409 /* wait for a key press before the following error handler will terminate the program
3410 this way the user at least can read the error message */
3411 printf("\n\nPress any key to exit\n");
3415 /* XXX - on UN*X, should we just use g_log_default_handler()?
3416 We want the error messages to go to the standard output;
3417 on Mac OS X, that will cause them to show up in various
3418 per-user logs accessible through Console (details depend
3419 on whether you're running 10.0 through 10.4 or running
3420 10.5 and later), and, on other UN*X desktop environments,
3421 if they don't show up in some form of console log, that's
3422 a deficiency in that desktop environment. (Too bad
3423 Windows doesn't set the standard output and error for
3424 GUI apps to something that shows up in such a log.) */
3425 g_log_default_handler(log_domain, log_level, message, user_data);
3432 * Helper for main_widgets_rearrange()
3434 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3435 gtk_container_remove(GTK_CONTAINER(data), widget);
3438 static GtkWidget *main_widget_layout(gint layout_content)
3440 switch(layout_content) {
3441 case(layout_pane_content_none):
3443 case(layout_pane_content_plist):
3445 case(layout_pane_content_pdetails):
3447 case(layout_pane_content_pbytes):
3448 return byte_nb_ptr_gbl;
3450 g_assert_not_reached();
3457 * Rearrange the main window widgets
3459 void main_widgets_rearrange(void) {
3460 GtkWidget *first_pane_widget1, *first_pane_widget2;
3461 GtkWidget *second_pane_widget1, *second_pane_widget2;
3462 gboolean split_top_left = FALSE;
3464 /* be a bit faster */
3465 gtk_widget_hide(main_vbox);
3467 /* be sure we don't lose a widget while rearranging */
3468 g_object_ref(G_OBJECT(menubar));
3469 g_object_ref(G_OBJECT(main_tb));
3470 g_object_ref(G_OBJECT(filter_tb));
3471 g_object_ref(G_OBJECT(wireless_tb));
3472 g_object_ref(G_OBJECT(pkt_scrollw));
3473 g_object_ref(G_OBJECT(tv_scrollw));
3474 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3475 g_object_ref(G_OBJECT(statusbar));
3476 g_object_ref(G_OBJECT(main_pane_v1));
3477 g_object_ref(G_OBJECT(main_pane_v2));
3478 g_object_ref(G_OBJECT(main_pane_h1));
3479 g_object_ref(G_OBJECT(main_pane_h2));
3480 g_object_ref(G_OBJECT(welcome_pane));
3482 /* empty all containers participating */
3483 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3484 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3485 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3486 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3487 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3489 statusbar_widgets_emptying(statusbar);
3491 /* add the menubar always at the top */
3492 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3495 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3497 /* filter toolbar in toolbar area */
3498 if (!prefs.filter_toolbar_show_in_statusbar) {
3499 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3502 /* airpcap toolbar */
3503 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3505 /* fill the main layout panes */
3506 switch(prefs.gui_layout_type) {
3507 case(layout_type_5):
3508 main_first_pane = main_pane_v1;
3509 main_second_pane = main_pane_v2;
3510 split_top_left = FALSE;
3512 case(layout_type_2):
3513 main_first_pane = main_pane_v1;
3514 main_second_pane = main_pane_h1;
3515 split_top_left = FALSE;
3517 case(layout_type_1):
3518 main_first_pane = main_pane_v1;
3519 main_second_pane = main_pane_h1;
3520 split_top_left = TRUE;
3522 case(layout_type_4):
3523 main_first_pane = main_pane_h1;
3524 main_second_pane = main_pane_v1;
3525 split_top_left = FALSE;
3527 case(layout_type_3):
3528 main_first_pane = main_pane_h1;
3529 main_second_pane = main_pane_v1;
3530 split_top_left = TRUE;
3532 case(layout_type_6):
3533 main_first_pane = main_pane_h1;
3534 main_second_pane = main_pane_h2;
3535 split_top_left = FALSE;
3538 main_first_pane = NULL;
3539 main_second_pane = NULL;
3540 g_assert_not_reached();
3542 if (split_top_left) {
3543 first_pane_widget1 = main_second_pane;
3544 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3545 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3546 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3548 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3549 first_pane_widget2 = main_second_pane;
3550 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3551 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3553 if (first_pane_widget1 != NULL)
3554 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3555 if (first_pane_widget2 != NULL)
3556 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3557 if (second_pane_widget1 != NULL)
3558 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3559 if (second_pane_widget2 != NULL)
3560 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3562 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3565 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3568 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3570 /* filter toolbar in statusbar hbox */
3571 if (prefs.filter_toolbar_show_in_statusbar) {
3572 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3575 /* statusbar widgets */
3576 statusbar_widgets_pack(statusbar);
3578 /* hide widgets on users recent settings */
3579 main_widgets_show_or_hide();
3581 gtk_widget_show(main_vbox);
3585 is_widget_visible(GtkWidget *widget, gpointer data)
3587 gboolean *is_visible = ( gboolean *)data;
3590 if (gtk_widget_get_visible(widget))
3597 main_widgets_show_or_hide(void)
3599 gboolean main_second_pane_show;
3601 if (recent.main_toolbar_show) {
3602 gtk_widget_show(main_tb);
3604 gtk_widget_hide(main_tb);
3607 statusbar_widgets_show_or_hide(statusbar);
3609 if (recent.filter_toolbar_show) {
3610 gtk_widget_show(filter_tb);
3612 gtk_widget_hide(filter_tb);
3615 if (recent.wireless_toolbar_show) {
3616 gtk_widget_show(wireless_tb);
3618 gtk_widget_hide(wireless_tb);
3621 if (recent.packet_list_show && have_capture_file) {
3622 gtk_widget_show(pkt_scrollw);
3624 gtk_widget_hide(pkt_scrollw);
3627 if (recent.tree_view_show && have_capture_file) {
3628 gtk_widget_show(tv_scrollw);
3630 gtk_widget_hide(tv_scrollw);
3633 if (recent.byte_view_show && have_capture_file) {
3634 gtk_widget_show(byte_nb_ptr_gbl);
3636 gtk_widget_hide(byte_nb_ptr_gbl);
3639 if (have_capture_file) {
3640 gtk_widget_show(main_first_pane);
3642 gtk_widget_hide(main_first_pane);
3646 * Is anything in "main_second_pane" visible?
3647 * If so, show it, otherwise hide it.
3649 main_second_pane_show = FALSE;
3650 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3651 &main_second_pane_show);
3652 if (main_second_pane_show) {
3653 gtk_widget_show(main_second_pane);
3655 gtk_widget_hide(main_second_pane);
3658 if (!have_capture_file) {
3660 gtk_widget_show(welcome_pane);
3663 gtk_widget_hide(welcome_pane);
3668 /* called, when the window state changes (minimized, maximized, ...) */
3670 window_state_event_cb (GtkWidget *widget _U_,
3674 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3676 if( (event->type) == (GDK_WINDOW_STATE)) {
3677 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3678 /* we might have dialogs popped up while we where iconified,
3680 display_queued_messages();
3688 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3690 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3692 if (event->keyval == GDK_F8) {
3695 } else if (event->keyval == GDK_F7) {
3698 } else if (event->state & NO_SHIFT_MOD_MASK) {
3699 return FALSE; /* Skip control, alt, and other modifiers */
3701 * A comment in gdkkeysyms.h says that it's autogenerated from
3702 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3703 * don't explicitly say so, g_ascii_isprint() should work as expected
3706 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3707 /* Forward the keypress on to the display filter entry */
3708 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3709 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3710 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3718 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3719 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3724 GtkAccelGroup *accel;
3727 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3728 set_titlebar_for_capture_file(NULL);
3730 gtk_widget_set_name(top_level, "main window");
3731 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3733 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3734 G_CALLBACK(window_state_event_cb), NULL);
3735 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3736 G_CALLBACK(top_level_key_pressed_cb), NULL );
3738 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3739 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3741 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3742 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3743 gtk_widget_show(main_vbox);
3746 menubar = main_menu_new(&accel);
3748 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3749 /* Mac OS X native menus are created and displayed by main_menu_new() */
3750 if(!prefs_p->gui_macosx_style) {
3752 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3753 gtk_widget_show(menubar);
3754 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3756 gtk_widget_hide(menubar);
3761 main_tb = toolbar_new();
3762 gtk_widget_show (main_tb);
3764 /* Filter toolbar */
3765 filter_tb = filter_toolbar_new();
3768 pkt_scrollw = packet_list_create();
3769 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3770 gtk_widget_show_all(pkt_scrollw);
3773 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3774 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3775 gtk_widget_show(tv_scrollw);
3777 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3778 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3779 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3780 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3781 gtk_widget_show(tree_view_gbl);
3784 byte_nb_ptr_gbl = byte_view_new();
3785 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3786 gtk_widget_show(byte_nb_ptr_gbl);
3788 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3789 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3791 /* Panes for the packet list, tree, and byte view */
3792 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3793 gtk_widget_show(main_pane_v1);
3794 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3795 gtk_widget_show(main_pane_v2);
3796 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3797 gtk_widget_show(main_pane_h1);
3798 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3799 gtk_widget_show(main_pane_h2);
3801 wireless_tb = airpcap_toolbar_new();
3803 wireless_tb = ws80211_toolbar_new();
3805 gtk_widget_show(wireless_tb);
3808 statusbar = statusbar_new();
3809 gtk_widget_show(statusbar);
3811 /* Pane for the welcome screen */
3812 welcome_pane = welcome_new();
3813 gtk_widget_show(welcome_pane);
3817 show_main_window(gboolean doing_work)
3819 main_set_for_capture_file(doing_work);
3821 /*** we have finished all init things, show the main window ***/
3822 gtk_widget_show(top_level);
3824 /* the window can be maximized only, if it's visible, so do it after show! */
3825 main_load_window_geometry(top_level);
3827 /* process all pending GUI events before continue */
3828 while (gtk_events_pending()) gtk_main_iteration();
3830 /* Pop up any queued-up alert boxes. */
3831 display_queued_messages();
3833 /* Move the main window to the front, in case it isn't already there */
3834 gdk_window_raise(gtk_widget_get_window(top_level));
3837 airpcap_toolbar_show(wireless_tb);
3838 #endif /* HAVE_AIRPCAP */
3841 static void copy_global_profile (const gchar *profile_name)
3843 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3845 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3846 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3847 "Can't create directory\n\"%s\":\n%s.",
3848 pf_dir_path, g_strerror(errno));
3850 g_free(pf_dir_path);
3853 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3854 &pf_dir_path, &pf_dir_path2) == -1) {
3855 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3856 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3857 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3859 g_free(pf_filename);
3860 g_free(pf_dir_path);
3861 g_free(pf_dir_path2);
3865 /* Change configuration profile */
3866 void change_configuration_profile (const gchar *profile_name)
3868 char *gdp_path, *dp_path;
3872 /* First check if profile exists */
3873 if (!profile_exists(profile_name, FALSE)) {
3874 if (profile_exists(profile_name, TRUE)) {
3875 /* Copy from global profile */
3876 copy_global_profile (profile_name);
3878 /* No personal and no global profile exists */
3883 /* Then check if changing to another profile */
3884 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3888 /* Get the current geometry, before writing it to disk */
3889 main_save_window_geometry(top_level);
3891 if (profile_exists(get_profile_name(), FALSE)) {
3892 /* Write recent file for profile we are leaving, if it still exists */
3893 write_profile_recent();
3896 /* Set profile name and update the status bar */
3897 set_profile_name (profile_name);
3898 profile_bar_update ();
3899 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3901 /* Reset current preferences and apply the new */
3905 (void) read_configuration_files (&gdp_path, &dp_path);
3907 recent_read_profile_static(&rf_path, &rf_open_errno);
3908 if (rf_path != NULL && rf_open_errno != 0) {
3909 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3910 "Could not open common recent file\n\"%s\": %s.",
3911 rf_path, g_strerror(rf_open_errno));
3913 if (recent.gui_fileopen_remembered_dir &&
3914 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3915 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3917 timestamp_set_type (recent.gui_time_format);
3918 timestamp_set_seconds_type (recent.gui_seconds_format);
3919 color_filters_enable(recent.packet_list_colorize);
3921 prefs_to_capture_opts();
3923 macros_post_update();
3925 /* Update window view and redraw the toolbar */
3926 main_titlebar_update();
3927 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3928 toolbar_redraw_all();
3930 /* Enable all protocols and disable from the disabled list */
3932 if (gdp_path == NULL && dp_path == NULL) {
3933 set_disabled_protos_list();
3936 /* Reload color filters */
3937 color_filters_reload();
3939 /* Reload list of interfaces on welcome page */
3940 welcome_if_panel_reload();
3942 /* Recreate the packet list according to new preferences */
3943 packet_list_recreate ();
3944 cfile.columns_changed = FALSE; /* Reset value */
3947 /* Update menus with new recent values */
3948 menu_recent_read_finished();
3950 /* Reload pane geometry, must be done after recreating the list */
3951 main_pane_load_window_geometry();
3954 /** redissect packets and update UI */
3955 void redissect_packets(void)
3957 cf_redissect_packets(&cfile);
3958 status_expert_update();
3967 * indent-tabs-mode: nil
3970 * ex: set shiftwidth=4 tabstop=8 expandtab:
3971 * :indentSize=4:tabSize=8:noTabs=true: