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.
34 #include <gdk/gdkkeysyms.h>
35 #if GTK_CHECK_VERSION(3,0,0)
36 # include <gdk/gdkkeysyms-compat.h>
49 #include "wsutil/wsgetopt.h"
52 #ifdef _WIN32 /* Needed for console I/O */
54 /* AttachConsole() needs this #define! */
55 #define _WIN32_WINNT 0x0501
61 #ifdef HAVE_LIBPORTAUDIO
62 #include <portaudio.h>
63 #endif /* HAVE_LIBPORTAUDIO */
65 #include <epan/epan.h>
66 #include <epan/filesystem.h>
67 #include <wsutil/privileges.h>
68 #include <epan/epan_dissect.h>
69 #include <epan/timestamp.h>
70 #include <epan/plugins.h>
71 #include <epan/dfilter/dfilter.h>
72 #include <epan/strutil.h>
73 #include <epan/addr_resolv.h>
74 #include <epan/emem.h>
75 #include <epan/ex-opt.h>
76 #include <epan/funnel.h>
77 #include <epan/expert.h>
78 #include <epan/frequency-utils.h>
79 #include <epan/prefs.h>
80 #include <epan/prefs-int.h>
82 #include <epan/stat_cmd_args.h>
84 #include <epan/column.h>
86 /* general (not GTK specific) */
88 #include "../summary.h"
89 #include "../filters.h"
90 #include "../disabled_protos.h"
92 #include "../color_filters.h"
94 #include "../register.h"
95 #include "../ringbuffer.h"
97 #include "../clopts_common.h"
98 #include "../console_io.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/recent.h"
110 #include "ui/recent_utils.h"
111 #include "ui/simple_dialog.h"
112 #include "ui/ui_util.h"
114 #include <wsutil/file_util.h>
117 #include "../capture_ui_utils.h"
118 #include "../capture-pcap-util.h"
119 #include "../capture_ifinfo.h"
120 #include "../capture.h"
121 #include "../capture_sync.h"
125 #include "../capture-wpcap.h"
126 #include "../capture_wpcap_packet.h"
127 #include <tchar.h> /* Needed for Unicode */
128 #include <wsutil/unicode-utils.h>
129 #include <commctrl.h>
130 #include <shellapi.h>
134 #include "ui/gtk/file_dlg.h"
135 #include "ui/gtk/gtkglobals.h"
136 #include "ui/gtk/color_utils.h"
137 #include "ui/gtk/gui_utils.h"
138 #include "ui/gtk/color_dlg.h"
139 #include "ui/gtk/filter_dlg.h"
140 #include "ui/gtk/uat_gui.h"
141 #include "ui/gtk/main.h"
142 #include "ui/gtk/main_80211_toolbar.h"
143 #include "ui/gtk/main_airpcap_toolbar.h"
144 #include "ui/gtk/main_filter_toolbar.h"
145 #include "ui/gtk/main_titlebar.h"
146 #include "ui/gtk/menus.h"
147 #include "ui/gtk/main_menubar_private.h"
148 #include "ui/gtk/macros_dlg.h"
149 #include "ui/gtk/main_statusbar_private.h"
150 #include "ui/gtk/main_toolbar.h"
151 #include "ui/gtk/main_toolbar_private.h"
152 #include "ui/gtk/main_welcome.h"
153 #include "ui/gtk/drag_and_drop.h"
154 #include "ui/gtk/capture_file_dlg.h"
155 #include "ui/gtk/packet_panes.h"
156 #include "ui/gtk/keys.h"
157 #include "ui/gtk/packet_win.h"
158 #include "ui/gtk/stock_icons.h"
159 #include "ui/gtk/find_dlg.h"
160 #include "ui/gtk/follow_tcp.h"
161 #include "ui/gtk/font_utils.h"
162 #include "ui/gtk/about_dlg.h"
163 #include "ui/gtk/help_dlg.h"
164 #include "ui/gtk/decode_as_dlg.h"
165 #include "ui/gtk/webbrowser.h"
166 #include "ui/gtk/capture_dlg.h"
167 #include "ui/gtk/capture_if_dlg.h"
168 #include "ui/gtk/capture_globals.h"
169 #include "ui/gtk/tap_param_dlg.h"
170 #include "ui/gtk/prefs_column.h"
171 #include "ui/gtk/prefs_dlg.h"
172 #include "ui/gtk/proto_help.h"
173 #include "ui/gtk/new_packet_list.h"
174 #include "ui/gtk/filter_expression_save_dlg.h"
177 #include "ui/gtk/iface_lists.h"
180 #include "ui/gtk/old-gtk-compat.h"
183 #include "../../image/wsicon16.xpm"
184 #include "../../image/wsicon32.xpm"
185 #include "../../image/wsicon48.xpm"
186 #include "../../image/wsicon64.xpm"
187 #include "../../image/wsiconcap16.xpm"
188 #include "../../image/wsiconcap32.xpm"
189 #include "../../image/wsiconcap48.xpm"
194 #include "airpcap_loader.h"
195 #include "airpcap_dlg.h"
196 #include "airpcap_gui_utils.h"
199 #include <epan/crypt/airpdcap_ws.h>
202 #ifdef HAVE_GTKOSXAPPLICATION
203 #include <igemacintegration/gtkosxapplication.h>
207 * Files under personal and global preferences directories in which
208 * GTK settings for Wireshark are stored.
210 #define RC_FILE "gtkrc"
214 static gboolean capture_stopping;
216 /* "exported" main widgets */
217 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
219 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
220 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
221 static GtkWidget *main_first_pane, *main_second_pane;
223 /* internally used widgets */
224 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
226 GtkWidget *wireless_tb;
228 int airpcap_dll_ret_val = -1;
231 GString *comp_info_str, *runtime_info_str;
233 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
235 static guint tap_update_timer_id;
238 static gboolean has_console; /* TRUE if app has console */
239 static gboolean console_wait; /* "Press any key..." */
240 static void destroy_console(void);
241 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
243 static void console_log_handler(const char *log_domain,
244 GLogLevelFlags log_level, const char *message, gpointer user_data);
246 static void create_main_window(gint, gint, gint, e_prefs*);
247 static void show_main_window(gboolean);
248 static void main_save_window_geometry(GtkWidget *widget);
251 /* Match selected byte pattern */
253 match_selected_cb_do(gpointer data, int action, gchar *text)
255 GtkWidget *filter_te;
256 char *cur_filter, *new_filter;
258 if ((!text) || (0 == strlen(text))) {
259 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
264 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
267 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
269 switch (action&MATCH_SELECTED_MASK) {
271 case MATCH_SELECTED_REPLACE:
272 new_filter = g_strdup(text);
275 case MATCH_SELECTED_AND:
276 if ((!cur_filter) || (0 == strlen(cur_filter)))
277 new_filter = g_strdup(text);
279 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
282 case MATCH_SELECTED_OR:
283 if ((!cur_filter) || (0 == strlen(cur_filter)))
284 new_filter = g_strdup(text);
286 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
289 case MATCH_SELECTED_NOT:
290 new_filter = g_strconcat("!(", text, ")", NULL);
293 case MATCH_SELECTED_AND_NOT:
294 if ((!cur_filter) || (0 == strlen(cur_filter)))
295 new_filter = g_strconcat("!(", text, ")", NULL);
297 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
300 case MATCH_SELECTED_OR_NOT:
301 if ((!cur_filter) || (0 == strlen(cur_filter)))
302 new_filter = g_strconcat("!(", text, ")", NULL);
304 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
308 g_assert_not_reached();
313 /* Free up the copy we got of the old filter text. */
316 /* Don't change the current display filter if we only want to copy the filter */
317 if (action&MATCH_SELECTED_COPY_ONLY) {
318 GString *gtk_text_str = g_string_new("");
319 g_string_append(gtk_text_str, new_filter);
320 copy_to_clipboard(gtk_text_str);
321 g_string_free(gtk_text_str, TRUE);
323 /* create a new one and set the display filter entry accordingly */
324 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
326 /* Run the display filter so it goes in effect. */
327 if (action&MATCH_SELECTED_APPLY_NOW)
328 main_filter_packets(&cfile, new_filter, FALSE);
331 /* Free up the new filter text. */
336 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
340 if (cfile.finfo_selected) {
341 filter = proto_construct_match_selected_string(cfile.finfo_selected,
343 match_selected_cb_do((data ? data : w), action, filter);
348 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
352 if (cfile.finfo_selected) {
353 filter = proto_construct_match_selected_string(cfile.finfo_selected,
355 if ((!filter) || (0 == strlen(filter))) {
356 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
357 "Could not acquire information to build a filter!\n"
358 "Try expanding or choosing another item.");
363 color_display_with_filter(filter);
366 color_filters_reset_tmp();
368 color_filters_set_tmp(filt_nr,filter, FALSE);
370 new_packet_list_colorize_packets();
376 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
378 gchar *selected_proto_url;
379 gchar *proto_abbrev = data;
384 if (cfile.finfo_selected) {
385 /* open wiki page using the protocol abbreviation */
386 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
387 browser_open_url(selected_proto_url);
388 g_free(selected_proto_url);
391 case(ESD_BTN_CANCEL):
394 g_assert_not_reached();
400 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
403 const gchar *proto_abbrev;
407 if (cfile.finfo_selected) {
408 /* convert selected field to protocol abbreviation */
409 /* XXX - could this conversion be simplified? */
410 field_id = cfile.finfo_selected->hfinfo->id;
411 /* if the selected field isn't a protocol, get it's parent */
412 if(!proto_registrar_is_protocol(field_id)) {
413 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
416 proto_abbrev = proto_registrar_get_abbrev(field_id);
418 if (!proto_is_private(field_id)) {
419 /* ask the user if the wiki page really should be opened */
420 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
421 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
423 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
425 "The Wireshark Wiki is a collaborative approach to provide information "
426 "about Wireshark in several ways (not limited to protocol specifics).\n"
428 "This Wiki is new, so the page of the selected protocol "
429 "may not exist and/or may not contain valuable information.\n"
431 "As everyone can edit the Wiki and add new content (or extend existing), "
432 "you are encouraged to add information if you can.\n"
434 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
436 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
437 "which will save you a lot of editing and will give a consistent look over the pages.",
438 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
439 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
441 /* appologize to the user that the wiki page cannot be opened */
442 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
443 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
445 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
447 "Since this is a private protocol, such information is not available in "
448 "a public wiki. Therefore this wiki entry is blocked.\n"
450 "Sorry for the inconvenience.\n",
451 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
456 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
458 gchar *selected_proto_url;
459 gchar *proto_abbrev = data;
463 if (cfile.finfo_selected) {
464 /* open reference page using the protocol abbreviation */
465 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
466 browser_open_url(selected_proto_url);
467 g_free(selected_proto_url);
470 case(ESD_BTN_CANCEL):
473 g_assert_not_reached();
478 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
481 const gchar *proto_abbrev;
485 if (cfile.finfo_selected) {
486 /* convert selected field to protocol abbreviation */
487 /* XXX - could this conversion be simplified? */
488 field_id = cfile.finfo_selected->hfinfo->id;
489 /* if the selected field isn't a protocol, get it's parent */
490 if(!proto_registrar_is_protocol(field_id)) {
491 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
494 proto_abbrev = proto_registrar_get_abbrev(field_id);
496 if (!proto_is_private(field_id)) {
497 /* ask the user if the wiki page really should be opened */
498 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
499 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
501 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
503 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
504 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
506 /* appologize to the user that the wiki page cannot be opened */
507 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
508 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
510 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
512 "Since this is a private protocol, such information is not available on "
513 "a public website. Therefore this filter entry is blocked.\n"
515 "Sorry for the inconvenience.\n",
516 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
522 is_address_column (gint column)
524 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
525 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
526 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
527 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
528 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
537 get_ip_address_list_from_packet_list_row(gpointer data)
539 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
540 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
543 GList *addr_list = NULL;
545 fdata = (frame_data *) new_packet_list_get_row_data(row);
550 if (!cf_read_frame (&cfile, fdata))
551 return NULL; /* error reading the frame */
553 epan_dissect_init(&edt, FALSE, FALSE);
554 col_custom_prime_edt(&edt, &cfile.cinfo);
556 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
557 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
559 /* First check selected column */
560 if (is_address_column (column)) {
561 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
564 for (col = 0; col < cfile.cinfo.num_cols; col++) {
565 /* Then check all columns except the selected */
566 if ((col != column) && (is_address_column (col))) {
567 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
571 epan_dissect_cleanup(&edt);
578 get_filter_from_packet_list_row_and_column(gpointer data)
580 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
581 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
585 fdata = (frame_data *) new_packet_list_get_row_data(row);
590 if (!cf_read_frame(&cfile, fdata))
591 return NULL; /* error reading the frame */
592 /* proto tree, visible. We need a proto tree if there's custom columns */
593 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
594 col_custom_prime_edt(&edt, &cfile.cinfo);
596 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
598 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
600 if ((cfile.cinfo.col_custom_occurrence[column]) ||
601 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
603 /* Only construct the filter when a single occurrence is displayed
604 * otherwise we might end up with a filter like "ip.proto==1,6".
606 * Or do we want to be able to filter on multiple occurrences so that
607 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
610 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
611 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
612 /* leak a little but safer than ep_ here */
613 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
614 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
615 if (hfi->parent == -1) {
617 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
618 } else if (hfi->type == FT_STRING) {
619 /* Custom string, add quotes */
620 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
621 cfile.cinfo.col_expr.col_expr_val[column]);
625 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
626 cfile.cinfo.col_expr.col_expr_val[column]);
631 epan_dissect_cleanup(&edt);
638 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
640 match_selected_cb_do(data,
642 get_filter_from_packet_list_row_and_column(data));
645 /* This function allows users to right click in the details window and copy the text
646 * information to the operating systems clipboard.
648 * We first check to see if a string representation is setup in the tree and then
649 * read the string. If not available then we try to grab the value. If all else
650 * fails we display a message to the user to indicate the copy could not be completed.
653 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
655 GString *gtk_text_str = g_string_new("");
656 char labelstring[256];
657 char *stringpointer = labelstring;
661 case COPY_SELECTED_DESCRIPTION:
662 if (cfile.finfo_selected->rep &&
663 strlen (cfile.finfo_selected->rep->representation) > 0) {
664 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
667 case COPY_SELECTED_FIELDNAME:
668 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
669 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
672 case COPY_SELECTED_VALUE:
673 if (cfile.edt !=0 ) {
674 g_string_append(gtk_text_str,
675 get_node_field_value(cfile.finfo_selected, cfile.edt));
682 if (gtk_text_str->len == 0) {
683 /* If no representation then... Try to read the value */
684 proto_item_fill_label(cfile.finfo_selected, stringpointer);
685 g_string_append(gtk_text_str, stringpointer);
688 if (gtk_text_str->len == 0) {
689 /* Could not get item so display error msg */
690 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
692 /* Copy string to clipboard */
693 copy_to_clipboard(gtk_text_str);
695 g_string_free(gtk_text_str, TRUE); /* Free the memory */
699 /* mark as reference time frame */
701 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
705 frame->flags.ref_time=1;
706 cfile.ref_time_count++;
708 frame->flags.ref_time=0;
709 cfile.ref_time_count--;
711 cf_reftime_packets(&cfile);
712 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
713 new_packet_list_freeze();
714 cfile.displayed_count--;
715 new_packet_list_recreate_visible_rows();
716 new_packet_list_thaw();
718 new_packet_list_queue_draw();
722 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
726 timestamp_set_type(TS_RELATIVE);
727 recent.gui_time_format = TS_RELATIVE;
728 cf_timestamp_auto_precision(&cfile);
729 new_packet_list_queue_draw();
734 g_assert_not_reached();
737 if (cfile.current_frame) {
738 set_frame_reftime(!cfile.current_frame->flags.ref_time,
739 cfile.current_frame, cfile.current_row);
745 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
747 static GtkWidget *reftime_dialog = NULL;
751 if (cfile.current_frame) {
752 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
753 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
754 "%sSwitch to the appropriate Time Display Format?%s\n\n"
755 "Time References don't work well with the currently selected Time Display Format.\n\n"
756 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
757 simple_dialog_primary_start(), simple_dialog_primary_end());
758 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
760 set_frame_reftime(!cfile.current_frame->flags.ref_time,
761 cfile.current_frame, cfile.current_row);
765 case REFTIME_FIND_NEXT:
766 cf_find_packet_time_reference(&cfile, SD_FORWARD);
768 case REFTIME_FIND_PREV:
769 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
775 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
777 cf_find_packet_marked(&cfile, SD_FORWARD);
781 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
783 cf_find_packet_marked(&cfile, SD_BACKWARD);
787 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
790 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
792 gboolean has_blurb = FALSE;
793 guint length = 0, byte_len;
794 GtkWidget *byte_view;
795 const guint8 *byte_data;
800 /* if nothing is selected */
801 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
804 * Which byte view is displaying the current protocol tree
807 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
808 if (byte_view == NULL)
811 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
812 if (byte_data == NULL)
815 cf_unselect_field(&cfile);
816 packet_hex_print(byte_view, byte_data,
817 cfile.current_frame, NULL, byte_len);
818 proto_help_menu_modify(sel, &cfile);
821 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
824 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
826 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
827 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
828 g_assert(byte_data != NULL);
830 cfile.finfo_selected = finfo;
831 set_menus_for_selected_tree_row(&cfile);
834 if (finfo->hfinfo->blurb != NULL &&
835 finfo->hfinfo->blurb[0] != '\0') {
837 length = (guint) strlen(finfo->hfinfo->blurb);
839 length = (guint) strlen(finfo->hfinfo->name);
841 finfo_length = finfo->length + finfo->appendix_length;
843 if (finfo_length == 0) {
845 } else if (finfo_length == 1) {
846 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
848 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
850 statusbar_pop_field_msg(); /* get rid of current help msg */
852 statusbar_push_field_msg(" %s (%s)%s",
853 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
854 finfo->hfinfo->abbrev, len_str);
857 * Don't show anything if the field name is zero-length;
858 * the pseudo-field for "proto_tree_add_text()" is such
859 * a field, and we don't want "Text (text)" showing up
860 * on the status line if you've selected such a field.
862 * XXX - there are zero-length fields for which we *do*
863 * want to show the field name.
865 * XXX - perhaps the name and abbrev field should be null
866 * pointers rather than null strings for that pseudo-field,
867 * but we'd have to add checks for null pointers in some
868 * places if we did that.
870 * Or perhaps protocol tree items added with
871 * "proto_tree_add_text()" should have -1 as the field index,
872 * with no pseudo-field being used, but that might also
873 * require special checks for -1 to be added.
875 statusbar_push_field_msg("%s", "");
878 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
880 proto_help_menu_modify(sel, &cfile);
883 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
885 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
888 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
890 expand_all_tree(cfile.edt->tree, tree_view_gbl);
893 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
895 if (cfile.finfo_selected) {
896 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
897 cfile.finfo_selected->hfinfo->abbrev,0);
898 /* Recreate the packet list according to new preferences */
899 new_packet_list_recreate ();
900 if (!prefs.gui_use_pref_save) {
903 cfile.cinfo.columns_changed = FALSE; /* Reset value */
907 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
910 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
912 /* the mouse position is at an entry, expand that one */
913 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
914 gtk_tree_path_free(path);
918 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
920 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, RESOLV_ALL);
923 /* Update main window items based on whether there's a capture in progress. */
925 main_set_for_capture_in_progress(gboolean capture_in_progress)
927 set_menus_for_capture_in_progress(capture_in_progress);
930 set_toolbar_for_capture_in_progress(capture_in_progress);
932 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
936 /* Update main window items based on whether we have a capture file. */
938 main_set_for_capture_file(gboolean have_capture_file_in)
940 have_capture_file = have_capture_file_in;
942 main_widgets_show_or_hide();
945 /* Update main window items based on whether we have captured packets. */
947 main_set_for_captured_packets(gboolean have_captured_packets)
949 set_menus_for_captured_packets(have_captured_packets);
950 set_toolbar_for_captured_packets(have_captured_packets);
953 /* Update main window items based on whether we have a packet history. */
955 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
957 set_menus_for_packet_history(back_history, forward_history);
958 set_toolbar_for_packet_history(back_history, forward_history);
964 /* get the current geometry, before writing it to disk */
965 main_save_window_geometry(top_level);
967 /* write user's recent file to disk
968 * It is no problem to write this file, even if we do not quit */
969 write_profile_recent();
972 /* XXX - should we check whether the capture file is an
973 unsaved temporary file for a live capture and, if so,
974 pop up a "do you want to exit without saving the capture
975 file?" dialog, and then just return, leaving said dialog
976 box to forcibly quit if the user clicks "OK"?
978 If so, note that this should be done in a subroutine that
979 returns TRUE if we do so, and FALSE otherwise, and if it
980 returns TRUE we should return TRUE without nuking anything.
982 Note that, if we do that, we might also want to check if
983 an "Update list of packets in real time" capture is in
984 progress and, if so, ask whether they want to terminate
985 the capture and discard it, and return TRUE, before nuking
986 any child capture, if they say they don't want to do so. */
989 /* Nuke any child capture in progress. */
990 capture_kill_child(&global_capture_opts);
993 /* Are we in the middle of reading a capture? */
994 if (cfile.state == FILE_READ_IN_PROGRESS) {
995 /* Yes, so we can't just close the file and quit, as
996 that may yank the rug out from under the read in
997 progress; instead, just set the state to
998 "FILE_READ_ABORTED" and return - the code doing the read
999 will check for that and, if it sees that, will clean
1001 cfile.state = FILE_READ_ABORTED;
1003 /* Say that the window should *not* be deleted;
1004 that'll be done by the code that cleans up. */
1007 /* Close any capture file we have open; on some OSes, you
1008 can't unlink a temporary capture file if you have it
1010 "cf_close()" will unlink it after closing it if
1011 it's a temporary file.
1013 We do this here, rather than after the main loop returns,
1014 as, after the main loop returns, the main window may have
1015 been destroyed (if this is called due to a "destroy"
1016 even on the main window rather than due to the user
1017 selecting a menu item), and there may be a crash
1018 or other problem when "cf_close()" tries to
1019 clean up stuff in the main window.
1021 XXX - is there a better place to put this?
1022 Or should we have a routine that *just* closes the
1023 capture file, and doesn't do anything with the UI,
1024 which we'd call here, and another routine that
1025 calls that routine and also cleans up the UI, which
1026 we'd call elsewhere? */
1029 /* Exit by leaving the main loop, so that any quit functions
1030 we registered get called. */
1033 /* Say that the window should be deleted. */
1039 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1041 /* If we're in the middle of stopping a capture, don't do anything;
1042 the user can try deleting the window after the capture stops. */
1043 if (capture_stopping)
1046 /* If there's unsaved data, let the user save it first.
1047 If they cancel out of it, don't quit. */
1048 if (do_file_close(&cfile, TRUE, " before quitting"))
1049 return main_do_quit();
1051 return TRUE; /* will this keep the window from being deleted? */
1056 main_pane_load_window_geometry(void)
1058 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1059 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1060 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1061 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1067 main_load_window_geometry(GtkWidget *widget)
1069 window_geometry_t geom;
1071 geom.set_pos = prefs.gui_geometry_save_position;
1072 geom.x = recent.gui_geometry_main_x;
1073 geom.y = recent.gui_geometry_main_y;
1074 geom.set_size = prefs.gui_geometry_save_size;
1075 if (recent.gui_geometry_main_width > 0 &&
1076 recent.gui_geometry_main_height > 0) {
1077 geom.width = recent.gui_geometry_main_width;
1078 geom.height = recent.gui_geometry_main_height;
1079 geom.set_maximized = prefs.gui_geometry_save_maximized;
1081 /* We assume this means the width and height weren't set in
1082 the "recent" file (or that there is no "recent" file),
1083 and weren't set to a default value, so we don't set the
1084 size. (The "recent" file code rejects non-positive width
1085 and height values.) */
1086 geom.set_size = FALSE;
1088 geom.maximized = recent.gui_geometry_main_maximized;
1090 window_set_geometry(widget, &geom);
1092 main_pane_load_window_geometry();
1093 statusbar_load_window_geometry();
1098 main_save_window_geometry(GtkWidget *widget)
1100 window_geometry_t geom;
1102 window_get_geometry(widget, &geom);
1104 if (prefs.gui_geometry_save_position) {
1105 recent.gui_geometry_main_x = geom.x;
1106 recent.gui_geometry_main_y = geom.y;
1109 if (prefs.gui_geometry_save_size) {
1110 recent.gui_geometry_main_width = geom.width;
1111 recent.gui_geometry_main_height = geom.height;
1114 if(prefs.gui_geometry_save_maximized) {
1115 recent.gui_geometry_main_maximized = geom.maximized;
1118 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1119 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1120 statusbar_save_window_geometry();
1124 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1126 /* If there's unsaved data, let the user save it first. */
1127 if (do_file_close(&cfile, TRUE, " before quitting"))
1132 print_usage(gboolean print_ver) {
1142 fprintf(output, "Wireshark " VERSION "%s\n"
1143 "Interactively dump and analyze network traffic.\n"
1144 "See http://www.wireshark.org for more information.\n"
1147 wireshark_svnversion, get_copyright_info());
1151 fprintf(output, "\n");
1152 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1153 fprintf(output, "\n");
1156 fprintf(output, "Capture interface:\n");
1157 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1158 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1159 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1160 fprintf(output, " -p don't capture in promiscuous mode\n");
1161 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1162 fprintf(output, " -S update packet display when new packets are captured\n");
1163 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1164 #ifdef HAVE_PCAP_CREATE
1165 fprintf(output, " -I capture in monitor mode, if available\n");
1167 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1168 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1170 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1171 fprintf(output, " -D print list of interfaces and exit\n");
1172 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1173 fprintf(output, "\n");
1174 fprintf(output, "Capture stop conditions:\n");
1175 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1176 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1177 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1178 fprintf(output, " files:NUM - stop after NUM files\n");
1179 /*fprintf(output, "\n");*/
1180 fprintf(output, "Capture output:\n");
1181 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1182 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1183 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1184 #endif /* HAVE_LIBPCAP */
1186 /*fprintf(output, "\n");*/
1187 fprintf(output, "Input file:\n");
1188 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1190 fprintf(output, "\n");
1191 fprintf(output, "Processing:\n");
1192 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1193 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1194 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1196 fprintf(output, "\n");
1197 fprintf(output, "User interface:\n");
1198 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1199 fprintf(output, " -d <display filter> start with the given display filter\n");
1200 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1201 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1202 fprintf(output, " filter\n");
1203 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1204 fprintf(output, " -m <font> set the font name used for most text\n");
1205 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1206 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1207 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1208 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1210 fprintf(output, "\n");
1211 fprintf(output, "Output:\n");
1212 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1214 fprintf(output, "\n");
1215 fprintf(output, "Miscellaneous:\n");
1216 fprintf(output, " -h display this help and exit\n");
1217 fprintf(output, " -v display version info and exit\n");
1218 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1219 fprintf(output, " persdata:path - personal data files\n");
1220 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1221 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1223 fprintf(output, " --display=DISPLAY X display to use\n");
1238 printf(PACKAGE " " VERSION "%s\n"
1245 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1246 runtime_info_str->str);
1254 * Print to the standard error. On Windows, create a console for the
1255 * standard error to show up on, if necessary.
1256 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1257 * terminal isn't the standard error?
1260 vfprintf_stderr(const char *fmt, va_list ap)
1265 vfprintf(stderr, fmt, ap);
1269 fprintf_stderr(const char *fmt, ...)
1274 vfprintf_stderr(fmt, ap);
1279 * Report an error in command-line arguments.
1280 * Creates a console on Windows.
1283 cmdarg_err(const char *fmt, ...)
1287 fprintf_stderr("wireshark: ");
1289 vfprintf_stderr(fmt, ap);
1291 fprintf_stderr("\n");
1295 * Report additional information for an error in command-line arguments.
1296 * Creates a console on Windows.
1297 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1298 * terminal isn't the standard error?
1301 cmdarg_err_cont(const char *fmt, ...)
1306 vfprintf_stderr(fmt, ap);
1307 fprintf_stderr("\n");
1312 Once every 3 seconds we get a callback here which we use to update
1316 tap_update_cb(gpointer data _U_)
1318 draw_tap_listeners(FALSE);
1322 /* Restart the tap update display timer with new configured interval */
1323 void reset_tap_update_timer(void)
1325 g_source_remove(tap_update_timer_id);
1326 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1330 protect_thread_critical_region(void)
1332 /* Threading support for TAP:s removed
1333 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1334 * See the commit for removed code:
1335 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
1339 unprotect_thread_critical_region(void)
1341 /* Threading support for TAP:s removed
1342 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1348 * Periodically process outstanding hostname lookups. If we have new items,
1349 * redraw the packet list and tree view.
1353 resolv_update_cb(gpointer data _U_)
1355 /* Anything new show up? */
1356 if (host_name_lookup_process(NULL)) {
1357 if (gtk_widget_get_window(pkt_scrollw))
1358 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1359 if (gtk_widget_get_window(tv_scrollw))
1360 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1363 /* Always check. Even if we don't do async lookups we could still get
1364 passive updates, e.g. from DNS packets. */
1369 /* Set main_window_name and it's icon title to the capture filename */
1371 set_display_filename(capture_file *cf)
1373 gchar *display_name;
1377 display_name = cf_get_display_name(cf);
1378 window_name = g_strdup_printf("%s%s", cf->unsaved_changes ? "*" : "",
1380 g_free(display_name);
1381 main_set_window_name(window_name);
1382 g_free(window_name);
1384 main_set_window_name("The Wireshark Network Analyzer");
1388 /* Update various parts of the main window for a capture file "unsaved
1389 changes" change - update the title to reflect whether there are
1390 unsaved changes or not, and update the menus and toolbar to
1391 enable or disable the "Save" operation. */
1393 main_update_for_unsaved_changes(capture_file *cf)
1395 set_display_filename(cf);
1396 set_menus_for_capture_file(cf);
1397 set_toolbar_for_capture_file(cf);
1402 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1404 /* Update menubar and toolbar */
1405 menu_auto_scroll_live_changed(auto_scroll_live_in);
1406 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1408 /* change auto scroll state */
1409 auto_scroll_live = auto_scroll_live_in;
1414 main_colorize_changed(gboolean packet_list_colorize)
1416 /* Update menubar and toolbar */
1417 menu_colorize_changed(packet_list_colorize);
1418 toolbar_colorize_changed(packet_list_colorize);
1420 /* change colorization */
1421 if(packet_list_colorize != recent.packet_list_colorize) {
1422 recent.packet_list_colorize = packet_list_colorize;
1423 color_filters_enable(packet_list_colorize);
1424 new_packet_list_colorize_packets();
1428 static GtkWidget *close_dlg = NULL;
1431 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1433 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1438 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1440 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1445 main_cf_cb_file_closing(capture_file *cf)
1447 /* if we have more than 10000 packets, show a splash screen while closing */
1448 /* XXX - don't know a better way to decide whether to show or not,
1449 * as most of the time is spend in various calls that destroy various
1450 * data structures, so it wouldn't be easy to use a progress bar,
1451 * rather than, say, a progress spinner, here! */
1452 if(cf->count > 10000) {
1453 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1454 "%sClosing file!%s\n\nPlease wait ...",
1455 simple_dialog_primary_start(),
1456 simple_dialog_primary_end());
1457 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1460 /* Destroy all windows that refer to the
1461 capture file we're closing. */
1462 destroy_packet_wins();
1464 /* Restore the standard title bar message. */
1465 main_set_window_name("The Wireshark Network Analyzer");
1467 /* Disable all menu items that make sense only if you have a capture. */
1468 set_menus_for_capture_file(NULL);
1469 set_toolbar_for_capture_file(NULL);
1470 main_set_for_captured_packets(FALSE);
1471 set_menus_for_selected_packet(cf);
1472 main_set_for_capture_in_progress(FALSE);
1473 set_capture_if_dialog_for_capture_in_progress(FALSE);
1474 set_menus_for_selected_tree_row(cf);
1476 /* Set up main window for no capture file. */
1477 main_set_for_capture_file(FALSE);
1479 main_window_update();
1483 main_cf_cb_file_closed(capture_file *cf _U_)
1485 if(close_dlg != NULL) {
1486 splash_destroy(close_dlg);
1493 main_cf_cb_file_read_started(capture_file *cf _U_)
1495 tap_param_dlg_update();
1497 /* Set up main window for a capture file. */
1498 main_set_for_capture_file(TRUE);
1502 main_cf_cb_file_read_finished(capture_file *cf)
1506 if (!cf->is_tempfile && cf->filename) {
1507 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1508 add_menu_recent_capture_file(cf->filename);
1510 /* Remember folder for next Open dialog and save it in recent */
1511 dir_path = get_dirname(g_strdup(cf->filename));
1512 set_last_open_dir(dir_path);
1516 /* Update the appropriate parts of the main window. */
1517 main_update_for_unsaved_changes(cf);
1519 /* Enable menu items that make sense if you have some captured packets. */
1520 main_set_for_captured_packets(TRUE);
1524 main_cf_cb_file_rescan_finished(capture_file *cf)
1528 if (!cf->is_tempfile && cf->filename) {
1529 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1530 add_menu_recent_capture_file(cf->filename);
1532 /* Remember folder for next Open dialog and save it in recent */
1533 dir_path = get_dirname(g_strdup(cf->filename));
1534 set_last_open_dir(dir_path);
1538 /* Update the appropriate parts of the main window. */
1539 main_update_for_unsaved_changes(cf);
1543 static GList *icon_list_create(
1544 const char **icon16_xpm,
1545 const char **icon32_xpm,
1546 const char **icon48_xpm,
1547 const char **icon64_xpm)
1549 GList *icon_list = NULL;
1550 GdkPixbuf * pixbuf16;
1551 GdkPixbuf * pixbuf32;
1552 GdkPixbuf * pixbuf48;
1553 GdkPixbuf * pixbuf64;
1556 if(icon16_xpm != NULL) {
1557 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1559 icon_list = g_list_append(icon_list, pixbuf16);
1562 if(icon32_xpm != NULL) {
1563 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1565 icon_list = g_list_append(icon_list, pixbuf32);
1568 if(icon48_xpm != NULL) {
1569 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1571 icon_list = g_list_append(icon_list, pixbuf48);
1574 if(icon64_xpm != NULL) {
1575 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1577 icon_list = g_list_append(icon_list, pixbuf64);
1584 main_capture_set_main_window_title(capture_options *capture_opts)
1586 GString *title = g_string_new("");
1588 g_string_append(title, "Capturing ");
1589 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1590 main_set_window_name(title->str);
1591 g_string_free(title, TRUE);
1595 main_capture_cb_capture_prepared(capture_options *capture_opts)
1597 static GList *icon_list = NULL;
1599 main_capture_set_main_window_title(capture_opts);
1601 if(icon_list == NULL) {
1602 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1604 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1606 /* Disable menu items that make no sense if you're currently running
1608 main_set_for_capture_in_progress(TRUE);
1609 set_capture_if_dialog_for_capture_in_progress(TRUE);
1611 /* Don't set up main window for a capture file. */
1612 main_set_for_capture_file(FALSE);
1616 main_capture_cb_capture_update_started(capture_options *capture_opts)
1618 /* We've done this in "prepared" above, but it will be cleared while
1619 switching to the next multiple file. */
1620 main_capture_set_main_window_title(capture_opts);
1622 main_set_for_capture_in_progress(TRUE);
1623 set_capture_if_dialog_for_capture_in_progress(TRUE);
1625 /* Enable menu items that make sense if you have some captured
1626 packets (yes, I know, we don't have any *yet*). */
1627 main_set_for_captured_packets(TRUE);
1629 /* Set up main window for a capture file. */
1630 main_set_for_capture_file(TRUE);
1634 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1636 capture_file *cf = capture_opts->cf;
1637 static GList *icon_list = NULL;
1639 /* The capture isn't stopping any more - it's stopped. */
1640 capture_stopping = FALSE;
1642 if (!cf->is_tempfile && cf->filename) {
1643 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1644 add_menu_recent_capture_file(cf->filename);
1647 /* Update the main window as appropriate */
1648 main_update_for_unsaved_changes(cf);
1650 /* Enable menu items that make sense if you're not currently running
1652 main_set_for_capture_in_progress(FALSE);
1653 set_capture_if_dialog_for_capture_in_progress(FALSE);
1655 /* Set up main window for a capture file. */
1656 main_set_for_capture_file(TRUE);
1658 if(icon_list == NULL) {
1659 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1661 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1663 if(global_capture_opts.quit_after_cap) {
1664 /* command line asked us to quit after the capture */
1665 /* don't pop up a dialog to ask for unsaved files etc. */
1671 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1673 /* Don't set up main window for a capture file. */
1674 main_set_for_capture_file(FALSE);
1678 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1681 capture_file *cf = capture_opts->cf;
1683 static GList *icon_list = NULL;
1685 /* The capture isn't stopping any more - it's stopped. */
1686 capture_stopping = FALSE;
1688 /*set_display_filename(cf);*/
1690 /* Enable menu items that make sense if you're not currently running
1692 main_set_for_capture_in_progress(FALSE);
1693 set_capture_if_dialog_for_capture_in_progress(FALSE);
1695 /* Restore the standard title bar message */
1696 /* (just in case we have trouble opening the capture file). */
1697 main_set_window_name("The Wireshark Network Analyzer");
1699 if(icon_list == NULL) {
1700 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1702 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1704 /* We don't have loaded the capture file, this will be done later.
1705 * For now we still have simply a blank screen. */
1707 if(global_capture_opts.quit_after_cap) {
1708 /* command line asked us to quit after the capture */
1709 /* don't pop up a dialog to ask for unsaved files etc. */
1715 main_capture_cb_capture_stopping(capture_options *capture_opts _U_)
1717 capture_stopping = TRUE;
1718 set_menus_for_capture_stopping();
1720 set_toolbar_for_capture_stopping();
1722 set_capture_if_dialog_for_capture_stopping();
1727 main_capture_cb_capture_failed(capture_options *capture_opts _U_)
1729 static GList *icon_list = NULL;
1731 /* Capture isn't stopping any more. */
1732 capture_stopping = FALSE;
1734 /* the capture failed before the first packet was captured
1735 reset title, menus and icon */
1737 main_set_window_name("The Wireshark Network Analyzer");
1739 main_set_for_capture_in_progress(FALSE);
1740 set_capture_if_dialog_for_capture_in_progress(FALSE);
1742 main_set_for_capture_file(FALSE);
1744 if(icon_list == NULL) {
1745 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1747 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1750 if(global_capture_opts.quit_after_cap) {
1751 /* command line asked us to quit after the capture */
1752 /* don't pop up a dialog to ask for unsaved files etc. */
1756 #endif /* HAVE_LIBPCAP */
1759 main_cf_cb_packet_selected(gpointer data)
1761 capture_file *cf = data;
1763 /* Display the GUI protocol tree and packet bytes.
1764 XXX - why do we dump core if we call "proto_tree_draw()"
1765 before calling "add_byte_views()"? */
1766 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1767 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1769 /* Note: Both string and hex value searches in the packet data produce a non-zero
1770 search_pos if successful */
1771 if(cf->search_in_progress &&
1772 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1773 highlight_field(cf->edt->tvb, cf->search_pos,
1774 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1777 /* A packet is selected. */
1778 set_menus_for_selected_packet(cf);
1782 main_cf_cb_packet_unselected(capture_file *cf)
1784 /* No packet is being displayed; clear the hex dump pane by getting
1785 rid of all the byte views. */
1786 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1787 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1789 /* Add a placeholder byte view so that there's at least something
1790 displayed in the byte view notebook. */
1791 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1793 /* And clear the protocol tree display as well. */
1794 proto_tree_draw(NULL, tree_view_gbl);
1796 /* No packet is selected. */
1797 set_menus_for_selected_packet(cf);
1801 main_cf_cb_field_unselected(capture_file *cf)
1803 set_menus_for_selected_tree_row(cf);
1807 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1810 case(cf_cb_file_closing):
1811 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1812 main_cf_cb_file_closing(data);
1814 case(cf_cb_file_closed):
1815 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1816 main_cf_cb_file_closed(data);
1818 case(cf_cb_file_read_started):
1819 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1820 main_cf_cb_file_read_started(data);
1822 case(cf_cb_file_read_finished):
1823 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1824 main_cf_cb_file_read_finished(data);
1826 case(cf_cb_file_reload_started):
1827 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1828 main_cf_cb_file_read_started(data);
1830 case(cf_cb_file_reload_finished):
1831 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1832 main_cf_cb_file_read_finished(data);
1834 case(cf_cb_file_rescan_started):
1835 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1837 case(cf_cb_file_rescan_finished):
1838 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1839 main_cf_cb_file_rescan_finished(data);
1841 case(cf_cb_file_fast_save_finished):
1842 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1843 main_cf_cb_file_rescan_finished(data);
1845 case(cf_cb_packet_selected):
1846 main_cf_cb_packet_selected(data);
1848 case(cf_cb_packet_unselected):
1849 main_cf_cb_packet_unselected(data);
1851 case(cf_cb_field_unselected):
1852 main_cf_cb_field_unselected(data);
1854 case(cf_cb_file_save_started):
1855 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1857 case(cf_cb_file_save_finished):
1858 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1860 case(cf_cb_file_save_failed):
1861 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1863 case(cf_cb_file_save_stopped):
1864 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1866 case(cf_cb_file_export_specified_packets_started):
1867 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1869 case(cf_cb_file_export_specified_packets_finished):
1870 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1872 case(cf_cb_file_export_specified_packets_failed):
1873 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1875 case(cf_cb_file_export_specified_packets_stopped):
1876 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1879 g_warning("main_cf_callback: event %u unknown", event);
1880 g_assert_not_reached();
1886 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1888 #ifdef HAVE_GTKOSXAPPLICATION
1889 GtkOSXApplication *theApp;
1892 case(capture_cb_capture_prepared):
1893 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1894 main_capture_cb_capture_prepared(capture_opts);
1896 case(capture_cb_capture_update_started):
1897 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1898 main_capture_cb_capture_update_started(capture_opts);
1899 #ifdef HAVE_GTKOSXAPPLICATION
1900 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1901 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1904 case(capture_cb_capture_update_continue):
1905 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1907 case(capture_cb_capture_update_finished):
1908 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1909 main_capture_cb_capture_update_finished(capture_opts);
1911 case(capture_cb_capture_fixed_started):
1912 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1913 main_capture_cb_capture_fixed_started(capture_opts);
1915 case(capture_cb_capture_fixed_continue):
1916 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1918 case(capture_cb_capture_fixed_finished):
1919 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1920 main_capture_cb_capture_fixed_finished(capture_opts);
1922 case(capture_cb_capture_stopping):
1923 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1924 /* Beware: this state won't be called, if the capture child
1925 * closes the capturing on it's own! */
1926 #ifdef HAVE_GTKOSXAPPLICATION
1927 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1928 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1930 main_capture_cb_capture_stopping(capture_opts);
1932 case(capture_cb_capture_failed):
1933 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1934 main_capture_cb_capture_failed(capture_opts);
1937 g_warning("main_capture_callback: event %u unknown", event);
1938 g_assert_not_reached();
1944 get_gtk_compiled_info(GString *str)
1946 g_string_append(str, "with ");
1947 g_string_append_printf(str,
1948 #ifdef GTK_MAJOR_VERSION
1949 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1952 "GTK+ (version unknown)");
1954 g_string_append(str, ", ");
1956 g_string_append(str, "with Cairo ");
1957 g_string_append(str, CAIRO_VERSION_STRING);
1958 g_string_append(str, ", ");
1961 g_string_append(str, "with Pango ");
1962 g_string_append(str, PANGO_VERSION_STRING);
1963 g_string_append(str, ", ");
1969 get_gui_compiled_info(GString *str)
1971 epan_get_compiled_version_info(str);
1973 g_string_append(str, ", ");
1974 #ifdef HAVE_LIBPORTAUDIO
1975 #ifdef PORTAUDIO_API_1
1976 g_string_append(str, "with PortAudio <= V18");
1977 #else /* PORTAUDIO_API_1 */
1978 g_string_append(str, "with ");
1979 g_string_append(str, Pa_GetVersionText());
1980 #endif /* PORTAUDIO_API_1 */
1981 #else /* HAVE_LIBPORTAUDIO */
1982 g_string_append(str, "without PortAudio");
1983 #endif /* HAVE_LIBPORTAUDIO */
1985 g_string_append(str, ", ");
1987 get_compiled_airpcap_version(str);
1989 g_string_append(str, "without AirPcap");
1994 get_gui_runtime_info(GString *str)
1996 epan_get_runtime_version_info(str);
1999 g_string_append(str, ", ");
2000 get_runtime_airpcap_version(str);
2004 g_string_append(str, ", ");
2005 u3_runtime_info(str);
2010 read_configuration_files(char **gdp_path, char **dp_path)
2012 int gpf_open_errno, gpf_read_errno;
2013 int cf_open_errno, df_open_errno;
2014 int gdp_open_errno, gdp_read_errno;
2015 int dp_open_errno, dp_read_errno;
2016 char *gpf_path, *pf_path;
2017 char *cf_path, *df_path;
2018 int pf_open_errno, pf_read_errno;
2021 /* load the decode as entries of this profile */
2022 load_decode_as_entries();
2024 /* Read the preference files. */
2025 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2026 &pf_open_errno, &pf_read_errno, &pf_path);
2028 if (gpf_path != NULL) {
2029 if (gpf_open_errno != 0) {
2030 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2031 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2032 g_strerror(gpf_open_errno));
2034 if (gpf_read_errno != 0) {
2035 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2036 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2037 g_strerror(gpf_read_errno));
2040 if (pf_path != NULL) {
2041 if (pf_open_errno != 0) {
2042 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2043 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2044 g_strerror(pf_open_errno));
2046 if (pf_read_errno != 0) {
2047 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2048 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2049 g_strerror(pf_read_errno));
2056 /* if the user wants a console to be always there, well, we should open one for him */
2057 if (prefs_p->gui_console_open == console_open_always) {
2062 /* Read the capture filter file. */
2063 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2064 if (cf_path != NULL) {
2065 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2066 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2067 g_strerror(cf_open_errno));
2071 /* Read the display filter file. */
2072 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2073 if (df_path != NULL) {
2074 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2075 "Could not open your display filter file\n\"%s\": %s.", df_path,
2076 g_strerror(df_open_errno));
2080 /* Read the disabled protocols file. */
2081 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2082 dp_path, &dp_open_errno, &dp_read_errno);
2083 if (*gdp_path != NULL) {
2084 if (gdp_open_errno != 0) {
2085 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2086 "Could not open global disabled protocols file\n\"%s\": %s.",
2087 *gdp_path, g_strerror(gdp_open_errno));
2089 if (gdp_read_errno != 0) {
2090 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2091 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2092 *gdp_path, g_strerror(gdp_read_errno));
2097 if (*dp_path != NULL) {
2098 if (dp_open_errno != 0) {
2099 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2100 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2101 g_strerror(dp_open_errno));
2103 if (dp_read_errno != 0) {
2104 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2105 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2106 g_strerror(dp_read_errno));
2115 /* Check if there's something important to tell the user during startup.
2116 * We want to do this *after* showing the main window so that any windows
2117 * we pop up will be above the main window.
2121 check_and_warn_user_startup(gchar *cf_name)
2123 check_and_warn_user_startup(gchar *cf_name _U_)
2126 gchar *cur_user, *cur_group;
2127 gpointer priv_warning_dialog;
2129 /* Tell the user not to run as root. */
2130 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2131 cur_user = get_cur_username();
2132 cur_group = get_cur_groupname();
2133 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2134 "Running as user \"%s\" and group \"%s\".\n"
2135 "This could be dangerous.\n\n"
2136 "If you're running Wireshark this way in order to perform live capture, "
2137 "you may want to be aware that there is a better way documented at\n"
2138 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2141 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2142 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2146 /* Warn the user if npf.sys isn't loaded. */
2147 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2148 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2149 "The NPF driver isn't running. You may have trouble\n"
2150 "capturing or listing interfaces.");
2151 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2152 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2159 /* And now our feature presentation... [ fade to music ] */
2161 main(int argc, char *argv[])
2163 char *init_progfile_dir_error;
2166 gboolean arg_error = FALSE;
2168 extern int info_update_freq; /* Found in about_dlg.c. */
2169 const gchar *filter;
2177 char *gdp_path, *dp_path;
2180 gboolean start_capture = FALSE;
2181 gboolean list_link_layer_types = FALSE;
2185 gboolean capture_option_specified = FALSE;
2192 gint pl_size = 280, tv_size = 95, bv_size = 75;
2193 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2194 dfilter_t *rfcode = NULL;
2195 gboolean rfilter_parse_failed = FALSE;
2198 GtkWidget *splash_win = NULL;
2199 GLogLevelFlags log_flags;
2200 guint go_to_packet = 0;
2201 gboolean jump_backwards = FALSE;
2202 dfilter_t *jump_to_filter = NULL;
2205 #ifdef HAVE_GTKOSXAPPLICATION
2206 GtkOSXApplication *theApp;
2210 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2211 #define OPTSTRING_B "B:"
2213 #define OPTSTRING_B ""
2214 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2215 #else /* HAVE_LIBPCAP */
2216 #define OPTSTRING_B ""
2217 #endif /* HAVE_LIBPCAP */
2219 #ifdef HAVE_PCAP_CREATE
2220 #define OPTSTRING_I "I"
2222 #define OPTSTRING_I ""
2225 #define OPTSTRING "a:b:" OPTSTRING_B "c:C:d:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:z:"
2227 static const char optstring[] = OPTSTRING;
2229 /* Set the C-language locale to the native environment. */
2230 setlocale(LC_ALL, "");
2232 arg_list_utf_16to8(argc, argv);
2236 * Get credential information for later use, and drop privileges
2237 * before doing anything else.
2238 * Let the user know if anything happened.
2240 init_process_policies();
2241 relinquish_special_privs_perm();
2244 * Attempt to get the pathname of the executable file.
2246 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2248 /* initialize the funnel mini-api */
2249 initialize_funnel_ops();
2251 AirPDcapInitContext(&airpdcap_ctx);
2254 /* Load wpcap if possible. Do this before collecting the run-time version information */
2257 /* ... and also load the packet.dll from wpcap */
2258 wpcap_packet_load();
2261 /* Load the airpcap.dll. This must also be done before collecting
2262 * run-time version information. */
2263 airpcap_dll_ret_val = load_airpcap();
2265 switch (airpcap_dll_ret_val) {
2266 case AIRPCAP_DLL_OK:
2267 /* load the airpcap interfaces */
2268 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2270 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2271 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2272 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2275 airpcap_if_active = NULL;
2279 /* select the first ad default (THIS SHOULD BE CHANGED) */
2280 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2285 * XXX - Maybe we need to warn the user if one of the following happens???
2287 case AIRPCAP_DLL_OLD:
2288 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2291 case AIRPCAP_DLL_ERROR:
2292 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2295 case AIRPCAP_DLL_NOT_FOUND:
2296 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2300 #endif /* HAVE_AIRPCAP */
2302 /* Start windows sockets */
2303 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2306 profile_store_persconffiles (TRUE);
2308 /* Assemble the compile-time version information string */
2309 comp_info_str = g_string_new("Compiled ");
2311 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2313 /* Assemble the run-time version information string */
2314 runtime_info_str = g_string_new("Running ");
2315 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
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 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 ... */
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(&global_capture_opts);
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 case 's': /* Set the snapshot (capture) length */
2607 case 'S': /* "Sync" mode: used for following file ala tail -f */
2608 case 'w': /* Write to capture file xxx */
2609 case 'y': /* Set the pcap data link type */
2610 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2611 case 'B': /* Buffer size */
2612 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2614 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2620 capture_option_specified = TRUE;
2625 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2626 case 'K': /* Kerberos keytab file */
2627 read_keytab_file(optarg);
2631 /*** all non capture option specific ***/
2633 /* Configuration profile settings were already processed just ignore them this time*/
2638 case 'j': /* Search backwards for a matching packet from filter in option J */
2639 jump_backwards = TRUE;
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_font_name);
2665 prefs_p->gui_font_name = g_strdup(optarg);
2667 case 'n': /* No name resolution */
2668 gbl_resolv_flags = RESOLV_NONE;
2670 case 'N': /* Select what types of addresses/port #s to resolve */
2671 if (gbl_resolv_flags == RESOLV_ALL)
2672 gbl_resolv_flags = RESOLV_NONE;
2673 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2674 if (badopt != '\0') {
2675 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2680 case 'o': /* Override preference from command line */
2681 switch (prefs_set_pref(optarg)) {
2684 case PREFS_SET_SYNTAX_ERR:
2685 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2688 case PREFS_SET_NO_SUCH_PREF:
2689 /* not a preference, might be a recent setting */
2690 switch (recent_set_arg(optarg)) {
2693 case PREFS_SET_SYNTAX_ERR:
2694 /* shouldn't happen, checked already above */
2695 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2698 case PREFS_SET_NO_SUCH_PREF:
2699 case PREFS_SET_OBSOLETE:
2700 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2705 g_assert_not_reached();
2708 case PREFS_SET_OBSOLETE:
2709 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2714 g_assert_not_reached();
2718 /* Path settings were already processed just ignore them this time*/
2720 case 'r': /* Read capture file xxx */
2721 /* We may set "last_open_dir" to "cf_name", and if we change
2722 "last_open_dir" later, we free the old value, so we have to
2723 set "cf_name" to something that's been allocated. */
2724 cf_name = g_strdup(optarg);
2726 case 'R': /* Read file filter */
2729 case 't': /* Time stamp type */
2730 if (strcmp(optarg, "r") == 0)
2731 timestamp_set_type(TS_RELATIVE);
2732 else if (strcmp(optarg, "a") == 0)
2733 timestamp_set_type(TS_ABSOLUTE);
2734 else if (strcmp(optarg, "ad") == 0)
2735 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2736 else if (strcmp(optarg, "d") == 0)
2737 timestamp_set_type(TS_DELTA);
2738 else if (strcmp(optarg, "dd") == 0)
2739 timestamp_set_type(TS_DELTA_DIS);
2740 else if (strcmp(optarg, "e") == 0)
2741 timestamp_set_type(TS_EPOCH);
2742 else if (strcmp(optarg, "u") == 0)
2743 timestamp_set_type(TS_UTC);
2744 else if (strcmp(optarg, "ud") == 0)
2745 timestamp_set_type(TS_UTC_WITH_DATE);
2747 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2748 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2749 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2753 case 'u': /* Seconds type */
2754 if (strcmp(optarg, "s") == 0)
2755 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2756 else if (strcmp(optarg, "hms") == 0)
2757 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2759 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2760 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2765 /* ext ops were already processed just ignore them this time*/
2768 /* We won't call the init function for the stat this soon
2769 as it would disallow MATE's fields (which are registered
2770 by the preferences set callback) from being used as
2771 part of a tap filter. Instead, we just add the argument
2772 to a list of stat arguments. */
2773 if (!process_stat_cmd_arg(optarg)) {
2774 cmdarg_err("Invalid -z argument.");
2775 cmdarg_err_cont(" -z argument must be one of :");
2776 list_stat_cmd_args();
2781 case '?': /* Bad flag - print usage message */
2790 if (cf_name != NULL) {
2792 * Input file name specified with "-r" *and* specified as a regular
2793 * command-line argument.
2795 cmdarg_err("File name specified both with -r and regular argument");
2799 * Input file name not specified with "-r", and a command-line argument
2800 * was specified; treat it as the input file name.
2802 * Yes, this is different from tshark, where non-flag command-line
2803 * arguments are a filter, but this works better on GUI desktops
2804 * where a command can be specified to be run to open a particular
2805 * file - yes, you could have "-r" as the last part of the command,
2806 * but that's a bit ugly.
2808 cf_name = g_strdup(argv[0]);
2816 * Extra command line arguments were specified; complain.
2818 cmdarg_err("Invalid argument: %s", argv[0]);
2823 #ifndef HAVE_LIBPCAP
2824 if (capture_option_specified) {
2825 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2833 fill_in_local_interfaces(&global_capture_opts);
2834 if (start_capture && list_link_layer_types) {
2835 /* Specifying *both* is bogus. */
2836 cmdarg_err("You can't specify both -L and a live capture.");
2840 if (list_link_layer_types) {
2841 /* We're supposed to list the link-layer types for an interface;
2842 did the user also specify a capture file to be read? */
2844 /* Yes - that's bogus. */
2845 cmdarg_err("You can't specify -L and a capture file to be read.");
2848 /* No - did they specify a ring buffer option? */
2849 if (global_capture_opts.multi_files_on) {
2850 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2854 /* We're supposed to do a live capture; did the user also specify
2855 a capture file to be read? */
2856 if (start_capture && cf_name) {
2857 /* Yes - that's bogus. */
2858 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2862 /* No - was the ring buffer option specified and, if so, does it make
2864 if (global_capture_opts.multi_files_on) {
2865 /* Ring buffer works only under certain conditions:
2866 a) ring buffer does not work with temporary files;
2867 b) real_time_mode and multi_files_on are mutually exclusive -
2868 real_time_mode takes precedence;
2869 c) it makes no sense to enable the ring buffer if the maximum
2870 file size is set to "infinite". */
2871 if (global_capture_opts.save_file == NULL) {
2872 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2873 global_capture_opts.multi_files_on = FALSE;
2875 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2876 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2877 /* XXX - this must be redesigned as the conditions changed */
2882 if (start_capture || list_link_layer_types) {
2883 /* Did the user specify an interface to use? */
2884 if (!capture_opts_trim_iface(&global_capture_opts,
2885 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2890 if (list_link_layer_types) {
2891 /* Get the list of link-layer types for the capture devices. */
2892 if_capabilities_t *caps;
2895 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2897 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2898 if (device.selected) {
2899 #if defined(HAVE_PCAP_CREATE)
2900 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2902 caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2905 cmdarg_err("%s", err_str);
2909 if (caps->data_link_types == NULL) {
2910 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2913 #if defined(HAVE_PCAP_CREATE)
2914 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2916 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2918 free_if_capabilities(caps);
2924 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2925 capture_opts_trim_ring_num_files(&global_capture_opts);
2926 #endif /* HAVE_LIBPCAP */
2928 /* Notify all registered modules that have had any of their preferences
2929 changed either from one of the preferences file or from the command
2930 line that their preferences have changed. */
2934 if ((global_capture_opts.num_selected == 0) &&
2935 (prefs.capture_device != NULL)) {
2938 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2939 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2940 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2941 device.selected = TRUE;
2942 global_capture_opts.num_selected++;
2943 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2944 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2951 /* disabled protocols as per configuration file */
2952 if (gdp_path == NULL && dp_path == NULL) {
2953 set_disabled_protos_list();
2956 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2958 /* read in rc file from global and personal configuration paths. */
2959 rc_file = get_datafile_path(RC_FILE);
2960 #if GTK_CHECK_VERSION(3,0,0)
2961 /* XXX resolve later */
2963 gtk_rc_parse(rc_file);
2965 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2966 gtk_rc_parse(rc_file);
2976 /* close the splash screen, as we are going to open the main window now */
2977 splash_destroy(splash_win);
2979 /************************************************************************/
2980 /* Everything is prepared now, preferences and command line was read in */
2982 /* Pop up the main window. */
2983 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2985 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2986 recent_read_dynamic(&rf_path, &rf_open_errno);
2987 if (rf_path != NULL && rf_open_errno != 0) {
2988 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2989 "Could not open recent file\n\"%s\": %s.",
2990 rf_path, g_strerror(rf_open_errno));
2993 color_filters_enable(recent.packet_list_colorize);
2995 /* rearrange all the widgets as we now have all recent settings ready for this */
2996 main_widgets_rearrange();
2998 /* Fill in column titles. This must be done after the top level window
3001 XXX - is that still true, with fixed-width columns? */
3003 menu_recent_read_finished();
3005 main_auto_scroll_live_changed(auto_scroll_live);
3008 switch (user_font_apply()) {
3011 case FA_FONT_NOT_RESIZEABLE:
3012 /* "user_font_apply()" popped up an alert box. */
3013 /* turn off zooming - font can't be resized */
3014 case FA_FONT_NOT_AVAILABLE:
3015 /* XXX - did we successfully load the un-zoomed version earlier?
3016 If so, this *probably* means the font is available, but not at
3017 this particular zoom level, but perhaps some other failure
3018 occurred; I'm not sure you can determine which is the case,
3020 /* turn off zooming - zoom level is unavailable */
3022 /* in any other case than FA_SUCCESS, turn off zooming */
3023 recent.gui_zoom_level = 0;
3024 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3027 dnd_init(top_level);
3029 color_filters_init();
3032 capture_filter_init();
3035 /* the window can be sized only, if it's not already shown, so do it now! */
3036 main_load_window_geometry(top_level);
3038 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3041 GtkWidget *filter_te;
3042 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3043 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3045 /* Run the display filter so it goes in effect. */
3046 main_filter_packets(&cfile, dfilter, FALSE);
3049 /* If we were given the name of a capture file, read it in now;
3050 we defer it until now, so that, if we can't open it, and pop
3051 up an alert box, the alert box is more likely to come up on
3052 top of the main window - but before the preference-file-error
3053 alert box, so, if we get one of those, it's more likely to come
3056 show_main_window(TRUE);
3057 check_and_warn_user_startup(cf_name);
3058 if (rfilter != NULL) {
3059 if (!dfilter_compile(rfilter, &rfcode)) {
3060 bad_dfilter_alert_box(top_level, rfilter);
3061 rfilter_parse_failed = TRUE;
3064 if (!rfilter_parse_failed) {
3065 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3066 /* "cf_open()" succeeded, so it closed the previous
3067 capture file, and thus destroyed any previous read filter
3068 attached to "cf". */
3070 cfile.rfcode = rfcode;
3071 /* Open stat windows; we do so after creating the main window,
3072 to avoid GTK warnings, and after successfully opening the
3073 capture file, so we know we have something to compute stats
3074 on, and after registering all dissectors, so that MATE will
3075 have registered its field array and we can have a tap filter
3076 with one of MATE's late-registered fields as part of the
3078 start_requested_stats();
3080 /* Read the capture file. */
3081 switch (cf_read(&cfile, FALSE)) {
3085 /* Just because we got an error, that doesn't mean we were unable
3086 to read any of the file; we handle what we could get from the
3088 /* if the user told us to jump to a specific packet, do it now */
3089 if(go_to_packet != 0) {
3090 /* Jump to the specified frame number, kept for backward
3092 cf_goto_frame(&cfile, go_to_packet);
3093 } else if (jfilter != NULL) {
3094 /* try to compile given filter */
3095 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3096 bad_dfilter_alert_box(top_level, jfilter);
3098 /* Filter ok, jump to the first packet matching the filter
3099 conditions. Default search direction is forward, but if
3100 option d was given, search backwards */
3101 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3106 case CF_READ_ABORTED:
3112 /* If the filename is not the absolute path, prepend the current dir. This happens
3113 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3114 if (!g_path_is_absolute(cf_name)) {
3115 char *old_cf_name = cf_name;
3116 char *pwd = g_get_current_dir();
3117 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3118 g_free(old_cf_name);
3122 /* Save the name of the containing directory specified in the
3123 path name, if any; we can write over cf_name, which is a
3124 good thing, given that "get_dirname()" does write over its
3126 s = get_dirname(cf_name);
3127 set_last_open_dir(s);
3132 dfilter_free(rfcode);
3133 cfile.rfcode = NULL;
3134 show_main_window(FALSE);
3135 /* Don't call check_and_warn_user_startup(): we did it above */
3136 main_set_for_capture_in_progress(FALSE);
3137 set_capture_if_dialog_for_capture_in_progress(FALSE);
3142 if (start_capture) {
3143 if (global_capture_opts.save_file != NULL) {
3144 /* Save the directory name for future file dialogs. */
3145 /* (get_dirname overwrites filename) */
3146 s = get_dirname(g_strdup(global_capture_opts.save_file));
3147 set_last_open_dir(s);
3150 /* "-k" was specified; start a capture. */
3151 show_main_window(FALSE);
3152 check_and_warn_user_startup(cf_name);
3154 /* If no user interfaces were specified on the command line,
3155 copy the list of selected interfaces to the set of interfaces
3156 to use for this capture. */
3157 if (global_capture_opts.ifaces->len == 0)
3158 collect_ifaces(&global_capture_opts);
3159 if (capture_start(&global_capture_opts)) {
3160 /* The capture started. Open stat windows; we do so after creating
3161 the main window, to avoid GTK warnings, and after successfully
3162 opening the capture file, so we know we have something to compute
3163 stats on, and after registering all dissectors, so that MATE will
3164 have registered its field array and we can have a tap filter with
3165 one of MATE's late-registered fields as part of the filter. */
3166 start_requested_stats();
3169 show_main_window(FALSE);
3170 check_and_warn_user_startup(cf_name);
3171 main_set_for_capture_in_progress(FALSE);
3172 set_capture_if_dialog_for_capture_in_progress(FALSE);
3175 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3176 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3177 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3179 #else /* HAVE_LIBPCAP */
3180 show_main_window(FALSE);
3181 check_and_warn_user_startup(cf_name);
3182 main_set_for_capture_in_progress(FALSE);
3183 set_capture_if_dialog_for_capture_in_progress(FALSE);
3184 #endif /* HAVE_LIBPCAP */
3187 /* register our pid if we are being run from a U3 device */
3190 profile_store_persconffiles (FALSE);
3192 #ifdef HAVE_GTKOSXAPPLICATION
3193 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3194 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3195 gtk_osxapplication_ready(theApp);
3198 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3201 gtk_iface_mon_start();
3204 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3206 /* ... back from GTK, we're going down now! */
3209 gtk_iface_mon_stop();
3212 /* deregister our pid */
3213 u3_deregister_pid();
3217 AirPDcapDestroyContext(&airpdcap_ctx);
3220 /* hide the (unresponsive) main window, while asking the user to close the console window */
3221 gtk_widget_hide(top_level);
3223 #ifdef HAVE_GTKOSXAPPLICATION
3224 g_object_unref(theApp);
3227 /* Shutdown windows sockets */
3230 /* For some unknown reason, the "atexit()" call in "create_console()"
3231 doesn't arrange that "destroy_console()" be called when we exit,
3232 so we call it here if a console was created. */
3241 /* We build this as a GUI subsystem application on Win32, so
3242 "WinMain()", not "main()", gets called.
3244 Hack shamelessly stolen from the Win32 port of the GIMP. */
3246 #define _stdcall __attribute__((stdcall))
3250 WinMain (struct HINSTANCE__ *hInstance,
3251 struct HINSTANCE__ *hPrevInstance,
3255 INITCOMMONCONTROLSEX comm_ctrl;
3258 * Initialize our DLL search path. MUST be called before LoadLibrary
3261 ws_init_dll_search_path();
3263 /* Initialize our controls. Required for native Windows file dialogs. */
3264 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3265 comm_ctrl.dwSize = sizeof(comm_ctrl);
3266 /* Includes the animate, header, hot key, list view, progress bar,
3267 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3270 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3271 InitCommonControlsEx(&comm_ctrl);
3273 /* RichEd20.DLL is needed for filter entries. */
3274 ws_load_library("riched20.dll");
3276 has_console = FALSE;
3277 console_wait = FALSE;
3278 return main (__argc, __argv);
3281 /* The code to create and desstroy console windows should not be necessary,
3282 at least as I read the GLib source code, as it looks as if GLib is, on
3283 Win32, *supposed* to create a console window into which to display its
3286 That doesn't happen, however. I suspect there's something completely
3287 broken about that code in GLib-for-Win32, and that it may be related
3288 to the breakage that forces us to just call "printf()" on the message
3289 rather than passing the message on to "g_log_default_handler()"
3290 (which is the routine that does the aforementioned non-functional
3291 console window creation). */
3294 * If this application has no console window to which its standard output
3295 * would go, create one.
3298 create_console(void)
3300 if (stdin_capture) {
3301 /* We've been handed "-i -". Don't mess with stdio. */
3306 /* We have no console to which to print the version string, so
3307 create one and make it the standard input, output, and error. */
3310 * See if we have an existing console (i.e. we were run from a
3313 if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3314 if (AllocConsole()) {
3315 console_wait = TRUE;
3316 SetConsoleTitle(_T("Wireshark Debug Console"));
3318 return; /* couldn't create console */
3322 ws_freopen("CONIN$", "r", stdin);
3323 ws_freopen("CONOUT$", "w", stdout);
3324 ws_freopen("CONOUT$", "w", stderr);
3325 fprintf(stdout, "\n");
3326 fprintf(stderr, "\n");
3328 /* Now register "destroy_console()" as a routine to be called just
3329 before the application exits, so that we can destroy the console
3330 after the user has typed a key (so that the console doesn't just
3331 disappear out from under them, giving the user no chance to see
3332 the message(s) we put in there). */
3333 atexit(destroy_console);
3335 /* Well, we have a console now. */
3341 destroy_console(void)
3344 printf("\n\nPress any key to exit\n");
3353 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3354 const char *message, gpointer user_data _U_)
3361 /* ignore log message, if log_level isn't interesting based
3362 upon the console log preferences.
3363 If the preferences haven't been loaded loaded yet, display the
3366 The default console_log_level preference value is such that only
3367 ERROR, CRITICAL and WARNING level messages are processed;
3368 MESSAGE, INFO and DEBUG level messages are ignored. */
3369 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3370 prefs.console_log_level != 0) {
3375 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3376 /* the user wants a console or the application will terminate immediately */
3380 /* For some unknown reason, the above doesn't appear to actually cause
3381 anything to be sent to the standard output, so we'll just splat the
3382 message out directly, just to make sure it gets out. */
3384 switch(log_level & G_LOG_LEVEL_MASK) {
3385 case G_LOG_LEVEL_ERROR:
3388 case G_LOG_LEVEL_CRITICAL:
3391 case G_LOG_LEVEL_WARNING:
3394 case G_LOG_LEVEL_MESSAGE:
3397 case G_LOG_LEVEL_INFO:
3400 case G_LOG_LEVEL_DEBUG:
3404 fprintf(stderr, "unknown log_level %u\n", log_level);
3406 g_assert_not_reached();
3409 /* create a "timestamp" */
3411 today = localtime(&curr);
3413 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3414 today->tm_hour, today->tm_min, today->tm_sec,
3415 log_domain != NULL ? log_domain : "",
3418 if(log_level & G_LOG_LEVEL_ERROR) {
3419 /* wait for a key press before the following error handler will terminate the program
3420 this way the user at least can read the error message */
3421 printf("\n\nPress any key to exit\n");
3425 /* XXX - on UN*X, should we just use g_log_default_handler()?
3426 We want the error messages to go to the standard output;
3427 on Mac OS X, that will cause them to show up in various
3428 per-user logs accessible through Console (details depend
3429 on whether you're running 10.0 through 10.4 or running
3430 10.5 and later), and, on other UN*X desktop environments,
3431 if they don't show up in some form of console log, that's
3432 a deficiency in that desktop environment. (Too bad
3433 Windows doesn't set the standard output and error for
3434 GUI apps to something that shows up in such a log.) */
3435 g_log_default_handler(log_domain, log_level, message, user_data);
3442 * Helper for main_widgets_rearrange()
3444 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3445 gtk_container_remove(GTK_CONTAINER(data), widget);
3448 static GtkWidget *main_widget_layout(gint layout_content)
3450 switch(layout_content) {
3451 case(layout_pane_content_none):
3453 case(layout_pane_content_plist):
3455 case(layout_pane_content_pdetails):
3457 case(layout_pane_content_pbytes):
3458 return byte_nb_ptr_gbl;
3460 g_assert_not_reached();
3467 * Rearrange the main window widgets
3469 void main_widgets_rearrange(void) {
3470 GtkWidget *first_pane_widget1, *first_pane_widget2;
3471 GtkWidget *second_pane_widget1, *second_pane_widget2;
3472 gboolean split_top_left = FALSE;
3474 /* be a bit faster */
3475 gtk_widget_hide(main_vbox);
3477 /* be sure we don't lose a widget while rearranging */
3478 g_object_ref(G_OBJECT(menubar));
3479 g_object_ref(G_OBJECT(main_tb));
3480 g_object_ref(G_OBJECT(filter_tb));
3481 g_object_ref(G_OBJECT(wireless_tb));
3482 g_object_ref(G_OBJECT(pkt_scrollw));
3483 g_object_ref(G_OBJECT(tv_scrollw));
3484 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3485 g_object_ref(G_OBJECT(statusbar));
3486 g_object_ref(G_OBJECT(main_pane_v1));
3487 g_object_ref(G_OBJECT(main_pane_v2));
3488 g_object_ref(G_OBJECT(main_pane_h1));
3489 g_object_ref(G_OBJECT(main_pane_h2));
3490 g_object_ref(G_OBJECT(welcome_pane));
3492 /* empty all containers participating */
3493 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3494 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3495 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3496 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3497 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3499 statusbar_widgets_emptying(statusbar);
3501 /* add the menubar always at the top */
3502 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3505 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3507 /* filter toolbar in toolbar area */
3508 if (!prefs.filter_toolbar_show_in_statusbar) {
3509 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3512 /* airpcap toolbar */
3513 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3515 /* fill the main layout panes */
3516 switch(prefs.gui_layout_type) {
3517 case(layout_type_5):
3518 main_first_pane = main_pane_v1;
3519 main_second_pane = main_pane_v2;
3520 split_top_left = FALSE;
3522 case(layout_type_2):
3523 main_first_pane = main_pane_v1;
3524 main_second_pane = main_pane_h1;
3525 split_top_left = FALSE;
3527 case(layout_type_1):
3528 main_first_pane = main_pane_v1;
3529 main_second_pane = main_pane_h1;
3530 split_top_left = TRUE;
3532 case(layout_type_4):
3533 main_first_pane = main_pane_h1;
3534 main_second_pane = main_pane_v1;
3535 split_top_left = FALSE;
3537 case(layout_type_3):
3538 main_first_pane = main_pane_h1;
3539 main_second_pane = main_pane_v1;
3540 split_top_left = TRUE;
3542 case(layout_type_6):
3543 main_first_pane = main_pane_h1;
3544 main_second_pane = main_pane_h2;
3545 split_top_left = FALSE;
3548 main_first_pane = NULL;
3549 main_second_pane = NULL;
3550 g_assert_not_reached();
3552 if (split_top_left) {
3553 first_pane_widget1 = main_second_pane;
3554 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3555 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3556 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3558 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3559 first_pane_widget2 = main_second_pane;
3560 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3561 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3563 if (first_pane_widget1 != NULL)
3564 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3565 if (first_pane_widget2 != NULL)
3566 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3567 if (second_pane_widget1 != NULL)
3568 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3569 if (second_pane_widget2 != NULL)
3570 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3572 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3575 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3578 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3580 /* filter toolbar in statusbar hbox */
3581 if (prefs.filter_toolbar_show_in_statusbar) {
3582 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3585 /* statusbar widgets */
3586 statusbar_widgets_pack(statusbar);
3588 /* hide widgets on users recent settings */
3589 main_widgets_show_or_hide();
3591 gtk_widget_show(main_vbox);
3595 is_widget_visible(GtkWidget *widget, gpointer data)
3597 gboolean *is_visible = data;
3600 if (gtk_widget_get_visible(widget))
3607 main_widgets_show_or_hide(void)
3609 gboolean main_second_pane_show;
3611 if (recent.main_toolbar_show) {
3612 gtk_widget_show(main_tb);
3614 gtk_widget_hide(main_tb);
3617 statusbar_widgets_show_or_hide(statusbar);
3619 if (recent.filter_toolbar_show) {
3620 gtk_widget_show(filter_tb);
3622 gtk_widget_hide(filter_tb);
3625 if (recent.wireless_toolbar_show) {
3626 gtk_widget_show(wireless_tb);
3628 gtk_widget_hide(wireless_tb);
3631 if (recent.packet_list_show && have_capture_file) {
3632 gtk_widget_show(pkt_scrollw);
3634 gtk_widget_hide(pkt_scrollw);
3637 if (recent.tree_view_show && have_capture_file) {
3638 gtk_widget_show(tv_scrollw);
3640 gtk_widget_hide(tv_scrollw);
3643 if (recent.byte_view_show && have_capture_file) {
3644 gtk_widget_show(byte_nb_ptr_gbl);
3646 gtk_widget_hide(byte_nb_ptr_gbl);
3649 if (have_capture_file) {
3650 gtk_widget_show(main_first_pane);
3652 gtk_widget_hide(main_first_pane);
3656 * Is anything in "main_second_pane" visible?
3657 * If so, show it, otherwise hide it.
3659 main_second_pane_show = FALSE;
3660 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3661 &main_second_pane_show);
3662 if (main_second_pane_show) {
3663 gtk_widget_show(main_second_pane);
3665 gtk_widget_hide(main_second_pane);
3668 if (!have_capture_file) {
3670 gtk_widget_show(welcome_pane);
3673 gtk_widget_hide(welcome_pane);
3678 /* called, when the window state changes (minimized, maximized, ...) */
3680 window_state_event_cb (GtkWidget *widget _U_,
3684 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3686 if( (event->type) == (GDK_WINDOW_STATE)) {
3687 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3688 /* we might have dialogs popped up while we where iconified,
3690 display_queued_messages();
3698 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3700 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3702 if (event->keyval == GDK_F8) {
3703 new_packet_list_next();
3705 } else if (event->keyval == GDK_F7) {
3706 new_packet_list_prev();
3708 } else if (event->state & NO_SHIFT_MOD_MASK) {
3709 return FALSE; /* Skip control, alt, and other modifiers */
3711 * A comment in gdkkeysyms.h says that it's autogenerated from
3712 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3713 * don't explicitly say so, isprint() should work as expected
3716 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3717 /* Forward the keypress on to the display filter entry */
3718 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3719 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3720 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3728 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3730 GtkAccelGroup *accel;
3733 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3734 main_set_window_name("The Wireshark Network Analyzer");
3736 gtk_widget_set_name(top_level, "main window");
3737 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3739 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3740 G_CALLBACK(window_state_event_cb), NULL);
3741 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3742 G_CALLBACK(top_level_key_pressed_cb), NULL );
3744 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3745 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3746 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3747 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3748 gtk_widget_show(main_vbox);
3751 menubar = main_menu_new(&accel);
3753 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3754 /* Mac OS X native menus are created and displayed by main_menu_new() */
3755 if(!prefs_p->gui_macosx_style) {
3757 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3758 gtk_widget_show(menubar);
3759 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3764 main_tb = toolbar_new();
3765 gtk_widget_show (main_tb);
3767 /* Filter toolbar */
3768 filter_tb = filter_toolbar_new();
3771 pkt_scrollw = new_packet_list_create();
3772 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3773 gtk_widget_show_all(pkt_scrollw);
3776 tv_scrollw = proto_tree_view_new(prefs_p, &tree_view_gbl);
3777 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3778 gtk_widget_show(tv_scrollw);
3780 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3781 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3782 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3783 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3784 gtk_widget_show(tree_view_gbl);
3787 byte_nb_ptr_gbl = byte_view_new();
3788 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3789 gtk_widget_show(byte_nb_ptr_gbl);
3791 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3792 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3794 /* Panes for the packet list, tree, and byte view */
3795 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3796 gtk_widget_show(main_pane_v1);
3797 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3798 gtk_widget_show(main_pane_v2);
3799 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3800 gtk_widget_show(main_pane_h1);
3801 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3802 gtk_widget_show(main_pane_h2);
3804 wireless_tb = airpcap_toolbar_new();
3806 gtk_widget_show(wireless_tb);
3808 wireless_tb = ws80211_toolbar_new();
3811 statusbar = statusbar_new();
3812 gtk_widget_show(statusbar);
3814 /* Pane for the welcome screen */
3815 welcome_pane = welcome_new();
3816 gtk_widget_show(welcome_pane);
3820 show_main_window(gboolean doing_work)
3822 main_set_for_capture_file(doing_work);
3824 /*** we have finished all init things, show the main window ***/
3825 gtk_widget_show(top_level);
3827 /* the window can be maximized only, if it's visible, so do it after show! */
3828 main_load_window_geometry(top_level);
3830 /* process all pending GUI events before continue */
3831 while (gtk_events_pending()) gtk_main_iteration();
3833 /* Pop up any queued-up alert boxes. */
3834 display_queued_messages();
3836 /* Move the main window to the front, in case it isn't already there */
3837 gdk_window_raise(gtk_widget_get_window(top_level));
3840 airpcap_toolbar_show(wireless_tb);
3841 #endif /* HAVE_AIRPCAP */
3844 /* Fill in capture options with values from the preferences */
3846 prefs_to_capture_opts(void)
3849 /* Set promiscuous mode from the preferences setting. */
3850 /* the same applies to other preferences settings as well. */
3851 global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
3852 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3853 global_capture_opts.show_info = prefs.capture_show_info;
3854 global_capture_opts.real_time_mode = prefs.capture_real_time;
3855 auto_scroll_live = prefs.capture_auto_scroll;
3856 #endif /* HAVE_LIBPCAP */
3858 /* Set the name resolution code's flags from the preferences. */
3859 gbl_resolv_flags = prefs.name_resolve;
3862 static void copy_global_profile (const gchar *profile_name)
3864 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3866 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3867 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3868 "Can't create directory\n\"%s\":\n%s.",
3869 pf_dir_path, g_strerror(errno));
3871 g_free(pf_dir_path);
3874 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3875 &pf_dir_path, &pf_dir_path2) == -1) {
3876 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3877 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3878 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3880 g_free(pf_filename);
3881 g_free(pf_dir_path);
3882 g_free(pf_dir_path2);
3886 /* Change configuration profile */
3887 void change_configuration_profile (const gchar *profile_name)
3889 char *gdp_path, *dp_path;
3893 /* First check if profile exists */
3894 if (!profile_exists(profile_name, FALSE)) {
3895 if (profile_exists(profile_name, TRUE)) {
3896 /* Copy from global profile */
3897 copy_global_profile (profile_name);
3899 /* No personal and no global profile exists */
3904 /* Then check if changing to another profile */
3905 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3909 /* Get the current geometry, before writing it to disk */
3910 main_save_window_geometry(top_level);
3912 if (profile_exists(get_profile_name(), FALSE)) {
3913 /* Write recent file for profile we are leaving, if it still exists */
3914 write_profile_recent();
3917 /* Set profile name and update the status bar */
3918 set_profile_name (profile_name);
3919 profile_bar_update ();
3920 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3922 /* Reset current preferences and apply the new */
3926 (void) read_configuration_files (&gdp_path, &dp_path);
3928 recent_read_profile_static(&rf_path, &rf_open_errno);
3929 if (rf_path != NULL && rf_open_errno != 0) {
3930 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3931 "Could not open common recent file\n\"%s\": %s.",
3932 rf_path, g_strerror(rf_open_errno));
3934 if (recent.gui_fileopen_remembered_dir &&
3935 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3936 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3938 timestamp_set_type (recent.gui_time_format);
3939 timestamp_set_seconds_type (recent.gui_seconds_format);
3940 color_filters_enable(recent.packet_list_colorize);
3942 prefs_to_capture_opts();
3944 macros_post_update();
3946 /* Update window view and redraw the toolbar */
3947 main_titlebar_update();
3948 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3949 toolbar_redraw_all();
3951 /* Enable all protocols and disable from the disabled list */
3953 if (gdp_path == NULL && dp_path == NULL) {
3954 set_disabled_protos_list();
3957 /* Reload color filters */
3958 color_filters_reload();
3960 /* Reload list of interfaces on welcome page */
3961 welcome_if_panel_reload();
3963 /* Recreate the packet list according to new preferences */
3964 new_packet_list_recreate ();
3965 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3968 /* Update menus with new recent values */
3969 menu_recent_read_finished();
3971 /* Reload pane geometry, must be done after recreating the list */
3972 main_pane_load_window_geometry();
3975 /** redissect packets and update UI */
3976 void redissect_packets(void)
3978 cf_redissect_packets(&cfile);
3979 status_expert_update();