5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10 * needed by dissect routines
11 * Jeff Foster, 2001/03/12, added support tabbed hex display windowss
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <gdk/gdkkeysyms.h>
33 #if GTK_CHECK_VERSION(3,0,0)
34 # include <gdk/gdkkeysyms-compat.h>
47 #include "wsutil/wsgetopt.h"
50 #ifdef _WIN32 /* Needed for console I/O */
52 /* AttachConsole() needs this #define! */
53 #define _WIN32_WINNT 0x0501
59 #ifdef HAVE_LIBPORTAUDIO
60 #include <portaudio.h>
61 #endif /* HAVE_LIBPORTAUDIO */
63 #include <epan/epan.h>
64 #include <epan/filesystem.h>
65 #include <wsutil/privileges.h>
66 #include <epan/epan_dissect.h>
67 #include <epan/timestamp.h>
68 #include <epan/plugins.h>
69 #include <epan/dfilter/dfilter.h>
70 #include <epan/strutil.h>
71 #include <epan/addr_resolv.h>
72 #include <epan/emem.h>
73 #include <epan/ex-opt.h>
74 #include <epan/funnel.h>
75 #include <epan/expert.h>
76 #include <epan/frequency-utils.h>
77 #include <epan/prefs.h>
78 #include <epan/prefs-int.h>
80 #include <epan/stat_cmd_args.h>
82 #include <epan/column.h>
84 /* general (not GTK specific) */
86 #include "../summary.h"
87 #include "../filters.h"
88 #include "../disabled_protos.h"
90 #include "../color_filters.h"
92 #include "../register.h"
93 #include "../ringbuffer.h"
95 #include "../clopts_common.h"
96 #include "../console_io.h"
97 #include "../cmdarg_err.h"
98 #include "../version_info.h"
103 #include "gtk_iface_monitor.h"
105 #include "ui/alert_box.h"
106 #include "ui/main_statusbar.h"
107 #include "ui/recent.h"
108 #include "ui/recent_utils.h"
109 #include "ui/simple_dialog.h"
110 #include "ui/ui_util.h"
113 #include "ui/capture_globals.h"
114 #include "ui/iface_lists.h"
117 #include <wsutil/file_util.h>
120 #include "capture_ui_utils.h"
121 #include "capture-pcap-util.h"
122 #include "capture_ifinfo.h"
124 #include "capture_sync.h"
128 #include "capture-wpcap.h"
129 #include "capture_wpcap_packet.h"
130 #include <tchar.h> /* Needed for Unicode */
131 #include <wsutil/unicode-utils.h>
132 #include <commctrl.h>
133 #include <shellapi.h>
137 #include "ui/gtk/file_dlg.h"
138 #include "ui/gtk/gtkglobals.h"
139 #include "ui/gtk/color_utils.h"
140 #include "ui/gtk/gui_utils.h"
141 #include "ui/gtk/color_dlg.h"
142 #include "ui/gtk/filter_dlg.h"
143 #include "ui/gtk/fileset_dlg.h"
144 #include "ui/gtk/uat_gui.h"
145 #include "ui/gtk/main.h"
146 #include "ui/gtk/main_80211_toolbar.h"
147 #include "ui/gtk/main_airpcap_toolbar.h"
148 #include "ui/gtk/main_filter_toolbar.h"
149 #include "ui/gtk/main_titlebar.h"
150 #include "ui/gtk/menus.h"
151 #include "ui/gtk/main_menubar_private.h"
152 #include "ui/gtk/macros_dlg.h"
153 #include "ui/gtk/main_statusbar_private.h"
154 #include "ui/gtk/main_toolbar.h"
155 #include "ui/gtk/main_toolbar_private.h"
156 #include "ui/gtk/main_welcome.h"
157 #include "ui/gtk/drag_and_drop.h"
158 #include "ui/gtk/capture_file_dlg.h"
159 #include "ui/gtk/packet_panes.h"
160 #include "ui/gtk/keys.h"
161 #include "ui/gtk/packet_win.h"
162 #include "ui/gtk/stock_icons.h"
163 #include "ui/gtk/find_dlg.h"
164 #include "ui/gtk/follow_tcp.h"
165 #include "ui/gtk/font_utils.h"
166 #include "ui/gtk/about_dlg.h"
167 #include "ui/gtk/help_dlg.h"
168 #include "ui/gtk/decode_as_dlg.h"
169 #include "ui/gtk/webbrowser.h"
170 #include "ui/gtk/capture_dlg.h"
171 #include "ui/gtk/capture_if_dlg.h"
172 #include "ui/gtk/tap_param_dlg.h"
173 #include "ui/gtk/prefs_column.h"
174 #include "ui/gtk/prefs_dlg.h"
175 #include "ui/gtk/proto_help.h"
176 #include "ui/gtk/packet_list.h"
177 #include "ui/gtk/filter_expression_save_dlg.h"
179 #include "ui/gtk/old-gtk-compat.h"
182 #include "../../image/wsicon16.xpm"
183 #include "../../image/wsicon32.xpm"
184 #include "../../image/wsicon48.xpm"
185 #include "../../image/wsicon64.xpm"
186 #include "../../image/wsiconcap16.xpm"
187 #include "../../image/wsiconcap32.xpm"
188 #include "../../image/wsiconcap48.xpm"
193 #include "airpcap_loader.h"
194 #include "airpcap_dlg.h"
195 #include "airpcap_gui_utils.h"
198 #include <epan/crypt/airpdcap_ws.h>
201 #ifdef HAVE_GTKOSXAPPLICATION
202 #include <igemacintegration/gtkosxapplication.h>
206 * Files under personal and global preferences directories in which
207 * GTK settings for Wireshark are stored.
209 #define RC_FILE "gtkrc"
213 static gboolean capture_stopping;
215 /* "exported" main widgets */
216 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
218 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
219 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
220 static GtkWidget *main_first_pane, *main_second_pane;
222 /* internally used widgets */
223 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
225 GtkWidget *wireless_tb;
227 int airpcap_dll_ret_val = -1;
230 GString *comp_info_str, *runtime_info_str;
232 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
234 static guint tap_update_timer_id;
237 static gboolean has_console; /* TRUE if app has console */
238 static gboolean console_wait; /* "Press any key..." */
239 static void destroy_console(void);
240 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
242 static void console_log_handler(const char *log_domain,
243 GLogLevelFlags log_level, const char *message, gpointer user_data);
245 static void create_main_window(gint, gint, gint, e_prefs*);
246 static void show_main_window(gboolean);
247 static void main_save_window_geometry(GtkWidget *widget);
250 /* Match selected byte pattern */
252 match_selected_cb_do(GtkWidget *filter_te, gpointer data, int action, gchar *text)
254 char *cur_filter, *new_filter;
256 if ((!text) || (0 == strlen(text))) {
257 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
264 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
266 switch (action&MATCH_SELECTED_MASK) {
268 case MATCH_SELECTED_REPLACE:
269 new_filter = g_strdup(text);
272 case MATCH_SELECTED_AND:
273 if ((!cur_filter) || (0 == strlen(cur_filter)))
274 new_filter = g_strdup(text);
276 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
279 case MATCH_SELECTED_OR:
280 if ((!cur_filter) || (0 == strlen(cur_filter)))
281 new_filter = g_strdup(text);
283 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
286 case MATCH_SELECTED_NOT:
287 new_filter = g_strconcat("!(", text, ")", NULL);
290 case MATCH_SELECTED_AND_NOT:
291 if ((!cur_filter) || (0 == strlen(cur_filter)))
292 new_filter = g_strconcat("!(", text, ")", NULL);
294 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
297 case MATCH_SELECTED_OR_NOT:
298 if ((!cur_filter) || (0 == strlen(cur_filter)))
299 new_filter = g_strconcat("!(", text, ")", NULL);
301 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
305 g_assert_not_reached();
310 /* Free up the copy we got of the old filter text. */
313 /* Don't change the current display filter if we only want to copy the filter */
314 if (action&MATCH_SELECTED_COPY_ONLY) {
315 GString *gtk_text_str = g_string_new("");
316 g_string_append(gtk_text_str, new_filter);
317 copy_to_clipboard(gtk_text_str);
318 g_string_free(gtk_text_str, TRUE);
320 /* create a new one and set the display filter entry accordingly */
321 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
323 /* Run the display filter so it goes in effect. */
324 if (action&MATCH_SELECTED_APPLY_NOW)
325 main_filter_packets(&cfile, new_filter, FALSE);
328 /* Free up the new filter text. */
333 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
337 if (cfile.finfo_selected) {
338 filter = proto_construct_match_selected_string(cfile.finfo_selected,
340 match_selected_cb_do(g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),data, action, filter);
345 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
349 if (cfile.finfo_selected) {
350 filter = proto_construct_match_selected_string(cfile.finfo_selected,
352 if ((!filter) || (0 == strlen(filter))) {
353 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
354 "Could not acquire information to build a filter!\n"
355 "Try expanding or choosing another item.");
360 color_display_with_filter(filter);
363 color_filters_reset_tmp();
365 color_filters_set_tmp(filt_nr,filter, FALSE);
367 packet_list_colorize_packets();
373 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
375 gchar *selected_proto_url;
376 gchar *proto_abbrev = data;
381 if (cfile.finfo_selected) {
382 /* open wiki page using the protocol abbreviation */
383 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
384 browser_open_url(selected_proto_url);
385 g_free(selected_proto_url);
388 case(ESD_BTN_CANCEL):
391 g_assert_not_reached();
397 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
400 const gchar *proto_abbrev;
404 if (cfile.finfo_selected) {
405 /* convert selected field to protocol abbreviation */
406 /* XXX - could this conversion be simplified? */
407 field_id = cfile.finfo_selected->hfinfo->id;
408 /* if the selected field isn't a protocol, get it's parent */
409 if(!proto_registrar_is_protocol(field_id)) {
410 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
413 proto_abbrev = proto_registrar_get_abbrev(field_id);
415 if (!proto_is_private(field_id)) {
416 /* ask the user if the wiki page really should be opened */
417 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
418 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
420 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
422 "The Wireshark Wiki is a collaborative approach to provide information "
423 "about Wireshark in several ways (not limited to protocol specifics).\n"
425 "This Wiki is new, so the page of the selected protocol "
426 "may not exist and/or may not contain valuable information.\n"
428 "As everyone can edit the Wiki and add new content (or extend existing), "
429 "you are encouraged to add information if you can.\n"
431 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
433 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
434 "which will save you a lot of editing and will give a consistent look over the pages.",
435 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
436 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
438 /* appologize to the user that the wiki page cannot be opened */
439 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
440 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
442 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
444 "Since this is a private protocol, such information is not available in "
445 "a public wiki. Therefore this wiki entry is blocked.\n"
447 "Sorry for the inconvenience.\n",
448 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
453 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
455 gchar *selected_proto_url;
456 gchar *proto_abbrev = data;
460 if (cfile.finfo_selected) {
461 /* open reference page using the protocol abbreviation */
462 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
463 browser_open_url(selected_proto_url);
464 g_free(selected_proto_url);
467 case(ESD_BTN_CANCEL):
470 g_assert_not_reached();
475 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
478 const gchar *proto_abbrev;
482 if (cfile.finfo_selected) {
483 /* convert selected field to protocol abbreviation */
484 /* XXX - could this conversion be simplified? */
485 field_id = cfile.finfo_selected->hfinfo->id;
486 /* if the selected field isn't a protocol, get it's parent */
487 if(!proto_registrar_is_protocol(field_id)) {
488 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
491 proto_abbrev = proto_registrar_get_abbrev(field_id);
493 if (!proto_is_private(field_id)) {
494 /* ask the user if the wiki page really should be opened */
495 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
496 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
498 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
500 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
501 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
503 /* appologize to the user that the wiki page cannot be opened */
504 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
505 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
507 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
509 "Since this is a private protocol, such information is not available on "
510 "a public website. Therefore this filter entry is blocked.\n"
512 "Sorry for the inconvenience.\n",
513 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
519 is_address_column (gint column)
521 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
522 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
523 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
524 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
525 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
534 get_ip_address_list_from_packet_list_row(gpointer data)
536 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
537 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
540 GList *addr_list = NULL;
542 fdata = (frame_data *) packet_list_get_row_data(row);
547 if (!cf_read_frame (&cfile, fdata))
548 return NULL; /* error reading the frame */
550 epan_dissect_init(&edt, FALSE, FALSE);
551 col_custom_prime_edt(&edt, &cfile.cinfo);
553 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
554 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
556 /* First check selected column */
557 if (is_address_column (column)) {
558 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
561 for (col = 0; col < cfile.cinfo.num_cols; col++) {
562 /* Then check all columns except the selected */
563 if ((col != column) && (is_address_column (col))) {
564 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
568 epan_dissect_cleanup(&edt);
575 get_filter_from_packet_list_row_and_column(gpointer data)
577 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
578 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
582 fdata = (frame_data *) packet_list_get_row_data(row);
587 if (!cf_read_frame(&cfile, fdata))
588 return NULL; /* error reading the frame */
589 /* proto tree, visible. We need a proto tree if there's custom columns */
590 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
591 col_custom_prime_edt(&edt, &cfile.cinfo);
593 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
595 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
597 if ((cfile.cinfo.col_custom_occurrence[column]) ||
598 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
600 /* Only construct the filter when a single occurrence is displayed
601 * otherwise we might end up with a filter like "ip.proto==1,6".
603 * Or do we want to be able to filter on multiple occurrences so that
604 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
607 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
608 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
609 /* leak a little but safer than ep_ here */
610 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
611 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
612 if (hfi->parent == -1) {
614 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
615 } else if (hfi->type == FT_STRING) {
616 /* Custom string, add quotes */
617 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
618 cfile.cinfo.col_expr.col_expr_val[column]);
622 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
623 cfile.cinfo.col_expr.col_expr_val[column]);
628 epan_dissect_cleanup(&edt);
635 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
637 match_selected_cb_do(g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
640 get_filter_from_packet_list_row_and_column(data));
643 /* This function allows users to right click in the details window and copy the text
644 * information to the operating systems clipboard.
646 * We first check to see if a string representation is setup in the tree and then
647 * read the string. If not available then we try to grab the value. If all else
648 * fails we display a message to the user to indicate the copy could not be completed.
651 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
653 GString *gtk_text_str = g_string_new("");
654 char labelstring[256];
655 char *stringpointer = labelstring;
659 case COPY_SELECTED_DESCRIPTION:
660 if (cfile.finfo_selected->rep &&
661 strlen (cfile.finfo_selected->rep->representation) > 0) {
662 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
665 case COPY_SELECTED_FIELDNAME:
666 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
667 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
670 case COPY_SELECTED_VALUE:
671 if (cfile.edt !=0 ) {
672 g_string_append(gtk_text_str,
673 get_node_field_value(cfile.finfo_selected, cfile.edt));
680 if (gtk_text_str->len == 0) {
681 /* If no representation then... Try to read the value */
682 proto_item_fill_label(cfile.finfo_selected, stringpointer);
683 g_string_append(gtk_text_str, stringpointer);
686 if (gtk_text_str->len == 0) {
687 /* Could not get item so display error msg */
688 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
690 /* Copy string to clipboard */
691 copy_to_clipboard(gtk_text_str);
693 g_string_free(gtk_text_str, TRUE); /* Free the memory */
697 /* mark as reference time frame */
699 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
703 frame->flags.ref_time=1;
704 cfile.ref_time_count++;
706 frame->flags.ref_time=0;
707 cfile.ref_time_count--;
709 cf_reftime_packets(&cfile);
710 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
711 packet_list_freeze();
712 cfile.displayed_count--;
713 packet_list_recreate_visible_rows();
716 packet_list_queue_draw();
720 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
724 timestamp_set_type(TS_RELATIVE);
725 recent.gui_time_format = TS_RELATIVE;
726 cf_timestamp_auto_precision(&cfile);
727 packet_list_queue_draw();
732 g_assert_not_reached();
735 if (cfile.current_frame) {
736 set_frame_reftime(!cfile.current_frame->flags.ref_time,
737 cfile.current_frame, cfile.current_row);
743 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
745 static GtkWidget *reftime_dialog = NULL;
749 if (cfile.current_frame) {
750 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
751 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
752 "%sSwitch to the appropriate Time Display Format?%s\n\n"
753 "Time References don't work well with the currently selected Time Display Format.\n\n"
754 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
755 simple_dialog_primary_start(), simple_dialog_primary_end());
756 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
758 set_frame_reftime(!cfile.current_frame->flags.ref_time,
759 cfile.current_frame, cfile.current_row);
763 case REFTIME_FIND_NEXT:
764 cf_find_packet_time_reference(&cfile, SD_FORWARD);
766 case REFTIME_FIND_PREV:
767 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
773 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
775 cf_find_packet_marked(&cfile, SD_FORWARD);
779 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
781 cf_find_packet_marked(&cfile, SD_BACKWARD);
785 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
788 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
790 gboolean has_blurb = FALSE;
791 guint length = 0, byte_len;
792 GtkWidget *byte_view;
793 const guint8 *byte_data;
798 /* if nothing is selected */
799 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
802 * Which byte view is displaying the current protocol tree
805 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
806 if (byte_view == NULL)
809 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
810 if (byte_data == NULL)
813 cf_unselect_field(&cfile);
814 packet_hex_print(byte_view, byte_data,
815 cfile.current_frame, NULL, byte_len);
816 proto_help_menu_modify(sel, &cfile);
819 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
822 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
824 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
825 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
826 g_assert(byte_data != NULL);
828 cfile.finfo_selected = finfo;
829 set_menus_for_selected_tree_row(&cfile);
832 if (finfo->hfinfo->blurb != NULL &&
833 finfo->hfinfo->blurb[0] != '\0') {
835 length = (guint) strlen(finfo->hfinfo->blurb);
837 length = (guint) strlen(finfo->hfinfo->name);
839 finfo_length = finfo->length + finfo->appendix_length;
841 if (finfo_length == 0) {
843 } else if (finfo_length == 1) {
844 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
846 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
848 statusbar_pop_field_msg(); /* get rid of current help msg */
850 statusbar_push_field_msg(" %s (%s)%s",
851 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
852 finfo->hfinfo->abbrev, len_str);
855 * Don't show anything if the field name is zero-length;
856 * the pseudo-field for "proto_tree_add_text()" is such
857 * a field, and we don't want "Text (text)" showing up
858 * on the status line if you've selected such a field.
860 * XXX - there are zero-length fields for which we *do*
861 * want to show the field name.
863 * XXX - perhaps the name and abbrev field should be null
864 * pointers rather than null strings for that pseudo-field,
865 * but we'd have to add checks for null pointers in some
866 * places if we did that.
868 * Or perhaps protocol tree items added with
869 * "proto_tree_add_text()" should have -1 as the field index,
870 * with no pseudo-field being used, but that might also
871 * require special checks for -1 to be added.
873 statusbar_push_field_msg("%s", "");
876 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
878 proto_help_menu_modify(sel, &cfile);
881 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
883 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
886 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
888 expand_all_tree(cfile.edt->tree, tree_view_gbl);
891 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
893 if (cfile.finfo_selected) {
894 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
895 cfile.finfo_selected->hfinfo->abbrev,0);
896 /* Recreate the packet list according to new preferences */
897 packet_list_recreate ();
898 if (!prefs.gui_use_pref_save) {
901 cfile.columns_changed = FALSE; /* Reset value */
905 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
908 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
910 /* the mouse position is at an entry, expand that one */
911 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
912 gtk_tree_path_free(path);
916 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
917 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
919 if (cfile.edt->tree) {
920 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
924 /* Update main window items based on whether there's a capture in progress. */
926 main_set_for_capture_in_progress(gboolean capture_in_progress)
928 set_menus_for_capture_in_progress(capture_in_progress);
931 set_toolbar_for_capture_in_progress(capture_in_progress);
933 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
937 /* Update main window items based on whether we have a capture file. */
939 main_set_for_capture_file(gboolean have_capture_file_in)
941 have_capture_file = have_capture_file_in;
943 main_widgets_show_or_hide();
946 /* Update main window items based on whether we have captured packets. */
948 main_set_for_captured_packets(gboolean have_captured_packets)
950 set_menus_for_captured_packets(have_captured_packets);
951 set_toolbar_for_captured_packets(have_captured_packets);
954 /* Update main window items based on whether we have a packet history. */
956 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
958 set_menus_for_packet_history(back_history, forward_history);
959 set_toolbar_for_packet_history(back_history, forward_history);
965 /* get the current geometry, before writing it to disk */
966 main_save_window_geometry(top_level);
968 /* write user's recent file to disk
969 * It is no problem to write this file, even if we do not quit */
970 write_profile_recent();
973 /* XXX - should we check whether the capture file is an
974 unsaved temporary file for a live capture and, if so,
975 pop up a "do you want to exit without saving the capture
976 file?" dialog, and then just return, leaving said dialog
977 box to forcibly quit if the user clicks "OK"?
979 If so, note that this should be done in a subroutine that
980 returns TRUE if we do so, and FALSE otherwise, and if it
981 returns TRUE we should return TRUE without nuking anything.
983 Note that, if we do that, we might also want to check if
984 an "Update list of packets in real time" capture is in
985 progress and, if so, ask whether they want to terminate
986 the capture and discard it, and return TRUE, before nuking
987 any child capture, if they say they don't want to do so. */
990 /* Nuke any child capture in progress. */
991 capture_kill_child(&global_capture_opts);
994 /* Are we in the middle of reading a capture? */
995 if (cfile.state == FILE_READ_IN_PROGRESS) {
996 /* Yes, so we can't just close the file and quit, as
997 that may yank the rug out from under the read in
998 progress; instead, just set the state to
999 "FILE_READ_ABORTED" and return - the code doing the read
1000 will check for that and, if it sees that, will clean
1002 cfile.state = FILE_READ_ABORTED;
1004 /* Say that the window should *not* be deleted;
1005 that'll be done by the code that cleans up. */
1008 /* Close any capture file we have open; on some OSes, you
1009 can't unlink a temporary capture file if you have it
1011 "cf_close()" will unlink it after closing it if
1012 it's a temporary file.
1014 We do this here, rather than after the main loop returns,
1015 as, after the main loop returns, the main window may have
1016 been destroyed (if this is called due to a "destroy"
1017 even on the main window rather than due to the user
1018 selecting a menu item), and there may be a crash
1019 or other problem when "cf_close()" tries to
1020 clean up stuff in the main window.
1022 XXX - is there a better place to put this?
1023 Or should we have a routine that *just* closes the
1024 capture file, and doesn't do anything with the UI,
1025 which we'd call here, and another routine that
1026 calls that routine and also cleans up the UI, which
1027 we'd call elsewhere? */
1030 /* Exit by leaving the main loop, so that any quit functions
1031 we registered get called. */
1034 /* Say that the window should be deleted. */
1040 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1042 /* If we're in the middle of stopping a capture, don't do anything;
1043 the user can try deleting the window after the capture stops. */
1044 if (capture_stopping)
1047 /* If there's unsaved data, let the user save it first.
1048 If they cancel out of it, don't quit. */
1049 if (do_file_close(&cfile, TRUE, " before quitting"))
1050 return main_do_quit();
1052 return TRUE; /* will this keep the window from being deleted? */
1057 main_pane_load_window_geometry(void)
1059 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1060 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1061 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1062 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1068 main_load_window_geometry(GtkWidget *widget)
1070 window_geometry_t geom;
1072 geom.set_pos = prefs.gui_geometry_save_position;
1073 geom.x = recent.gui_geometry_main_x;
1074 geom.y = recent.gui_geometry_main_y;
1075 geom.set_size = prefs.gui_geometry_save_size;
1076 if (recent.gui_geometry_main_width > 0 &&
1077 recent.gui_geometry_main_height > 0) {
1078 geom.width = recent.gui_geometry_main_width;
1079 geom.height = recent.gui_geometry_main_height;
1080 geom.set_maximized = prefs.gui_geometry_save_maximized;
1082 /* We assume this means the width and height weren't set in
1083 the "recent" file (or that there is no "recent" file),
1084 and weren't set to a default value, so we don't set the
1085 size. (The "recent" file code rejects non-positive width
1086 and height values.) */
1087 geom.set_size = FALSE;
1089 geom.maximized = recent.gui_geometry_main_maximized;
1091 window_set_geometry(widget, &geom);
1093 main_pane_load_window_geometry();
1094 statusbar_load_window_geometry();
1099 main_save_window_geometry(GtkWidget *widget)
1101 window_geometry_t geom;
1103 window_get_geometry(widget, &geom);
1105 if (prefs.gui_geometry_save_position) {
1106 recent.gui_geometry_main_x = geom.x;
1107 recent.gui_geometry_main_y = geom.y;
1110 if (prefs.gui_geometry_save_size) {
1111 recent.gui_geometry_main_width = geom.width;
1112 recent.gui_geometry_main_height = geom.height;
1115 if(prefs.gui_geometry_save_maximized) {
1116 recent.gui_geometry_main_maximized = geom.maximized;
1119 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1120 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1121 statusbar_save_window_geometry();
1125 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1127 /* If there's unsaved data, let the user save it first. */
1128 if (do_file_close(&cfile, TRUE, " before quitting"))
1133 print_usage(gboolean print_ver) {
1143 fprintf(output, "Wireshark " VERSION "%s\n"
1144 "Interactively dump and analyze network traffic.\n"
1145 "See http://www.wireshark.org for more information.\n"
1148 wireshark_svnversion, get_copyright_info());
1152 fprintf(output, "\n");
1153 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1154 fprintf(output, "\n");
1157 fprintf(output, "Capture interface:\n");
1158 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1159 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1160 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1161 fprintf(output, " -p don't capture in promiscuous mode\n");
1162 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1163 fprintf(output, " -S update packet display when new packets are captured\n");
1164 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1165 #ifdef HAVE_PCAP_CREATE
1166 fprintf(output, " -I capture in monitor mode, if available\n");
1168 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1169 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1171 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1172 fprintf(output, " -D print list of interfaces and exit\n");
1173 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1174 fprintf(output, "\n");
1175 fprintf(output, "Capture stop conditions:\n");
1176 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1177 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1178 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1179 fprintf(output, " files:NUM - stop after NUM files\n");
1180 /*fprintf(output, "\n");*/
1181 fprintf(output, "Capture output:\n");
1182 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1183 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1184 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1185 #endif /* HAVE_LIBPCAP */
1186 #ifdef HAVE_PCAP_REMOTE
1187 fprintf(output, "RPCAP options:\n");
1188 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1190 /*fprintf(output, "\n");*/
1191 fprintf(output, "Input file:\n");
1192 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1194 fprintf(output, "\n");
1195 fprintf(output, "Processing:\n");
1196 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1197 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1198 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1200 fprintf(output, "\n");
1201 fprintf(output, "User interface:\n");
1202 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1203 fprintf(output, " -d <display filter> start with the given display filter\n");
1204 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1205 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1206 fprintf(output, " filter\n");
1207 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1208 fprintf(output, " -m <font> set the font name used for most text\n");
1209 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1210 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1211 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1212 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1214 fprintf(output, "\n");
1215 fprintf(output, "Output:\n");
1216 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1218 fprintf(output, "\n");
1219 fprintf(output, "Miscellaneous:\n");
1220 fprintf(output, " -h display this help and exit\n");
1221 fprintf(output, " -v display version info and exit\n");
1222 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1223 fprintf(output, " persdata:path - personal data files\n");
1224 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1225 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1227 fprintf(output, " --display=DISPLAY X display to use\n");
1242 printf(PACKAGE " " VERSION "%s\n"
1249 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1250 runtime_info_str->str);
1258 * Print to the standard error. On Windows, create a console for the
1259 * standard error to show up on, if necessary.
1260 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1261 * terminal isn't the standard error?
1264 vfprintf_stderr(const char *fmt, va_list ap)
1269 vfprintf(stderr, fmt, ap);
1273 fprintf_stderr(const char *fmt, ...)
1278 vfprintf_stderr(fmt, ap);
1283 * Report an error in command-line arguments.
1284 * Creates a console on Windows.
1287 cmdarg_err(const char *fmt, ...)
1291 fprintf_stderr("wireshark: ");
1293 vfprintf_stderr(fmt, ap);
1295 fprintf_stderr("\n");
1299 * Report additional information for an error in command-line arguments.
1300 * Creates a console on Windows.
1301 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1302 * terminal isn't the standard error?
1305 cmdarg_err_cont(const char *fmt, ...)
1310 vfprintf_stderr(fmt, ap);
1311 fprintf_stderr("\n");
1316 Once every 3 seconds we get a callback here which we use to update
1320 tap_update_cb(gpointer data _U_)
1322 draw_tap_listeners(FALSE);
1326 /* Restart the tap update display timer with new configured interval */
1327 void reset_tap_update_timer(void)
1329 g_source_remove(tap_update_timer_id);
1330 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1334 * Periodically process outstanding hostname lookups. If we have new items,
1335 * redraw the packet list and tree view.
1339 resolv_update_cb(gpointer data _U_)
1341 /* Anything new show up? */
1342 if (host_name_lookup_process(NULL)) {
1343 if (gtk_widget_get_window(pkt_scrollw))
1344 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1345 if (gtk_widget_get_window(tv_scrollw))
1346 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1349 /* Always check. Even if we don't do async lookups we could still get
1350 passive updates, e.g. from DNS packets. */
1355 /* Set main_window_name and it's icon title to the capture filename */
1357 set_display_filename(capture_file *cf)
1359 gchar *display_name;
1363 display_name = cf_get_display_name(cf);
1364 window_name = g_strdup_printf("%s%s", cf->unsaved_changes ? "*" : "",
1366 g_free(display_name);
1367 main_set_window_name(window_name);
1368 g_free(window_name);
1370 main_set_window_name("The Wireshark Network Analyzer");
1374 /* Update various parts of the main window for a capture file "unsaved
1375 changes" change - update the title to reflect whether there are
1376 unsaved changes or not, and update the menus and toolbar to
1377 enable or disable the "Save" operation. */
1379 main_update_for_unsaved_changes(capture_file *cf)
1381 set_display_filename(cf);
1382 set_menus_for_capture_file(cf);
1383 set_toolbar_for_capture_file(cf);
1388 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1390 /* Update menubar and toolbar */
1391 menu_auto_scroll_live_changed(auto_scroll_live_in);
1392 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1394 /* change auto scroll state */
1395 auto_scroll_live = auto_scroll_live_in;
1400 main_colorize_changed(gboolean packet_list_colorize)
1402 /* Update menubar and toolbar */
1403 menu_colorize_changed(packet_list_colorize);
1404 toolbar_colorize_changed(packet_list_colorize);
1406 /* change colorization */
1407 if(packet_list_colorize != recent.packet_list_colorize) {
1408 recent.packet_list_colorize = packet_list_colorize;
1409 color_filters_enable(packet_list_colorize);
1410 packet_list_colorize_packets();
1414 static GtkWidget *close_dlg = NULL;
1417 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1419 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1424 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1426 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1431 main_cf_cb_file_closing(capture_file *cf)
1433 /* if we have more than 10000 packets, show a splash screen while closing */
1434 /* XXX - don't know a better way to decide whether to show or not,
1435 * as most of the time is spend in various calls that destroy various
1436 * data structures, so it wouldn't be easy to use a progress bar,
1437 * rather than, say, a progress spinner, here! */
1438 if(cf->count > 10000) {
1439 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1440 "%sClosing file!%s\n\nPlease wait ...",
1441 simple_dialog_primary_start(),
1442 simple_dialog_primary_end());
1443 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1446 /* Destroy all windows that refer to the
1447 capture file we're closing. */
1448 destroy_packet_wins();
1450 /* Restore the standard title bar message. */
1451 main_set_window_name("The Wireshark Network Analyzer");
1453 /* Disable all menu items that make sense only if you have a capture. */
1454 set_menus_for_capture_file(NULL);
1455 set_toolbar_for_capture_file(NULL);
1456 main_set_for_captured_packets(FALSE);
1457 set_menus_for_selected_packet(cf);
1458 main_set_for_capture_in_progress(FALSE);
1459 set_capture_if_dialog_for_capture_in_progress(FALSE);
1460 set_menus_for_selected_tree_row(cf);
1462 /* Set up main window for no capture file. */
1463 main_set_for_capture_file(FALSE);
1465 main_window_update();
1469 main_cf_cb_file_closed(capture_file *cf _U_)
1471 if(close_dlg != NULL) {
1472 splash_destroy(close_dlg);
1479 main_cf_cb_file_read_started(capture_file *cf _U_)
1481 tap_param_dlg_update();
1483 /* Set up main window for a capture file. */
1484 main_set_for_capture_file(TRUE);
1488 main_cf_cb_file_read_finished(capture_file *cf)
1492 if (!cf->is_tempfile && cf->filename) {
1493 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1494 add_menu_recent_capture_file(cf->filename);
1496 /* Remember folder for next Open dialog and save it in recent */
1497 dir_path = get_dirname(g_strdup(cf->filename));
1498 set_last_open_dir(dir_path);
1502 /* Update the appropriate parts of the main window. */
1503 main_update_for_unsaved_changes(cf);
1505 /* Enable menu items that make sense if you have some captured packets. */
1506 main_set_for_captured_packets(TRUE);
1510 main_cf_cb_file_rescan_finished(capture_file *cf)
1514 if (!cf->is_tempfile && cf->filename) {
1515 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1516 add_menu_recent_capture_file(cf->filename);
1518 /* Remember folder for next Open dialog and save it in recent */
1519 dir_path = get_dirname(g_strdup(cf->filename));
1520 set_last_open_dir(dir_path);
1524 /* Update the appropriate parts of the main window. */
1525 main_update_for_unsaved_changes(cf);
1529 static GList *icon_list_create(
1530 const char **icon16_xpm,
1531 const char **icon32_xpm,
1532 const char **icon48_xpm,
1533 const char **icon64_xpm)
1535 GList *icon_list = NULL;
1536 GdkPixbuf * pixbuf16;
1537 GdkPixbuf * pixbuf32;
1538 GdkPixbuf * pixbuf48;
1539 GdkPixbuf * pixbuf64;
1542 if(icon16_xpm != NULL) {
1543 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1545 icon_list = g_list_append(icon_list, pixbuf16);
1548 if(icon32_xpm != NULL) {
1549 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1551 icon_list = g_list_append(icon_list, pixbuf32);
1554 if(icon48_xpm != NULL) {
1555 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1557 icon_list = g_list_append(icon_list, pixbuf48);
1560 if(icon64_xpm != NULL) {
1561 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1563 icon_list = g_list_append(icon_list, pixbuf64);
1570 main_capture_set_main_window_title(capture_options *capture_opts)
1572 GString *title = g_string_new("");
1574 g_string_append(title, "Capturing ");
1575 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1576 main_set_window_name(title->str);
1577 g_string_free(title, TRUE);
1581 main_capture_cb_capture_prepared(capture_options *capture_opts)
1583 static GList *icon_list = NULL;
1585 main_capture_set_main_window_title(capture_opts);
1587 if(icon_list == NULL) {
1588 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1590 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1592 /* Disable menu items that make no sense if you're currently running
1594 main_set_for_capture_in_progress(TRUE);
1595 set_capture_if_dialog_for_capture_in_progress(TRUE);
1597 /* Don't set up main window for a capture file. */
1598 main_set_for_capture_file(FALSE);
1602 main_capture_cb_capture_update_started(capture_options *capture_opts)
1604 /* We've done this in "prepared" above, but it will be cleared while
1605 switching to the next multiple file. */
1606 main_capture_set_main_window_title(capture_opts);
1608 main_set_for_capture_in_progress(TRUE);
1609 set_capture_if_dialog_for_capture_in_progress(TRUE);
1611 /* Enable menu items that make sense if you have some captured
1612 packets (yes, I know, we don't have any *yet*). */
1613 main_set_for_captured_packets(TRUE);
1615 /* Set up main window for a capture file. */
1616 main_set_for_capture_file(TRUE);
1620 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1622 capture_file *cf = capture_opts->cf;
1623 static GList *icon_list = NULL;
1625 /* The capture isn't stopping any more - it's stopped. */
1626 capture_stopping = FALSE;
1628 if (!cf->is_tempfile && cf->filename) {
1629 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1630 add_menu_recent_capture_file(cf->filename);
1633 /* Update the main window as appropriate */
1634 main_update_for_unsaved_changes(cf);
1636 /* Enable menu items that make sense if you're not currently running
1638 main_set_for_capture_in_progress(FALSE);
1639 set_capture_if_dialog_for_capture_in_progress(FALSE);
1641 /* Set up main window for a capture file. */
1642 main_set_for_capture_file(TRUE);
1644 if(icon_list == NULL) {
1645 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1647 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1649 if(global_capture_opts.quit_after_cap) {
1650 /* command line asked us to quit after the capture */
1651 /* don't pop up a dialog to ask for unsaved files etc. */
1657 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1659 /* Don't set up main window for a capture file. */
1660 main_set_for_capture_file(FALSE);
1664 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1667 capture_file *cf = capture_opts->cf;
1669 static GList *icon_list = NULL;
1671 /* The capture isn't stopping any more - it's stopped. */
1672 capture_stopping = FALSE;
1674 /*set_display_filename(cf);*/
1676 /* Enable menu items that make sense if you're not currently running
1678 main_set_for_capture_in_progress(FALSE);
1679 set_capture_if_dialog_for_capture_in_progress(FALSE);
1681 /* Restore the standard title bar message */
1682 /* (just in case we have trouble opening the capture file). */
1683 main_set_window_name("The Wireshark Network Analyzer");
1685 if(icon_list == NULL) {
1686 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1688 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1690 /* We don't have loaded the capture file, this will be done later.
1691 * For now we still have simply a blank screen. */
1693 if(global_capture_opts.quit_after_cap) {
1694 /* command line asked us to quit after the capture */
1695 /* don't pop up a dialog to ask for unsaved files etc. */
1701 main_capture_cb_capture_stopping(capture_options *capture_opts _U_)
1703 capture_stopping = TRUE;
1704 set_menus_for_capture_stopping();
1706 set_toolbar_for_capture_stopping();
1708 set_capture_if_dialog_for_capture_stopping();
1713 main_capture_cb_capture_failed(capture_options *capture_opts _U_)
1715 static GList *icon_list = NULL;
1717 /* Capture isn't stopping any more. */
1718 capture_stopping = FALSE;
1720 /* the capture failed before the first packet was captured
1721 reset title, menus and icon */
1723 main_set_window_name("The Wireshark Network Analyzer");
1725 main_set_for_capture_in_progress(FALSE);
1726 set_capture_if_dialog_for_capture_in_progress(FALSE);
1728 main_set_for_capture_file(FALSE);
1730 if(icon_list == NULL) {
1731 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1733 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1736 if(global_capture_opts.quit_after_cap) {
1737 /* command line asked us to quit after the capture */
1738 /* don't pop up a dialog to ask for unsaved files etc. */
1742 #endif /* HAVE_LIBPCAP */
1745 main_cf_cb_packet_selected(gpointer data)
1747 capture_file *cf = data;
1749 /* Display the GUI protocol tree and packet bytes.
1750 XXX - why do we dump core if we call "proto_tree_draw()"
1751 before calling "add_byte_views()"? */
1752 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1753 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1755 /* Note: Both string and hex value searches in the packet data produce a non-zero
1756 search_pos if successful */
1757 if(cf->search_in_progress &&
1758 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1759 highlight_field(cf->edt->tvb, cf->search_pos,
1760 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1763 /* A packet is selected. */
1764 set_menus_for_selected_packet(cf);
1768 main_cf_cb_packet_unselected(capture_file *cf)
1770 /* No packet is being displayed; clear the hex dump pane by getting
1771 rid of all the byte views. */
1772 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1773 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1775 /* Add a placeholder byte view so that there's at least something
1776 displayed in the byte view notebook. */
1777 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1779 /* And clear the protocol tree display as well. */
1780 proto_tree_draw(NULL, tree_view_gbl);
1782 /* No packet is selected. */
1783 set_menus_for_selected_packet(cf);
1787 main_cf_cb_field_unselected(capture_file *cf)
1789 set_menus_for_selected_tree_row(cf);
1793 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1796 case(cf_cb_file_opened):
1797 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1798 fileset_file_opened(data);
1800 case(cf_cb_file_closing):
1801 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1802 main_cf_cb_file_closing(data);
1804 case(cf_cb_file_closed):
1805 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1806 main_cf_cb_file_closed(data);
1807 fileset_file_closed();
1809 case(cf_cb_file_read_started):
1810 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1811 main_cf_cb_file_read_started(data);
1813 case(cf_cb_file_read_finished):
1814 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1815 main_cf_cb_file_read_finished(data);
1817 case(cf_cb_file_reload_started):
1818 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1819 main_cf_cb_file_read_started(data);
1821 case(cf_cb_file_reload_finished):
1822 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1823 main_cf_cb_file_read_finished(data);
1825 case(cf_cb_file_rescan_started):
1826 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1828 case(cf_cb_file_rescan_finished):
1829 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1830 main_cf_cb_file_rescan_finished(data);
1832 case(cf_cb_file_fast_save_finished):
1833 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1834 main_cf_cb_file_rescan_finished(data);
1836 case(cf_cb_packet_selected):
1837 main_cf_cb_packet_selected(data);
1839 case(cf_cb_packet_unselected):
1840 main_cf_cb_packet_unselected(data);
1842 case(cf_cb_field_unselected):
1843 main_cf_cb_field_unselected(data);
1845 case(cf_cb_file_save_started):
1846 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1848 case(cf_cb_file_save_finished):
1849 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1851 case(cf_cb_file_save_failed):
1852 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1854 case(cf_cb_file_save_stopped):
1855 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1857 case(cf_cb_file_export_specified_packets_started):
1858 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1860 case(cf_cb_file_export_specified_packets_finished):
1861 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1863 case(cf_cb_file_export_specified_packets_failed):
1864 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1866 case(cf_cb_file_export_specified_packets_stopped):
1867 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1870 g_warning("main_cf_callback: event %u unknown", event);
1871 g_assert_not_reached();
1877 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1879 #ifdef HAVE_GTKOSXAPPLICATION
1880 GtkOSXApplication *theApp;
1883 case(capture_cb_capture_prepared):
1884 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1885 main_capture_cb_capture_prepared(capture_opts);
1887 case(capture_cb_capture_update_started):
1888 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1889 main_capture_cb_capture_update_started(capture_opts);
1890 #ifdef HAVE_GTKOSXAPPLICATION
1891 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1892 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1895 case(capture_cb_capture_update_continue):
1896 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1898 case(capture_cb_capture_update_finished):
1899 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1900 main_capture_cb_capture_update_finished(capture_opts);
1902 case(capture_cb_capture_fixed_started):
1903 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1904 main_capture_cb_capture_fixed_started(capture_opts);
1906 case(capture_cb_capture_fixed_continue):
1907 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1909 case(capture_cb_capture_fixed_finished):
1910 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1911 main_capture_cb_capture_fixed_finished(capture_opts);
1913 case(capture_cb_capture_stopping):
1914 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1915 /* Beware: this state won't be called, if the capture child
1916 * closes the capturing on it's own! */
1917 #ifdef HAVE_GTKOSXAPPLICATION
1918 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1919 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1921 main_capture_cb_capture_stopping(capture_opts);
1923 case(capture_cb_capture_failed):
1924 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1925 main_capture_cb_capture_failed(capture_opts);
1928 g_warning("main_capture_callback: event %u unknown", event);
1929 g_assert_not_reached();
1935 get_gtk_compiled_info(GString *str)
1937 g_string_append(str, "with ");
1938 g_string_append_printf(str,
1939 #ifdef GTK_MAJOR_VERSION
1940 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1943 "GTK+ (version unknown)");
1945 g_string_append(str, ", ");
1947 g_string_append(str, "with Cairo ");
1948 g_string_append(str, CAIRO_VERSION_STRING);
1949 g_string_append(str, ", ");
1952 g_string_append(str, "with Pango ");
1953 g_string_append(str, PANGO_VERSION_STRING);
1954 g_string_append(str, ", ");
1960 get_gui_compiled_info(GString *str)
1962 epan_get_compiled_version_info(str);
1964 g_string_append(str, ", ");
1965 #ifdef HAVE_LIBPORTAUDIO
1966 #ifdef PORTAUDIO_API_1
1967 g_string_append(str, "with PortAudio <= V18");
1968 #else /* PORTAUDIO_API_1 */
1969 g_string_append(str, "with ");
1970 g_string_append(str, Pa_GetVersionText());
1971 #endif /* PORTAUDIO_API_1 */
1972 #else /* HAVE_LIBPORTAUDIO */
1973 g_string_append(str, "without PortAudio");
1974 #endif /* HAVE_LIBPORTAUDIO */
1976 g_string_append(str, ", ");
1978 get_compiled_airpcap_version(str);
1980 g_string_append(str, "without AirPcap");
1985 get_gui_runtime_info(GString *str)
1987 epan_get_runtime_version_info(str);
1990 g_string_append(str, ", ");
1991 get_runtime_airpcap_version(str);
1995 g_string_append(str, ", ");
1996 u3_runtime_info(str);
2001 read_configuration_files(char **gdp_path, char **dp_path)
2003 int gpf_open_errno, gpf_read_errno;
2004 int cf_open_errno, df_open_errno;
2005 int gdp_open_errno, gdp_read_errno;
2006 int dp_open_errno, dp_read_errno;
2007 char *gpf_path, *pf_path;
2008 char *cf_path, *df_path;
2009 int pf_open_errno, pf_read_errno;
2012 /* load the decode as entries of this profile */
2013 load_decode_as_entries();
2015 /* Read the preference files. */
2016 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2017 &pf_open_errno, &pf_read_errno, &pf_path);
2019 if (gpf_path != NULL) {
2020 if (gpf_open_errno != 0) {
2021 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2022 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2023 g_strerror(gpf_open_errno));
2025 if (gpf_read_errno != 0) {
2026 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2027 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2028 g_strerror(gpf_read_errno));
2031 if (pf_path != NULL) {
2032 if (pf_open_errno != 0) {
2033 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2034 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2035 g_strerror(pf_open_errno));
2037 if (pf_read_errno != 0) {
2038 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2039 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2040 g_strerror(pf_read_errno));
2047 /* if the user wants a console to be always there, well, we should open one for him */
2048 if (prefs_p->gui_console_open == console_open_always) {
2053 /* Read the capture filter file. */
2054 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2055 if (cf_path != NULL) {
2056 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2057 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2058 g_strerror(cf_open_errno));
2062 /* Read the display filter file. */
2063 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2064 if (df_path != NULL) {
2065 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2066 "Could not open your display filter file\n\"%s\": %s.", df_path,
2067 g_strerror(df_open_errno));
2071 /* Read the disabled protocols file. */
2072 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2073 dp_path, &dp_open_errno, &dp_read_errno);
2074 if (*gdp_path != NULL) {
2075 if (gdp_open_errno != 0) {
2076 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2077 "Could not open global disabled protocols file\n\"%s\": %s.",
2078 *gdp_path, g_strerror(gdp_open_errno));
2080 if (gdp_read_errno != 0) {
2081 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2082 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2083 *gdp_path, g_strerror(gdp_read_errno));
2088 if (*dp_path != NULL) {
2089 if (dp_open_errno != 0) {
2090 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2091 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2092 g_strerror(dp_open_errno));
2094 if (dp_read_errno != 0) {
2095 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2096 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2097 g_strerror(dp_read_errno));
2106 /* Check if there's something important to tell the user during startup.
2107 * We want to do this *after* showing the main window so that any windows
2108 * we pop up will be above the main window.
2112 check_and_warn_user_startup(gchar *cf_name)
2114 check_and_warn_user_startup(gchar *cf_name _U_)
2117 gchar *cur_user, *cur_group;
2118 gpointer priv_warning_dialog;
2120 /* Tell the user not to run as root. */
2121 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2122 cur_user = get_cur_username();
2123 cur_group = get_cur_groupname();
2124 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2125 "Running as user \"%s\" and group \"%s\".\n"
2126 "This could be dangerous.\n\n"
2127 "If you're running Wireshark this way in order to perform live capture, "
2128 "you may want to be aware that there is a better way documented at\n"
2129 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2132 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2133 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2137 /* Warn the user if npf.sys isn't loaded. */
2138 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2139 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2140 "The NPF driver isn't running. You may have trouble\n"
2141 "capturing or listing interfaces.");
2142 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2143 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2150 /* And now our feature presentation... [ fade to music ] */
2152 main(int argc, char *argv[])
2154 char *init_progfile_dir_error;
2157 gboolean arg_error = FALSE;
2159 extern int info_update_freq; /* Found in about_dlg.c. */
2160 const gchar *filter;
2168 char *gdp_path, *dp_path;
2171 gboolean start_capture = FALSE;
2172 gboolean list_link_layer_types = FALSE;
2176 gboolean capture_option_specified = FALSE;
2183 gint pl_size = 280, tv_size = 95, bv_size = 75;
2184 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2185 dfilter_t *rfcode = NULL;
2186 gboolean rfilter_parse_failed = FALSE;
2189 GtkWidget *splash_win = NULL;
2190 GLogLevelFlags log_flags;
2191 guint go_to_packet = 0;
2192 gboolean jump_backwards = FALSE;
2193 dfilter_t *jump_to_filter = NULL;
2196 #ifdef HAVE_GTKOSXAPPLICATION
2197 GtkOSXApplication *theApp;
2201 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2202 #define OPTSTRING_B "B:"
2204 #define OPTSTRING_B ""
2205 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2206 #else /* HAVE_LIBPCAP */
2207 #define OPTSTRING_B ""
2208 #endif /* HAVE_LIBPCAP */
2209 #ifdef HAVE_PCAP_REMOTE
2210 #define OPTSTRING_A "A:"
2212 #define OPTSTRING_A ""
2214 #ifdef HAVE_PCAP_CREATE
2215 #define OPTSTRING_I "I"
2217 #define OPTSTRING_I ""
2220 #define OPTSTRING "a:" 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:"
2222 static const char optstring[] = OPTSTRING;
2224 /* Set the C-language locale to the native environment. */
2225 setlocale(LC_ALL, "");
2227 arg_list_utf_16to8(argc, argv);
2231 * Get credential information for later use, and drop privileges
2232 * before doing anything else.
2233 * Let the user know if anything happened.
2235 init_process_policies();
2236 relinquish_special_privs_perm();
2239 * Attempt to get the pathname of the executable file.
2241 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2243 /* initialize the funnel mini-api */
2244 initialize_funnel_ops();
2246 AirPDcapInitContext(&airpdcap_ctx);
2249 /* Load wpcap if possible. Do this before collecting the run-time version information */
2252 /* ... and also load the packet.dll from wpcap */
2253 wpcap_packet_load();
2256 /* Load the airpcap.dll. This must also be done before collecting
2257 * run-time version information. */
2258 airpcap_dll_ret_val = load_airpcap();
2260 switch (airpcap_dll_ret_val) {
2261 case AIRPCAP_DLL_OK:
2262 /* load the airpcap interfaces */
2263 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2265 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2266 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2267 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2270 airpcap_if_active = NULL;
2274 /* select the first ad default (THIS SHOULD BE CHANGED) */
2275 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2280 * XXX - Maybe we need to warn the user if one of the following happens???
2282 case AIRPCAP_DLL_OLD:
2283 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2286 case AIRPCAP_DLL_ERROR:
2287 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2290 case AIRPCAP_DLL_NOT_FOUND:
2291 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2295 #endif /* HAVE_AIRPCAP */
2297 /* Start windows sockets */
2298 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2301 profile_store_persconffiles (TRUE);
2303 /* Assemble the compile-time version information string */
2304 comp_info_str = g_string_new("Compiled ");
2306 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2308 /* Assemble the run-time version information string */
2309 runtime_info_str = g_string_new("Running ");
2310 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2312 /* Read the profile independent recent file. We have to do this here so we can */
2313 /* set the profile before it can be set from the command line parameterts */
2314 recent_read_static(&rf_path, &rf_open_errno);
2315 if (rf_path != NULL && rf_open_errno != 0) {
2316 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2317 "Could not open common recent file\n\"%s\": %s.",
2318 rf_path, g_strerror(rf_open_errno));
2321 /* "pre-scan" the command line parameters, if we have "console only"
2322 parameters. We do this so we don't start GTK+ if we're only showing
2323 command-line help or version information.
2325 XXX - this pre-scan is done before we start GTK+, so we haven't
2326 run gtk_init() on the arguments. That means that GTK+ arguments
2327 have not been removed from the argument list; those arguments
2328 begin with "--", and will be treated as an error by getopt().
2330 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2333 optind_initial = optind;
2334 while ((opt = getopt(argc, argv, optstring)) != -1) {
2336 case 'C': /* Configuration Profile */
2337 if (profile_exists (optarg, FALSE)) {
2338 set_profile_name (optarg);
2340 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2344 case 'D': /* Print a list of capture devices and exit */
2346 if_list = capture_interface_list(&err, &err_str);
2347 if (if_list == NULL) {
2349 case CANT_GET_INTERFACE_LIST:
2350 case DONT_HAVE_PCAP:
2351 cmdarg_err("%s", err_str);
2355 case NO_INTERFACES_FOUND:
2356 cmdarg_err("There are no interfaces on which a capture can be done");
2361 capture_opts_print_interfaces(if_list);
2362 free_interface_list(if_list);
2365 capture_option_specified = TRUE;
2369 case 'h': /* Print help and exit */
2375 if (strcmp(optarg, "-") == 0)
2376 stdin_capture = TRUE;
2379 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2380 status = filesystem_opt(opt, optarg);
2382 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2386 case 'v': /* Show version and exit */
2392 * Extension command line options have to be processed before
2393 * we call epan_init() as they are supposed to be used by dissectors
2394 * or taps very early in the registration process.
2398 case '?': /* Ignore errors - the "real" scan will catch them. */
2403 /* Init the "Open file" dialog directory */
2404 /* (do this after the path settings are processed) */
2406 /* Read the profile dependent (static part) of the recent file. */
2407 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2408 /* recent lists which is done in the dynamic part. */
2409 /* We have to do this already here, so command line parameters can overwrite these values. */
2410 recent_read_profile_static(&rf_path, &rf_open_errno);
2411 if (rf_path != NULL && rf_open_errno != 0) {
2412 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2413 "Could not open recent file\n\"%s\": %s.",
2414 rf_path, g_strerror(rf_open_errno));
2417 if (recent.gui_fileopen_remembered_dir &&
2418 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2419 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2421 set_last_open_dir(get_persdatafile_dir());
2424 /* Set getopt index back to initial value, so it will start with the
2425 first command line parameter again. Also reset opterr to 1, so that
2426 error messages are printed by getopt().
2428 XXX - this seems to work on most platforms, but time will tell.
2429 The Single UNIX Specification says "The getopt() function need
2430 not be reentrant", so this isn't guaranteed to work. The Mac
2431 OS X 10.4[.x] getopt() man page says
2433 In order to use getopt() to evaluate multiple sets of arguments, or to
2434 evaluate a single set of arguments multiple times, the variable optreset
2435 must be set to 1 before the second and each additional set of calls to
2436 getopt(), and the variable optind must be reinitialized.
2440 The optreset variable was added to make it possible to call the getopt()
2441 function multiple times. This is an extension to the IEEE Std 1003.2
2442 (``POSIX.2'') specification.
2444 which I think comes from one of the other BSDs.
2446 XXX - if we want to control all the command-line option errors, so
2447 that we can display them where we choose (e.g., in a window), we'd
2448 want to leave opterr as 0, and produce our own messages using optopt.
2449 We'd have to check the value of optopt to see if it's a valid option
2450 letter, in which case *presumably* the error is "this option requires
2451 an argument but none was specified", or not a valid option letter,
2452 in which case *presumably* the error is "this option isn't valid".
2453 Some versions of getopt() let you supply a option string beginning
2454 with ':', which means that getopt() will return ':' rather than '?'
2455 for "this option requires an argument but none was specified", but
2457 optind = optind_initial;
2460 #if !GLIB_CHECK_VERSION(2,31,0)
2461 g_thread_init(NULL);
2464 /* Set the current locale according to the program environment.
2465 * We haven't localized anything, but some GTK widgets are localized
2466 * (the file selection dialogue, for example).
2467 * This also sets the C-language locale to the native environment. */
2468 setlocale (LC_ALL, "");
2470 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2471 gtk_init (&argc, &argv);
2473 cf_callback_add(main_cf_callback, NULL);
2475 capture_callback_add(main_capture_callback, NULL);
2477 cf_callback_add(statusbar_cf_callback, NULL);
2479 capture_callback_add(statusbar_capture_callback, NULL);
2482 /* Arrange that if we have no console window, and a GLib message logging
2483 routine is called to log a message, we pop up a console window.
2485 We do that by inserting our own handler for all messages logged
2486 to the default domain; that handler pops up a console if necessary,
2487 and then calls the default handler. */
2489 /* We might want to have component specific log levels later ... */
2493 G_LOG_LEVEL_CRITICAL|
2494 G_LOG_LEVEL_WARNING|
2495 G_LOG_LEVEL_MESSAGE|
2498 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2500 g_log_set_handler(NULL,
2502 console_log_handler, NULL /* user_data */);
2503 g_log_set_handler(LOG_DOMAIN_MAIN,
2505 console_log_handler, NULL /* user_data */);
2508 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2510 console_log_handler, NULL /* user_data */);
2511 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2513 console_log_handler, NULL /* user_data */);
2515 /* Set the initial values in the capture options. This might be overwritten
2516 by preference settings and then again by the command line parameters. */
2517 capture_opts_init(&global_capture_opts, &cfile);
2520 /* Initialize whatever we need to allocate colors for GTK+ */
2523 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2524 filter = get_conn_cfilter();
2525 if ( *filter != '\0' ) {
2526 info_update_freq = 1000; /* Milliseconds */
2529 /* We won't come till here, if we had a "console only" command line parameter. */
2530 splash_win = splash_new("Loading Wireshark ...");
2531 if (init_progfile_dir_error != NULL) {
2532 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2533 "Can't get pathname of Wireshark: %s.\n"
2534 "It won't be possible to capture traffic.\n"
2535 "Report this to the Wireshark developers.",
2536 init_progfile_dir_error);
2537 g_free(init_progfile_dir_error);
2540 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2542 /* Register all dissectors; we must do this before checking for the
2543 "-G" flag, as the "-G" flag dumps information registered by the
2544 dissectors, and we must do it before we read the preferences, in
2545 case any dissectors register preferences. */
2546 epan_init(register_all_protocols,register_all_protocol_handoffs,
2547 splash_update, (gpointer) splash_win,
2548 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2549 write_failure_alert_box);
2551 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2553 /* Register all tap listeners; we do this before we parse the arguments,
2554 as the "-z" argument can specify a registered tap. */
2556 /* we register the plugin taps before the other taps because
2557 stats_tree taps plugins will be registered as tap listeners
2558 by stats_tree_stat.c and need to registered before that */
2561 register_all_plugin_tap_listeners();
2564 register_all_tap_listeners();
2566 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2568 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2569 /* Removed thread code:
2570 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2573 /* this is to keep tap extensions updating once every 3 seconds */
2574 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2576 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2578 cap_file_init(&cfile);
2580 /* Fill in capture options with values from the preferences */
2581 prefs_to_capture_opts();
2583 /*#ifdef HAVE_LIBPCAP
2584 fill_in_local_interfaces();
2586 /* Now get our args */
2587 while ((opt = getopt(argc, argv, optstring)) != -1) {
2589 /*** capture option specific ***/
2590 case 'a': /* autostop criteria */
2591 case 'b': /* Ringbuffer option */
2592 case 'c': /* Capture xxx packets */
2593 case 'f': /* capture filter */
2594 case 'k': /* Start capture immediately */
2595 case 'H': /* Hide capture info dialog box */
2596 case 'p': /* Don't capture in promiscuous mode */
2597 case 'i': /* Use interface x */
2598 #ifdef HAVE_PCAP_CREATE
2599 case 'I': /* Capture in monitor mode, if available */
2601 #ifdef HAVE_PCAP_REMOTE
2602 case 'A': /* Authentication */
2604 case 's': /* Set the snapshot (capture) length */
2605 case 'S': /* "Sync" mode: used for following file ala tail -f */
2606 case 'w': /* Write to capture file xxx */
2607 case 'y': /* Set the pcap data link type */
2608 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2609 case 'B': /* Buffer size */
2610 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2612 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2618 capture_option_specified = TRUE;
2623 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2624 case 'K': /* Kerberos keytab file */
2625 read_keytab_file(optarg);
2629 /*** all non capture option specific ***/
2631 /* Configuration profile settings were already processed just ignore them this time*/
2636 case 'j': /* Search backwards for a matching packet from filter in option J */
2637 jump_backwards = TRUE;
2639 case 'g': /* Go to packet with the given packet number */
2640 go_to_packet = get_positive_int(optarg, "go to packet");
2642 case 'J': /* Jump to the first packet which matches the filter criteria */
2645 case 'l': /* Automatic scrolling in live capture mode */
2647 auto_scroll_live = TRUE;
2649 capture_option_specified = TRUE;
2653 case 'L': /* Print list of link-layer types and exit */
2655 list_link_layer_types = TRUE;
2657 capture_option_specified = TRUE;
2661 case 'm': /* Fixed-width font for the display */
2662 g_free(prefs_p->gui_font_name);
2663 prefs_p->gui_font_name = g_strdup(optarg);
2665 case 'n': /* No name resolution */
2666 gbl_resolv_flags.mac_name = FALSE;
2667 gbl_resolv_flags.network_name = FALSE;
2668 gbl_resolv_flags.transport_name = FALSE;
2669 gbl_resolv_flags.concurrent_dns = FALSE;
2671 case 'N': /* Select what types of addresses/port #s to resolve */
2672 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2673 if (badopt != '\0') {
2674 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2679 case 'o': /* Override preference from command line */
2680 switch (prefs_set_pref(optarg)) {
2683 case PREFS_SET_SYNTAX_ERR:
2684 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2687 case PREFS_SET_NO_SUCH_PREF:
2688 /* not a preference, might be a recent setting */
2689 switch (recent_set_arg(optarg)) {
2692 case PREFS_SET_SYNTAX_ERR:
2693 /* shouldn't happen, checked already above */
2694 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2697 case PREFS_SET_NO_SUCH_PREF:
2698 case PREFS_SET_OBSOLETE:
2699 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2704 g_assert_not_reached();
2707 case PREFS_SET_OBSOLETE:
2708 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2713 g_assert_not_reached();
2717 /* Path settings were already processed just ignore them this time*/
2719 case 'r': /* Read capture file xxx */
2720 /* We may set "last_open_dir" to "cf_name", and if we change
2721 "last_open_dir" later, we free the old value, so we have to
2722 set "cf_name" to something that's been allocated. */
2723 cf_name = g_strdup(optarg);
2725 case 'R': /* Read file filter */
2728 case 't': /* Time stamp type */
2729 if (strcmp(optarg, "r") == 0)
2730 timestamp_set_type(TS_RELATIVE);
2731 else if (strcmp(optarg, "a") == 0)
2732 timestamp_set_type(TS_ABSOLUTE);
2733 else if (strcmp(optarg, "ad") == 0)
2734 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2735 else if (strcmp(optarg, "d") == 0)
2736 timestamp_set_type(TS_DELTA);
2737 else if (strcmp(optarg, "dd") == 0)
2738 timestamp_set_type(TS_DELTA_DIS);
2739 else if (strcmp(optarg, "e") == 0)
2740 timestamp_set_type(TS_EPOCH);
2741 else if (strcmp(optarg, "u") == 0)
2742 timestamp_set_type(TS_UTC);
2743 else if (strcmp(optarg, "ud") == 0)
2744 timestamp_set_type(TS_UTC_WITH_DATE);
2746 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2747 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2748 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2752 case 'u': /* Seconds type */
2753 if (strcmp(optarg, "s") == 0)
2754 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2755 else if (strcmp(optarg, "hms") == 0)
2756 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2758 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2759 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2764 /* ext ops were already processed just ignore them this time*/
2767 /* We won't call the init function for the stat this soon
2768 as it would disallow MATE's fields (which are registered
2769 by the preferences set callback) from being used as
2770 part of a tap filter. Instead, we just add the argument
2771 to a list of stat arguments. */
2772 if (!process_stat_cmd_arg(optarg)) {
2773 cmdarg_err("Invalid -z argument.");
2774 cmdarg_err_cont(" -z argument must be one of :");
2775 list_stat_cmd_args();
2780 case '?': /* Bad flag - print usage message */
2789 if (cf_name != NULL) {
2791 * Input file name specified with "-r" *and* specified as a regular
2792 * command-line argument.
2794 cmdarg_err("File name specified both with -r and regular argument");
2798 * Input file name not specified with "-r", and a command-line argument
2799 * was specified; treat it as the input file name.
2801 * Yes, this is different from tshark, where non-flag command-line
2802 * arguments are a filter, but this works better on GUI desktops
2803 * where a command can be specified to be run to open a particular
2804 * file - yes, you could have "-r" as the last part of the command,
2805 * but that's a bit ugly.
2807 cf_name = g_strdup(argv[0]);
2815 * Extra command line arguments were specified; complain.
2817 cmdarg_err("Invalid argument: %s", argv[0]);
2822 #ifndef HAVE_LIBPCAP
2823 if (capture_option_specified) {
2824 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2832 fill_in_local_interfaces();
2833 if (start_capture && list_link_layer_types) {
2834 /* Specifying *both* is bogus. */
2835 cmdarg_err("You can't specify both -L and a live capture.");
2839 if (list_link_layer_types) {
2840 /* We're supposed to list the link-layer types for an interface;
2841 did the user also specify a capture file to be read? */
2843 /* Yes - that's bogus. */
2844 cmdarg_err("You can't specify -L and a capture file to be read.");
2847 /* No - did they specify a ring buffer option? */
2848 if (global_capture_opts.multi_files_on) {
2849 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2853 /* We're supposed to do a live capture; did the user also specify
2854 a capture file to be read? */
2855 if (start_capture && cf_name) {
2856 /* Yes - that's bogus. */
2857 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2861 /* No - was the ring buffer option specified and, if so, does it make
2863 if (global_capture_opts.multi_files_on) {
2864 /* Ring buffer works only under certain conditions:
2865 a) ring buffer does not work with temporary files;
2866 b) real_time_mode and multi_files_on are mutually exclusive -
2867 real_time_mode takes precedence;
2868 c) it makes no sense to enable the ring buffer if the maximum
2869 file size is set to "infinite". */
2870 if (global_capture_opts.save_file == NULL) {
2871 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2872 global_capture_opts.multi_files_on = FALSE;
2874 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2875 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2876 /* XXX - this must be redesigned as the conditions changed */
2881 if (start_capture || list_link_layer_types) {
2882 /* Did the user specify an interface to use? */
2883 if (!capture_opts_trim_iface(&global_capture_opts,
2884 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL)) {
2889 if (list_link_layer_types) {
2890 /* Get the list of link-layer types for the capture devices. */
2891 if_capabilities_t *caps;
2894 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2896 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2897 if (device.selected) {
2898 #if defined(HAVE_PCAP_CREATE)
2899 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2901 caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2904 cmdarg_err("%s", err_str);
2908 if (caps->data_link_types == NULL) {
2909 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2912 #if defined(HAVE_PCAP_CREATE)
2913 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2915 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2917 free_if_capabilities(caps);
2923 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2924 capture_opts_trim_ring_num_files(&global_capture_opts);
2925 #endif /* HAVE_LIBPCAP */
2927 /* Notify all registered modules that have had any of their preferences
2928 changed either from one of the preferences file or from the command
2929 line that their preferences have changed. */
2933 if ((global_capture_opts.num_selected == 0) &&
2934 (prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0')) {
2937 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2938 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2939 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2940 device.selected = TRUE;
2941 global_capture_opts.num_selected++;
2942 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2943 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2950 /* disabled protocols as per configuration file */
2951 if (gdp_path == NULL && dp_path == NULL) {
2952 set_disabled_protos_list();
2955 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2957 /* read in rc file from global and personal configuration paths. */
2958 rc_file = get_datafile_path(RC_FILE);
2959 #if GTK_CHECK_VERSION(3,0,0)
2960 /* XXX resolve later */
2962 gtk_rc_parse(rc_file);
2964 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2965 gtk_rc_parse(rc_file);
2975 /* close the splash screen, as we are going to open the main window now */
2976 splash_destroy(splash_win);
2978 /************************************************************************/
2979 /* Everything is prepared now, preferences and command line was read in */
2981 /* Pop up the main window. */
2982 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2984 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2985 recent_read_dynamic(&rf_path, &rf_open_errno);
2986 if (rf_path != NULL && rf_open_errno != 0) {
2987 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2988 "Could not open recent file\n\"%s\": %s.",
2989 rf_path, g_strerror(rf_open_errno));
2992 color_filters_enable(recent.packet_list_colorize);
2994 /* rearrange all the widgets as we now have all recent settings ready for this */
2995 main_widgets_rearrange();
2997 /* Fill in column titles. This must be done after the top level window
3000 XXX - is that still true, with fixed-width columns? */
3002 menu_recent_read_finished();
3004 main_auto_scroll_live_changed(auto_scroll_live);
3007 switch (user_font_apply()) {
3010 case FA_FONT_NOT_RESIZEABLE:
3011 /* "user_font_apply()" popped up an alert box. */
3012 /* turn off zooming - font can't be resized */
3013 case FA_FONT_NOT_AVAILABLE:
3014 /* XXX - did we successfully load the un-zoomed version earlier?
3015 If so, this *probably* means the font is available, but not at
3016 this particular zoom level, but perhaps some other failure
3017 occurred; I'm not sure you can determine which is the case,
3019 /* turn off zooming - zoom level is unavailable */
3021 /* in any other case than FA_SUCCESS, turn off zooming */
3022 recent.gui_zoom_level = 0;
3023 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3026 dnd_init(top_level);
3028 color_filters_init();
3031 capture_filter_init();
3034 /* the window can be sized only, if it's not already shown, so do it now! */
3035 main_load_window_geometry(top_level);
3037 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3040 GtkWidget *filter_te;
3041 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3042 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3044 /* Run the display filter so it goes in effect. */
3045 main_filter_packets(&cfile, dfilter, FALSE);
3048 /* If we were given the name of a capture file, read it in now;
3049 we defer it until now, so that, if we can't open it, and pop
3050 up an alert box, the alert box is more likely to come up on
3051 top of the main window - but before the preference-file-error
3052 alert box, so, if we get one of those, it's more likely to come
3055 show_main_window(TRUE);
3056 check_and_warn_user_startup(cf_name);
3057 if (rfilter != NULL) {
3058 if (!dfilter_compile(rfilter, &rfcode)) {
3059 bad_dfilter_alert_box(top_level, rfilter);
3060 rfilter_parse_failed = TRUE;
3063 if (!rfilter_parse_failed) {
3064 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3065 /* "cf_open()" succeeded, so it closed the previous
3066 capture file, and thus destroyed any previous read filter
3067 attached to "cf". */
3069 cfile.rfcode = rfcode;
3070 /* Open stat windows; we do so after creating the main window,
3071 to avoid GTK warnings, and after successfully opening the
3072 capture file, so we know we have something to compute stats
3073 on, and after registering all dissectors, so that MATE will
3074 have registered its field array and we can have a tap filter
3075 with one of MATE's late-registered fields as part of the
3077 start_requested_stats();
3079 /* Read the capture file. */
3080 switch (cf_read(&cfile, FALSE)) {
3084 /* Just because we got an error, that doesn't mean we were unable
3085 to read any of the file; we handle what we could get from the
3087 /* if the user told us to jump to a specific packet, do it now */
3088 if(go_to_packet != 0) {
3089 /* Jump to the specified frame number, kept for backward
3091 cf_goto_frame(&cfile, go_to_packet);
3092 } else if (jfilter != NULL) {
3093 /* try to compile given filter */
3094 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3095 bad_dfilter_alert_box(top_level, jfilter);
3097 /* Filter ok, jump to the first packet matching the filter
3098 conditions. Default search direction is forward, but if
3099 option d was given, search backwards */
3100 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3105 case CF_READ_ABORTED:
3111 /* If the filename is not the absolute path, prepend the current dir. This happens
3112 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3113 if (!g_path_is_absolute(cf_name)) {
3114 char *old_cf_name = cf_name;
3115 char *pwd = g_get_current_dir();
3116 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3117 g_free(old_cf_name);
3121 /* Save the name of the containing directory specified in the
3122 path name, if any; we can write over cf_name, which is a
3123 good thing, given that "get_dirname()" does write over its
3125 s = get_dirname(cf_name);
3126 set_last_open_dir(s);
3131 dfilter_free(rfcode);
3132 cfile.rfcode = NULL;
3133 show_main_window(FALSE);
3134 /* Don't call check_and_warn_user_startup(): we did it above */
3135 main_set_for_capture_in_progress(FALSE);
3136 set_capture_if_dialog_for_capture_in_progress(FALSE);
3141 if (start_capture) {
3142 if (global_capture_opts.save_file != NULL) {
3143 /* Save the directory name for future file dialogs. */
3144 /* (get_dirname overwrites filename) */
3145 s = get_dirname(g_strdup(global_capture_opts.save_file));
3146 set_last_open_dir(s);
3149 /* "-k" was specified; start a capture. */
3150 show_main_window(FALSE);
3151 check_and_warn_user_startup(cf_name);
3153 /* If no user interfaces were specified on the command line,
3154 copy the list of selected interfaces to the set of interfaces
3155 to use for this capture. */
3156 if (global_capture_opts.ifaces->len == 0)
3157 collect_ifaces(&global_capture_opts);
3158 if (capture_start(&global_capture_opts)) {
3159 /* The capture started. Open stat windows; we do so after creating
3160 the main window, to avoid GTK warnings, and after successfully
3161 opening the capture file, so we know we have something to compute
3162 stats on, and after registering all dissectors, so that MATE will
3163 have registered its field array and we can have a tap filter with
3164 one of MATE's late-registered fields as part of the filter. */
3165 start_requested_stats();
3168 show_main_window(FALSE);
3169 check_and_warn_user_startup(cf_name);
3170 main_set_for_capture_in_progress(FALSE);
3171 set_capture_if_dialog_for_capture_in_progress(FALSE);
3174 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3175 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3176 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3178 #else /* HAVE_LIBPCAP */
3179 show_main_window(FALSE);
3180 check_and_warn_user_startup(cf_name);
3181 main_set_for_capture_in_progress(FALSE);
3182 set_capture_if_dialog_for_capture_in_progress(FALSE);
3183 #endif /* HAVE_LIBPCAP */
3186 /* register our pid if we are being run from a U3 device */
3189 profile_store_persconffiles (FALSE);
3191 #ifdef HAVE_GTKOSXAPPLICATION
3192 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3193 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3194 gtk_osxapplication_ready(theApp);
3197 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3200 gtk_iface_mon_start();
3203 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3205 /* ... back from GTK, we're going down now! */
3208 gtk_iface_mon_stop();
3211 /* deregister our pid */
3212 u3_deregister_pid();
3216 AirPDcapDestroyContext(&airpdcap_ctx);
3219 /* hide the (unresponsive) main window, while asking the user to close the console window */
3220 gtk_widget_hide(top_level);
3222 #ifdef HAVE_GTKOSXAPPLICATION
3223 g_object_unref(theApp);
3226 /* Shutdown windows sockets */
3229 /* For some unknown reason, the "atexit()" call in "create_console()"
3230 doesn't arrange that "destroy_console()" be called when we exit,
3231 so we call it here if a console was created. */
3240 /* We build this as a GUI subsystem application on Win32, so
3241 "WinMain()", not "main()", gets called.
3243 Hack shamelessly stolen from the Win32 port of the GIMP. */
3245 #define _stdcall __attribute__((stdcall))
3249 WinMain (struct HINSTANCE__ *hInstance,
3250 struct HINSTANCE__ *hPrevInstance,
3254 INITCOMMONCONTROLSEX comm_ctrl;
3257 * Initialize our DLL search path. MUST be called before LoadLibrary
3260 ws_init_dll_search_path();
3262 /* Initialize our controls. Required for native Windows file dialogs. */
3263 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3264 comm_ctrl.dwSize = sizeof(comm_ctrl);
3265 /* Includes the animate, header, hot key, list view, progress bar,
3266 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3269 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3270 InitCommonControlsEx(&comm_ctrl);
3272 /* RichEd20.DLL is needed for filter entries. */
3273 ws_load_library("riched20.dll");
3275 has_console = FALSE;
3276 console_wait = FALSE;
3277 return main (__argc, __argv);
3280 /* The code to create and desstroy console windows should not be necessary,
3281 at least as I read the GLib source code, as it looks as if GLib is, on
3282 Win32, *supposed* to create a console window into which to display its
3285 That doesn't happen, however. I suspect there's something completely
3286 broken about that code in GLib-for-Win32, and that it may be related
3287 to the breakage that forces us to just call "printf()" on the message
3288 rather than passing the message on to "g_log_default_handler()"
3289 (which is the routine that does the aforementioned non-functional
3290 console window creation). */
3293 * If this application has no console window to which its standard output
3294 * would go, create one.
3297 create_console(void)
3299 if (stdin_capture) {
3300 /* We've been handed "-i -". Don't mess with stdio. */
3305 /* We have no console to which to print the version string, so
3306 create one and make it the standard input, output, and error. */
3309 * See if we have an existing console (i.e. we were run from a
3312 if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3313 if (AllocConsole()) {
3314 console_wait = TRUE;
3315 SetConsoleTitle(_T("Wireshark Debug Console"));
3317 return; /* couldn't create console */
3321 ws_freopen("CONIN$", "r", stdin);
3322 ws_freopen("CONOUT$", "w", stdout);
3323 ws_freopen("CONOUT$", "w", stderr);
3324 fprintf(stdout, "\n");
3325 fprintf(stderr, "\n");
3327 /* Now register "destroy_console()" as a routine to be called just
3328 before the application exits, so that we can destroy the console
3329 after the user has typed a key (so that the console doesn't just
3330 disappear out from under them, giving the user no chance to see
3331 the message(s) we put in there). */
3332 atexit(destroy_console);
3334 /* Well, we have a console now. */
3340 destroy_console(void)
3343 printf("\n\nPress any key to exit\n");
3352 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3353 const char *message, gpointer user_data _U_)
3360 /* ignore log message, if log_level isn't interesting based
3361 upon the console log preferences.
3362 If the preferences haven't been loaded loaded yet, display the
3365 The default console_log_level preference value is such that only
3366 ERROR, CRITICAL and WARNING level messages are processed;
3367 MESSAGE, INFO and DEBUG level messages are ignored. */
3368 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3369 prefs.console_log_level != 0) {
3374 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3375 /* the user wants a console or the application will terminate immediately */
3379 /* For some unknown reason, the above doesn't appear to actually cause
3380 anything to be sent to the standard output, so we'll just splat the
3381 message out directly, just to make sure it gets out. */
3383 switch(log_level & G_LOG_LEVEL_MASK) {
3384 case G_LOG_LEVEL_ERROR:
3387 case G_LOG_LEVEL_CRITICAL:
3390 case G_LOG_LEVEL_WARNING:
3393 case G_LOG_LEVEL_MESSAGE:
3396 case G_LOG_LEVEL_INFO:
3399 case G_LOG_LEVEL_DEBUG:
3403 fprintf(stderr, "unknown log_level %u\n", log_level);
3405 g_assert_not_reached();
3408 /* create a "timestamp" */
3410 today = localtime(&curr);
3412 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3413 today->tm_hour, today->tm_min, today->tm_sec,
3414 log_domain != NULL ? log_domain : "",
3417 if(log_level & G_LOG_LEVEL_ERROR) {
3418 /* wait for a key press before the following error handler will terminate the program
3419 this way the user at least can read the error message */
3420 printf("\n\nPress any key to exit\n");
3424 /* XXX - on UN*X, should we just use g_log_default_handler()?
3425 We want the error messages to go to the standard output;
3426 on Mac OS X, that will cause them to show up in various
3427 per-user logs accessible through Console (details depend
3428 on whether you're running 10.0 through 10.4 or running
3429 10.5 and later), and, on other UN*X desktop environments,
3430 if they don't show up in some form of console log, that's
3431 a deficiency in that desktop environment. (Too bad
3432 Windows doesn't set the standard output and error for
3433 GUI apps to something that shows up in such a log.) */
3434 g_log_default_handler(log_domain, log_level, message, user_data);
3441 * Helper for main_widgets_rearrange()
3443 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3444 gtk_container_remove(GTK_CONTAINER(data), widget);
3447 static GtkWidget *main_widget_layout(gint layout_content)
3449 switch(layout_content) {
3450 case(layout_pane_content_none):
3452 case(layout_pane_content_plist):
3454 case(layout_pane_content_pdetails):
3456 case(layout_pane_content_pbytes):
3457 return byte_nb_ptr_gbl;
3459 g_assert_not_reached();
3466 * Rearrange the main window widgets
3468 void main_widgets_rearrange(void) {
3469 GtkWidget *first_pane_widget1, *first_pane_widget2;
3470 GtkWidget *second_pane_widget1, *second_pane_widget2;
3471 gboolean split_top_left = FALSE;
3473 /* be a bit faster */
3474 gtk_widget_hide(main_vbox);
3476 /* be sure we don't lose a widget while rearranging */
3477 g_object_ref(G_OBJECT(menubar));
3478 g_object_ref(G_OBJECT(main_tb));
3479 g_object_ref(G_OBJECT(filter_tb));
3480 g_object_ref(G_OBJECT(wireless_tb));
3481 g_object_ref(G_OBJECT(pkt_scrollw));
3482 g_object_ref(G_OBJECT(tv_scrollw));
3483 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3484 g_object_ref(G_OBJECT(statusbar));
3485 g_object_ref(G_OBJECT(main_pane_v1));
3486 g_object_ref(G_OBJECT(main_pane_v2));
3487 g_object_ref(G_OBJECT(main_pane_h1));
3488 g_object_ref(G_OBJECT(main_pane_h2));
3489 g_object_ref(G_OBJECT(welcome_pane));
3491 /* empty all containers participating */
3492 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3493 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3494 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3495 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3496 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3498 statusbar_widgets_emptying(statusbar);
3500 /* add the menubar always at the top */
3501 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3504 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3506 /* filter toolbar in toolbar area */
3507 if (!prefs.filter_toolbar_show_in_statusbar) {
3508 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3511 /* airpcap toolbar */
3512 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3514 /* fill the main layout panes */
3515 switch(prefs.gui_layout_type) {
3516 case(layout_type_5):
3517 main_first_pane = main_pane_v1;
3518 main_second_pane = main_pane_v2;
3519 split_top_left = FALSE;
3521 case(layout_type_2):
3522 main_first_pane = main_pane_v1;
3523 main_second_pane = main_pane_h1;
3524 split_top_left = FALSE;
3526 case(layout_type_1):
3527 main_first_pane = main_pane_v1;
3528 main_second_pane = main_pane_h1;
3529 split_top_left = TRUE;
3531 case(layout_type_4):
3532 main_first_pane = main_pane_h1;
3533 main_second_pane = main_pane_v1;
3534 split_top_left = FALSE;
3536 case(layout_type_3):
3537 main_first_pane = main_pane_h1;
3538 main_second_pane = main_pane_v1;
3539 split_top_left = TRUE;
3541 case(layout_type_6):
3542 main_first_pane = main_pane_h1;
3543 main_second_pane = main_pane_h2;
3544 split_top_left = FALSE;
3547 main_first_pane = NULL;
3548 main_second_pane = NULL;
3549 g_assert_not_reached();
3551 if (split_top_left) {
3552 first_pane_widget1 = main_second_pane;
3553 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3554 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3555 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3557 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3558 first_pane_widget2 = main_second_pane;
3559 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3560 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3562 if (first_pane_widget1 != NULL)
3563 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3564 if (first_pane_widget2 != NULL)
3565 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3566 if (second_pane_widget1 != NULL)
3567 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3568 if (second_pane_widget2 != NULL)
3569 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3571 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3574 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3577 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3579 /* filter toolbar in statusbar hbox */
3580 if (prefs.filter_toolbar_show_in_statusbar) {
3581 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3584 /* statusbar widgets */
3585 statusbar_widgets_pack(statusbar);
3587 /* hide widgets on users recent settings */
3588 main_widgets_show_or_hide();
3590 gtk_widget_show(main_vbox);
3594 is_widget_visible(GtkWidget *widget, gpointer data)
3596 gboolean *is_visible = data;
3599 if (gtk_widget_get_visible(widget))
3606 main_widgets_show_or_hide(void)
3608 gboolean main_second_pane_show;
3610 if (recent.main_toolbar_show) {
3611 gtk_widget_show(main_tb);
3613 gtk_widget_hide(main_tb);
3616 statusbar_widgets_show_or_hide(statusbar);
3618 if (recent.filter_toolbar_show) {
3619 gtk_widget_show(filter_tb);
3621 gtk_widget_hide(filter_tb);
3624 if (recent.wireless_toolbar_show) {
3625 gtk_widget_show(wireless_tb);
3627 gtk_widget_hide(wireless_tb);
3630 if (recent.packet_list_show && have_capture_file) {
3631 gtk_widget_show(pkt_scrollw);
3633 gtk_widget_hide(pkt_scrollw);
3636 if (recent.tree_view_show && have_capture_file) {
3637 gtk_widget_show(tv_scrollw);
3639 gtk_widget_hide(tv_scrollw);
3642 if (recent.byte_view_show && have_capture_file) {
3643 gtk_widget_show(byte_nb_ptr_gbl);
3645 gtk_widget_hide(byte_nb_ptr_gbl);
3648 if (have_capture_file) {
3649 gtk_widget_show(main_first_pane);
3651 gtk_widget_hide(main_first_pane);
3655 * Is anything in "main_second_pane" visible?
3656 * If so, show it, otherwise hide it.
3658 main_second_pane_show = FALSE;
3659 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3660 &main_second_pane_show);
3661 if (main_second_pane_show) {
3662 gtk_widget_show(main_second_pane);
3664 gtk_widget_hide(main_second_pane);
3667 if (!have_capture_file) {
3669 gtk_widget_show(welcome_pane);
3672 gtk_widget_hide(welcome_pane);
3677 /* called, when the window state changes (minimized, maximized, ...) */
3679 window_state_event_cb (GtkWidget *widget _U_,
3683 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3685 if( (event->type) == (GDK_WINDOW_STATE)) {
3686 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3687 /* we might have dialogs popped up while we where iconified,
3689 display_queued_messages();
3697 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3699 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3701 if (event->keyval == GDK_F8) {
3704 } else if (event->keyval == GDK_F7) {
3707 } else if (event->state & NO_SHIFT_MOD_MASK) {
3708 return FALSE; /* Skip control, alt, and other modifiers */
3710 * A comment in gdkkeysyms.h says that it's autogenerated from
3711 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3712 * don't explicitly say so, isprint() should work as expected
3715 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3716 /* Forward the keypress on to the display filter entry */
3717 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3718 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3719 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3727 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3729 GtkAccelGroup *accel;
3732 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3733 main_set_window_name("The Wireshark Network Analyzer");
3735 gtk_widget_set_name(top_level, "main window");
3736 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3738 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3739 G_CALLBACK(window_state_event_cb), NULL);
3740 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3741 G_CALLBACK(top_level_key_pressed_cb), NULL );
3743 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3744 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 = 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 wireless_tb = ws80211_toolbar_new();
3808 gtk_widget_show(wireless_tb);
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 */
3859 static void copy_global_profile (const gchar *profile_name)
3861 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3863 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3864 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3865 "Can't create directory\n\"%s\":\n%s.",
3866 pf_dir_path, g_strerror(errno));
3868 g_free(pf_dir_path);
3871 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3872 &pf_dir_path, &pf_dir_path2) == -1) {
3873 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3874 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3875 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3877 g_free(pf_filename);
3878 g_free(pf_dir_path);
3879 g_free(pf_dir_path2);
3883 /* Change configuration profile */
3884 void change_configuration_profile (const gchar *profile_name)
3886 char *gdp_path, *dp_path;
3890 /* First check if profile exists */
3891 if (!profile_exists(profile_name, FALSE)) {
3892 if (profile_exists(profile_name, TRUE)) {
3893 /* Copy from global profile */
3894 copy_global_profile (profile_name);
3896 /* No personal and no global profile exists */
3901 /* Then check if changing to another profile */
3902 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3906 /* Get the current geometry, before writing it to disk */
3907 main_save_window_geometry(top_level);
3909 if (profile_exists(get_profile_name(), FALSE)) {
3910 /* Write recent file for profile we are leaving, if it still exists */
3911 write_profile_recent();
3914 /* Set profile name and update the status bar */
3915 set_profile_name (profile_name);
3916 profile_bar_update ();
3917 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3919 /* Reset current preferences and apply the new */
3923 (void) read_configuration_files (&gdp_path, &dp_path);
3925 recent_read_profile_static(&rf_path, &rf_open_errno);
3926 if (rf_path != NULL && rf_open_errno != 0) {
3927 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3928 "Could not open common recent file\n\"%s\": %s.",
3929 rf_path, g_strerror(rf_open_errno));
3931 if (recent.gui_fileopen_remembered_dir &&
3932 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3933 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3935 timestamp_set_type (recent.gui_time_format);
3936 timestamp_set_seconds_type (recent.gui_seconds_format);
3937 color_filters_enable(recent.packet_list_colorize);
3939 prefs_to_capture_opts();
3941 macros_post_update();
3943 /* Update window view and redraw the toolbar */
3944 main_titlebar_update();
3945 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3946 toolbar_redraw_all();
3948 /* Enable all protocols and disable from the disabled list */
3950 if (gdp_path == NULL && dp_path == NULL) {
3951 set_disabled_protos_list();
3954 /* Reload color filters */
3955 color_filters_reload();
3957 /* Reload list of interfaces on welcome page */
3958 welcome_if_panel_reload();
3960 /* Recreate the packet list according to new preferences */
3961 packet_list_recreate ();
3962 cfile.columns_changed = FALSE; /* Reset value */
3965 /* Update menus with new recent values */
3966 menu_recent_read_finished();
3968 /* Reload pane geometry, must be done after recreating the list */
3969 main_pane_load_window_geometry();
3972 /** redissect packets and update UI */
3973 void redissect_packets(void)
3975 cf_redissect_packets(&cfile);
3976 status_expert_update();