5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10 * needed by dissect routines
11 * Jeff Foster, 2001/03/12, added support tabbed hex display windowss
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <gdk/gdkkeysyms.h>
33 #if GTK_CHECK_VERSION(3,0,0)
34 # include <gdk/gdkkeysyms-compat.h>
47 #include "wsutil/wsgetopt.h"
50 #ifdef _WIN32 /* Needed for console I/O */
52 /* AttachConsole() needs this #define! */
53 /* But we're not calling it from here any more; do we need this? */
54 #define _WIN32_WINNT 0x0501
59 #include <ui/win32/console_win32.h>
62 #ifdef HAVE_LIBPORTAUDIO
63 #include <portaudio.h>
64 #endif /* HAVE_LIBPORTAUDIO */
66 #include <wsutil/crash_info.h>
67 #include <wsutil/u3.h>
68 #include <wsutil/privileges.h>
69 #include <wsutil/file_util.h>
71 #include <wiretap/merge.h>
73 #include <epan/epan.h>
74 #include <epan/filesystem.h>
75 #include <epan/epan_dissect.h>
76 #include <epan/timestamp.h>
77 #include <epan/plugins.h>
78 #include <epan/dfilter/dfilter.h>
79 #include <epan/strutil.h>
80 #include <epan/addr_resolv.h>
81 #include <epan/emem.h>
82 #include <epan/ex-opt.h>
83 #include <epan/funnel.h>
84 #include <epan/expert.h>
85 #include <epan/frequency-utils.h>
86 #include <epan/prefs.h>
87 #include <epan/prefs-int.h>
89 #include <epan/stat_cmd_args.h>
91 #include <epan/column.h>
92 #include <epan/disabled_protos.h>
93 #include <epan/print.h>
95 /* general (not GTK specific) */
97 #include "../frame_tvbuff.h"
98 #include "../summary.h"
99 #include "../filters.h"
100 #include "../color.h"
101 #include "../color_filters.h"
102 #include "../register.h"
103 #include "../ringbuffer.h"
105 #include "../clopts_common.h"
106 #include "../cmdarg_err.h"
107 #include "../version_info.h"
110 #include "gtk_iface_monitor.h"
112 #include "ui/alert_box.h"
113 #include "ui/main_statusbar.h"
114 #include "ui/preference_utils.h"
115 #include "ui/recent.h"
116 #include "ui/recent_utils.h"
117 #include "ui/software_update.h"
118 #include "ui/simple_dialog.h"
119 #include "ui/ui_util.h"
122 #include "ui/capture_globals.h"
123 #include "ui/iface_lists.h"
127 #include "capture_ui_utils.h"
128 #include "capture-pcap-util.h"
129 #include "capture_ifinfo.h"
131 #include "capture_sync.h"
135 #include "capture-wpcap.h"
136 #include "capture_wpcap_packet.h"
137 #include <tchar.h> /* Needed for Unicode */
138 #include <wsutil/unicode-utils.h>
139 #include <commctrl.h>
140 #include <shellapi.h>
144 #include "ui/gtk/file_dlg.h"
145 #include "ui/gtk/gtkglobals.h"
146 #include "ui/gtk/color_utils.h"
147 #include "ui/gtk/gui_utils.h"
148 #include "ui/gtk/color_dlg.h"
149 #include "ui/gtk/filter_dlg.h"
150 #include "ui/gtk/fileset_dlg.h"
151 #include "ui/gtk/uat_gui.h"
152 #include "ui/gtk/main.h"
153 #include "ui/gtk/main_80211_toolbar.h"
154 #include "ui/gtk/main_airpcap_toolbar.h"
155 #include "ui/gtk/main_filter_toolbar.h"
156 #include "ui/gtk/main_titlebar.h"
157 #include "ui/gtk/menus.h"
158 #include "ui/gtk/main_menubar_private.h"
159 #include "ui/gtk/macros_dlg.h"
160 #include "ui/gtk/main_statusbar_private.h"
161 #include "ui/gtk/main_toolbar.h"
162 #include "ui/gtk/main_toolbar_private.h"
163 #include "ui/gtk/main_welcome.h"
164 #include "ui/gtk/drag_and_drop.h"
165 #include "ui/gtk/capture_file_dlg.h"
166 #include "ui/gtk/packet_panes.h"
167 #include "ui/gtk/keys.h"
168 #include "ui/gtk/packet_win.h"
169 #include "ui/gtk/stock_icons.h"
170 #include "ui/gtk/find_dlg.h"
171 #include "ui/gtk/follow_tcp.h"
172 #include "ui/gtk/font_utils.h"
173 #include "ui/gtk/about_dlg.h"
174 #include "ui/gtk/help_dlg.h"
175 #include "ui/gtk/decode_as_dlg.h"
176 #include "ui/gtk/webbrowser.h"
177 #include "ui/gtk/capture_dlg.h"
178 #include "ui/gtk/capture_if_dlg.h"
179 #include "ui/gtk/tap_param_dlg.h"
180 #include "ui/gtk/prefs_column.h"
181 #include "ui/gtk/prefs_dlg.h"
182 #include "ui/gtk/proto_help.h"
183 #include "ui/gtk/packet_list.h"
184 #include "ui/gtk/filter_expression_save_dlg.h"
186 #include "ui/gtk/old-gtk-compat.h"
190 #include "wsiconcap.h"
195 #include "airpcap_loader.h"
196 #include "airpcap_dlg.h"
197 #include "airpcap_gui_utils.h"
200 #include <epan/crypt/airpdcap_ws.h>
203 #ifdef HAVE_GTKOSXAPPLICATION
204 #include <gtkmacintegration/gtkosxapplication.h>
208 * Files under personal and global preferences directories in which
209 * GTK settings for Wireshark are stored.
211 #define RC_FILE "gtkrc"
214 capture_options global_capture_opts;
215 capture_session global_capture_session;
220 static gboolean capture_stopping;
222 /* "exported" main widgets */
223 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
225 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
226 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
227 static GtkWidget *main_first_pane, *main_second_pane;
229 /* internally used widgets */
230 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
232 GtkWidget *wireless_tb;
234 int airpcap_dll_ret_val = -1;
237 GString *comp_info_str, *runtime_info_str;
239 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
241 static guint tap_update_timer_id;
243 static void console_log_handler(const char *log_domain,
244 GLogLevelFlags log_level, const char *message, gpointer user_data);
246 static void create_main_window(gint, gint, gint, e_prefs*);
247 static void show_main_window(gboolean);
248 static void main_save_window_geometry(GtkWidget *widget);
251 /* Match selected byte pattern */
253 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
255 char *cur_filter, *new_filter;
257 if ((!text) || (0 == strlen(text))) {
258 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
264 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
266 switch (action&MATCH_SELECTED_MASK) {
268 case MATCH_SELECTED_REPLACE:
269 new_filter = g_strdup(text);
272 case MATCH_SELECTED_AND:
273 if ((!cur_filter) || (0 == strlen(cur_filter)))
274 new_filter = g_strdup(text);
276 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
279 case MATCH_SELECTED_OR:
280 if ((!cur_filter) || (0 == strlen(cur_filter)))
281 new_filter = g_strdup(text);
283 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
286 case MATCH_SELECTED_NOT:
287 new_filter = g_strconcat("!(", text, ")", NULL);
290 case MATCH_SELECTED_AND_NOT:
291 if ((!cur_filter) || (0 == strlen(cur_filter)))
292 new_filter = g_strconcat("!(", text, ")", NULL);
294 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
297 case MATCH_SELECTED_OR_NOT:
298 if ((!cur_filter) || (0 == strlen(cur_filter)))
299 new_filter = g_strconcat("!(", text, ")", NULL);
301 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
305 g_assert_not_reached();
310 /* Free up the copy we got of the old filter text. */
313 /* Don't change the current display filter if we only want to copy the filter */
314 if (action&MATCH_SELECTED_COPY_ONLY) {
315 GString *gtk_text_str = g_string_new("");
316 g_string_append(gtk_text_str, new_filter);
317 copy_to_clipboard(gtk_text_str);
318 g_string_free(gtk_text_str, TRUE);
320 /* create a new one and set the display filter entry accordingly */
321 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
323 /* Run the display filter so it goes in effect. */
324 if (action&MATCH_SELECTED_APPLY_NOW)
325 main_filter_packets(&cfile, new_filter, FALSE);
328 /* Free up the new filter text. */
333 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
337 if (cfile.finfo_selected) {
338 filter = proto_construct_match_selected_string(cfile.finfo_selected,
340 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
345 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
349 if (cfile.finfo_selected) {
350 filter = proto_construct_match_selected_string(cfile.finfo_selected,
352 if ((!filter) || (0 == strlen(filter))) {
353 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
354 "Could not acquire information to build a filter!\n"
355 "Try expanding or choosing another item.");
360 color_display_with_filter(filter);
363 color_filters_reset_tmp();
365 color_filters_set_tmp(filt_nr,filter, FALSE);
367 packet_list_colorize_packets();
373 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
375 gchar *selected_proto_url;
376 gchar *proto_abbrev = (gchar *)data;
381 if (cfile.finfo_selected) {
382 /* open wiki page using the protocol abbreviation */
383 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
384 browser_open_url(selected_proto_url);
385 g_free(selected_proto_url);
388 case(ESD_BTN_CANCEL):
391 g_assert_not_reached();
397 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
400 const gchar *proto_abbrev;
404 if (cfile.finfo_selected) {
405 /* convert selected field to protocol abbreviation */
406 /* XXX - could this conversion be simplified? */
407 field_id = cfile.finfo_selected->hfinfo->id;
408 /* if the selected field isn't a protocol, get its parent */
409 if(!proto_registrar_is_protocol(field_id)) {
410 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
413 proto_abbrev = proto_registrar_get_abbrev(field_id);
415 if (!proto_is_private(field_id)) {
416 /* ask the user if the wiki page really should be opened */
417 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
418 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
420 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
422 "The Wireshark Wiki is a collaborative approach to provide information "
423 "about Wireshark in several ways (not limited to protocol specifics).\n"
425 "This Wiki is new, so the page of the selected protocol "
426 "may not exist and/or may not contain valuable information.\n"
428 "As everyone can edit the Wiki and add new content (or extend existing), "
429 "you are encouraged to add information if you can.\n"
431 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
433 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
434 "which will save you a lot of editing and will give a consistent look over the pages.",
435 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
436 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
438 /* appologize to the user that the wiki page cannot be opened */
439 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
440 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
442 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
444 "Since this is a private protocol, such information is not available in "
445 "a public wiki. Therefore this wiki entry is blocked.\n"
447 "Sorry for the inconvenience.\n",
448 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
453 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
455 gchar *selected_proto_url;
456 gchar *proto_abbrev = (gchar *)data;
460 if (cfile.finfo_selected) {
461 /* open reference page using the protocol abbreviation */
462 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
463 browser_open_url(selected_proto_url);
464 g_free(selected_proto_url);
467 case(ESD_BTN_CANCEL):
470 g_assert_not_reached();
475 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
478 const gchar *proto_abbrev;
482 if (cfile.finfo_selected) {
483 /* convert selected field to protocol abbreviation */
484 /* XXX - could this conversion be simplified? */
485 field_id = cfile.finfo_selected->hfinfo->id;
486 /* if the selected field isn't a protocol, get its parent */
487 if(!proto_registrar_is_protocol(field_id)) {
488 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
491 proto_abbrev = proto_registrar_get_abbrev(field_id);
493 if (!proto_is_private(field_id)) {
494 /* ask the user if the wiki page really should be opened */
495 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
496 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
498 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
500 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
501 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
503 /* appologize to the user that the wiki page cannot be opened */
504 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
505 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
507 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
509 "Since this is a private protocol, such information is not available on "
510 "a public website. Therefore this filter entry is blocked.\n"
512 "Sorry for the inconvenience.\n",
513 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
519 is_address_column (gint column)
521 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
522 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
523 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
524 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
525 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
534 get_ip_address_list_from_packet_list_row(gpointer data)
536 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
537 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
540 GList *addr_list = NULL;
542 fdata = (frame_data *) packet_list_get_row_data(row);
547 if (!cf_read_frame (&cfile, fdata))
548 return NULL; /* error reading the frame */
550 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
551 col_custom_prime_edt(&edt, &cfile.cinfo);
553 epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
554 fdata, &cfile.cinfo);
555 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
557 /* First check selected column */
558 if (is_address_column (column)) {
559 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
562 for (col = 0; col < cfile.cinfo.num_cols; col++) {
563 /* Then check all columns except the selected */
564 if ((col != column) && (is_address_column (col))) {
565 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
569 epan_dissect_cleanup(&edt);
576 get_filter_from_packet_list_row_and_column(gpointer data)
578 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
579 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
583 fdata = (frame_data *) packet_list_get_row_data(row);
588 if (!cf_read_frame(&cfile, fdata))
589 return NULL; /* error reading the frame */
590 /* proto tree, visible. We need a proto tree if there's custom columns */
591 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
592 col_custom_prime_edt(&edt, &cfile.cinfo);
594 epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
595 fdata, &cfile.cinfo);
596 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
598 if ((cfile.cinfo.col_custom_occurrence[column]) ||
599 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
601 /* Only construct the filter when a single occurrence is displayed
602 * otherwise we might end up with a filter like "ip.proto==1,6".
604 * Or do we want to be able to filter on multiple occurrences so that
605 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
608 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
609 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
610 /* leak a little but safer than ep_ here */
611 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
612 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
613 if (hfi && hfi->parent == -1) {
615 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
616 } else if (hfi && hfi->type == FT_STRING) {
617 /* Custom string, add quotes */
618 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
619 cfile.cinfo.col_expr.col_expr_val[column]);
623 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
624 cfile.cinfo.col_expr.col_expr_val[column]);
629 epan_dissect_cleanup(&edt);
636 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
638 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
640 get_filter_from_packet_list_row_and_column((GtkWidget *)data));
643 /* This function allows users to right click in the details window and copy the text
644 * information to the operating systems clipboard.
646 * We first check to see if a string representation is setup in the tree and then
647 * read the string. If not available then we try to grab the value. If all else
648 * fails we display a message to the user to indicate the copy could not be completed.
651 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
653 GString *gtk_text_str = g_string_new("");
654 char labelstring[ITEM_LABEL_LENGTH];
655 char *stringpointer = labelstring;
659 case COPY_SELECTED_DESCRIPTION:
660 if (cfile.finfo_selected->rep &&
661 strlen (cfile.finfo_selected->rep->representation) > 0) {
662 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
665 case COPY_SELECTED_FIELDNAME:
666 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
667 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
670 case COPY_SELECTED_VALUE:
671 if (cfile.edt !=0 ) {
672 g_string_append(gtk_text_str,
673 get_node_field_value(cfile.finfo_selected, cfile.edt));
680 if (gtk_text_str->len == 0) {
681 /* If no representation then... Try to read the value */
682 proto_item_fill_label(cfile.finfo_selected, stringpointer);
683 g_string_append(gtk_text_str, stringpointer);
686 if (gtk_text_str->len == 0) {
687 /* Could not get item so display error msg */
688 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
690 /* Copy string to clipboard */
691 copy_to_clipboard(gtk_text_str);
693 g_string_free(gtk_text_str, TRUE); /* Free the memory */
697 /* mark as reference time frame */
699 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
703 frame->flags.ref_time=1;
704 cfile.ref_time_count++;
706 frame->flags.ref_time=0;
707 cfile.ref_time_count--;
709 cf_reftime_packets(&cfile);
710 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
711 packet_list_freeze();
712 cfile.displayed_count--;
713 packet_list_recreate_visible_rows();
716 packet_list_queue_draw();
720 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
724 timestamp_set_type(TS_RELATIVE);
725 recent.gui_time_format = TS_RELATIVE;
726 cf_timestamp_auto_precision(&cfile);
727 packet_list_queue_draw();
732 g_assert_not_reached();
735 if (cfile.current_frame) {
736 set_frame_reftime(!cfile.current_frame->flags.ref_time,
737 cfile.current_frame, cfile.current_row);
743 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
745 static GtkWidget *reftime_dialog = NULL;
749 if (cfile.current_frame) {
750 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
751 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
752 "%sSwitch to the appropriate Time Display Format?%s\n\n"
753 "Time References don't work well with the currently selected Time Display Format.\n\n"
754 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
755 simple_dialog_primary_start(), simple_dialog_primary_end());
756 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
758 set_frame_reftime(!cfile.current_frame->flags.ref_time,
759 cfile.current_frame, cfile.current_row);
763 case REFTIME_FIND_NEXT:
764 cf_find_packet_time_reference(&cfile, SD_FORWARD);
766 case REFTIME_FIND_PREV:
767 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
773 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
775 cf_find_packet_marked(&cfile, SD_FORWARD);
779 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
781 cf_find_packet_marked(&cfile, SD_BACKWARD);
785 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
788 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
790 gboolean has_blurb = FALSE;
791 guint length = 0, byte_len;
792 GtkWidget *byte_view;
793 const guint8 *byte_data;
798 /* if nothing is selected */
799 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
802 * Which byte view is displaying the current protocol tree
805 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
806 if (byte_view == NULL)
809 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
810 if (byte_data == NULL)
813 cf_unselect_field(&cfile);
814 packet_hex_print(byte_view, byte_data,
815 cfile.current_frame, NULL, byte_len);
816 proto_help_menu_modify(sel, &cfile);
819 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
822 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
824 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
825 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
826 g_assert(byte_data != NULL);
828 cfile.finfo_selected = finfo;
829 set_menus_for_selected_tree_row(&cfile);
832 if (finfo->hfinfo->blurb != NULL &&
833 finfo->hfinfo->blurb[0] != '\0') {
835 length = (guint) strlen(finfo->hfinfo->blurb);
837 length = (guint) strlen(finfo->hfinfo->name);
839 finfo_length = finfo->length + finfo->appendix_length;
841 if (finfo_length == 0) {
843 } else if (finfo_length == 1) {
844 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
846 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
848 statusbar_pop_field_msg(); /* get rid of current help msg */
850 statusbar_push_field_msg(" %s (%s)%s",
851 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
852 finfo->hfinfo->abbrev, len_str);
855 * Don't show anything if the field name is zero-length;
856 * the pseudo-field for "proto_tree_add_text()" is such
857 * a field, and we don't want "Text (text)" showing up
858 * on the status line if you've selected such a field.
860 * XXX - there are zero-length fields for which we *do*
861 * want to show the field name.
863 * XXX - perhaps the name and abbrev field should be null
864 * pointers rather than null strings for that pseudo-field,
865 * but we'd have to add checks for null pointers in some
866 * places if we did that.
868 * Or perhaps protocol tree items added with
869 * "proto_tree_add_text()" should have -1 as the field index,
870 * with no pseudo-field being used, but that might also
871 * require special checks for -1 to be added.
873 statusbar_push_field_msg("%s", "");
876 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
878 proto_help_menu_modify(sel, &cfile);
881 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
884 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
887 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
890 expand_all_tree(cfile.edt->tree, tree_view_gbl);
893 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
895 if (cfile.finfo_selected) {
896 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
897 cfile.finfo_selected->hfinfo->abbrev,0);
898 /* Recreate the packet list according to new preferences */
899 packet_list_recreate ();
900 if (!prefs.gui_use_pref_save) {
903 cfile.columns_changed = FALSE; /* Reset value */
907 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
911 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
913 /* the mouse position is at an entry, expand that one */
914 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
915 gtk_tree_path_free(path);
919 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
923 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
925 /* the mouse position is at an entry, expand that one */
927 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
928 gtk_tree_path_free(path);
932 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
934 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
936 if (cfile.edt->tree) {
937 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
941 /* Update main window items based on whether there's a capture in progress. */
943 main_set_for_capture_in_progress(gboolean capture_in_progress)
945 set_menus_for_capture_in_progress(capture_in_progress);
948 set_toolbar_for_capture_in_progress(capture_in_progress);
950 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
954 /* Update main window items based on whether we have a capture file. */
956 main_set_for_capture_file(gboolean have_capture_file_in)
958 have_capture_file = have_capture_file_in;
960 main_widgets_show_or_hide();
963 /* Update main window items based on whether we have captured packets. */
965 main_set_for_captured_packets(gboolean have_captured_packets)
967 set_menus_for_captured_packets(have_captured_packets);
968 set_toolbar_for_captured_packets(have_captured_packets);
971 /* Update main window items based on whether we have a packet history. */
973 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
975 set_menus_for_packet_history(back_history, forward_history);
976 set_toolbar_for_packet_history(back_history, forward_history);
982 /* get the current geometry, before writing it to disk */
983 main_save_window_geometry(top_level);
985 /* write user's recent file to disk
986 * It is no problem to write this file, even if we do not quit */
987 write_profile_recent();
990 /* XXX - should we check whether the capture file is an
991 unsaved temporary file for a live capture and, if so,
992 pop up a "do you want to exit without saving the capture
993 file?" dialog, and then just return, leaving said dialog
994 box to forcibly quit if the user clicks "OK"?
996 If so, note that this should be done in a subroutine that
997 returns TRUE if we do so, and FALSE otherwise, and if it
998 returns TRUE we should return TRUE without nuking anything.
1000 Note that, if we do that, we might also want to check if
1001 an "Update list of packets in real time" capture is in
1002 progress and, if so, ask whether they want to terminate
1003 the capture and discard it, and return TRUE, before nuking
1004 any child capture, if they say they don't want to do so. */
1007 /* Nuke any child capture in progress. */
1008 capture_kill_child(&global_capture_session);
1011 /* Are we in the middle of reading a capture? */
1012 if (cfile.state == FILE_READ_IN_PROGRESS) {
1013 /* Yes, so we can't just close the file and quit, as
1014 that may yank the rug out from under the read in
1015 progress; instead, just set the state to
1016 "FILE_READ_ABORTED" and return - the code doing the read
1017 will check for that and, if it sees that, will clean
1019 cfile.state = FILE_READ_ABORTED;
1021 /* Say that the window should *not* be deleted;
1022 that'll be done by the code that cleans up. */
1025 /* Close any capture file we have open; on some OSes, you
1026 can't unlink a temporary capture file if you have it
1028 "cf_close()" will unlink it after closing it if
1029 it's a temporary file.
1031 We do this here, rather than after the main loop returns,
1032 as, after the main loop returns, the main window may have
1033 been destroyed (if this is called due to a "destroy"
1034 even on the main window rather than due to the user
1035 selecting a menu item), and there may be a crash
1036 or other problem when "cf_close()" tries to
1037 clean up stuff in the main window.
1039 XXX - is there a better place to put this?
1040 Or should we have a routine that *just* closes the
1041 capture file, and doesn't do anything with the UI,
1042 which we'd call here, and another routine that
1043 calls that routine and also cleans up the UI, which
1044 we'd call elsewhere? */
1047 /* Exit by leaving the main loop, so that any quit functions
1048 we registered get called. */
1051 /* Say that the window should be deleted. */
1057 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1059 /* If we're in the middle of stopping a capture, don't do anything;
1060 the user can try deleting the window after the capture stops. */
1061 if (capture_stopping)
1064 /* If there's unsaved data, let the user save it first.
1065 If they cancel out of it, don't quit. */
1066 if (do_file_close(&cfile, TRUE, " before quitting"))
1067 return main_do_quit();
1069 return TRUE; /* will this keep the window from being deleted? */
1074 main_pane_load_window_geometry(void)
1076 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1077 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1078 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1079 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1085 main_load_window_geometry(GtkWidget *widget)
1087 window_geometry_t geom;
1089 geom.set_pos = prefs.gui_geometry_save_position;
1090 geom.x = recent.gui_geometry_main_x;
1091 geom.y = recent.gui_geometry_main_y;
1092 geom.set_size = prefs.gui_geometry_save_size;
1093 if (recent.gui_geometry_main_width > 0 &&
1094 recent.gui_geometry_main_height > 0) {
1095 geom.width = recent.gui_geometry_main_width;
1096 geom.height = recent.gui_geometry_main_height;
1097 geom.set_maximized = prefs.gui_geometry_save_maximized;
1099 /* We assume this means the width and height weren't set in
1100 the "recent" file (or that there is no "recent" file),
1101 and weren't set to a default value, so we don't set the
1102 size. (The "recent" file code rejects non-positive width
1103 and height values.) */
1104 geom.set_size = FALSE;
1106 geom.maximized = recent.gui_geometry_main_maximized;
1108 window_set_geometry(widget, &geom);
1110 main_pane_load_window_geometry();
1111 statusbar_load_window_geometry();
1116 main_save_window_geometry(GtkWidget *widget)
1118 window_geometry_t geom;
1120 window_get_geometry(widget, &geom);
1122 if (prefs.gui_geometry_save_position) {
1123 recent.gui_geometry_main_x = geom.x;
1124 recent.gui_geometry_main_y = geom.y;
1127 if (prefs.gui_geometry_save_size) {
1128 recent.gui_geometry_main_width = geom.width;
1129 recent.gui_geometry_main_height = geom.height;
1132 if(prefs.gui_geometry_save_maximized) {
1133 recent.gui_geometry_main_maximized = geom.maximized;
1136 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1137 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1138 statusbar_save_window_geometry();
1142 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1144 /* If there's unsaved data, let the user save it first. */
1145 if (do_file_close(&cfile, TRUE, " before quitting"))
1150 print_usage(gboolean print_ver) {
1160 fprintf(output, "Wireshark " VERSION "%s\n"
1161 "Interactively dump and analyze network traffic.\n"
1162 "See http://www.wireshark.org for more information.\n"
1165 wireshark_svnversion, get_copyright_info());
1169 fprintf(output, "\n");
1170 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1171 fprintf(output, "\n");
1174 fprintf(output, "Capture interface:\n");
1175 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1176 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1177 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1178 fprintf(output, " -p don't capture in promiscuous mode\n");
1179 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1180 fprintf(output, " -S update packet display when new packets are captured\n");
1181 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1182 #ifdef HAVE_PCAP_CREATE
1183 fprintf(output, " -I capture in monitor mode, if available\n");
1185 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1186 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1188 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1189 fprintf(output, " -D print list of interfaces and exit\n");
1190 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1191 fprintf(output, "\n");
1192 fprintf(output, "Capture stop conditions:\n");
1193 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1194 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1195 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1196 fprintf(output, " files:NUM - stop after NUM files\n");
1197 /*fprintf(output, "\n");*/
1198 fprintf(output, "Capture output:\n");
1199 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1200 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1201 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1202 #endif /* HAVE_LIBPCAP */
1203 #ifdef HAVE_PCAP_REMOTE
1204 fprintf(output, "RPCAP options:\n");
1205 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1207 /*fprintf(output, "\n");*/
1208 fprintf(output, "Input file:\n");
1209 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1211 fprintf(output, "\n");
1212 fprintf(output, "Processing:\n");
1213 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1214 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1215 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1217 fprintf(output, "\n");
1218 fprintf(output, "User interface:\n");
1219 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1220 fprintf(output, " -Y <display filter> start with the given display filter\n");
1221 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1222 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1223 fprintf(output, " filter\n");
1224 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1225 fprintf(output, " -m <font> set the font name used for most text\n");
1226 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
1227 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1228 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1229 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1231 fprintf(output, "\n");
1232 fprintf(output, "Output:\n");
1233 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1235 fprintf(output, "\n");
1236 fprintf(output, "Miscellaneous:\n");
1237 fprintf(output, " -h display this help and exit\n");
1238 fprintf(output, " -v display version info and exit\n");
1239 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1240 fprintf(output, " persdata:path - personal data files\n");
1241 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1242 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1244 fprintf(output, " --display=DISPLAY X display to use\n");
1255 printf(PACKAGE " " VERSION "%s\n"
1262 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1263 runtime_info_str->str);
1267 * Report an error in command-line arguments.
1268 * Creates a console on Windows.
1271 cmdarg_err(const char *fmt, ...)
1278 fprintf(stderr, "wireshark: ");
1280 vfprintf(stderr, fmt, ap);
1282 fprintf(stderr, "\n");
1286 * Report additional information for an error in command-line arguments.
1287 * Creates a console on Windows.
1288 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1289 * terminal isn't the standard error?
1292 cmdarg_err_cont(const char *fmt, ...)
1300 vfprintf(stderr, fmt, ap);
1301 fprintf(stderr, "\n");
1306 Once every 3 seconds we get a callback here which we use to update
1310 tap_update_cb(gpointer data _U_)
1312 draw_tap_listeners(FALSE);
1317 * Periodically process outstanding hostname lookups. If we have new items,
1318 * redraw the packet list and tree view.
1322 resolv_update_cb(gpointer data _U_)
1324 /* Anything new show up? */
1325 if (host_name_lookup_process()) {
1326 if (gtk_widget_get_window(pkt_scrollw))
1327 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1328 if (gtk_widget_get_window(tv_scrollw))
1329 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1332 /* Always check. Even if we don't do async lookups we could still get
1333 passive updates, e.g. from DNS packets. */
1338 /* Update various parts of the main window for a capture file "unsaved
1339 changes" change - update the title to reflect whether there are
1340 unsaved changes or not, and update the menus and toolbar to
1341 enable or disable the "Save" operation. */
1343 main_update_for_unsaved_changes(capture_file *cf)
1345 set_titlebar_for_capture_file(cf);
1346 set_menus_for_capture_file(cf);
1347 set_toolbar_for_capture_file(cf);
1352 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1354 /* Update menubar and toolbar */
1355 menu_auto_scroll_live_changed(auto_scroll_live_in);
1356 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1358 /* change auto scroll state */
1359 auto_scroll_live = auto_scroll_live_in;
1364 main_colorize_changed(gboolean packet_list_colorize)
1366 /* Update menubar and toolbar */
1367 menu_colorize_changed(packet_list_colorize);
1368 toolbar_colorize_changed(packet_list_colorize);
1370 /* change colorization */
1371 if(packet_list_colorize != recent.packet_list_colorize) {
1372 recent.packet_list_colorize = packet_list_colorize;
1373 color_filters_enable(packet_list_colorize);
1374 packet_list_colorize_packets();
1378 static GtkWidget *close_dlg = NULL;
1381 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1383 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1388 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1390 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1395 main_cf_cb_file_closing(capture_file *cf)
1397 /* if we have more than 10000 packets, show a splash screen while closing */
1398 /* XXX - don't know a better way to decide whether to show or not,
1399 * as most of the time is spend in various calls that destroy various
1400 * data structures, so it wouldn't be easy to use a progress bar,
1401 * rather than, say, a progress spinner, here! */
1402 if(cf->count > 10000) {
1403 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1404 "%sClosing file!%s\n\nPlease wait ...",
1405 simple_dialog_primary_start(),
1406 simple_dialog_primary_end());
1407 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1409 /* Clear maunally resolved addresses */
1410 manually_resolve_cleanup();
1411 /* Destroy all windows that refer to the
1412 capture file we're closing. */
1413 destroy_packet_wins();
1415 /* Update the titlebar to reflect the lack of a capture file. */
1416 set_titlebar_for_capture_file(NULL);
1418 /* Disable all menu and toolbar items that make sense only if
1419 you have a capture. */
1420 set_menus_for_capture_file(NULL);
1421 set_toolbar_for_capture_file(NULL);
1422 main_set_for_captured_packets(FALSE);
1423 set_menus_for_selected_packet(cf);
1424 main_set_for_capture_in_progress(FALSE);
1425 set_capture_if_dialog_for_capture_in_progress(FALSE);
1426 set_menus_for_selected_tree_row(cf);
1428 /* Set up main window for no capture file. */
1429 main_set_for_capture_file(FALSE);
1431 main_window_update();
1436 main_cf_cb_file_closed(capture_file *cf _U_)
1438 if(close_dlg != NULL) {
1439 splash_destroy(close_dlg);
1446 main_cf_cb_file_read_started(capture_file *cf _U_)
1448 tap_param_dlg_update();
1450 /* Set up main window for a capture file. */
1451 main_set_for_capture_file(TRUE);
1455 main_cf_cb_file_read_finished(capture_file *cf)
1459 if (!cf->is_tempfile && cf->filename) {
1460 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1461 add_menu_recent_capture_file(cf->filename);
1463 /* Remember folder for next Open dialog and save it in recent */
1464 dir_path = get_dirname(g_strdup(cf->filename));
1465 set_last_open_dir(dir_path);
1469 /* Update the appropriate parts of the main window. */
1470 main_update_for_unsaved_changes(cf);
1472 /* Enable menu items that make sense if you have some captured packets. */
1473 main_set_for_captured_packets(TRUE);
1477 main_cf_cb_file_rescan_finished(capture_file *cf)
1481 if (!cf->is_tempfile && cf->filename) {
1482 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1483 add_menu_recent_capture_file(cf->filename);
1485 /* Remember folder for next Open dialog and save it in recent */
1486 dir_path = get_dirname(g_strdup(cf->filename));
1487 set_last_open_dir(dir_path);
1491 /* Update the appropriate parts of the main window. */
1492 main_update_for_unsaved_changes(cf);
1496 static GList *icon_list_create(
1497 const guint8 *icon16_pb,
1498 const guint8 *icon32_pb,
1499 const guint8 *icon48_pb,
1500 const guint8 *icon64_pb)
1502 GList *icon_list = NULL;
1503 GdkPixbuf * pixbuf16;
1504 GdkPixbuf * pixbuf32;
1505 GdkPixbuf * pixbuf48;
1506 GdkPixbuf * pixbuf64;
1509 if(icon16_pb != NULL) {
1510 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1512 icon_list = g_list_append(icon_list, pixbuf16);
1515 if(icon32_pb != NULL) {
1516 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1518 icon_list = g_list_append(icon_list, pixbuf32);
1521 if(icon48_pb != NULL) {
1522 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1524 icon_list = g_list_append(icon_list, pixbuf48);
1527 if(icon64_pb != NULL) {
1528 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1530 icon_list = g_list_append(icon_list, pixbuf64);
1537 main_capture_cb_capture_prepared(capture_session *cap_session)
1539 static GList *icon_list = NULL;
1541 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1543 if(icon_list == NULL) {
1544 icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1546 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1548 /* Disable menu items that make no sense if you're currently running
1550 main_set_for_capture_in_progress(TRUE);
1551 set_capture_if_dialog_for_capture_in_progress(TRUE);
1553 /* Don't set up main window for a capture file. */
1554 main_set_for_capture_file(FALSE);
1558 main_capture_cb_capture_update_started(capture_session *cap_session)
1560 /* We've done this in "prepared" above, but it will be cleared while
1561 switching to the next multiple file. */
1562 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1564 main_set_for_capture_in_progress(TRUE);
1565 set_capture_if_dialog_for_capture_in_progress(TRUE);
1567 /* Enable menu items that make sense if you have some captured
1568 packets (yes, I know, we don't have any *yet*). */
1569 main_set_for_captured_packets(TRUE);
1571 /* Set up main window for a capture file. */
1572 main_set_for_capture_file(TRUE);
1576 main_capture_cb_capture_update_finished(capture_session *cap_session)
1578 capture_file *cf = (capture_file *)cap_session->cf;
1579 static GList *icon_list = NULL;
1581 /* The capture isn't stopping any more - it's stopped. */
1582 capture_stopping = FALSE;
1584 if (!cf->is_tempfile && cf->filename) {
1585 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1586 add_menu_recent_capture_file(cf->filename);
1589 /* Enable menu items that make sense if you're not currently running
1591 main_set_for_capture_in_progress(FALSE);
1592 set_capture_if_dialog_for_capture_in_progress(FALSE);
1594 /* Update the main window as appropriate. This has to occur AFTER
1595 * main_set_for_capture_in_progress() or else some of the menus are
1596 * incorrectly disabled (see bug
1597 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1598 main_update_for_unsaved_changes(cf);
1600 /* Set up main window for a capture file. */
1601 main_set_for_capture_file(TRUE);
1603 if(icon_list == NULL) {
1604 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1606 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1608 if(global_capture_opts.quit_after_cap) {
1609 /* command line asked us to quit after the capture */
1610 /* don't pop up a dialog to ask for unsaved files etc. */
1616 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1618 /* Don't set up main window for a capture file. */
1619 main_set_for_capture_file(FALSE);
1623 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1626 capture_file *cf = (capture_file *)cap_session->cf;
1628 static GList *icon_list = NULL;
1630 /* The capture isn't stopping any more - it's stopped. */
1631 capture_stopping = FALSE;
1633 /*set_titlebar_for_capture_file(cf);*/
1635 /* Enable menu items that make sense if you're not currently running
1637 main_set_for_capture_in_progress(FALSE);
1638 set_capture_if_dialog_for_capture_in_progress(FALSE);
1640 /* Restore the standard title bar message */
1641 /* (just in case we have trouble opening the capture file). */
1642 set_titlebar_for_capture_file(NULL);
1644 if(icon_list == NULL) {
1645 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1647 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1649 /* We don't have loaded the capture file, this will be done later.
1650 * For now we still have simply a blank screen. */
1652 if(global_capture_opts.quit_after_cap) {
1653 /* command line asked us to quit after the capture */
1654 /* don't pop up a dialog to ask for unsaved files etc. */
1660 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1662 capture_stopping = TRUE;
1663 set_menus_for_capture_stopping();
1665 set_toolbar_for_capture_stopping();
1667 set_capture_if_dialog_for_capture_stopping();
1672 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1674 static GList *icon_list = NULL;
1676 /* Capture isn't stopping any more. */
1677 capture_stopping = FALSE;
1679 /* the capture failed before the first packet was captured
1680 reset title, menus and icon */
1681 set_titlebar_for_capture_file(NULL);
1683 main_set_for_capture_in_progress(FALSE);
1684 set_capture_if_dialog_for_capture_in_progress(FALSE);
1686 main_set_for_capture_file(FALSE);
1688 if(icon_list == NULL) {
1689 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1691 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1694 if(global_capture_opts.quit_after_cap) {
1695 /* command line asked us to quit after the capture */
1696 /* don't pop up a dialog to ask for unsaved files etc. */
1700 #endif /* HAVE_LIBPCAP */
1703 main_cf_cb_packet_selected(gpointer data)
1705 capture_file *cf = (capture_file *)data;
1707 /* Display the GUI protocol tree and packet bytes.
1708 XXX - why do we dump core if we call "proto_tree_draw()"
1709 before calling "add_byte_views()"? */
1710 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1711 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1713 /* Note: Both string and hex value searches in the packet data produce a non-zero
1714 search_pos if successful */
1715 if(cf->search_in_progress &&
1716 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1717 highlight_field(cf->edt->tvb, cf->search_pos,
1718 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1721 /* A packet is selected. */
1722 set_menus_for_selected_packet(cf);
1726 main_cf_cb_packet_unselected(capture_file *cf)
1728 /* No packet is being displayed; clear the hex dump pane by getting
1729 rid of all the byte views. */
1730 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1731 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1733 /* Add a placeholder byte view so that there's at least something
1734 displayed in the byte view notebook. */
1735 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1737 /* And clear the protocol tree display as well. */
1738 proto_tree_draw(NULL, tree_view_gbl);
1740 /* No packet is selected. */
1741 set_menus_for_selected_packet(cf);
1745 main_cf_cb_field_unselected(capture_file *cf)
1747 set_menus_for_selected_tree_row(cf);
1751 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1753 capture_file *cf = (capture_file *)data;
1755 case(cf_cb_file_opened):
1756 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1757 fileset_file_opened(cf);
1759 case(cf_cb_file_closing):
1760 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1761 main_cf_cb_file_closing(cf);
1763 case(cf_cb_file_closed):
1764 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1765 main_cf_cb_file_closed(cf);
1766 fileset_file_closed();
1768 case(cf_cb_file_read_started):
1769 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1770 main_cf_cb_file_read_started(cf);
1772 case(cf_cb_file_read_finished):
1773 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1774 main_cf_cb_file_read_finished(cf);
1776 case(cf_cb_file_reload_started):
1777 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1778 main_cf_cb_file_read_started(cf);
1780 case(cf_cb_file_reload_finished):
1781 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1782 main_cf_cb_file_read_finished(cf);
1784 case(cf_cb_file_rescan_started):
1785 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1787 case(cf_cb_file_rescan_finished):
1788 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1789 main_cf_cb_file_rescan_finished(cf);
1791 case(cf_cb_file_fast_save_finished):
1792 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1793 main_cf_cb_file_rescan_finished(cf);
1795 case(cf_cb_packet_selected):
1796 main_cf_cb_packet_selected(cf);
1798 case(cf_cb_packet_unselected):
1799 main_cf_cb_packet_unselected(cf);
1801 case(cf_cb_field_unselected):
1802 main_cf_cb_field_unselected(cf);
1804 case(cf_cb_file_save_started):
1805 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1807 case(cf_cb_file_save_finished):
1808 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1810 case(cf_cb_file_save_failed):
1811 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1813 case(cf_cb_file_save_stopped):
1814 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1816 case(cf_cb_file_export_specified_packets_started):
1817 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1819 case(cf_cb_file_export_specified_packets_finished):
1820 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1822 case(cf_cb_file_export_specified_packets_failed):
1823 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1825 case(cf_cb_file_export_specified_packets_stopped):
1826 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1829 g_warning("main_cf_callback: event %u unknown", event);
1830 g_assert_not_reached();
1836 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1838 #ifdef HAVE_GTKOSXAPPLICATION
1839 GtkosxApplication *theApp;
1842 case(capture_cb_capture_prepared):
1843 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1844 main_capture_cb_capture_prepared(cap_session);
1846 case(capture_cb_capture_update_started):
1847 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1848 main_capture_cb_capture_update_started(cap_session);
1849 #ifdef HAVE_GTKOSXAPPLICATION
1850 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1851 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1854 case(capture_cb_capture_update_continue):
1855 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1857 case(capture_cb_capture_update_finished):
1858 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1859 main_capture_cb_capture_update_finished(cap_session);
1861 case(capture_cb_capture_fixed_started):
1862 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1863 main_capture_cb_capture_fixed_started(cap_session);
1865 case(capture_cb_capture_fixed_continue):
1866 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1868 case(capture_cb_capture_fixed_finished):
1869 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1870 main_capture_cb_capture_fixed_finished(cap_session);
1872 case(capture_cb_capture_stopping):
1873 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1874 /* Beware: this state won't be called, if the capture child
1875 * closes the capturing on its own! */
1876 #ifdef HAVE_GTKOSXAPPLICATION
1877 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1878 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1880 main_capture_cb_capture_stopping(cap_session);
1882 case(capture_cb_capture_failed):
1883 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1884 main_capture_cb_capture_failed(cap_session);
1887 g_warning("main_capture_callback: event %u unknown", event);
1888 g_assert_not_reached();
1894 get_gtk_compiled_info(GString *str)
1896 g_string_append(str, "with ");
1897 g_string_append_printf(str,
1898 #ifdef GTK_MAJOR_VERSION
1899 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1902 "GTK+ (version unknown)");
1904 g_string_append(str, ", ");
1906 g_string_append(str, "with Cairo ");
1907 g_string_append(str, CAIRO_VERSION_STRING);
1908 g_string_append(str, ", ");
1911 g_string_append(str, "with Pango ");
1912 g_string_append(str, PANGO_VERSION_STRING);
1913 g_string_append(str, ", ");
1919 get_gui_compiled_info(GString *str)
1921 epan_get_compiled_version_info(str);
1923 g_string_append(str, ", ");
1924 #ifdef HAVE_LIBPORTAUDIO
1925 #ifdef PORTAUDIO_API_1
1926 g_string_append(str, "with PortAudio <= V18");
1927 #else /* PORTAUDIO_API_1 */
1928 g_string_append(str, "with ");
1929 g_string_append(str, Pa_GetVersionText());
1930 #endif /* PORTAUDIO_API_1 */
1931 #else /* HAVE_LIBPORTAUDIO */
1932 g_string_append(str, "without PortAudio");
1933 #endif /* HAVE_LIBPORTAUDIO */
1935 g_string_append(str, ", ");
1937 get_compiled_airpcap_version(str);
1939 g_string_append(str, "without AirPcap");
1944 get_gui_runtime_info(GString *str)
1946 epan_get_runtime_version_info(str);
1949 g_string_append(str, ", ");
1950 get_runtime_airpcap_version(str);
1954 g_string_append(str, ", ");
1955 u3_runtime_info(str);
1960 read_configuration_files(char **gdp_path, char **dp_path)
1962 int gpf_open_errno, gpf_read_errno;
1963 int cf_open_errno, df_open_errno;
1964 int gdp_open_errno, gdp_read_errno;
1965 int dp_open_errno, dp_read_errno;
1966 char *gpf_path, *pf_path;
1967 char *cf_path, *df_path;
1968 int pf_open_errno, pf_read_errno;
1971 /* load the decode as entries of this profile */
1972 load_decode_as_entries();
1974 /* Read the preference files. */
1975 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1976 &pf_open_errno, &pf_read_errno, &pf_path);
1978 if (gpf_path != NULL) {
1979 if (gpf_open_errno != 0) {
1980 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1981 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1982 g_strerror(gpf_open_errno));
1984 if (gpf_read_errno != 0) {
1985 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1986 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1987 g_strerror(gpf_read_errno));
1990 if (pf_path != NULL) {
1991 if (pf_open_errno != 0) {
1992 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1993 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1994 g_strerror(pf_open_errno));
1996 if (pf_read_errno != 0) {
1997 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1998 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1999 g_strerror(pf_read_errno));
2006 /* if the user wants a console to be always there, well, we should open one for him */
2007 if (prefs_p->gui_console_open == console_open_always) {
2012 /* Read the capture filter file. */
2013 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2014 if (cf_path != NULL) {
2015 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2016 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2017 g_strerror(cf_open_errno));
2021 /* Read the display filter file. */
2022 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2023 if (df_path != NULL) {
2024 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2025 "Could not open your display filter file\n\"%s\": %s.", df_path,
2026 g_strerror(df_open_errno));
2030 /* Read the disabled protocols file. */
2031 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2032 dp_path, &dp_open_errno, &dp_read_errno);
2033 if (*gdp_path != NULL) {
2034 if (gdp_open_errno != 0) {
2035 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2036 "Could not open global disabled protocols file\n\"%s\": %s.",
2037 *gdp_path, g_strerror(gdp_open_errno));
2039 if (gdp_read_errno != 0) {
2040 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2041 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2042 *gdp_path, g_strerror(gdp_read_errno));
2047 if (*dp_path != NULL) {
2048 if (dp_open_errno != 0) {
2049 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2050 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2051 g_strerror(dp_open_errno));
2053 if (dp_read_errno != 0) {
2054 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2055 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2056 g_strerror(dp_read_errno));
2065 /* Check if there's something important to tell the user during startup.
2066 * We want to do this *after* showing the main window so that any windows
2067 * we pop up will be above the main window.
2071 check_and_warn_user_startup(gchar *cf_name)
2073 check_and_warn_user_startup(gchar *cf_name _U_)
2076 gchar *cur_user, *cur_group;
2077 gpointer priv_warning_dialog;
2079 /* Tell the user not to run as root. */
2080 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2081 cur_user = get_cur_username();
2082 cur_group = get_cur_groupname();
2083 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2084 "Running as user \"%s\" and group \"%s\".\n"
2085 "This could be dangerous.\n\n"
2086 "If you're running Wireshark this way in order to perform live capture, "
2087 "you may want to be aware that there is a better way documented at\n"
2088 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2091 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2092 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2096 /* Warn the user if npf.sys isn't loaded. */
2097 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2098 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2099 "The NPF driver isn't running. You may have trouble\n"
2100 "capturing or listing interfaces.");
2101 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2102 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2109 /* And now our feature presentation... [ fade to music ] */
2111 main(int argc, char *argv[])
2113 char *init_progfile_dir_error;
2116 gboolean arg_error = FALSE;
2118 extern int info_update_freq; /* Found in about_dlg.c. */
2119 const gchar *filter;
2127 char *gdp_path, *dp_path;
2130 gboolean start_capture = FALSE;
2131 gboolean list_link_layer_types = FALSE;
2135 gboolean capture_option_specified = FALSE;
2142 gint pl_size = 280, tv_size = 95, bv_size = 75;
2143 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2144 dfilter_t *rfcode = NULL;
2145 gboolean rfilter_parse_failed = FALSE;
2148 GtkWidget *splash_win = NULL;
2149 GLogLevelFlags log_flags;
2150 guint go_to_packet = 0;
2151 search_direction jump_backwards = SD_FORWARD;
2152 dfilter_t *jump_to_filter = NULL;
2155 #ifdef HAVE_GTKOSXAPPLICATION
2156 GtkosxApplication *theApp;
2160 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2161 #define OPTSTRING_B "B:"
2163 #define OPTSTRING_B ""
2164 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2165 #else /* HAVE_LIBPCAP */
2166 #define OPTSTRING_B ""
2167 #endif /* HAVE_LIBPCAP */
2168 #ifdef HAVE_PCAP_REMOTE
2169 #define OPTSTRING_A "A:"
2171 #define OPTSTRING_A ""
2173 #ifdef HAVE_PCAP_CREATE
2174 #define OPTSTRING_I "I"
2176 #define OPTSTRING_I ""
2179 #define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:Y:z:"
2181 static const char optstring[] = OPTSTRING;
2184 /* Set the C-language locale to the native environment. */
2185 setlocale(LC_ALL, "");
2187 arg_list_utf_16to8(argc, argv);
2188 create_app_running_mutex();
2192 * Get credential information for later use, and drop privileges
2193 * before doing anything else.
2194 * Let the user know if anything happened.
2196 init_process_policies();
2197 relinquish_special_privs_perm();
2200 * Attempt to get the pathname of the executable file.
2202 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2204 /* initialize the funnel mini-api */
2205 initialize_funnel_ops();
2207 AirPDcapInitContext(&airpdcap_ctx);
2210 /* Load wpcap if possible. Do this before collecting the run-time version information */
2213 /* ... and also load the packet.dll from wpcap */
2214 wpcap_packet_load();
2217 /* Load the airpcap.dll. This must also be done before collecting
2218 * run-time version information. */
2219 airpcap_dll_ret_val = load_airpcap();
2221 switch (airpcap_dll_ret_val) {
2222 case AIRPCAP_DLL_OK:
2223 /* load the airpcap interfaces */
2224 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2226 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2227 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2228 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2231 airpcap_if_active = NULL;
2235 /* select the first ad default (THIS SHOULD BE CHANGED) */
2236 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2241 * XXX - Maybe we need to warn the user if one of the following happens???
2243 case AIRPCAP_DLL_OLD:
2244 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2247 case AIRPCAP_DLL_ERROR:
2248 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2251 case AIRPCAP_DLL_NOT_FOUND:
2252 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2256 #endif /* HAVE_AIRPCAP */
2259 /* Assemble the compile-time version information string */
2260 comp_info_str = g_string_new("Compiled ");
2262 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2264 /* Assemble the run-time version information string */
2265 runtime_info_str = g_string_new("Running ");
2266 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2269 ws_add_crash_info(PACKAGE " " VERSION "%s\n"
2274 wireshark_svnversion, comp_info_str->str, runtime_info_str->str);
2276 /* Start windows sockets */
2277 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2280 profile_store_persconffiles (TRUE);
2282 /* Read the profile independent recent file. We have to do this here so we can */
2283 /* set the profile before it can be set from the command line parameterts */
2284 recent_read_static(&rf_path, &rf_open_errno);
2285 if (rf_path != NULL && rf_open_errno != 0) {
2286 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2287 "Could not open common recent file\n\"%s\": %s.",
2288 rf_path, g_strerror(rf_open_errno));
2291 /* "pre-scan" the command line parameters, if we have "console only"
2292 parameters. We do this so we don't start GTK+ if we're only showing
2293 command-line help or version information.
2295 XXX - this pre-scan is done before we start GTK+, so we haven't
2296 run gtk_init() on the arguments. That means that GTK+ arguments
2297 have not been removed from the argument list; those arguments
2298 begin with "--", and will be treated as an error by getopt().
2300 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2303 optind_initial = optind;
2304 while ((opt = getopt(argc, argv, optstring)) != -1) {
2306 case 'C': /* Configuration Profile */
2307 if (profile_exists (optarg, FALSE)) {
2308 set_profile_name (optarg);
2310 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2314 case 'D': /* Print a list of capture devices and exit */
2316 if_list = capture_interface_list(&err, &err_str,main_window_update);
2317 if (if_list == NULL) {
2319 case CANT_GET_INTERFACE_LIST:
2320 case DONT_HAVE_PCAP:
2321 cmdarg_err("%s", err_str);
2325 case NO_INTERFACES_FOUND:
2326 cmdarg_err("There are no interfaces on which a capture can be done");
2334 capture_opts_print_interfaces(if_list);
2335 free_interface_list(if_list);
2340 #else /* HAVE_LIBPCAP */
2341 capture_option_specified = TRUE;
2343 #endif /* HAVE_LIBPCAP */
2345 case 'h': /* Print help and exit */
2351 if (strcmp(optarg, "-") == 0)
2352 set_stdin_capture(TRUE);
2355 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2356 status = filesystem_opt(opt, optarg);
2358 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2362 case 'v': /* Show version and exit */
2374 * Extension command line options have to be processed before
2375 * we call epan_init() as they are supposed to be used by dissectors
2376 * or taps very early in the registration process.
2380 case '?': /* Ignore errors - the "real" scan will catch them. */
2385 /* Init the "Open file" dialog directory */
2386 /* (do this after the path settings are processed) */
2388 /* Read the profile dependent (static part) of the recent file. */
2389 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2390 /* recent lists which is done in the dynamic part. */
2391 /* We have to do this already here, so command line parameters can overwrite these values. */
2392 recent_read_profile_static(&rf_path, &rf_open_errno);
2393 if (rf_path != NULL && rf_open_errno != 0) {
2394 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2395 "Could not open recent file\n\"%s\": %s.",
2396 rf_path, g_strerror(rf_open_errno));
2399 if (recent.gui_fileopen_remembered_dir &&
2400 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2401 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2403 set_last_open_dir(get_persdatafile_dir());
2406 /* Set getopt index back to initial value, so it will start with the
2407 first command line parameter again. Also reset opterr to 1, so that
2408 error messages are printed by getopt().
2410 XXX - this seems to work on most platforms, but time will tell.
2411 The Single UNIX Specification says "The getopt() function need
2412 not be reentrant", so this isn't guaranteed to work. The Mac
2413 OS X 10.4[.x] getopt() man page says
2415 In order to use getopt() to evaluate multiple sets of arguments, or to
2416 evaluate a single set of arguments multiple times, the variable optreset
2417 must be set to 1 before the second and each additional set of calls to
2418 getopt(), and the variable optind must be reinitialized.
2422 The optreset variable was added to make it possible to call the getopt()
2423 function multiple times. This is an extension to the IEEE Std 1003.2
2424 (``POSIX.2'') specification.
2426 which I think comes from one of the other BSDs.
2428 XXX - if we want to control all the command-line option errors, so
2429 that we can display them where we choose (e.g., in a window), we'd
2430 want to leave opterr as 0, and produce our own messages using optopt.
2431 We'd have to check the value of optopt to see if it's a valid option
2432 letter, in which case *presumably* the error is "this option requires
2433 an argument but none was specified", or not a valid option letter,
2434 in which case *presumably* the error is "this option isn't valid".
2435 Some versions of getopt() let you supply a option string beginning
2436 with ':', which means that getopt() will return ':' rather than '?'
2437 for "this option requires an argument but none was specified", but
2439 optind = optind_initial;
2442 #if !GLIB_CHECK_VERSION(2,31,0)
2443 g_thread_init(NULL);
2446 /* Set the current locale according to the program environment.
2447 * We haven't localized anything, but some GTK widgets are localized
2448 * (the file selection dialogue, for example).
2449 * This also sets the C-language locale to the native environment. */
2450 setlocale (LC_ALL, "");
2452 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2453 gtk_init (&argc, &argv);
2455 cf_callback_add(main_cf_callback, NULL);
2457 capture_callback_add(main_capture_callback, NULL);
2459 cf_callback_add(statusbar_cf_callback, NULL);
2461 capture_callback_add(statusbar_capture_callback, NULL);
2464 /* Arrange that if we have no console window, and a GLib message logging
2465 routine is called to log a message, we pop up a console window.
2467 We do that by inserting our own handler for all messages logged
2468 to the default domain; that handler pops up a console if necessary,
2469 and then calls the default handler. */
2471 /* We might want to have component specific log levels later ... */
2473 log_flags = (GLogLevelFlags)
2475 G_LOG_LEVEL_CRITICAL|
2476 G_LOG_LEVEL_WARNING|
2477 G_LOG_LEVEL_MESSAGE|
2480 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION);
2482 g_log_set_handler(NULL,
2484 console_log_handler, NULL /* user_data */);
2485 g_log_set_handler(LOG_DOMAIN_MAIN,
2487 console_log_handler, NULL /* user_data */);
2490 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2492 console_log_handler, NULL /* user_data */);
2493 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2495 console_log_handler, NULL /* user_data */);
2497 /* Set the initial values in the capture options. This might be overwritten
2498 by preference settings and then again by the command line parameters. */
2499 capture_opts_init(&global_capture_opts);
2501 capture_session_init(&global_capture_session, (void *)&cfile);
2504 /* Initialize whatever we need to allocate colors for GTK+ */
2507 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2508 filter = get_conn_cfilter();
2509 if ( *filter != '\0' ) {
2510 info_update_freq = 1000; /* Milliseconds */
2513 /* We won't come till here, if we had a "console only" command line parameter. */
2514 splash_win = splash_new("Loading Wireshark ...");
2515 if (init_progfile_dir_error != NULL) {
2516 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2517 "Can't get pathname of Wireshark: %s.\n"
2518 "It won't be possible to capture traffic.\n"
2519 "Report this to the Wireshark developers.",
2520 init_progfile_dir_error);
2521 g_free(init_progfile_dir_error);
2524 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2526 /* Register all dissectors; we must do this before checking for the
2527 "-G" flag, as the "-G" flag dumps information registered by the
2528 dissectors, and we must do it before we read the preferences, in
2529 case any dissectors register preferences. */
2530 epan_init(register_all_protocols,register_all_protocol_handoffs,
2531 splash_update, (gpointer) splash_win,
2532 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2533 write_failure_alert_box);
2535 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2537 /* Register all tap listeners; we do this before we parse the arguments,
2538 as the "-z" argument can specify a registered tap. */
2540 /* we register the plugin taps before the other taps because
2541 stats_tree taps plugins will be registered as tap listeners
2542 by stats_tree_stat.c and need to registered before that */
2545 register_all_plugin_tap_listeners();
2548 register_all_tap_listeners();
2550 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2552 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2553 /* Removed thread code:
2554 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2557 /* this is to keep tap extensions updating once every 3 seconds */
2558 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2560 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2562 cap_file_init(&cfile);
2564 /* Fill in capture options with values from the preferences */
2565 prefs_to_capture_opts();
2567 /*#ifdef HAVE_LIBPCAP
2568 fill_in_local_interfaces();
2570 /* Now get our args */
2571 while ((opt = getopt(argc, argv, optstring)) != -1) {
2573 /*** capture option specific ***/
2574 case 'a': /* autostop criteria */
2575 case 'b': /* Ringbuffer option */
2576 case 'c': /* Capture xxx packets */
2577 case 'f': /* capture filter */
2578 case 'k': /* Start capture immediately */
2579 case 'H': /* Hide capture info dialog box */
2580 case 'p': /* Don't capture in promiscuous mode */
2581 case 'i': /* Use interface x */
2582 #ifdef HAVE_PCAP_CREATE
2583 case 'I': /* Capture in monitor mode, if available */
2585 #ifdef HAVE_PCAP_REMOTE
2586 case 'A': /* Authentication */
2588 case 's': /* Set the snapshot (capture) length */
2589 case 'S': /* "Sync" mode: used for following file ala tail -f */
2590 case 'w': /* Write to capture file xxx */
2591 case 'y': /* Set the pcap data link type */
2592 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2593 case 'B': /* Buffer size */
2594 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2596 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2602 capture_option_specified = TRUE;
2607 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2608 case 'K': /* Kerberos keytab file */
2609 read_keytab_file(optarg);
2613 /*** all non capture option specific ***/
2615 /* Configuration profile settings were already processed just ignore them this time*/
2617 case 'j': /* Search backwards for a matching packet from filter in option J */
2618 jump_backwards = SD_BACKWARD;
2620 case 'g': /* Go to packet with the given packet number */
2621 go_to_packet = get_positive_int(optarg, "go to packet");
2623 case 'J': /* Jump to the first packet which matches the filter criteria */
2626 case 'l': /* Automatic scrolling in live capture mode */
2628 auto_scroll_live = TRUE;
2630 capture_option_specified = TRUE;
2634 case 'L': /* Print list of link-layer types and exit */
2636 list_link_layer_types = TRUE;
2638 capture_option_specified = TRUE;
2642 case 'm': /* Fixed-width font for the display */
2643 g_free(prefs_p->gui_gtk2_font_name);
2644 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2646 case 'n': /* No name resolution */
2647 gbl_resolv_flags.mac_name = FALSE;
2648 gbl_resolv_flags.network_name = FALSE;
2649 gbl_resolv_flags.transport_name = FALSE;
2650 gbl_resolv_flags.concurrent_dns = FALSE;
2652 case 'N': /* Select what types of addresses/port #s to resolve */
2653 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2654 if (badopt != '\0') {
2655 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2660 case 'o': /* Override preference from command line */
2661 switch (prefs_set_pref(optarg)) {
2664 case PREFS_SET_SYNTAX_ERR:
2665 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2668 case PREFS_SET_NO_SUCH_PREF:
2669 /* not a preference, might be a recent setting */
2670 switch (recent_set_arg(optarg)) {
2673 case PREFS_SET_SYNTAX_ERR:
2674 /* shouldn't happen, checked already above */
2675 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2678 case PREFS_SET_NO_SUCH_PREF:
2679 case PREFS_SET_OBSOLETE:
2680 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2685 g_assert_not_reached();
2688 case PREFS_SET_OBSOLETE:
2689 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2694 g_assert_not_reached();
2698 /* Path settings were already processed just ignore them this time*/
2700 case 'r': /* Read capture file xxx */
2701 /* We may set "last_open_dir" to "cf_name", and if we change
2702 "last_open_dir" later, we free the old value, so we have to
2703 set "cf_name" to something that's been allocated. */
2704 cf_name = g_strdup(optarg);
2706 case 'R': /* Read file filter */
2709 case 't': /* Time stamp type */
2710 if (strcmp(optarg, "r") == 0)
2711 timestamp_set_type(TS_RELATIVE);
2712 else if (strcmp(optarg, "a") == 0)
2713 timestamp_set_type(TS_ABSOLUTE);
2714 else if (strcmp(optarg, "ad") == 0)
2715 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2716 else if (strcmp(optarg, "d") == 0)
2717 timestamp_set_type(TS_DELTA);
2718 else if (strcmp(optarg, "dd") == 0)
2719 timestamp_set_type(TS_DELTA_DIS);
2720 else if (strcmp(optarg, "e") == 0)
2721 timestamp_set_type(TS_EPOCH);
2722 else if (strcmp(optarg, "u") == 0)
2723 timestamp_set_type(TS_UTC);
2724 else if (strcmp(optarg, "ud") == 0)
2725 timestamp_set_type(TS_UTC_WITH_DATE);
2727 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2728 cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with date, \"d\" for delta,");
2729 cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative, \"u\" for UTC, ");
2730 cmdarg_err_cont("or \"ud\" for UTC with date.");
2734 case 'u': /* Seconds type */
2735 if (strcmp(optarg, "s") == 0)
2736 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2737 else if (strcmp(optarg, "hms") == 0)
2738 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2740 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2741 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2746 /* ext ops were already processed just ignore them this time*/
2752 /* We won't call the init function for the stat this soon
2753 as it would disallow MATE's fields (which are registered
2754 by the preferences set callback) from being used as
2755 part of a tap filter. Instead, we just add the argument
2756 to a list of stat arguments. */
2757 if (!process_stat_cmd_arg(optarg)) {
2758 cmdarg_err("Invalid -z argument.");
2759 cmdarg_err_cont(" -z argument must be one of :");
2760 list_stat_cmd_args();
2765 case '?': /* Bad flag - print usage message */
2774 if (cf_name != NULL) {
2776 * Input file name specified with "-r" *and* specified as a regular
2777 * command-line argument.
2779 cmdarg_err("File name specified both with -r and regular argument");
2783 * Input file name not specified with "-r", and a command-line argument
2784 * was specified; treat it as the input file name.
2786 * Yes, this is different from tshark, where non-flag command-line
2787 * arguments are a filter, but this works better on GUI desktops
2788 * where a command can be specified to be run to open a particular
2789 * file - yes, you could have "-r" as the last part of the command,
2790 * but that's a bit ugly.
2792 #ifndef HAVE_GTKOSXAPPLICATION
2794 * For GTK+ Mac Integration, file name passed as free argument passed
2795 * through grag-and-drop and opened twice sometimes causing crashes.
2796 * Subject to report to GTK+ MAC.
2798 cf_name = g_strdup(argv[0]);
2807 * Extra command line arguments were specified; complain.
2809 cmdarg_err("Invalid argument: %s", argv[0]);
2814 #ifndef HAVE_LIBPCAP
2815 if (capture_option_specified) {
2816 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2824 fill_in_local_interfaces(main_window_update);
2825 if (start_capture && list_link_layer_types) {
2826 /* Specifying *both* is bogus. */
2827 cmdarg_err("You can't specify both -L and a live capture.");
2831 if (list_link_layer_types) {
2832 /* We're supposed to list the link-layer types for an interface;
2833 did the user also specify a capture file to be read? */
2835 /* Yes - that's bogus. */
2836 cmdarg_err("You can't specify -L and a capture file to be read.");
2839 /* No - did they specify a ring buffer option? */
2840 if (global_capture_opts.multi_files_on) {
2841 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2845 /* We're supposed to do a live capture; did the user also specify
2846 a capture file to be read? */
2847 if (start_capture && cf_name) {
2848 /* Yes - that's bogus. */
2849 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2853 /* No - was the ring buffer option specified and, if so, does it make
2855 if (global_capture_opts.multi_files_on) {
2856 /* Ring buffer works only under certain conditions:
2857 a) ring buffer does not work with temporary files;
2858 b) real_time_mode and multi_files_on are mutually exclusive -
2859 real_time_mode takes precedence;
2860 c) it makes no sense to enable the ring buffer if the maximum
2861 file size is set to "infinite". */
2862 if (global_capture_opts.save_file == NULL) {
2863 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2864 global_capture_opts.multi_files_on = FALSE;
2866 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2867 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2868 /* XXX - this must be redesigned as the conditions changed */
2873 if (start_capture || list_link_layer_types) {
2874 /* We're supposed to do a live capture or get a list of link-layer
2875 types for a live capture device; if the user didn't specify an
2876 interface to use, pick a default. */
2877 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2878 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2884 if (list_link_layer_types) {
2885 /* Get the list of link-layer types for the capture devices. */
2886 if_capabilities_t *caps;
2889 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2891 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2892 if (device.selected) {
2893 #if defined(HAVE_PCAP_CREATE)
2894 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str, main_window_update);
2896 caps = capture_get_if_capabilities(device.name, FALSE, &err_str,main_window_update);
2899 cmdarg_err("%s", err_str);
2903 if (caps->data_link_types == NULL) {
2904 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2910 #if defined(HAVE_PCAP_CREATE)
2911 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2913 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2918 free_if_capabilities(caps);
2924 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2925 capture_opts_trim_ring_num_files(&global_capture_opts);
2926 #endif /* HAVE_LIBPCAP */
2928 /* Notify all registered modules that have had any of their preferences
2929 changed either from one of the preferences file or from the command
2930 line that their preferences have changed. */
2934 if ((global_capture_opts.num_selected == 0) &&
2935 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2938 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2939 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2940 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2941 device.selected = TRUE;
2942 global_capture_opts.num_selected++;
2943 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2944 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2949 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2950 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2951 device.selected = TRUE;
2952 global_capture_opts.num_selected++;
2953 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2954 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2958 /* disabled protocols as per configuration file */
2959 if (gdp_path == NULL && dp_path == NULL) {
2960 set_disabled_protos_list();
2963 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2965 /* read in rc file from global and personal configuration paths. */
2966 rc_file = get_datafile_path(RC_FILE);
2967 #if GTK_CHECK_VERSION(3,0,0)
2968 /* XXX resolve later */
2970 gtk_rc_parse(rc_file);
2972 rc_file = get_persconffile_path(RC_FILE, FALSE);
2973 gtk_rc_parse(rc_file);
2983 /* close the splash screen, as we are going to open the main window now */
2984 splash_destroy(splash_win);
2986 /************************************************************************/
2987 /* Everything is prepared now, preferences and command line was read in */
2989 /* Pop up the main window. */
2990 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2992 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2993 recent_read_dynamic(&rf_path, &rf_open_errno);
2994 if (rf_path != NULL && rf_open_errno != 0) {
2995 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2996 "Could not open recent file\n\"%s\": %s.",
2997 rf_path, g_strerror(rf_open_errno));
3000 color_filters_enable(recent.packet_list_colorize);
3002 /* rearrange all the widgets as we now have all recent settings ready for this */
3003 main_widgets_rearrange();
3005 /* Fill in column titles. This must be done after the top level window
3008 XXX - is that still true, with fixed-width columns? */
3010 menu_recent_read_finished();
3012 main_auto_scroll_live_changed(auto_scroll_live);
3015 switch (user_font_apply()) {
3018 case FA_FONT_NOT_RESIZEABLE:
3019 /* "user_font_apply()" popped up an alert box. */
3020 /* turn off zooming - font can't be resized */
3021 case FA_FONT_NOT_AVAILABLE:
3022 /* XXX - did we successfully load the un-zoomed version earlier?
3023 If so, this *probably* means the font is available, but not at
3024 this particular zoom level, but perhaps some other failure
3025 occurred; I'm not sure you can determine which is the case,
3027 /* turn off zooming - zoom level is unavailable */
3029 /* in any other case than FA_SUCCESS, turn off zooming */
3030 recent.gui_zoom_level = 0;
3031 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3034 dnd_init(top_level);
3036 color_filters_init();
3039 capture_filter_init();
3042 /* the window can be sized only, if it's not already shown, so do it now! */
3043 main_load_window_geometry(top_level);
3045 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3047 /* If we were given the name of a capture file, read it in now;
3048 we defer it until now, so that, if we can't open it, and pop
3049 up an alert box, the alert box is more likely to come up on
3050 top of the main window - but before the preference-file-error
3051 alert box, so, if we get one of those, it's more likely to come
3054 show_main_window(TRUE);
3055 check_and_warn_user_startup(cf_name);
3056 if (rfilter != NULL) {
3057 if (!dfilter_compile(rfilter, &rfcode)) {
3058 bad_dfilter_alert_box(top_level, rfilter);
3059 rfilter_parse_failed = TRUE;
3062 if (!rfilter_parse_failed) {
3063 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3064 /* "cf_open()" succeeded, so it closed the previous
3065 capture file, and thus destroyed any previous read filter
3066 attached to "cf". */
3068 cfile.rfcode = rfcode;
3069 /* Open stat windows; we do so after creating the main window,
3070 to avoid GTK warnings, and after successfully opening the
3071 capture file, so we know we have something to compute stats
3072 on, and after registering all dissectors, so that MATE will
3073 have registered its field array and we can have a tap filter
3074 with one of MATE's late-registered fields as part of the
3076 start_requested_stats();
3078 /* Read the capture file. */
3079 switch (cf_read(&cfile, FALSE)) {
3083 /* Just because we got an error, that doesn't mean we were unable
3084 to read any of the file; we handle what we could get from the
3086 /* if the user told us to jump to a specific packet, do it now */
3087 if(go_to_packet != 0) {
3088 /* Jump to the specified frame number, kept for backward
3090 cf_goto_frame(&cfile, go_to_packet);
3091 } else if (jfilter != NULL) {
3092 /* try to compile given filter */
3093 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3094 bad_dfilter_alert_box(top_level, jfilter);
3096 /* Filter ok, jump to the first packet matching the filter
3097 conditions. Default search direction is forward, but if
3098 option d was given, search backwards */
3099 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3104 case CF_READ_ABORTED:
3110 /* If the filename is not the absolute path, prepend the current dir. This happens
3111 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3112 if (!g_path_is_absolute(cf_name)) {
3113 char *old_cf_name = cf_name;
3114 char *pwd = g_get_current_dir();
3115 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3116 g_free(old_cf_name);
3120 /* Save the name of the containing directory specified in the
3121 path name, if any; we can write over cf_name, which is a
3122 good thing, given that "get_dirname()" does write over its
3124 s = get_dirname(cf_name);
3125 set_last_open_dir(s);
3130 dfilter_free(rfcode);
3131 cfile.rfcode = NULL;
3132 show_main_window(FALSE);
3133 /* Don't call check_and_warn_user_startup(): we did it above */
3134 main_set_for_capture_in_progress(FALSE);
3135 set_capture_if_dialog_for_capture_in_progress(FALSE);
3140 if (start_capture) {
3141 if (global_capture_opts.save_file != NULL) {
3142 /* Save the directory name for future file dialogs. */
3143 /* (get_dirname overwrites filename) */
3144 s = get_dirname(g_strdup(global_capture_opts.save_file));
3145 set_last_open_dir(s);
3148 /* "-k" was specified; start a capture. */
3149 show_main_window(FALSE);
3150 check_and_warn_user_startup(cf_name);
3152 /* If no user interfaces were specified on the command line,
3153 copy the list of selected interfaces to the set of interfaces
3154 to use for this capture. */
3155 if (global_capture_opts.ifaces->len == 0)
3156 collect_ifaces(&global_capture_opts);
3157 if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3158 /* The capture started. Open stat windows; we do so after creating
3159 the main window, to avoid GTK warnings, and after successfully
3160 opening the capture file, so we know we have something to compute
3161 stats on, and after registering all dissectors, so that MATE will
3162 have registered its field array and we can have a tap filter with
3163 one of MATE's late-registered fields as part of the filter. */
3164 start_requested_stats();
3167 show_main_window(FALSE);
3168 check_and_warn_user_startup(cf_name);
3169 main_set_for_capture_in_progress(FALSE);
3170 set_capture_if_dialog_for_capture_in_progress(FALSE);
3173 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3174 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3175 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3177 #else /* HAVE_LIBPCAP */
3178 show_main_window(FALSE);
3179 check_and_warn_user_startup(cf_name);
3180 main_set_for_capture_in_progress(FALSE);
3181 set_capture_if_dialog_for_capture_in_progress(FALSE);
3182 #endif /* HAVE_LIBPCAP */
3186 GtkWidget *filter_te;
3187 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3188 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3190 /* Run the display filter so it goes in effect. */
3191 main_filter_packets(&cfile, dfilter, FALSE);
3195 /* register our pid if we are being run from a U3 device */
3198 profile_store_persconffiles (FALSE);
3200 #ifdef HAVE_GTKOSXAPPLICATION
3201 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3202 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3203 gtkosx_application_ready(theApp);
3206 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3209 gtk_iface_mon_start();
3212 software_update_init();
3214 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3216 /* ... back from GTK, we're going down now! */
3219 gtk_iface_mon_stop();
3222 /* deregister our pid */
3223 u3_deregister_pid();
3227 AirPDcapDestroyContext(&airpdcap_ctx);
3230 /* hide the (unresponsive) main window, while asking the user to close the console window */
3231 gtk_widget_hide(top_level);
3233 #ifdef HAVE_GTKOSXAPPLICATION
3234 g_object_unref(theApp);
3237 software_update_cleanup();
3239 /* Shutdown windows sockets */
3242 /* For some unknown reason, the "atexit()" call in "create_console()"
3243 doesn't arrange that "destroy_console()" be called when we exit,
3244 so we call it here if a console was created. */
3253 /* We build this as a GUI subsystem application on Win32, so
3254 "WinMain()", not "main()", gets called.
3256 Hack shamelessly stolen from the Win32 port of the GIMP. */
3258 #define _stdcall __attribute__((stdcall))
3262 WinMain (struct HINSTANCE__ *hInstance,
3263 struct HINSTANCE__ *hPrevInstance,
3267 INITCOMMONCONTROLSEX comm_ctrl;
3270 * Initialize our DLL search path. MUST be called before LoadLibrary
3273 ws_init_dll_search_path();
3275 /* Initialize our controls. Required for native Windows file dialogs. */
3276 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3277 comm_ctrl.dwSize = sizeof(comm_ctrl);
3278 /* Includes the animate, header, hot key, list view, progress bar,
3279 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3282 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3283 InitCommonControlsEx(&comm_ctrl);
3285 /* RichEd20.DLL is needed for filter entries. */
3286 ws_load_library("riched20.dll");
3288 set_has_console(FALSE);
3289 set_console_wait(FALSE);
3290 return main (__argc, __argv);
3297 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3298 const char *message, gpointer user_data _U_)
3305 /* ignore log message, if log_level isn't interesting based
3306 upon the console log preferences.
3307 If the preferences haven't been loaded loaded yet, display the
3310 The default console_log_level preference value is such that only
3311 ERROR, CRITICAL and WARNING level messages are processed;
3312 MESSAGE, INFO and DEBUG level messages are ignored. */
3313 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3314 prefs.console_log_level != 0) {
3319 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3320 /* the user wants a console or the application will terminate immediately */
3323 if (get_has_console()) {
3324 /* For some unknown reason, the above doesn't appear to actually cause
3325 anything to be sent to the standard output, so we'll just splat the
3326 message out directly, just to make sure it gets out. */
3328 switch(log_level & G_LOG_LEVEL_MASK) {
3329 case G_LOG_LEVEL_ERROR:
3332 case G_LOG_LEVEL_CRITICAL:
3335 case G_LOG_LEVEL_WARNING:
3338 case G_LOG_LEVEL_MESSAGE:
3341 case G_LOG_LEVEL_INFO:
3344 case G_LOG_LEVEL_DEBUG:
3348 fprintf(stderr, "unknown log_level %u\n", log_level);
3350 g_assert_not_reached();
3353 /* create a "timestamp" */
3355 today = localtime(&curr);
3357 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3358 today->tm_hour, today->tm_min, today->tm_sec,
3359 log_domain != NULL ? log_domain : "",
3362 if(log_level & G_LOG_LEVEL_ERROR) {
3363 /* wait for a key press before the following error handler will terminate the program
3364 this way the user at least can read the error message */
3365 printf("\n\nPress any key to exit\n");
3369 /* XXX - on UN*X, should we just use g_log_default_handler()?
3370 We want the error messages to go to the standard output;
3371 on Mac OS X, that will cause them to show up in various
3372 per-user logs accessible through Console (details depend
3373 on whether you're running 10.0 through 10.4 or running
3374 10.5 and later), and, on other UN*X desktop environments,
3375 if they don't show up in some form of console log, that's
3376 a deficiency in that desktop environment. (Too bad
3377 Windows doesn't set the standard output and error for
3378 GUI apps to something that shows up in such a log.) */
3379 g_log_default_handler(log_domain, log_level, message, user_data);
3386 * Helper for main_widgets_rearrange()
3388 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3389 gtk_container_remove(GTK_CONTAINER(data), widget);
3392 static GtkWidget *main_widget_layout(gint layout_content)
3394 switch(layout_content) {
3395 case(layout_pane_content_none):
3397 case(layout_pane_content_plist):
3399 case(layout_pane_content_pdetails):
3401 case(layout_pane_content_pbytes):
3402 return byte_nb_ptr_gbl;
3404 g_assert_not_reached();
3411 * Rearrange the main window widgets
3413 void main_widgets_rearrange(void) {
3414 GtkWidget *first_pane_widget1, *first_pane_widget2;
3415 GtkWidget *second_pane_widget1, *second_pane_widget2;
3416 gboolean split_top_left = FALSE;
3418 /* be a bit faster */
3419 gtk_widget_hide(main_vbox);
3421 /* be sure we don't lose a widget while rearranging */
3422 g_object_ref(G_OBJECT(menubar));
3423 g_object_ref(G_OBJECT(main_tb));
3424 g_object_ref(G_OBJECT(filter_tb));
3425 g_object_ref(G_OBJECT(wireless_tb));
3426 g_object_ref(G_OBJECT(pkt_scrollw));
3427 g_object_ref(G_OBJECT(tv_scrollw));
3428 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3429 g_object_ref(G_OBJECT(statusbar));
3430 g_object_ref(G_OBJECT(main_pane_v1));
3431 g_object_ref(G_OBJECT(main_pane_v2));
3432 g_object_ref(G_OBJECT(main_pane_h1));
3433 g_object_ref(G_OBJECT(main_pane_h2));
3434 g_object_ref(G_OBJECT(welcome_pane));
3436 /* empty all containers participating */
3437 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3438 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3439 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3440 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3441 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3443 statusbar_widgets_emptying(statusbar);
3445 /* add the menubar always at the top */
3446 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3449 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3451 /* filter toolbar in toolbar area */
3452 if (!prefs.filter_toolbar_show_in_statusbar) {
3453 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3456 /* airpcap toolbar */
3457 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3459 /* fill the main layout panes */
3460 switch(prefs.gui_layout_type) {
3461 case(layout_type_5):
3462 main_first_pane = main_pane_v1;
3463 main_second_pane = main_pane_v2;
3464 split_top_left = FALSE;
3466 case(layout_type_2):
3467 main_first_pane = main_pane_v1;
3468 main_second_pane = main_pane_h1;
3469 split_top_left = FALSE;
3471 case(layout_type_1):
3472 main_first_pane = main_pane_v1;
3473 main_second_pane = main_pane_h1;
3474 split_top_left = TRUE;
3476 case(layout_type_4):
3477 main_first_pane = main_pane_h1;
3478 main_second_pane = main_pane_v1;
3479 split_top_left = FALSE;
3481 case(layout_type_3):
3482 main_first_pane = main_pane_h1;
3483 main_second_pane = main_pane_v1;
3484 split_top_left = TRUE;
3486 case(layout_type_6):
3487 main_first_pane = main_pane_h1;
3488 main_second_pane = main_pane_h2;
3489 split_top_left = FALSE;
3492 main_first_pane = NULL;
3493 main_second_pane = NULL;
3494 g_assert_not_reached();
3496 if (split_top_left) {
3497 first_pane_widget1 = main_second_pane;
3498 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3499 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3500 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3502 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3503 first_pane_widget2 = main_second_pane;
3504 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3505 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3507 if (first_pane_widget1 != NULL)
3508 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3509 if (first_pane_widget2 != NULL)
3510 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3511 if (second_pane_widget1 != NULL)
3512 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3513 if (second_pane_widget2 != NULL)
3514 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3516 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3519 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3522 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3524 /* filter toolbar in statusbar hbox */
3525 if (prefs.filter_toolbar_show_in_statusbar) {
3526 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3529 /* statusbar widgets */
3530 statusbar_widgets_pack(statusbar);
3532 /* hide widgets on users recent settings */
3533 main_widgets_show_or_hide();
3535 gtk_widget_show(main_vbox);
3539 is_widget_visible(GtkWidget *widget, gpointer data)
3541 gboolean *is_visible = ( gboolean *)data;
3544 if (gtk_widget_get_visible(widget))
3551 main_widgets_show_or_hide(void)
3553 gboolean main_second_pane_show;
3555 if (recent.main_toolbar_show) {
3556 gtk_widget_show(main_tb);
3558 gtk_widget_hide(main_tb);
3561 statusbar_widgets_show_or_hide(statusbar);
3563 if (recent.filter_toolbar_show) {
3564 gtk_widget_show(filter_tb);
3566 gtk_widget_hide(filter_tb);
3569 if (recent.wireless_toolbar_show) {
3570 gtk_widget_show(wireless_tb);
3572 gtk_widget_hide(wireless_tb);
3575 if (recent.packet_list_show && have_capture_file) {
3576 gtk_widget_show(pkt_scrollw);
3578 gtk_widget_hide(pkt_scrollw);
3581 if (recent.tree_view_show && have_capture_file) {
3582 gtk_widget_show(tv_scrollw);
3584 gtk_widget_hide(tv_scrollw);
3587 if (recent.byte_view_show && have_capture_file) {
3588 gtk_widget_show(byte_nb_ptr_gbl);
3590 gtk_widget_hide(byte_nb_ptr_gbl);
3593 if (have_capture_file) {
3594 gtk_widget_show(main_first_pane);
3596 gtk_widget_hide(main_first_pane);
3600 * Is anything in "main_second_pane" visible?
3601 * If so, show it, otherwise hide it.
3603 main_second_pane_show = FALSE;
3604 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3605 &main_second_pane_show);
3606 if (main_second_pane_show) {
3607 gtk_widget_show(main_second_pane);
3609 gtk_widget_hide(main_second_pane);
3612 if (!have_capture_file) {
3614 gtk_widget_show(welcome_pane);
3617 gtk_widget_hide(welcome_pane);
3622 /* called, when the window state changes (minimized, maximized, ...) */
3624 window_state_event_cb (GtkWidget *widget _U_,
3628 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3630 if( (event->type) == (GDK_WINDOW_STATE)) {
3631 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3632 /* we might have dialogs popped up while we where iconified,
3634 display_queued_messages();
3642 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3644 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3646 if (event->keyval == GDK_F8) {
3649 } else if (event->keyval == GDK_F7) {
3652 } else if (event->state & NO_SHIFT_MOD_MASK) {
3653 return FALSE; /* Skip control, alt, and other modifiers */
3655 * A comment in gdkkeysyms.h says that it's autogenerated from
3656 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3657 * don't explicitly say so, isprint() should work as expected
3660 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3661 /* Forward the keypress on to the display filter entry */
3662 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3663 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3664 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3672 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3673 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3678 GtkAccelGroup *accel;
3681 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3682 set_titlebar_for_capture_file(NULL);
3684 gtk_widget_set_name(top_level, "main window");
3685 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3687 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3688 G_CALLBACK(window_state_event_cb), NULL);
3689 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3690 G_CALLBACK(top_level_key_pressed_cb), NULL );
3692 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3693 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3695 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3696 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3697 gtk_widget_show(main_vbox);
3700 menubar = main_menu_new(&accel);
3702 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3703 /* Mac OS X native menus are created and displayed by main_menu_new() */
3704 if(!prefs_p->gui_macosx_style) {
3706 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3707 gtk_widget_show(menubar);
3708 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3710 gtk_widget_hide(menubar);
3715 main_tb = toolbar_new();
3716 gtk_widget_show (main_tb);
3718 /* Filter toolbar */
3719 filter_tb = filter_toolbar_new();
3722 pkt_scrollw = packet_list_create();
3723 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3724 gtk_widget_show_all(pkt_scrollw);
3727 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3728 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3729 gtk_widget_show(tv_scrollw);
3731 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3732 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3733 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3734 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3735 gtk_widget_show(tree_view_gbl);
3738 byte_nb_ptr_gbl = byte_view_new();
3739 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3740 gtk_widget_show(byte_nb_ptr_gbl);
3742 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3743 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3745 /* Panes for the packet list, tree, and byte view */
3746 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3747 gtk_widget_show(main_pane_v1);
3748 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3749 gtk_widget_show(main_pane_v2);
3750 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3751 gtk_widget_show(main_pane_h1);
3752 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3753 gtk_widget_show(main_pane_h2);
3755 wireless_tb = airpcap_toolbar_new();
3757 wireless_tb = ws80211_toolbar_new();
3759 gtk_widget_show(wireless_tb);
3762 statusbar = statusbar_new();
3763 gtk_widget_show(statusbar);
3765 /* Pane for the welcome screen */
3766 welcome_pane = welcome_new();
3767 gtk_widget_show(welcome_pane);
3771 show_main_window(gboolean doing_work)
3773 main_set_for_capture_file(doing_work);
3775 /*** we have finished all init things, show the main window ***/
3776 gtk_widget_show(top_level);
3778 /* the window can be maximized only, if it's visible, so do it after show! */
3779 main_load_window_geometry(top_level);
3781 /* process all pending GUI events before continue */
3782 while (gtk_events_pending()) gtk_main_iteration();
3784 /* Pop up any queued-up alert boxes. */
3785 display_queued_messages();
3787 /* Move the main window to the front, in case it isn't already there */
3788 gdk_window_raise(gtk_widget_get_window(top_level));
3791 airpcap_toolbar_show(wireless_tb);
3792 #endif /* HAVE_AIRPCAP */
3795 static void copy_global_profile (const gchar *profile_name)
3797 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3799 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3800 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3801 "Can't create directory\n\"%s\":\n%s.",
3802 pf_dir_path, g_strerror(errno));
3804 g_free(pf_dir_path);
3807 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3808 &pf_dir_path, &pf_dir_path2) == -1) {
3809 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3810 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3811 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3813 g_free(pf_filename);
3814 g_free(pf_dir_path);
3815 g_free(pf_dir_path2);
3819 /* Change configuration profile */
3820 void change_configuration_profile (const gchar *profile_name)
3822 char *gdp_path, *dp_path;
3826 /* First check if profile exists */
3827 if (!profile_exists(profile_name, FALSE)) {
3828 if (profile_exists(profile_name, TRUE)) {
3829 /* Copy from global profile */
3830 copy_global_profile (profile_name);
3832 /* No personal and no global profile exists */
3837 /* Then check if changing to another profile */
3838 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3842 /* Get the current geometry, before writing it to disk */
3843 main_save_window_geometry(top_level);
3845 if (profile_exists(get_profile_name(), FALSE)) {
3846 /* Write recent file for profile we are leaving, if it still exists */
3847 write_profile_recent();
3850 /* Set profile name and update the status bar */
3851 set_profile_name (profile_name);
3852 profile_bar_update ();
3853 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3855 /* Reset current preferences and apply the new */
3859 (void) read_configuration_files (&gdp_path, &dp_path);
3861 recent_read_profile_static(&rf_path, &rf_open_errno);
3862 if (rf_path != NULL && rf_open_errno != 0) {
3863 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3864 "Could not open common recent file\n\"%s\": %s.",
3865 rf_path, g_strerror(rf_open_errno));
3867 if (recent.gui_fileopen_remembered_dir &&
3868 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3869 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3871 timestamp_set_type (recent.gui_time_format);
3872 timestamp_set_seconds_type (recent.gui_seconds_format);
3873 color_filters_enable(recent.packet_list_colorize);
3875 prefs_to_capture_opts();
3877 macros_post_update();
3879 /* Update window view and redraw the toolbar */
3880 main_titlebar_update();
3881 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3882 toolbar_redraw_all();
3884 /* Enable all protocols and disable from the disabled list */
3886 if (gdp_path == NULL && dp_path == NULL) {
3887 set_disabled_protos_list();
3890 /* Reload color filters */
3891 color_filters_reload();
3893 /* Reload list of interfaces on welcome page */
3894 welcome_if_panel_reload();
3896 /* Recreate the packet list according to new preferences */
3897 packet_list_recreate ();
3898 cfile.columns_changed = FALSE; /* Reset value */
3901 /* Update menus with new recent values */
3902 menu_recent_read_finished();
3904 /* Reload pane geometry, must be done after recreating the list */
3905 main_pane_load_window_geometry();
3908 /** redissect packets and update UI */
3909 void redissect_packets(void)
3911 cf_redissect_packets(&cfile);
3912 status_expert_update();