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 #define _WIN32_WINNT 0x0501
57 #include <ui/win32/console_win32.h>
60 #ifdef HAVE_LIBPORTAUDIO
61 #include <portaudio.h>
62 #endif /* HAVE_LIBPORTAUDIO */
64 #include <wsutil/crash_info.h>
66 #include <epan/epan.h>
67 #include <epan/filesystem.h>
68 #include <wsutil/privileges.h>
69 #include <epan/epan_dissect.h>
70 #include <epan/timestamp.h>
71 #include <epan/plugins.h>
72 #include <epan/dfilter/dfilter.h>
73 #include <epan/strutil.h>
74 #include <epan/addr_resolv.h>
75 #include <epan/emem.h>
76 #include <epan/ex-opt.h>
77 #include <epan/funnel.h>
78 #include <epan/expert.h>
79 #include <epan/frequency-utils.h>
80 #include <epan/prefs.h>
81 #include <epan/prefs-int.h>
83 #include <epan/stat_cmd_args.h>
85 #include <epan/column.h>
87 /* general (not GTK specific) */
89 #include "../summary.h"
90 #include "../filters.h"
91 #include "../disabled_protos.h"
93 #include "../color_filters.h"
95 #include "../register.h"
96 #include "../ringbuffer.h"
98 #include "../clopts_common.h"
99 #include "../cmdarg_err.h"
100 #include "../version_info.h"
101 #include "../merge.h"
105 #include "gtk_iface_monitor.h"
107 #include "ui/alert_box.h"
108 #include "ui/main_statusbar.h"
109 #include "ui/preference_utils.h"
110 #include "ui/recent.h"
111 #include "ui/recent_utils.h"
112 #include "ui/software_update.h"
113 #include "ui/simple_dialog.h"
114 #include "ui/ui_util.h"
117 #include "ui/capture_globals.h"
118 #include "ui/iface_lists.h"
121 #include <wsutil/file_util.h>
124 #include "capture_ui_utils.h"
125 #include "capture-pcap-util.h"
126 #include "capture_ifinfo.h"
128 #include "capture_sync.h"
132 #include "capture-wpcap.h"
133 #include "capture_wpcap_packet.h"
134 #include <tchar.h> /* Needed for Unicode */
135 #include <wsutil/unicode-utils.h>
136 #include <commctrl.h>
137 #include <shellapi.h>
141 #include "ui/gtk/file_dlg.h"
142 #include "ui/gtk/gtkglobals.h"
143 #include "ui/gtk/color_utils.h"
144 #include "ui/gtk/gui_utils.h"
145 #include "ui/gtk/color_dlg.h"
146 #include "ui/gtk/filter_dlg.h"
147 #include "ui/gtk/fileset_dlg.h"
148 #include "ui/gtk/uat_gui.h"
149 #include "ui/gtk/main.h"
150 #include "ui/gtk/main_80211_toolbar.h"
151 #include "ui/gtk/main_airpcap_toolbar.h"
152 #include "ui/gtk/main_filter_toolbar.h"
153 #include "ui/gtk/main_titlebar.h"
154 #include "ui/gtk/menus.h"
155 #include "ui/gtk/main_menubar_private.h"
156 #include "ui/gtk/macros_dlg.h"
157 #include "ui/gtk/main_statusbar_private.h"
158 #include "ui/gtk/main_toolbar.h"
159 #include "ui/gtk/main_toolbar_private.h"
160 #include "ui/gtk/main_welcome.h"
161 #include "ui/gtk/drag_and_drop.h"
162 #include "ui/gtk/capture_file_dlg.h"
163 #include "ui/gtk/packet_panes.h"
164 #include "ui/gtk/keys.h"
165 #include "ui/gtk/packet_win.h"
166 #include "ui/gtk/stock_icons.h"
167 #include "ui/gtk/find_dlg.h"
168 #include "ui/gtk/follow_tcp.h"
169 #include "ui/gtk/font_utils.h"
170 #include "ui/gtk/about_dlg.h"
171 #include "ui/gtk/help_dlg.h"
172 #include "ui/gtk/decode_as_dlg.h"
173 #include "ui/gtk/webbrowser.h"
174 #include "ui/gtk/capture_dlg.h"
175 #include "ui/gtk/capture_if_dlg.h"
176 #include "ui/gtk/tap_param_dlg.h"
177 #include "ui/gtk/prefs_column.h"
178 #include "ui/gtk/prefs_dlg.h"
179 #include "ui/gtk/proto_help.h"
180 #include "ui/gtk/packet_list.h"
181 #include "ui/gtk/filter_expression_save_dlg.h"
183 #include "ui/gtk/old-gtk-compat.h"
187 #include "wsiconcap.h"
192 #include "airpcap_loader.h"
193 #include "airpcap_dlg.h"
194 #include "airpcap_gui_utils.h"
197 #include <epan/crypt/airpdcap_ws.h>
200 #ifdef HAVE_GTKOSXAPPLICATION
201 #include <gtkmacintegration/gtkosxapplication.h>
205 * Files under personal and global preferences directories in which
206 * GTK settings for Wireshark are stored.
208 #define RC_FILE "gtkrc"
212 static gboolean capture_stopping;
214 /* "exported" main widgets */
215 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
217 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
218 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
219 static GtkWidget *main_first_pane, *main_second_pane;
221 /* internally used widgets */
222 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
224 GtkWidget *wireless_tb;
226 int airpcap_dll_ret_val = -1;
229 GString *comp_info_str, *runtime_info_str;
231 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
233 static guint tap_update_timer_id;
235 static void console_log_handler(const char *log_domain,
236 GLogLevelFlags log_level, const char *message, gpointer user_data);
238 static void create_main_window(gint, gint, gint, e_prefs*);
239 static void show_main_window(gboolean);
240 static void main_save_window_geometry(GtkWidget *widget);
243 /* Match selected byte pattern */
245 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
247 char *cur_filter, *new_filter;
249 if ((!text) || (0 == strlen(text))) {
250 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
256 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
258 switch (action&MATCH_SELECTED_MASK) {
260 case MATCH_SELECTED_REPLACE:
261 new_filter = g_strdup(text);
264 case MATCH_SELECTED_AND:
265 if ((!cur_filter) || (0 == strlen(cur_filter)))
266 new_filter = g_strdup(text);
268 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
271 case MATCH_SELECTED_OR:
272 if ((!cur_filter) || (0 == strlen(cur_filter)))
273 new_filter = g_strdup(text);
275 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
278 case MATCH_SELECTED_NOT:
279 new_filter = g_strconcat("!(", text, ")", NULL);
282 case MATCH_SELECTED_AND_NOT:
283 if ((!cur_filter) || (0 == strlen(cur_filter)))
284 new_filter = g_strconcat("!(", text, ")", NULL);
286 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
289 case MATCH_SELECTED_OR_NOT:
290 if ((!cur_filter) || (0 == strlen(cur_filter)))
291 new_filter = g_strconcat("!(", text, ")", NULL);
293 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
297 g_assert_not_reached();
302 /* Free up the copy we got of the old filter text. */
305 /* Don't change the current display filter if we only want to copy the filter */
306 if (action&MATCH_SELECTED_COPY_ONLY) {
307 GString *gtk_text_str = g_string_new("");
308 g_string_append(gtk_text_str, new_filter);
309 copy_to_clipboard(gtk_text_str);
310 g_string_free(gtk_text_str, TRUE);
312 /* create a new one and set the display filter entry accordingly */
313 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
315 /* Run the display filter so it goes in effect. */
316 if (action&MATCH_SELECTED_APPLY_NOW)
317 main_filter_packets(&cfile, new_filter, FALSE);
320 /* Free up the new filter text. */
325 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
329 if (cfile.finfo_selected) {
330 filter = proto_construct_match_selected_string(cfile.finfo_selected,
332 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
337 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
341 if (cfile.finfo_selected) {
342 filter = proto_construct_match_selected_string(cfile.finfo_selected,
344 if ((!filter) || (0 == strlen(filter))) {
345 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
346 "Could not acquire information to build a filter!\n"
347 "Try expanding or choosing another item.");
352 color_display_with_filter(filter);
355 color_filters_reset_tmp();
357 color_filters_set_tmp(filt_nr,filter, FALSE);
359 packet_list_colorize_packets();
365 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
367 gchar *selected_proto_url;
368 gchar *proto_abbrev = (gchar *)data;
373 if (cfile.finfo_selected) {
374 /* open wiki page using the protocol abbreviation */
375 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
376 browser_open_url(selected_proto_url);
377 g_free(selected_proto_url);
380 case(ESD_BTN_CANCEL):
383 g_assert_not_reached();
389 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
392 const gchar *proto_abbrev;
396 if (cfile.finfo_selected) {
397 /* convert selected field to protocol abbreviation */
398 /* XXX - could this conversion be simplified? */
399 field_id = cfile.finfo_selected->hfinfo->id;
400 /* if the selected field isn't a protocol, get its parent */
401 if(!proto_registrar_is_protocol(field_id)) {
402 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
405 proto_abbrev = proto_registrar_get_abbrev(field_id);
407 if (!proto_is_private(field_id)) {
408 /* ask the user if the wiki page really should be opened */
409 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
410 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
412 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
414 "The Wireshark Wiki is a collaborative approach to provide information "
415 "about Wireshark in several ways (not limited to protocol specifics).\n"
417 "This Wiki is new, so the page of the selected protocol "
418 "may not exist and/or may not contain valuable information.\n"
420 "As everyone can edit the Wiki and add new content (or extend existing), "
421 "you are encouraged to add information if you can.\n"
423 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
425 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
426 "which will save you a lot of editing and will give a consistent look over the pages.",
427 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
428 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
430 /* appologize to the user that the wiki page cannot be opened */
431 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
432 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
434 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
436 "Since this is a private protocol, such information is not available in "
437 "a public wiki. Therefore this wiki entry is blocked.\n"
439 "Sorry for the inconvenience.\n",
440 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
445 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
447 gchar *selected_proto_url;
448 gchar *proto_abbrev = (gchar *)data;
452 if (cfile.finfo_selected) {
453 /* open reference page using the protocol abbreviation */
454 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
455 browser_open_url(selected_proto_url);
456 g_free(selected_proto_url);
459 case(ESD_BTN_CANCEL):
462 g_assert_not_reached();
467 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
470 const gchar *proto_abbrev;
474 if (cfile.finfo_selected) {
475 /* convert selected field to protocol abbreviation */
476 /* XXX - could this conversion be simplified? */
477 field_id = cfile.finfo_selected->hfinfo->id;
478 /* if the selected field isn't a protocol, get its parent */
479 if(!proto_registrar_is_protocol(field_id)) {
480 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
483 proto_abbrev = proto_registrar_get_abbrev(field_id);
485 if (!proto_is_private(field_id)) {
486 /* ask the user if the wiki page really should be opened */
487 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
488 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
490 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
492 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
493 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
495 /* appologize to the user that the wiki page cannot be opened */
496 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
497 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
499 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
501 "Since this is a private protocol, such information is not available on "
502 "a public website. Therefore this filter entry is blocked.\n"
504 "Sorry for the inconvenience.\n",
505 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
511 is_address_column (gint column)
513 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
514 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
515 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
516 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
517 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
526 get_ip_address_list_from_packet_list_row(gpointer data)
528 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
529 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
532 GList *addr_list = NULL;
534 fdata = (frame_data *) packet_list_get_row_data(row);
539 if (!cf_read_frame (&cfile, fdata))
540 return NULL; /* error reading the frame */
542 epan_dissect_init(&edt, FALSE, FALSE);
543 col_custom_prime_edt(&edt, &cfile.cinfo);
545 epan_dissect_run(&edt, &cfile.phdr, cfile.pd, fdata, &cfile.cinfo);
546 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
548 /* First check selected column */
549 if (is_address_column (column)) {
550 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
553 for (col = 0; col < cfile.cinfo.num_cols; col++) {
554 /* Then check all columns except the selected */
555 if ((col != column) && (is_address_column (col))) {
556 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
560 epan_dissect_cleanup(&edt);
567 get_filter_from_packet_list_row_and_column(gpointer data)
569 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
570 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
574 fdata = (frame_data *) packet_list_get_row_data(row);
579 if (!cf_read_frame(&cfile, fdata))
580 return NULL; /* error reading the frame */
581 /* proto tree, visible. We need a proto tree if there's custom columns */
582 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
583 col_custom_prime_edt(&edt, &cfile.cinfo);
585 epan_dissect_run(&edt, &cfile.phdr, cfile.pd, fdata, &cfile.cinfo);
586 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
588 if ((cfile.cinfo.col_custom_occurrence[column]) ||
589 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
591 /* Only construct the filter when a single occurrence is displayed
592 * otherwise we might end up with a filter like "ip.proto==1,6".
594 * Or do we want to be able to filter on multiple occurrences so that
595 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
598 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
599 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
600 /* leak a little but safer than ep_ here */
601 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
602 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
603 if (hfi && hfi->parent == -1) {
605 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
606 } else if (hfi && hfi->type == FT_STRING) {
607 /* Custom string, add quotes */
608 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
609 cfile.cinfo.col_expr.col_expr_val[column]);
613 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
614 cfile.cinfo.col_expr.col_expr_val[column]);
619 epan_dissect_cleanup(&edt);
626 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
628 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
630 get_filter_from_packet_list_row_and_column((GtkWidget *)data));
633 /* This function allows users to right click in the details window and copy the text
634 * information to the operating systems clipboard.
636 * We first check to see if a string representation is setup in the tree and then
637 * read the string. If not available then we try to grab the value. If all else
638 * fails we display a message to the user to indicate the copy could not be completed.
641 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
643 GString *gtk_text_str = g_string_new("");
644 char labelstring[ITEM_LABEL_LENGTH];
645 char *stringpointer = labelstring;
649 case COPY_SELECTED_DESCRIPTION:
650 if (cfile.finfo_selected->rep &&
651 strlen (cfile.finfo_selected->rep->representation) > 0) {
652 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
655 case COPY_SELECTED_FIELDNAME:
656 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
657 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
660 case COPY_SELECTED_VALUE:
661 if (cfile.edt !=0 ) {
662 g_string_append(gtk_text_str,
663 get_node_field_value(cfile.finfo_selected, cfile.edt));
670 if (gtk_text_str->len == 0) {
671 /* If no representation then... Try to read the value */
672 proto_item_fill_label(cfile.finfo_selected, stringpointer);
673 g_string_append(gtk_text_str, stringpointer);
676 if (gtk_text_str->len == 0) {
677 /* Could not get item so display error msg */
678 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
680 /* Copy string to clipboard */
681 copy_to_clipboard(gtk_text_str);
683 g_string_free(gtk_text_str, TRUE); /* Free the memory */
687 /* mark as reference time frame */
689 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
693 frame->flags.ref_time=1;
694 cfile.ref_time_count++;
696 frame->flags.ref_time=0;
697 cfile.ref_time_count--;
699 cf_reftime_packets(&cfile);
700 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
701 packet_list_freeze();
702 cfile.displayed_count--;
703 packet_list_recreate_visible_rows();
706 packet_list_queue_draw();
710 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
714 timestamp_set_type(TS_RELATIVE);
715 recent.gui_time_format = TS_RELATIVE;
716 cf_timestamp_auto_precision(&cfile);
717 packet_list_queue_draw();
722 g_assert_not_reached();
725 if (cfile.current_frame) {
726 set_frame_reftime(!cfile.current_frame->flags.ref_time,
727 cfile.current_frame, cfile.current_row);
733 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
735 static GtkWidget *reftime_dialog = NULL;
739 if (cfile.current_frame) {
740 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
741 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
742 "%sSwitch to the appropriate Time Display Format?%s\n\n"
743 "Time References don't work well with the currently selected Time Display Format.\n\n"
744 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
745 simple_dialog_primary_start(), simple_dialog_primary_end());
746 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
748 set_frame_reftime(!cfile.current_frame->flags.ref_time,
749 cfile.current_frame, cfile.current_row);
753 case REFTIME_FIND_NEXT:
754 cf_find_packet_time_reference(&cfile, SD_FORWARD);
756 case REFTIME_FIND_PREV:
757 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
763 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
765 cf_find_packet_marked(&cfile, SD_FORWARD);
769 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
771 cf_find_packet_marked(&cfile, SD_BACKWARD);
775 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
778 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
780 gboolean has_blurb = FALSE;
781 guint length = 0, byte_len;
782 GtkWidget *byte_view;
783 const guint8 *byte_data;
788 /* if nothing is selected */
789 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
792 * Which byte view is displaying the current protocol tree
795 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
796 if (byte_view == NULL)
799 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
800 if (byte_data == NULL)
803 cf_unselect_field(&cfile);
804 packet_hex_print(byte_view, byte_data,
805 cfile.current_frame, NULL, byte_len);
806 proto_help_menu_modify(sel, &cfile);
809 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
812 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
814 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
815 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
816 g_assert(byte_data != NULL);
818 cfile.finfo_selected = finfo;
819 set_menus_for_selected_tree_row(&cfile);
822 if (finfo->hfinfo->blurb != NULL &&
823 finfo->hfinfo->blurb[0] != '\0') {
825 length = (guint) strlen(finfo->hfinfo->blurb);
827 length = (guint) strlen(finfo->hfinfo->name);
829 finfo_length = finfo->length + finfo->appendix_length;
831 if (finfo_length == 0) {
833 } else if (finfo_length == 1) {
834 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
836 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
838 statusbar_pop_field_msg(); /* get rid of current help msg */
840 statusbar_push_field_msg(" %s (%s)%s",
841 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
842 finfo->hfinfo->abbrev, len_str);
845 * Don't show anything if the field name is zero-length;
846 * the pseudo-field for "proto_tree_add_text()" is such
847 * a field, and we don't want "Text (text)" showing up
848 * on the status line if you've selected such a field.
850 * XXX - there are zero-length fields for which we *do*
851 * want to show the field name.
853 * XXX - perhaps the name and abbrev field should be null
854 * pointers rather than null strings for that pseudo-field,
855 * but we'd have to add checks for null pointers in some
856 * places if we did that.
858 * Or perhaps protocol tree items added with
859 * "proto_tree_add_text()" should have -1 as the field index,
860 * with no pseudo-field being used, but that might also
861 * require special checks for -1 to be added.
863 statusbar_push_field_msg("%s", "");
866 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
868 proto_help_menu_modify(sel, &cfile);
871 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
873 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
876 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
878 expand_all_tree(cfile.edt->tree, tree_view_gbl);
881 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
883 if (cfile.finfo_selected) {
884 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
885 cfile.finfo_selected->hfinfo->abbrev,0);
886 /* Recreate the packet list according to new preferences */
887 packet_list_recreate ();
888 if (!prefs.gui_use_pref_save) {
891 cfile.columns_changed = FALSE; /* Reset value */
895 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
898 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
900 /* the mouse position is at an entry, expand that one */
901 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
902 gtk_tree_path_free(path);
906 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
907 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
909 if (cfile.edt->tree) {
910 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
914 /* Update main window items based on whether there's a capture in progress. */
916 main_set_for_capture_in_progress(gboolean capture_in_progress)
918 set_menus_for_capture_in_progress(capture_in_progress);
921 set_toolbar_for_capture_in_progress(capture_in_progress);
923 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
927 /* Update main window items based on whether we have a capture file. */
929 main_set_for_capture_file(gboolean have_capture_file_in)
931 have_capture_file = have_capture_file_in;
933 main_widgets_show_or_hide();
936 /* Update main window items based on whether we have captured packets. */
938 main_set_for_captured_packets(gboolean have_captured_packets)
940 set_menus_for_captured_packets(have_captured_packets);
941 set_toolbar_for_captured_packets(have_captured_packets);
944 /* Update main window items based on whether we have a packet history. */
946 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
948 set_menus_for_packet_history(back_history, forward_history);
949 set_toolbar_for_packet_history(back_history, forward_history);
955 /* get the current geometry, before writing it to disk */
956 main_save_window_geometry(top_level);
958 /* write user's recent file to disk
959 * It is no problem to write this file, even if we do not quit */
960 write_profile_recent();
963 /* XXX - should we check whether the capture file is an
964 unsaved temporary file for a live capture and, if so,
965 pop up a "do you want to exit without saving the capture
966 file?" dialog, and then just return, leaving said dialog
967 box to forcibly quit if the user clicks "OK"?
969 If so, note that this should be done in a subroutine that
970 returns TRUE if we do so, and FALSE otherwise, and if it
971 returns TRUE we should return TRUE without nuking anything.
973 Note that, if we do that, we might also want to check if
974 an "Update list of packets in real time" capture is in
975 progress and, if so, ask whether they want to terminate
976 the capture and discard it, and return TRUE, before nuking
977 any child capture, if they say they don't want to do so. */
980 /* Nuke any child capture in progress. */
981 capture_kill_child(&global_capture_opts);
984 /* Are we in the middle of reading a capture? */
985 if (cfile.state == FILE_READ_IN_PROGRESS) {
986 /* Yes, so we can't just close the file and quit, as
987 that may yank the rug out from under the read in
988 progress; instead, just set the state to
989 "FILE_READ_ABORTED" and return - the code doing the read
990 will check for that and, if it sees that, will clean
992 cfile.state = FILE_READ_ABORTED;
994 /* Say that the window should *not* be deleted;
995 that'll be done by the code that cleans up. */
998 /* Close any capture file we have open; on some OSes, you
999 can't unlink a temporary capture file if you have it
1001 "cf_close()" will unlink it after closing it if
1002 it's a temporary file.
1004 We do this here, rather than after the main loop returns,
1005 as, after the main loop returns, the main window may have
1006 been destroyed (if this is called due to a "destroy"
1007 even on the main window rather than due to the user
1008 selecting a menu item), and there may be a crash
1009 or other problem when "cf_close()" tries to
1010 clean up stuff in the main window.
1012 XXX - is there a better place to put this?
1013 Or should we have a routine that *just* closes the
1014 capture file, and doesn't do anything with the UI,
1015 which we'd call here, and another routine that
1016 calls that routine and also cleans up the UI, which
1017 we'd call elsewhere? */
1020 /* Exit by leaving the main loop, so that any quit functions
1021 we registered get called. */
1024 /* Say that the window should be deleted. */
1030 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1032 /* If we're in the middle of stopping a capture, don't do anything;
1033 the user can try deleting the window after the capture stops. */
1034 if (capture_stopping)
1037 /* If there's unsaved data, let the user save it first.
1038 If they cancel out of it, don't quit. */
1039 if (do_file_close(&cfile, TRUE, " before quitting"))
1040 return main_do_quit();
1042 return TRUE; /* will this keep the window from being deleted? */
1047 main_pane_load_window_geometry(void)
1049 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1050 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1051 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1052 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1058 main_load_window_geometry(GtkWidget *widget)
1060 window_geometry_t geom;
1062 geom.set_pos = prefs.gui_geometry_save_position;
1063 geom.x = recent.gui_geometry_main_x;
1064 geom.y = recent.gui_geometry_main_y;
1065 geom.set_size = prefs.gui_geometry_save_size;
1066 if (recent.gui_geometry_main_width > 0 &&
1067 recent.gui_geometry_main_height > 0) {
1068 geom.width = recent.gui_geometry_main_width;
1069 geom.height = recent.gui_geometry_main_height;
1070 geom.set_maximized = prefs.gui_geometry_save_maximized;
1072 /* We assume this means the width and height weren't set in
1073 the "recent" file (or that there is no "recent" file),
1074 and weren't set to a default value, so we don't set the
1075 size. (The "recent" file code rejects non-positive width
1076 and height values.) */
1077 geom.set_size = FALSE;
1079 geom.maximized = recent.gui_geometry_main_maximized;
1081 window_set_geometry(widget, &geom);
1083 main_pane_load_window_geometry();
1084 statusbar_load_window_geometry();
1089 main_save_window_geometry(GtkWidget *widget)
1091 window_geometry_t geom;
1093 window_get_geometry(widget, &geom);
1095 if (prefs.gui_geometry_save_position) {
1096 recent.gui_geometry_main_x = geom.x;
1097 recent.gui_geometry_main_y = geom.y;
1100 if (prefs.gui_geometry_save_size) {
1101 recent.gui_geometry_main_width = geom.width;
1102 recent.gui_geometry_main_height = geom.height;
1105 if(prefs.gui_geometry_save_maximized) {
1106 recent.gui_geometry_main_maximized = geom.maximized;
1109 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1110 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1111 statusbar_save_window_geometry();
1115 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1117 /* If there's unsaved data, let the user save it first. */
1118 if (do_file_close(&cfile, TRUE, " before quitting"))
1123 print_usage(gboolean print_ver) {
1133 fprintf(output, "Wireshark " VERSION "%s\n"
1134 "Interactively dump and analyze network traffic.\n"
1135 "See http://www.wireshark.org for more information.\n"
1138 wireshark_svnversion, get_copyright_info());
1142 fprintf(output, "\n");
1143 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1144 fprintf(output, "\n");
1147 fprintf(output, "Capture interface:\n");
1148 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1149 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1150 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1151 fprintf(output, " -p don't capture in promiscuous mode\n");
1152 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1153 fprintf(output, " -S update packet display when new packets are captured\n");
1154 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1155 #ifdef HAVE_PCAP_CREATE
1156 fprintf(output, " -I capture in monitor mode, if available\n");
1158 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1159 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1161 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1162 fprintf(output, " -D print list of interfaces and exit\n");
1163 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1164 fprintf(output, "\n");
1165 fprintf(output, "Capture stop conditions:\n");
1166 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1167 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1168 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1169 fprintf(output, " files:NUM - stop after NUM files\n");
1170 /*fprintf(output, "\n");*/
1171 fprintf(output, "Capture output:\n");
1172 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1173 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1174 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1175 #endif /* HAVE_LIBPCAP */
1176 #ifdef HAVE_PCAP_REMOTE
1177 fprintf(output, "RPCAP options:\n");
1178 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1180 /*fprintf(output, "\n");*/
1181 fprintf(output, "Input file:\n");
1182 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1184 fprintf(output, "\n");
1185 fprintf(output, "Processing:\n");
1186 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1187 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1188 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1190 fprintf(output, "\n");
1191 fprintf(output, "User interface:\n");
1192 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1193 fprintf(output, " -Y <display filter> start with the given display filter\n");
1194 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1195 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1196 fprintf(output, " filter\n");
1197 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1198 fprintf(output, " -m <font> set the font name used for most text\n");
1199 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1200 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1201 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1202 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1204 fprintf(output, "\n");
1205 fprintf(output, "Output:\n");
1206 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1208 fprintf(output, "\n");
1209 fprintf(output, "Miscellaneous:\n");
1210 fprintf(output, " -h display this help and exit\n");
1211 fprintf(output, " -v display version info and exit\n");
1212 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1213 fprintf(output, " persdata:path - personal data files\n");
1214 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1215 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1217 fprintf(output, " --display=DISPLAY X display to use\n");
1232 printf(PACKAGE " " VERSION "%s\n"
1239 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1240 runtime_info_str->str);
1248 * Print to the standard error. On Windows, create a console for the
1249 * standard error to show up on, if necessary.
1250 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1251 * terminal isn't the standard error?
1254 vfprintf_stderr(const char *fmt, va_list ap)
1259 vfprintf(stderr, fmt, ap);
1263 fprintf_stderr(const char *fmt, ...)
1268 vfprintf_stderr(fmt, ap);
1273 * Report an error in command-line arguments.
1274 * Creates a console on Windows.
1277 cmdarg_err(const char *fmt, ...)
1281 fprintf_stderr("wireshark: ");
1283 vfprintf_stderr(fmt, ap);
1285 fprintf_stderr("\n");
1289 * Report additional information for an error in command-line arguments.
1290 * Creates a console on Windows.
1291 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1292 * terminal isn't the standard error?
1295 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);
1316 /* Restart the tap update display timer with new configured interval */
1317 void reset_tap_update_timer(void)
1319 g_source_remove(tap_update_timer_id);
1320 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1324 * Periodically process outstanding hostname lookups. If we have new items,
1325 * redraw the packet list and tree view.
1329 resolv_update_cb(gpointer data _U_)
1331 /* Anything new show up? */
1332 if (host_name_lookup_process()) {
1333 if (gtk_widget_get_window(pkt_scrollw))
1334 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1335 if (gtk_widget_get_window(tv_scrollw))
1336 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1339 /* Always check. Even if we don't do async lookups we could still get
1340 passive updates, e.g. from DNS packets. */
1345 /* Set main_window_name and its icon title to the capture filename */
1347 set_titlebar_for_capture_file(capture_file *cf)
1349 gchar *display_name;
1353 display_name = cf_get_display_name(cf);
1354 window_name = g_strdup_printf("%s%s", cf->unsaved_changes ? "*" : "",
1356 g_free(display_name);
1357 main_set_window_name(window_name);
1358 g_free(window_name);
1360 main_set_window_name("The Wireshark Network Analyzer");
1364 /* Update various parts of the main window for a capture file "unsaved
1365 changes" change - update the title to reflect whether there are
1366 unsaved changes or not, and update the menus and toolbar to
1367 enable or disable the "Save" operation. */
1369 main_update_for_unsaved_changes(capture_file *cf)
1371 set_titlebar_for_capture_file(cf);
1372 set_menus_for_capture_file(cf);
1373 set_toolbar_for_capture_file(cf);
1378 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1380 /* Update menubar and toolbar */
1381 menu_auto_scroll_live_changed(auto_scroll_live_in);
1382 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1384 /* change auto scroll state */
1385 auto_scroll_live = auto_scroll_live_in;
1390 main_colorize_changed(gboolean packet_list_colorize)
1392 /* Update menubar and toolbar */
1393 menu_colorize_changed(packet_list_colorize);
1394 toolbar_colorize_changed(packet_list_colorize);
1396 /* change colorization */
1397 if(packet_list_colorize != recent.packet_list_colorize) {
1398 recent.packet_list_colorize = packet_list_colorize;
1399 color_filters_enable(packet_list_colorize);
1400 packet_list_colorize_packets();
1404 static GtkWidget *close_dlg = NULL;
1407 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1409 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1414 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1416 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1421 main_cf_cb_file_closing(capture_file *cf)
1423 /* if we have more than 10000 packets, show a splash screen while closing */
1424 /* XXX - don't know a better way to decide whether to show or not,
1425 * as most of the time is spend in various calls that destroy various
1426 * data structures, so it wouldn't be easy to use a progress bar,
1427 * rather than, say, a progress spinner, here! */
1428 if(cf->count > 10000) {
1429 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1430 "%sClosing file!%s\n\nPlease wait ...",
1431 simple_dialog_primary_start(),
1432 simple_dialog_primary_end());
1433 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1436 /* Destroy all windows that refer to the
1437 capture file we're closing. */
1438 destroy_packet_wins();
1440 /* Restore the standard title bar message. */
1441 main_set_window_name("The Wireshark Network Analyzer");
1443 /* Disable all menu items that make sense only if you have a capture. */
1444 set_menus_for_capture_file(NULL);
1445 set_toolbar_for_capture_file(NULL);
1446 main_set_for_captured_packets(FALSE);
1447 set_menus_for_selected_packet(cf);
1448 main_set_for_capture_in_progress(FALSE);
1449 set_capture_if_dialog_for_capture_in_progress(FALSE);
1450 set_menus_for_selected_tree_row(cf);
1452 /* Set up main window for no capture file. */
1453 main_set_for_capture_file(FALSE);
1455 main_window_update();
1459 main_cf_cb_file_closed(capture_file *cf _U_)
1461 if(close_dlg != NULL) {
1462 splash_destroy(close_dlg);
1469 main_cf_cb_file_read_started(capture_file *cf _U_)
1471 tap_param_dlg_update();
1473 /* Set up main window for a capture file. */
1474 main_set_for_capture_file(TRUE);
1478 main_cf_cb_file_read_finished(capture_file *cf)
1482 if (!cf->is_tempfile && cf->filename) {
1483 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1484 add_menu_recent_capture_file(cf->filename);
1486 /* Remember folder for next Open dialog and save it in recent */
1487 dir_path = get_dirname(g_strdup(cf->filename));
1488 set_last_open_dir(dir_path);
1492 /* Update the appropriate parts of the main window. */
1493 main_update_for_unsaved_changes(cf);
1495 /* Enable menu items that make sense if you have some captured packets. */
1496 main_set_for_captured_packets(TRUE);
1500 main_cf_cb_file_rescan_finished(capture_file *cf)
1504 if (!cf->is_tempfile && cf->filename) {
1505 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1506 add_menu_recent_capture_file(cf->filename);
1508 /* Remember folder for next Open dialog and save it in recent */
1509 dir_path = get_dirname(g_strdup(cf->filename));
1510 set_last_open_dir(dir_path);
1514 /* Update the appropriate parts of the main window. */
1515 main_update_for_unsaved_changes(cf);
1519 static GList *icon_list_create(
1520 const guint8 *icon16_pb,
1521 const guint8 *icon32_pb,
1522 const guint8 *icon48_pb,
1523 const guint8 *icon64_pb)
1525 GList *icon_list = NULL;
1526 GdkPixbuf * pixbuf16;
1527 GdkPixbuf * pixbuf32;
1528 GdkPixbuf * pixbuf48;
1529 GdkPixbuf * pixbuf64;
1532 if(icon16_pb != NULL) {
1533 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1535 icon_list = g_list_append(icon_list, pixbuf16);
1538 if(icon32_pb != NULL) {
1539 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1541 icon_list = g_list_append(icon_list, pixbuf32);
1544 if(icon48_pb != NULL) {
1545 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1547 icon_list = g_list_append(icon_list, pixbuf48);
1550 if(icon64_pb != NULL) {
1551 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1553 icon_list = g_list_append(icon_list, pixbuf64);
1560 main_capture_set_main_window_title(capture_options *capture_opts)
1562 GString *title = g_string_new("");
1564 g_string_append(title, "Capturing ");
1565 g_string_append_printf(title, "from %s ", cf_get_tempfile_source((capture_file *)capture_opts->cf));
1566 main_set_window_name(title->str);
1567 g_string_free(title, TRUE);
1571 main_capture_cb_capture_prepared(capture_options *capture_opts)
1573 static GList *icon_list = NULL;
1575 main_capture_set_main_window_title(capture_opts);
1577 if(icon_list == NULL) {
1578 icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1580 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1582 /* Disable menu items that make no sense if you're currently running
1584 main_set_for_capture_in_progress(TRUE);
1585 set_capture_if_dialog_for_capture_in_progress(TRUE);
1587 /* Don't set up main window for a capture file. */
1588 main_set_for_capture_file(FALSE);
1592 main_capture_cb_capture_update_started(capture_options *capture_opts)
1594 /* We've done this in "prepared" above, but it will be cleared while
1595 switching to the next multiple file. */
1596 main_capture_set_main_window_title(capture_opts);
1598 main_set_for_capture_in_progress(TRUE);
1599 set_capture_if_dialog_for_capture_in_progress(TRUE);
1601 /* Enable menu items that make sense if you have some captured
1602 packets (yes, I know, we don't have any *yet*). */
1603 main_set_for_captured_packets(TRUE);
1605 /* Set up main window for a capture file. */
1606 main_set_for_capture_file(TRUE);
1610 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1612 capture_file *cf = (capture_file *)capture_opts->cf;
1613 static GList *icon_list = NULL;
1615 /* The capture isn't stopping any more - it's stopped. */
1616 capture_stopping = FALSE;
1618 if (!cf->is_tempfile && cf->filename) {
1619 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1620 add_menu_recent_capture_file(cf->filename);
1623 /* Enable menu items that make sense if you're not currently running
1625 main_set_for_capture_in_progress(FALSE);
1626 set_capture_if_dialog_for_capture_in_progress(FALSE);
1628 /* Update the main window as appropriate. This has to occur AFTER
1629 * main_set_for_capture_in_progress() or else some of the menus are
1630 * incorrectly disabled (see bug
1631 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1632 main_update_for_unsaved_changes(cf);
1634 /* Set up main window for a capture file. */
1635 main_set_for_capture_file(TRUE);
1637 if(icon_list == NULL) {
1638 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1640 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1642 if(global_capture_opts.quit_after_cap) {
1643 /* command line asked us to quit after the capture */
1644 /* don't pop up a dialog to ask for unsaved files etc. */
1650 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1652 /* Don't set up main window for a capture file. */
1653 main_set_for_capture_file(FALSE);
1657 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1660 capture_file *cf = capture_opts->cf;
1662 static GList *icon_list = NULL;
1664 /* The capture isn't stopping any more - it's stopped. */
1665 capture_stopping = FALSE;
1667 /*set_titlebar_for_capture_file(cf);*/
1669 /* Enable menu items that make sense if you're not currently running
1671 main_set_for_capture_in_progress(FALSE);
1672 set_capture_if_dialog_for_capture_in_progress(FALSE);
1674 /* Restore the standard title bar message */
1675 /* (just in case we have trouble opening the capture file). */
1676 main_set_window_name("The Wireshark Network Analyzer");
1678 if(icon_list == NULL) {
1679 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1681 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1683 /* We don't have loaded the capture file, this will be done later.
1684 * For now we still have simply a blank screen. */
1686 if(global_capture_opts.quit_after_cap) {
1687 /* command line asked us to quit after the capture */
1688 /* don't pop up a dialog to ask for unsaved files etc. */
1694 main_capture_cb_capture_stopping(capture_options *capture_opts _U_)
1696 capture_stopping = TRUE;
1697 set_menus_for_capture_stopping();
1699 set_toolbar_for_capture_stopping();
1701 set_capture_if_dialog_for_capture_stopping();
1706 main_capture_cb_capture_failed(capture_options *capture_opts _U_)
1708 static GList *icon_list = NULL;
1710 /* Capture isn't stopping any more. */
1711 capture_stopping = FALSE;
1713 /* the capture failed before the first packet was captured
1714 reset title, menus and icon */
1716 main_set_window_name("The Wireshark Network Analyzer");
1718 main_set_for_capture_in_progress(FALSE);
1719 set_capture_if_dialog_for_capture_in_progress(FALSE);
1721 main_set_for_capture_file(FALSE);
1723 if(icon_list == NULL) {
1724 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1726 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1729 if(global_capture_opts.quit_after_cap) {
1730 /* command line asked us to quit after the capture */
1731 /* don't pop up a dialog to ask for unsaved files etc. */
1735 #endif /* HAVE_LIBPCAP */
1738 main_cf_cb_packet_selected(gpointer data)
1740 capture_file *cf = (capture_file *)data;
1742 /* Display the GUI protocol tree and packet bytes.
1743 XXX - why do we dump core if we call "proto_tree_draw()"
1744 before calling "add_byte_views()"? */
1745 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1746 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1748 /* Note: Both string and hex value searches in the packet data produce a non-zero
1749 search_pos if successful */
1750 if(cf->search_in_progress &&
1751 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1752 highlight_field(cf->edt->tvb, cf->search_pos,
1753 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1756 /* A packet is selected. */
1757 set_menus_for_selected_packet(cf);
1761 main_cf_cb_packet_unselected(capture_file *cf)
1763 /* No packet is being displayed; clear the hex dump pane by getting
1764 rid of all the byte views. */
1765 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1766 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1768 /* Add a placeholder byte view so that there's at least something
1769 displayed in the byte view notebook. */
1770 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1772 /* And clear the protocol tree display as well. */
1773 proto_tree_draw(NULL, tree_view_gbl);
1775 /* No packet is selected. */
1776 set_menus_for_selected_packet(cf);
1780 main_cf_cb_field_unselected(capture_file *cf)
1782 set_menus_for_selected_tree_row(cf);
1786 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1788 capture_file *cf = (capture_file *)data;
1790 case(cf_cb_file_opened):
1791 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1792 fileset_file_opened(cf);
1794 case(cf_cb_file_closing):
1795 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1796 main_cf_cb_file_closing(cf);
1798 case(cf_cb_file_closed):
1799 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1800 main_cf_cb_file_closed(cf);
1801 fileset_file_closed();
1803 case(cf_cb_file_read_started):
1804 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1805 main_cf_cb_file_read_started(cf);
1807 case(cf_cb_file_read_finished):
1808 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1809 main_cf_cb_file_read_finished(cf);
1811 case(cf_cb_file_reload_started):
1812 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1813 main_cf_cb_file_read_started(cf);
1815 case(cf_cb_file_reload_finished):
1816 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1817 main_cf_cb_file_read_finished(cf);
1819 case(cf_cb_file_rescan_started):
1820 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1822 case(cf_cb_file_rescan_finished):
1823 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1824 main_cf_cb_file_rescan_finished(cf);
1826 case(cf_cb_file_fast_save_finished):
1827 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1828 main_cf_cb_file_rescan_finished(cf);
1830 case(cf_cb_packet_selected):
1831 main_cf_cb_packet_selected(cf);
1833 case(cf_cb_packet_unselected):
1834 main_cf_cb_packet_unselected(cf);
1836 case(cf_cb_field_unselected):
1837 main_cf_cb_field_unselected(cf);
1839 case(cf_cb_file_save_started):
1840 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1842 case(cf_cb_file_save_finished):
1843 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1845 case(cf_cb_file_save_failed):
1846 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1848 case(cf_cb_file_save_stopped):
1849 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1851 case(cf_cb_file_export_specified_packets_started):
1852 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1854 case(cf_cb_file_export_specified_packets_finished):
1855 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1857 case(cf_cb_file_export_specified_packets_failed):
1858 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1860 case(cf_cb_file_export_specified_packets_stopped):
1861 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1864 g_warning("main_cf_callback: event %u unknown", event);
1865 g_assert_not_reached();
1871 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1873 #ifdef HAVE_GTKOSXAPPLICATION
1874 GtkosxApplication *theApp;
1877 case(capture_cb_capture_prepared):
1878 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1879 main_capture_cb_capture_prepared(capture_opts);
1881 case(capture_cb_capture_update_started):
1882 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1883 main_capture_cb_capture_update_started(capture_opts);
1884 #ifdef HAVE_GTKOSXAPPLICATION
1885 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1886 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1889 case(capture_cb_capture_update_continue):
1890 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1892 case(capture_cb_capture_update_finished):
1893 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1894 main_capture_cb_capture_update_finished(capture_opts);
1896 case(capture_cb_capture_fixed_started):
1897 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1898 main_capture_cb_capture_fixed_started(capture_opts);
1900 case(capture_cb_capture_fixed_continue):
1901 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1903 case(capture_cb_capture_fixed_finished):
1904 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1905 main_capture_cb_capture_fixed_finished(capture_opts);
1907 case(capture_cb_capture_stopping):
1908 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1909 /* Beware: this state won't be called, if the capture child
1910 * closes the capturing on its own! */
1911 #ifdef HAVE_GTKOSXAPPLICATION
1912 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1913 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1915 main_capture_cb_capture_stopping(capture_opts);
1917 case(capture_cb_capture_failed):
1918 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1919 main_capture_cb_capture_failed(capture_opts);
1922 g_warning("main_capture_callback: event %u unknown", event);
1923 g_assert_not_reached();
1929 get_gtk_compiled_info(GString *str)
1931 g_string_append(str, "with ");
1932 g_string_append_printf(str,
1933 #ifdef GTK_MAJOR_VERSION
1934 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1937 "GTK+ (version unknown)");
1939 g_string_append(str, ", ");
1941 g_string_append(str, "with Cairo ");
1942 g_string_append(str, CAIRO_VERSION_STRING);
1943 g_string_append(str, ", ");
1946 g_string_append(str, "with Pango ");
1947 g_string_append(str, PANGO_VERSION_STRING);
1948 g_string_append(str, ", ");
1954 get_gui_compiled_info(GString *str)
1956 epan_get_compiled_version_info(str);
1958 g_string_append(str, ", ");
1959 #ifdef HAVE_LIBPORTAUDIO
1960 #ifdef PORTAUDIO_API_1
1961 g_string_append(str, "with PortAudio <= V18");
1962 #else /* PORTAUDIO_API_1 */
1963 g_string_append(str, "with ");
1964 g_string_append(str, Pa_GetVersionText());
1965 #endif /* PORTAUDIO_API_1 */
1966 #else /* HAVE_LIBPORTAUDIO */
1967 g_string_append(str, "without PortAudio");
1968 #endif /* HAVE_LIBPORTAUDIO */
1970 g_string_append(str, ", ");
1972 get_compiled_airpcap_version(str);
1974 g_string_append(str, "without AirPcap");
1979 get_gui_runtime_info(GString *str)
1981 epan_get_runtime_version_info(str);
1984 g_string_append(str, ", ");
1985 get_runtime_airpcap_version(str);
1989 g_string_append(str, ", ");
1990 u3_runtime_info(str);
1995 read_configuration_files(char **gdp_path, char **dp_path)
1997 int gpf_open_errno, gpf_read_errno;
1998 int cf_open_errno, df_open_errno;
1999 int gdp_open_errno, gdp_read_errno;
2000 int dp_open_errno, dp_read_errno;
2001 char *gpf_path, *pf_path;
2002 char *cf_path, *df_path;
2003 int pf_open_errno, pf_read_errno;
2006 /* load the decode as entries of this profile */
2007 load_decode_as_entries();
2009 /* Read the preference files. */
2010 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2011 &pf_open_errno, &pf_read_errno, &pf_path);
2013 if (gpf_path != NULL) {
2014 if (gpf_open_errno != 0) {
2015 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2016 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2017 g_strerror(gpf_open_errno));
2019 if (gpf_read_errno != 0) {
2020 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2021 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2022 g_strerror(gpf_read_errno));
2025 if (pf_path != NULL) {
2026 if (pf_open_errno != 0) {
2027 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2028 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2029 g_strerror(pf_open_errno));
2031 if (pf_read_errno != 0) {
2032 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2033 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2034 g_strerror(pf_read_errno));
2041 /* if the user wants a console to be always there, well, we should open one for him */
2042 if (prefs_p->gui_console_open == console_open_always) {
2047 /* Read the capture filter file. */
2048 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2049 if (cf_path != NULL) {
2050 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2051 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2052 g_strerror(cf_open_errno));
2056 /* Read the display filter file. */
2057 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2058 if (df_path != NULL) {
2059 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2060 "Could not open your display filter file\n\"%s\": %s.", df_path,
2061 g_strerror(df_open_errno));
2065 /* Read the disabled protocols file. */
2066 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2067 dp_path, &dp_open_errno, &dp_read_errno);
2068 if (*gdp_path != NULL) {
2069 if (gdp_open_errno != 0) {
2070 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2071 "Could not open global disabled protocols file\n\"%s\": %s.",
2072 *gdp_path, g_strerror(gdp_open_errno));
2074 if (gdp_read_errno != 0) {
2075 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2076 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2077 *gdp_path, g_strerror(gdp_read_errno));
2082 if (*dp_path != NULL) {
2083 if (dp_open_errno != 0) {
2084 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2085 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2086 g_strerror(dp_open_errno));
2088 if (dp_read_errno != 0) {
2089 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2090 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2091 g_strerror(dp_read_errno));
2100 /* Check if there's something important to tell the user during startup.
2101 * We want to do this *after* showing the main window so that any windows
2102 * we pop up will be above the main window.
2106 check_and_warn_user_startup(gchar *cf_name)
2108 check_and_warn_user_startup(gchar *cf_name _U_)
2111 gchar *cur_user, *cur_group;
2112 gpointer priv_warning_dialog;
2114 /* Tell the user not to run as root. */
2115 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2116 cur_user = get_cur_username();
2117 cur_group = get_cur_groupname();
2118 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2119 "Running as user \"%s\" and group \"%s\".\n"
2120 "This could be dangerous.\n\n"
2121 "If you're running Wireshark this way in order to perform live capture, "
2122 "you may want to be aware that there is a better way documented at\n"
2123 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2126 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2127 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2131 /* Warn the user if npf.sys isn't loaded. */
2132 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2133 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2134 "The NPF driver isn't running. You may have trouble\n"
2135 "capturing or listing interfaces.");
2136 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2137 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2144 /* And now our feature presentation... [ fade to music ] */
2146 main(int argc, char *argv[])
2148 char *init_progfile_dir_error;
2151 gboolean arg_error = FALSE;
2153 extern int info_update_freq; /* Found in about_dlg.c. */
2154 const gchar *filter;
2162 char *gdp_path, *dp_path;
2165 gboolean start_capture = FALSE;
2166 gboolean list_link_layer_types = FALSE;
2170 gboolean capture_option_specified = FALSE;
2177 gint pl_size = 280, tv_size = 95, bv_size = 75;
2178 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2179 dfilter_t *rfcode = NULL;
2180 gboolean rfilter_parse_failed = FALSE;
2183 GtkWidget *splash_win = NULL;
2184 GLogLevelFlags log_flags;
2185 guint go_to_packet = 0;
2186 search_direction jump_backwards = SD_FORWARD;
2187 dfilter_t *jump_to_filter = NULL;
2190 #ifdef HAVE_GTKOSXAPPLICATION
2191 GtkosxApplication *theApp;
2195 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2196 #define OPTSTRING_B "B:"
2198 #define OPTSTRING_B ""
2199 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2200 #else /* HAVE_LIBPCAP */
2201 #define OPTSTRING_B ""
2202 #endif /* HAVE_LIBPCAP */
2203 #ifdef HAVE_PCAP_REMOTE
2204 #define OPTSTRING_A "A:"
2206 #define OPTSTRING_A ""
2208 #ifdef HAVE_PCAP_CREATE
2209 #define OPTSTRING_I "I"
2211 #define OPTSTRING_I ""
2214 #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:"
2216 static const char optstring[] = OPTSTRING;
2219 /* Set the C-language locale to the native environment. */
2220 setlocale(LC_ALL, "");
2222 arg_list_utf_16to8(argc, argv);
2223 create_app_running_mutex();
2227 * Get credential information for later use, and drop privileges
2228 * before doing anything else.
2229 * Let the user know if anything happened.
2231 init_process_policies();
2232 relinquish_special_privs_perm();
2235 * Attempt to get the pathname of the executable file.
2237 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2239 /* initialize the funnel mini-api */
2240 initialize_funnel_ops();
2242 AirPDcapInitContext(&airpdcap_ctx);
2245 /* Load wpcap if possible. Do this before collecting the run-time version information */
2248 /* ... and also load the packet.dll from wpcap */
2249 wpcap_packet_load();
2252 /* Load the airpcap.dll. This must also be done before collecting
2253 * run-time version information. */
2254 airpcap_dll_ret_val = load_airpcap();
2256 switch (airpcap_dll_ret_val) {
2257 case AIRPCAP_DLL_OK:
2258 /* load the airpcap interfaces */
2259 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2261 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2262 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2263 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2266 airpcap_if_active = NULL;
2270 /* select the first ad default (THIS SHOULD BE CHANGED) */
2271 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2276 * XXX - Maybe we need to warn the user if one of the following happens???
2278 case AIRPCAP_DLL_OLD:
2279 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2282 case AIRPCAP_DLL_ERROR:
2283 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2286 case AIRPCAP_DLL_NOT_FOUND:
2287 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2291 #endif /* HAVE_AIRPCAP */
2294 /* Assemble the compile-time version information string */
2295 comp_info_str = g_string_new("Compiled ");
2297 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2299 /* Assemble the run-time version information string */
2300 runtime_info_str = g_string_new("Running ");
2301 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2304 ws_add_crash_info(PACKAGE " " VERSION "%s\n"
2309 wireshark_svnversion, comp_info_str->str, runtime_info_str->str);
2311 /* Start windows sockets */
2312 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2315 profile_store_persconffiles (TRUE);
2317 /* Read the profile independent recent file. We have to do this here so we can */
2318 /* set the profile before it can be set from the command line parameterts */
2319 recent_read_static(&rf_path, &rf_open_errno);
2320 if (rf_path != NULL && rf_open_errno != 0) {
2321 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2322 "Could not open common recent file\n\"%s\": %s.",
2323 rf_path, g_strerror(rf_open_errno));
2326 /* "pre-scan" the command line parameters, if we have "console only"
2327 parameters. We do this so we don't start GTK+ if we're only showing
2328 command-line help or version information.
2330 XXX - this pre-scan is done before we start GTK+, so we haven't
2331 run gtk_init() on the arguments. That means that GTK+ arguments
2332 have not been removed from the argument list; those arguments
2333 begin with "--", and will be treated as an error by getopt().
2335 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2338 optind_initial = optind;
2339 while ((opt = getopt(argc, argv, optstring)) != -1) {
2341 case 'C': /* Configuration Profile */
2342 if (profile_exists (optarg, FALSE)) {
2343 set_profile_name (optarg);
2345 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2349 case 'D': /* Print a list of capture devices and exit */
2351 if_list = capture_interface_list(&err, &err_str);
2352 if (if_list == NULL) {
2354 case CANT_GET_INTERFACE_LIST:
2355 case DONT_HAVE_PCAP:
2356 cmdarg_err("%s", err_str);
2360 case NO_INTERFACES_FOUND:
2361 cmdarg_err("There are no interfaces on which a capture can be done");
2366 capture_opts_print_interfaces(if_list);
2367 free_interface_list(if_list);
2370 capture_option_specified = TRUE;
2374 case 'h': /* Print help and exit */
2380 if (strcmp(optarg, "-") == 0)
2381 set_stdin_capture(TRUE);
2384 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2385 status = filesystem_opt(opt, optarg);
2387 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2391 case 'v': /* Show version and exit */
2397 * Extension command line options have to be processed before
2398 * we call epan_init() as they are supposed to be used by dissectors
2399 * or taps very early in the registration process.
2403 case '?': /* Ignore errors - the "real" scan will catch them. */
2408 /* Init the "Open file" dialog directory */
2409 /* (do this after the path settings are processed) */
2411 /* Read the profile dependent (static part) of the recent file. */
2412 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2413 /* recent lists which is done in the dynamic part. */
2414 /* We have to do this already here, so command line parameters can overwrite these values. */
2415 recent_read_profile_static(&rf_path, &rf_open_errno);
2416 if (rf_path != NULL && rf_open_errno != 0) {
2417 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2418 "Could not open recent file\n\"%s\": %s.",
2419 rf_path, g_strerror(rf_open_errno));
2422 if (recent.gui_fileopen_remembered_dir &&
2423 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2424 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2426 set_last_open_dir(get_persdatafile_dir());
2429 /* Set getopt index back to initial value, so it will start with the
2430 first command line parameter again. Also reset opterr to 1, so that
2431 error messages are printed by getopt().
2433 XXX - this seems to work on most platforms, but time will tell.
2434 The Single UNIX Specification says "The getopt() function need
2435 not be reentrant", so this isn't guaranteed to work. The Mac
2436 OS X 10.4[.x] getopt() man page says
2438 In order to use getopt() to evaluate multiple sets of arguments, or to
2439 evaluate a single set of arguments multiple times, the variable optreset
2440 must be set to 1 before the second and each additional set of calls to
2441 getopt(), and the variable optind must be reinitialized.
2445 The optreset variable was added to make it possible to call the getopt()
2446 function multiple times. This is an extension to the IEEE Std 1003.2
2447 (``POSIX.2'') specification.
2449 which I think comes from one of the other BSDs.
2451 XXX - if we want to control all the command-line option errors, so
2452 that we can display them where we choose (e.g., in a window), we'd
2453 want to leave opterr as 0, and produce our own messages using optopt.
2454 We'd have to check the value of optopt to see if it's a valid option
2455 letter, in which case *presumably* the error is "this option requires
2456 an argument but none was specified", or not a valid option letter,
2457 in which case *presumably* the error is "this option isn't valid".
2458 Some versions of getopt() let you supply a option string beginning
2459 with ':', which means that getopt() will return ':' rather than '?'
2460 for "this option requires an argument but none was specified", but
2462 optind = optind_initial;
2465 #if !GLIB_CHECK_VERSION(2,31,0)
2466 g_thread_init(NULL);
2469 /* Set the current locale according to the program environment.
2470 * We haven't localized anything, but some GTK widgets are localized
2471 * (the file selection dialogue, for example).
2472 * This also sets the C-language locale to the native environment. */
2473 setlocale (LC_ALL, "");
2475 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2476 gtk_init (&argc, &argv);
2478 cf_callback_add(main_cf_callback, NULL);
2480 capture_callback_add(main_capture_callback, NULL);
2482 cf_callback_add(statusbar_cf_callback, NULL);
2484 capture_callback_add(statusbar_capture_callback, NULL);
2487 /* Arrange that if we have no console window, and a GLib message logging
2488 routine is called to log a message, we pop up a console window.
2490 We do that by inserting our own handler for all messages logged
2491 to the default domain; that handler pops up a console if necessary,
2492 and then calls the default handler. */
2494 /* We might want to have component specific log levels later ... */
2496 log_flags = (GLogLevelFlags)
2498 G_LOG_LEVEL_CRITICAL|
2499 G_LOG_LEVEL_WARNING|
2500 G_LOG_LEVEL_MESSAGE|
2503 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION);
2505 g_log_set_handler(NULL,
2507 console_log_handler, NULL /* user_data */);
2508 g_log_set_handler(LOG_DOMAIN_MAIN,
2510 console_log_handler, NULL /* user_data */);
2513 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2515 console_log_handler, NULL /* user_data */);
2516 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2518 console_log_handler, NULL /* user_data */);
2520 /* Set the initial values in the capture options. This might be overwritten
2521 by preference settings and then again by the command line parameters. */
2522 capture_opts_init(&global_capture_opts, &cfile);
2525 /* Initialize whatever we need to allocate colors for GTK+ */
2528 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2529 filter = get_conn_cfilter();
2530 if ( *filter != '\0' ) {
2531 info_update_freq = 1000; /* Milliseconds */
2534 /* We won't come till here, if we had a "console only" command line parameter. */
2535 splash_win = splash_new("Loading Wireshark ...");
2536 if (init_progfile_dir_error != NULL) {
2537 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2538 "Can't get pathname of Wireshark: %s.\n"
2539 "It won't be possible to capture traffic.\n"
2540 "Report this to the Wireshark developers.",
2541 init_progfile_dir_error);
2542 g_free(init_progfile_dir_error);
2545 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2547 /* Register all dissectors; we must do this before checking for the
2548 "-G" flag, as the "-G" flag dumps information registered by the
2549 dissectors, and we must do it before we read the preferences, in
2550 case any dissectors register preferences. */
2551 epan_init(register_all_protocols,register_all_protocol_handoffs,
2552 splash_update, (gpointer) splash_win,
2553 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2554 write_failure_alert_box);
2556 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2558 /* Register all tap listeners; we do this before we parse the arguments,
2559 as the "-z" argument can specify a registered tap. */
2561 /* we register the plugin taps before the other taps because
2562 stats_tree taps plugins will be registered as tap listeners
2563 by stats_tree_stat.c and need to registered before that */
2566 register_all_plugin_tap_listeners();
2569 register_all_tap_listeners();
2571 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2573 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2574 /* Removed thread code:
2575 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2578 /* this is to keep tap extensions updating once every 3 seconds */
2579 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2581 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2583 cap_file_init(&cfile);
2585 /* Fill in capture options with values from the preferences */
2586 prefs_to_capture_opts();
2588 /*#ifdef HAVE_LIBPCAP
2589 fill_in_local_interfaces();
2591 /* Now get our args */
2592 while ((opt = getopt(argc, argv, optstring)) != -1) {
2594 /*** capture option specific ***/
2595 case 'a': /* autostop criteria */
2596 case 'b': /* Ringbuffer option */
2597 case 'c': /* Capture xxx packets */
2598 case 'f': /* capture filter */
2599 case 'k': /* Start capture immediately */
2600 case 'H': /* Hide capture info dialog box */
2601 case 'p': /* Don't capture in promiscuous mode */
2602 case 'i': /* Use interface x */
2603 #ifdef HAVE_PCAP_CREATE
2604 case 'I': /* Capture in monitor mode, if available */
2606 #ifdef HAVE_PCAP_REMOTE
2607 case 'A': /* Authentication */
2609 case 's': /* Set the snapshot (capture) length */
2610 case 'S': /* "Sync" mode: used for following file ala tail -f */
2611 case 'w': /* Write to capture file xxx */
2612 case 'y': /* Set the pcap data link type */
2613 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2614 case 'B': /* Buffer size */
2615 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2617 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2623 capture_option_specified = TRUE;
2628 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2629 case 'K': /* Kerberos keytab file */
2630 read_keytab_file(optarg);
2634 /*** all non capture option specific ***/
2636 /* Configuration profile settings were already processed just ignore them this time*/
2638 case 'j': /* Search backwards for a matching packet from filter in option J */
2639 jump_backwards = SD_BACKWARD;
2641 case 'g': /* Go to packet with the given packet number */
2642 go_to_packet = get_positive_int(optarg, "go to packet");
2644 case 'J': /* Jump to the first packet which matches the filter criteria */
2647 case 'l': /* Automatic scrolling in live capture mode */
2649 auto_scroll_live = TRUE;
2651 capture_option_specified = TRUE;
2655 case 'L': /* Print list of link-layer types and exit */
2657 list_link_layer_types = TRUE;
2659 capture_option_specified = TRUE;
2663 case 'm': /* Fixed-width font for the display */
2664 g_free(prefs_p->gui_gtk2_font_name);
2665 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2667 case 'n': /* No name resolution */
2668 gbl_resolv_flags.mac_name = FALSE;
2669 gbl_resolv_flags.network_name = FALSE;
2670 gbl_resolv_flags.transport_name = FALSE;
2671 gbl_resolv_flags.concurrent_dns = FALSE;
2673 case 'N': /* Select what types of addresses/port #s to resolve */
2674 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2675 if (badopt != '\0') {
2676 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2681 case 'o': /* Override preference from command line */
2682 switch (prefs_set_pref(optarg)) {
2685 case PREFS_SET_SYNTAX_ERR:
2686 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2689 case PREFS_SET_NO_SUCH_PREF:
2690 /* not a preference, might be a recent setting */
2691 switch (recent_set_arg(optarg)) {
2694 case PREFS_SET_SYNTAX_ERR:
2695 /* shouldn't happen, checked already above */
2696 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2699 case PREFS_SET_NO_SUCH_PREF:
2700 case PREFS_SET_OBSOLETE:
2701 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2706 g_assert_not_reached();
2709 case PREFS_SET_OBSOLETE:
2710 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2715 g_assert_not_reached();
2719 /* Path settings were already processed just ignore them this time*/
2721 case 'r': /* Read capture file xxx */
2722 /* We may set "last_open_dir" to "cf_name", and if we change
2723 "last_open_dir" later, we free the old value, so we have to
2724 set "cf_name" to something that's been allocated. */
2725 cf_name = g_strdup(optarg);
2727 case 'R': /* Read file filter */
2730 case 't': /* Time stamp type */
2731 if (strcmp(optarg, "r") == 0)
2732 timestamp_set_type(TS_RELATIVE);
2733 else if (strcmp(optarg, "a") == 0)
2734 timestamp_set_type(TS_ABSOLUTE);
2735 else if (strcmp(optarg, "ad") == 0)
2736 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2737 else if (strcmp(optarg, "d") == 0)
2738 timestamp_set_type(TS_DELTA);
2739 else if (strcmp(optarg, "dd") == 0)
2740 timestamp_set_type(TS_DELTA_DIS);
2741 else if (strcmp(optarg, "e") == 0)
2742 timestamp_set_type(TS_EPOCH);
2743 else if (strcmp(optarg, "u") == 0)
2744 timestamp_set_type(TS_UTC);
2745 else if (strcmp(optarg, "ud") == 0)
2746 timestamp_set_type(TS_UTC_WITH_DATE);
2748 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2749 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2750 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2754 case 'u': /* Seconds type */
2755 if (strcmp(optarg, "s") == 0)
2756 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2757 else if (strcmp(optarg, "hms") == 0)
2758 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2760 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2761 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2766 /* ext ops were already processed just ignore them this time*/
2772 /* We won't call the init function for the stat this soon
2773 as it would disallow MATE's fields (which are registered
2774 by the preferences set callback) from being used as
2775 part of a tap filter. Instead, we just add the argument
2776 to a list of stat arguments. */
2777 if (!process_stat_cmd_arg(optarg)) {
2778 cmdarg_err("Invalid -z argument.");
2779 cmdarg_err_cont(" -z argument must be one of :");
2780 list_stat_cmd_args();
2785 case '?': /* Bad flag - print usage message */
2794 if (cf_name != NULL) {
2796 * Input file name specified with "-r" *and* specified as a regular
2797 * command-line argument.
2799 cmdarg_err("File name specified both with -r and regular argument");
2803 * Input file name not specified with "-r", and a command-line argument
2804 * was specified; treat it as the input file name.
2806 * Yes, this is different from tshark, where non-flag command-line
2807 * arguments are a filter, but this works better on GUI desktops
2808 * where a command can be specified to be run to open a particular
2809 * file - yes, you could have "-r" as the last part of the command,
2810 * but that's a bit ugly.
2812 #ifndef HAVE_GTKOSXAPPLICATION
2814 * For GTK+ Mac Integration, file name passed as free argument passed
2815 * through grag-and-drop and opened twice sometimes causing crashes.
2816 * Subject to report to GTK+ MAC.
2818 cf_name = g_strdup(argv[0]);
2827 * Extra command line arguments were specified; complain.
2829 cmdarg_err("Invalid argument: %s", argv[0]);
2834 #ifndef HAVE_LIBPCAP
2835 if (capture_option_specified) {
2836 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2844 fill_in_local_interfaces();
2845 if (start_capture && list_link_layer_types) {
2846 /* Specifying *both* is bogus. */
2847 cmdarg_err("You can't specify both -L and a live capture.");
2851 if (list_link_layer_types) {
2852 /* We're supposed to list the link-layer types for an interface;
2853 did the user also specify a capture file to be read? */
2855 /* Yes - that's bogus. */
2856 cmdarg_err("You can't specify -L and a capture file to be read.");
2859 /* No - did they specify a ring buffer option? */
2860 if (global_capture_opts.multi_files_on) {
2861 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2865 /* We're supposed to do a live capture; did the user also specify
2866 a capture file to be read? */
2867 if (start_capture && cf_name) {
2868 /* Yes - that's bogus. */
2869 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2873 /* No - was the ring buffer option specified and, if so, does it make
2875 if (global_capture_opts.multi_files_on) {
2876 /* Ring buffer works only under certain conditions:
2877 a) ring buffer does not work with temporary files;
2878 b) real_time_mode and multi_files_on are mutually exclusive -
2879 real_time_mode takes precedence;
2880 c) it makes no sense to enable the ring buffer if the maximum
2881 file size is set to "infinite". */
2882 if (global_capture_opts.save_file == NULL) {
2883 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2884 global_capture_opts.multi_files_on = FALSE;
2886 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2887 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2888 /* XXX - this must be redesigned as the conditions changed */
2893 if (start_capture || list_link_layer_types) {
2894 /* Did the user specify an interface to use? */
2895 status = capture_opts_trim_iface(&global_capture_opts,
2896 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2902 if (list_link_layer_types) {
2903 /* Get the list of link-layer types for the capture devices. */
2904 if_capabilities_t *caps;
2907 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2909 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2910 if (device.selected) {
2911 #if defined(HAVE_PCAP_CREATE)
2912 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2914 caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2917 cmdarg_err("%s", err_str);
2921 if (caps->data_link_types == NULL) {
2922 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2925 #if defined(HAVE_PCAP_CREATE)
2926 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2928 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2930 free_if_capabilities(caps);
2936 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2937 capture_opts_trim_ring_num_files(&global_capture_opts);
2938 #endif /* HAVE_LIBPCAP */
2940 /* Notify all registered modules that have had any of their preferences
2941 changed either from one of the preferences file or from the command
2942 line that their preferences have changed. */
2946 if ((global_capture_opts.num_selected == 0) &&
2947 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2950 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2951 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2952 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2953 device.selected = TRUE;
2954 global_capture_opts.num_selected++;
2955 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2956 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2963 /* disabled protocols as per configuration file */
2964 if (gdp_path == NULL && dp_path == NULL) {
2965 set_disabled_protos_list();
2968 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2970 /* read in rc file from global and personal configuration paths. */
2971 rc_file = get_datafile_path(RC_FILE);
2972 #if GTK_CHECK_VERSION(3,0,0)
2973 /* XXX resolve later */
2975 gtk_rc_parse(rc_file);
2977 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2978 gtk_rc_parse(rc_file);
2988 /* close the splash screen, as we are going to open the main window now */
2989 splash_destroy(splash_win);
2991 /************************************************************************/
2992 /* Everything is prepared now, preferences and command line was read in */
2994 /* Pop up the main window. */
2995 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2997 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2998 recent_read_dynamic(&rf_path, &rf_open_errno);
2999 if (rf_path != NULL && rf_open_errno != 0) {
3000 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3001 "Could not open recent file\n\"%s\": %s.",
3002 rf_path, g_strerror(rf_open_errno));
3005 color_filters_enable(recent.packet_list_colorize);
3007 /* rearrange all the widgets as we now have all recent settings ready for this */
3008 main_widgets_rearrange();
3010 /* Fill in column titles. This must be done after the top level window
3013 XXX - is that still true, with fixed-width columns? */
3015 menu_recent_read_finished();
3017 main_auto_scroll_live_changed(auto_scroll_live);
3020 switch (user_font_apply()) {
3023 case FA_FONT_NOT_RESIZEABLE:
3024 /* "user_font_apply()" popped up an alert box. */
3025 /* turn off zooming - font can't be resized */
3026 case FA_FONT_NOT_AVAILABLE:
3027 /* XXX - did we successfully load the un-zoomed version earlier?
3028 If so, this *probably* means the font is available, but not at
3029 this particular zoom level, but perhaps some other failure
3030 occurred; I'm not sure you can determine which is the case,
3032 /* turn off zooming - zoom level is unavailable */
3034 /* in any other case than FA_SUCCESS, turn off zooming */
3035 recent.gui_zoom_level = 0;
3036 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3039 dnd_init(top_level);
3041 color_filters_init();
3044 capture_filter_init();
3047 /* the window can be sized only, if it's not already shown, so do it now! */
3048 main_load_window_geometry(top_level);
3050 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3052 /* If we were given the name of a capture file, read it in now;
3053 we defer it until now, so that, if we can't open it, and pop
3054 up an alert box, the alert box is more likely to come up on
3055 top of the main window - but before the preference-file-error
3056 alert box, so, if we get one of those, it's more likely to come
3059 show_main_window(TRUE);
3060 check_and_warn_user_startup(cf_name);
3061 if (rfilter != NULL) {
3062 if (!dfilter_compile(rfilter, &rfcode)) {
3063 bad_dfilter_alert_box(top_level, rfilter);
3064 rfilter_parse_failed = TRUE;
3067 if (!rfilter_parse_failed) {
3068 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3069 /* "cf_open()" succeeded, so it closed the previous
3070 capture file, and thus destroyed any previous read filter
3071 attached to "cf". */
3073 cfile.rfcode = rfcode;
3074 /* Open stat windows; we do so after creating the main window,
3075 to avoid GTK warnings, and after successfully opening the
3076 capture file, so we know we have something to compute stats
3077 on, and after registering all dissectors, so that MATE will
3078 have registered its field array and we can have a tap filter
3079 with one of MATE's late-registered fields as part of the
3081 start_requested_stats();
3083 /* Read the capture file. */
3084 switch (cf_read(&cfile, FALSE)) {
3088 /* Just because we got an error, that doesn't mean we were unable
3089 to read any of the file; we handle what we could get from the
3091 /* if the user told us to jump to a specific packet, do it now */
3092 if(go_to_packet != 0) {
3093 /* Jump to the specified frame number, kept for backward
3095 cf_goto_frame(&cfile, go_to_packet);
3096 } else if (jfilter != NULL) {
3097 /* try to compile given filter */
3098 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3099 bad_dfilter_alert_box(top_level, jfilter);
3101 /* Filter ok, jump to the first packet matching the filter
3102 conditions. Default search direction is forward, but if
3103 option d was given, search backwards */
3104 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3109 case CF_READ_ABORTED:
3115 /* If the filename is not the absolute path, prepend the current dir. This happens
3116 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3117 if (!g_path_is_absolute(cf_name)) {
3118 char *old_cf_name = cf_name;
3119 char *pwd = g_get_current_dir();
3120 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3121 g_free(old_cf_name);
3125 /* Save the name of the containing directory specified in the
3126 path name, if any; we can write over cf_name, which is a
3127 good thing, given that "get_dirname()" does write over its
3129 s = get_dirname(cf_name);
3130 set_last_open_dir(s);
3135 dfilter_free(rfcode);
3136 cfile.rfcode = NULL;
3137 show_main_window(FALSE);
3138 /* Don't call check_and_warn_user_startup(): we did it above */
3139 main_set_for_capture_in_progress(FALSE);
3140 set_capture_if_dialog_for_capture_in_progress(FALSE);
3145 if (start_capture) {
3146 if (global_capture_opts.save_file != NULL) {
3147 /* Save the directory name for future file dialogs. */
3148 /* (get_dirname overwrites filename) */
3149 s = get_dirname(g_strdup(global_capture_opts.save_file));
3150 set_last_open_dir(s);
3153 /* "-k" was specified; start a capture. */
3154 show_main_window(FALSE);
3155 check_and_warn_user_startup(cf_name);
3157 /* If no user interfaces were specified on the command line,
3158 copy the list of selected interfaces to the set of interfaces
3159 to use for this capture. */
3160 if (global_capture_opts.ifaces->len == 0)
3161 collect_ifaces(&global_capture_opts);
3162 if (capture_start(&global_capture_opts)) {
3163 /* The capture started. Open stat windows; we do so after creating
3164 the main window, to avoid GTK warnings, and after successfully
3165 opening the capture file, so we know we have something to compute
3166 stats on, and after registering all dissectors, so that MATE will
3167 have registered its field array and we can have a tap filter with
3168 one of MATE's late-registered fields as part of the filter. */
3169 start_requested_stats();
3172 show_main_window(FALSE);
3173 check_and_warn_user_startup(cf_name);
3174 main_set_for_capture_in_progress(FALSE);
3175 set_capture_if_dialog_for_capture_in_progress(FALSE);
3178 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3179 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3180 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3182 #else /* HAVE_LIBPCAP */
3183 show_main_window(FALSE);
3184 check_and_warn_user_startup(cf_name);
3185 main_set_for_capture_in_progress(FALSE);
3186 set_capture_if_dialog_for_capture_in_progress(FALSE);
3187 #endif /* HAVE_LIBPCAP */
3191 GtkWidget *filter_te;
3192 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3193 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3195 /* Run the display filter so it goes in effect. */
3196 main_filter_packets(&cfile, dfilter, FALSE);
3200 /* register our pid if we are being run from a U3 device */
3203 profile_store_persconffiles (FALSE);
3205 #ifdef HAVE_GTKOSXAPPLICATION
3206 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3207 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3208 gtkosx_application_ready(theApp);
3211 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3214 gtk_iface_mon_start();
3217 software_update_init();
3219 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3221 /* ... back from GTK, we're going down now! */
3224 gtk_iface_mon_stop();
3227 /* deregister our pid */
3228 u3_deregister_pid();
3232 AirPDcapDestroyContext(&airpdcap_ctx);
3235 /* hide the (unresponsive) main window, while asking the user to close the console window */
3236 gtk_widget_hide(top_level);
3238 #ifdef HAVE_GTKOSXAPPLICATION
3239 g_object_unref(theApp);
3242 software_update_cleanup();
3244 /* Shutdown windows sockets */
3247 /* For some unknown reason, the "atexit()" call in "create_console()"
3248 doesn't arrange that "destroy_console()" be called when we exit,
3249 so we call it here if a console was created. */
3258 /* We build this as a GUI subsystem application on Win32, so
3259 "WinMain()", not "main()", gets called.
3261 Hack shamelessly stolen from the Win32 port of the GIMP. */
3263 #define _stdcall __attribute__((stdcall))
3267 WinMain (struct HINSTANCE__ *hInstance,
3268 struct HINSTANCE__ *hPrevInstance,
3272 INITCOMMONCONTROLSEX comm_ctrl;
3275 * Initialize our DLL search path. MUST be called before LoadLibrary
3278 ws_init_dll_search_path();
3280 /* Initialize our controls. Required for native Windows file dialogs. */
3281 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3282 comm_ctrl.dwSize = sizeof(comm_ctrl);
3283 /* Includes the animate, header, hot key, list view, progress bar,
3284 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3287 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3288 InitCommonControlsEx(&comm_ctrl);
3290 /* RichEd20.DLL is needed for filter entries. */
3291 ws_load_library("riched20.dll");
3293 set_has_console(FALSE);
3294 set_console_wait(FALSE);
3295 return main (__argc, __argv);
3302 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3303 const char *message, gpointer user_data _U_)
3310 /* ignore log message, if log_level isn't interesting based
3311 upon the console log preferences.
3312 If the preferences haven't been loaded loaded yet, display the
3315 The default console_log_level preference value is such that only
3316 ERROR, CRITICAL and WARNING level messages are processed;
3317 MESSAGE, INFO and DEBUG level messages are ignored. */
3318 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3319 prefs.console_log_level != 0) {
3324 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3325 /* the user wants a console or the application will terminate immediately */
3328 if (get_has_console()) {
3329 /* For some unknown reason, the above doesn't appear to actually cause
3330 anything to be sent to the standard output, so we'll just splat the
3331 message out directly, just to make sure it gets out. */
3333 switch(log_level & G_LOG_LEVEL_MASK) {
3334 case G_LOG_LEVEL_ERROR:
3337 case G_LOG_LEVEL_CRITICAL:
3340 case G_LOG_LEVEL_WARNING:
3343 case G_LOG_LEVEL_MESSAGE:
3346 case G_LOG_LEVEL_INFO:
3349 case G_LOG_LEVEL_DEBUG:
3353 fprintf(stderr, "unknown log_level %u\n", log_level);
3355 g_assert_not_reached();
3358 /* create a "timestamp" */
3360 today = localtime(&curr);
3362 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3363 today->tm_hour, today->tm_min, today->tm_sec,
3364 log_domain != NULL ? log_domain : "",
3367 if(log_level & G_LOG_LEVEL_ERROR) {
3368 /* wait for a key press before the following error handler will terminate the program
3369 this way the user at least can read the error message */
3370 printf("\n\nPress any key to exit\n");
3374 /* XXX - on UN*X, should we just use g_log_default_handler()?
3375 We want the error messages to go to the standard output;
3376 on Mac OS X, that will cause them to show up in various
3377 per-user logs accessible through Console (details depend
3378 on whether you're running 10.0 through 10.4 or running
3379 10.5 and later), and, on other UN*X desktop environments,
3380 if they don't show up in some form of console log, that's
3381 a deficiency in that desktop environment. (Too bad
3382 Windows doesn't set the standard output and error for
3383 GUI apps to something that shows up in such a log.) */
3384 g_log_default_handler(log_domain, log_level, message, user_data);
3391 * Helper for main_widgets_rearrange()
3393 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3394 gtk_container_remove(GTK_CONTAINER(data), widget);
3397 static GtkWidget *main_widget_layout(gint layout_content)
3399 switch(layout_content) {
3400 case(layout_pane_content_none):
3402 case(layout_pane_content_plist):
3404 case(layout_pane_content_pdetails):
3406 case(layout_pane_content_pbytes):
3407 return byte_nb_ptr_gbl;
3409 g_assert_not_reached();
3416 * Rearrange the main window widgets
3418 void main_widgets_rearrange(void) {
3419 GtkWidget *first_pane_widget1, *first_pane_widget2;
3420 GtkWidget *second_pane_widget1, *second_pane_widget2;
3421 gboolean split_top_left = FALSE;
3423 /* be a bit faster */
3424 gtk_widget_hide(main_vbox);
3426 /* be sure we don't lose a widget while rearranging */
3427 g_object_ref(G_OBJECT(menubar));
3428 g_object_ref(G_OBJECT(main_tb));
3429 g_object_ref(G_OBJECT(filter_tb));
3430 g_object_ref(G_OBJECT(wireless_tb));
3431 g_object_ref(G_OBJECT(pkt_scrollw));
3432 g_object_ref(G_OBJECT(tv_scrollw));
3433 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3434 g_object_ref(G_OBJECT(statusbar));
3435 g_object_ref(G_OBJECT(main_pane_v1));
3436 g_object_ref(G_OBJECT(main_pane_v2));
3437 g_object_ref(G_OBJECT(main_pane_h1));
3438 g_object_ref(G_OBJECT(main_pane_h2));
3439 g_object_ref(G_OBJECT(welcome_pane));
3441 /* empty all containers participating */
3442 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3443 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3444 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3445 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3446 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3448 statusbar_widgets_emptying(statusbar);
3450 /* add the menubar always at the top */
3451 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3454 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3456 /* filter toolbar in toolbar area */
3457 if (!prefs.filter_toolbar_show_in_statusbar) {
3458 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3461 /* airpcap toolbar */
3462 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3464 /* fill the main layout panes */
3465 switch(prefs.gui_layout_type) {
3466 case(layout_type_5):
3467 main_first_pane = main_pane_v1;
3468 main_second_pane = main_pane_v2;
3469 split_top_left = FALSE;
3471 case(layout_type_2):
3472 main_first_pane = main_pane_v1;
3473 main_second_pane = main_pane_h1;
3474 split_top_left = FALSE;
3476 case(layout_type_1):
3477 main_first_pane = main_pane_v1;
3478 main_second_pane = main_pane_h1;
3479 split_top_left = TRUE;
3481 case(layout_type_4):
3482 main_first_pane = main_pane_h1;
3483 main_second_pane = main_pane_v1;
3484 split_top_left = FALSE;
3486 case(layout_type_3):
3487 main_first_pane = main_pane_h1;
3488 main_second_pane = main_pane_v1;
3489 split_top_left = TRUE;
3491 case(layout_type_6):
3492 main_first_pane = main_pane_h1;
3493 main_second_pane = main_pane_h2;
3494 split_top_left = FALSE;
3497 main_first_pane = NULL;
3498 main_second_pane = NULL;
3499 g_assert_not_reached();
3501 if (split_top_left) {
3502 first_pane_widget1 = main_second_pane;
3503 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3504 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3505 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3507 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3508 first_pane_widget2 = main_second_pane;
3509 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3510 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3512 if (first_pane_widget1 != NULL)
3513 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3514 if (first_pane_widget2 != NULL)
3515 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3516 if (second_pane_widget1 != NULL)
3517 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3518 if (second_pane_widget2 != NULL)
3519 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3521 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3524 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3527 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3529 /* filter toolbar in statusbar hbox */
3530 if (prefs.filter_toolbar_show_in_statusbar) {
3531 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3534 /* statusbar widgets */
3535 statusbar_widgets_pack(statusbar);
3537 /* hide widgets on users recent settings */
3538 main_widgets_show_or_hide();
3540 gtk_widget_show(main_vbox);
3544 is_widget_visible(GtkWidget *widget, gpointer data)
3546 gboolean *is_visible = ( gboolean *)data;
3549 if (gtk_widget_get_visible(widget))
3556 main_widgets_show_or_hide(void)
3558 gboolean main_second_pane_show;
3560 if (recent.main_toolbar_show) {
3561 gtk_widget_show(main_tb);
3563 gtk_widget_hide(main_tb);
3566 statusbar_widgets_show_or_hide(statusbar);
3568 if (recent.filter_toolbar_show) {
3569 gtk_widget_show(filter_tb);
3571 gtk_widget_hide(filter_tb);
3574 if (recent.wireless_toolbar_show) {
3575 gtk_widget_show(wireless_tb);
3577 gtk_widget_hide(wireless_tb);
3580 if (recent.packet_list_show && have_capture_file) {
3581 gtk_widget_show(pkt_scrollw);
3583 gtk_widget_hide(pkt_scrollw);
3586 if (recent.tree_view_show && have_capture_file) {
3587 gtk_widget_show(tv_scrollw);
3589 gtk_widget_hide(tv_scrollw);
3592 if (recent.byte_view_show && have_capture_file) {
3593 gtk_widget_show(byte_nb_ptr_gbl);
3595 gtk_widget_hide(byte_nb_ptr_gbl);
3598 if (have_capture_file) {
3599 gtk_widget_show(main_first_pane);
3601 gtk_widget_hide(main_first_pane);
3605 * Is anything in "main_second_pane" visible?
3606 * If so, show it, otherwise hide it.
3608 main_second_pane_show = FALSE;
3609 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3610 &main_second_pane_show);
3611 if (main_second_pane_show) {
3612 gtk_widget_show(main_second_pane);
3614 gtk_widget_hide(main_second_pane);
3617 if (!have_capture_file) {
3619 gtk_widget_show(welcome_pane);
3622 gtk_widget_hide(welcome_pane);
3627 /* called, when the window state changes (minimized, maximized, ...) */
3629 window_state_event_cb (GtkWidget *widget _U_,
3633 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3635 if( (event->type) == (GDK_WINDOW_STATE)) {
3636 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3637 /* we might have dialogs popped up while we where iconified,
3639 display_queued_messages();
3647 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3649 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3651 if (event->keyval == GDK_F8) {
3654 } else if (event->keyval == GDK_F7) {
3657 } else if (event->state & NO_SHIFT_MOD_MASK) {
3658 return FALSE; /* Skip control, alt, and other modifiers */
3660 * A comment in gdkkeysyms.h says that it's autogenerated from
3661 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3662 * don't explicitly say so, isprint() should work as expected
3665 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3666 /* Forward the keypress on to the display filter entry */
3667 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3668 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3669 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3677 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3678 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3683 GtkAccelGroup *accel;
3686 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3687 main_set_window_name("The Wireshark Network Analyzer");
3689 gtk_widget_set_name(top_level, "main window");
3690 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3692 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3693 G_CALLBACK(window_state_event_cb), NULL);
3694 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3695 G_CALLBACK(top_level_key_pressed_cb), NULL );
3697 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3698 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3700 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3701 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3702 gtk_widget_show(main_vbox);
3705 menubar = main_menu_new(&accel);
3707 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3708 /* Mac OS X native menus are created and displayed by main_menu_new() */
3709 if(!prefs_p->gui_macosx_style) {
3711 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3712 gtk_widget_show(menubar);
3713 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3715 gtk_widget_hide(menubar);
3720 main_tb = toolbar_new();
3721 gtk_widget_show (main_tb);
3723 /* Filter toolbar */
3724 filter_tb = filter_toolbar_new();
3727 pkt_scrollw = packet_list_create();
3728 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3729 gtk_widget_show_all(pkt_scrollw);
3732 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3733 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3734 gtk_widget_show(tv_scrollw);
3736 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3737 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3738 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3739 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3740 gtk_widget_show(tree_view_gbl);
3743 byte_nb_ptr_gbl = byte_view_new();
3744 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3745 gtk_widget_show(byte_nb_ptr_gbl);
3747 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3748 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3750 /* Panes for the packet list, tree, and byte view */
3751 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3752 gtk_widget_show(main_pane_v1);
3753 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3754 gtk_widget_show(main_pane_v2);
3755 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3756 gtk_widget_show(main_pane_h1);
3757 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3758 gtk_widget_show(main_pane_h2);
3760 wireless_tb = airpcap_toolbar_new();
3762 wireless_tb = ws80211_toolbar_new();
3764 gtk_widget_show(wireless_tb);
3767 statusbar = statusbar_new();
3768 gtk_widget_show(statusbar);
3770 /* Pane for the welcome screen */
3771 welcome_pane = welcome_new();
3772 gtk_widget_show(welcome_pane);
3776 show_main_window(gboolean doing_work)
3778 main_set_for_capture_file(doing_work);
3780 /*** we have finished all init things, show the main window ***/
3781 gtk_widget_show(top_level);
3783 /* the window can be maximized only, if it's visible, so do it after show! */
3784 main_load_window_geometry(top_level);
3786 /* process all pending GUI events before continue */
3787 while (gtk_events_pending()) gtk_main_iteration();
3789 /* Pop up any queued-up alert boxes. */
3790 display_queued_messages();
3792 /* Move the main window to the front, in case it isn't already there */
3793 gdk_window_raise(gtk_widget_get_window(top_level));
3796 airpcap_toolbar_show(wireless_tb);
3797 #endif /* HAVE_AIRPCAP */
3800 static void copy_global_profile (const gchar *profile_name)
3802 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3804 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3805 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3806 "Can't create directory\n\"%s\":\n%s.",
3807 pf_dir_path, g_strerror(errno));
3809 g_free(pf_dir_path);
3812 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3813 &pf_dir_path, &pf_dir_path2) == -1) {
3814 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3815 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3816 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3818 g_free(pf_filename);
3819 g_free(pf_dir_path);
3820 g_free(pf_dir_path2);
3824 /* Change configuration profile */
3825 void change_configuration_profile (const gchar *profile_name)
3827 char *gdp_path, *dp_path;
3831 /* First check if profile exists */
3832 if (!profile_exists(profile_name, FALSE)) {
3833 if (profile_exists(profile_name, TRUE)) {
3834 /* Copy from global profile */
3835 copy_global_profile (profile_name);
3837 /* No personal and no global profile exists */
3842 /* Then check if changing to another profile */
3843 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3847 /* Get the current geometry, before writing it to disk */
3848 main_save_window_geometry(top_level);
3850 if (profile_exists(get_profile_name(), FALSE)) {
3851 /* Write recent file for profile we are leaving, if it still exists */
3852 write_profile_recent();
3855 /* Set profile name and update the status bar */
3856 set_profile_name (profile_name);
3857 profile_bar_update ();
3858 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3860 /* Reset current preferences and apply the new */
3864 (void) read_configuration_files (&gdp_path, &dp_path);
3866 recent_read_profile_static(&rf_path, &rf_open_errno);
3867 if (rf_path != NULL && rf_open_errno != 0) {
3868 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3869 "Could not open common recent file\n\"%s\": %s.",
3870 rf_path, g_strerror(rf_open_errno));
3872 if (recent.gui_fileopen_remembered_dir &&
3873 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3874 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3876 timestamp_set_type (recent.gui_time_format);
3877 timestamp_set_seconds_type (recent.gui_seconds_format);
3878 color_filters_enable(recent.packet_list_colorize);
3880 prefs_to_capture_opts();
3882 macros_post_update();
3884 /* Update window view and redraw the toolbar */
3885 main_titlebar_update();
3886 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3887 toolbar_redraw_all();
3889 /* Enable all protocols and disable from the disabled list */
3891 if (gdp_path == NULL && dp_path == NULL) {
3892 set_disabled_protos_list();
3895 /* Reload color filters */
3896 color_filters_reload();
3898 /* Reload list of interfaces on welcome page */
3899 welcome_if_panel_reload();
3901 /* Recreate the packet list according to new preferences */
3902 packet_list_recreate ();
3903 cfile.columns_changed = FALSE; /* Reset value */
3906 /* Update menus with new recent values */
3907 menu_recent_read_finished();
3909 /* Reload pane geometry, must be done after recreating the list */
3910 main_pane_load_window_geometry();
3913 /** redissect packets and update UI */
3914 void redissect_packets(void)
3916 cf_redissect_packets(&cfile);
3917 status_expert_update();