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 */
54 #include <ui/win32/console_win32.h>
57 #ifdef HAVE_LIBPORTAUDIO
58 #include <portaudio.h>
59 #endif /* HAVE_LIBPORTAUDIO */
61 #include <wsutil/crash_info.h>
62 #include <wsutil/filesystem.h>
63 #include <wsutil/file_util.h>
64 #include <wsutil/privileges.h>
65 #include <wsutil/report_err.h>
66 #include <wsutil/u3.h>
68 #include <wiretap/merge.h>
70 #include <epan/addr_resolv.h>
71 #include <epan/column.h>
72 #include <epan/disabled_protos.h>
73 #include <epan/epan.h>
74 #include <epan/epan_dissect.h>
75 #include <epan/dfilter/dfilter.h>
76 #include <epan/strutil.h>
77 #include <epan/emem.h>
78 #include <epan/ex-opt.h>
79 #include <epan/funnel.h>
80 #include <epan/expert.h>
81 #include <epan/frequency-utils.h>
82 #include <epan/prefs.h>
83 #include <epan/prefs-int.h>
85 #include <epan/stat_cmd_args.h>
87 #include <epan/print.h>
88 #include <epan/timestamp.h>
90 #include <wsutil/plugins.h>
92 /* general (not GTK specific) */
94 #include "../frame_tvbuff.h"
95 #include "../summary.h"
96 #include "../filters.h"
98 #include "../color_filters.h"
99 #include "../register.h"
100 #include "../ringbuffer.h"
102 #include "../clopts_common.h"
103 #include "../cmdarg_err.h"
104 #include "../version_info.h"
107 #include "gtk_iface_monitor.h"
109 #include "ui/alert_box.h"
110 #include "ui/decode_as_utils.h"
111 #include "ui/main_statusbar.h"
112 #include "ui/persfilepath_opt.h"
113 #include "ui/preference_utils.h"
114 #include "ui/recent.h"
115 #include "ui/recent_utils.h"
116 #include "ui/software_update.h"
117 #include "ui/simple_dialog.h"
118 #include "ui/ui_util.h"
121 #include "ui/capture_globals.h"
122 #include "ui/iface_lists.h"
125 #include "codecs/codecs.h"
128 #include "capture_ui_utils.h"
129 #include "capture-pcap-util.h"
130 #include "capture_ifinfo.h"
132 #include "capture_sync.h"
136 #include "capture-wpcap.h"
137 #include "capture_wpcap_packet.h"
138 #include <tchar.h> /* Needed for Unicode */
139 #include <wsutil/unicode-utils.h>
140 #include <commctrl.h>
141 #include <shellapi.h>
145 #include "ui/gtk/file_dlg.h"
146 #include "ui/gtk/gtkglobals.h"
147 #include "ui/gtk/color_utils.h"
148 #include "ui/gtk/gui_utils.h"
149 #include "ui/gtk/color_dlg.h"
150 #include "ui/gtk/filter_dlg.h"
151 #include "ui/gtk/fileset_dlg.h"
152 #include "ui/gtk/uat_gui.h"
153 #include "ui/gtk/main.h"
154 #include "ui/gtk/main_80211_toolbar.h"
155 #include "ui/gtk/main_airpcap_toolbar.h"
156 #include "ui/gtk/main_filter_toolbar.h"
157 #include "ui/gtk/main_titlebar.h"
158 #include "ui/gtk/menus.h"
159 #include "ui/gtk/main_menubar_private.h"
160 #include "ui/gtk/macros_dlg.h"
161 #include "ui/gtk/main_statusbar_private.h"
162 #include "ui/gtk/main_toolbar.h"
163 #include "ui/gtk/main_toolbar_private.h"
164 #include "ui/gtk/main_welcome.h"
165 #include "ui/gtk/drag_and_drop.h"
166 #include "ui/gtk/capture_file_dlg.h"
167 #include "ui/gtk/packet_panes.h"
168 #include "ui/gtk/keys.h"
169 #include "ui/gtk/packet_win.h"
170 #include "ui/gtk/stock_icons.h"
171 #include "ui/gtk/find_dlg.h"
172 #include "ui/gtk/follow_tcp.h"
173 #include "ui/gtk/font_utils.h"
174 #include "ui/gtk/about_dlg.h"
175 #include "ui/gtk/help_dlg.h"
176 #include "ui/gtk/decode_as_dlg.h"
177 #include "ui/gtk/webbrowser.h"
178 #include "ui/gtk/capture_dlg.h"
179 #include "ui/gtk/capture_if_dlg.h"
180 #include "ui/gtk/tap_param_dlg.h"
181 #include "ui/gtk/prefs_column.h"
182 #include "ui/gtk/prefs_dlg.h"
183 #include "ui/gtk/proto_help.h"
184 #include "ui/gtk/packet_list.h"
185 #include "ui/gtk/filter_expression_save_dlg.h"
187 #include "ui/gtk/old-gtk-compat.h"
191 #include "wsiconcap.h"
196 #include "airpcap_loader.h"
197 #include "airpcap_dlg.h"
198 #include "airpcap_gui_utils.h"
201 #include <epan/crypt/airpdcap_ws.h>
204 #ifdef HAVE_GTKOSXAPPLICATION
205 #include <gtkmacintegration/gtkosxapplication.h>
209 * Files under personal and global preferences directories in which
210 * GTK settings for Wireshark are stored.
212 #define RC_FILE "gtkrc"
215 capture_options global_capture_opts;
216 capture_session global_capture_session;
221 static gboolean capture_stopping;
223 /* "exported" main widgets */
224 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
226 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
227 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
228 static GtkWidget *main_first_pane, *main_second_pane;
230 /* internally used widgets */
231 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
233 GtkWidget *wireless_tb;
235 int airpcap_dll_ret_val = -1;
238 GString *comp_info_str, *runtime_info_str;
240 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
242 static guint tap_update_timer_id;
244 static void console_log_handler(const char *log_domain,
245 GLogLevelFlags log_level, const char *message, gpointer user_data);
247 static void create_main_window(gint, gint, gint, e_prefs*);
248 static void show_main_window(gboolean);
249 static void main_save_window_geometry(GtkWidget *widget);
252 /* Match selected byte pattern */
254 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
256 char *cur_filter, *new_filter;
258 if ((!text) || (0 == strlen(text))) {
259 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
265 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
267 switch (action&MATCH_SELECTED_MASK) {
269 case MATCH_SELECTED_REPLACE:
270 new_filter = g_strdup(text);
273 case MATCH_SELECTED_AND:
274 if ((!cur_filter) || (0 == strlen(cur_filter)))
275 new_filter = g_strdup(text);
277 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
280 case MATCH_SELECTED_OR:
281 if ((!cur_filter) || (0 == strlen(cur_filter)))
282 new_filter = g_strdup(text);
284 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
287 case MATCH_SELECTED_NOT:
288 new_filter = g_strconcat("!(", text, ")", NULL);
291 case MATCH_SELECTED_AND_NOT:
292 if ((!cur_filter) || (0 == strlen(cur_filter)))
293 new_filter = g_strconcat("!(", text, ")", NULL);
295 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
298 case MATCH_SELECTED_OR_NOT:
299 if ((!cur_filter) || (0 == strlen(cur_filter)))
300 new_filter = g_strconcat("!(", text, ")", NULL);
302 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
306 g_assert_not_reached();
311 /* Free up the copy we got of the old filter text. */
314 /* Don't change the current display filter if we only want to copy the filter */
315 if (action&MATCH_SELECTED_COPY_ONLY) {
316 GString *gtk_text_str = g_string_new("");
317 g_string_append(gtk_text_str, new_filter);
318 copy_to_clipboard(gtk_text_str);
319 g_string_free(gtk_text_str, TRUE);
321 /* create a new one and set the display filter entry accordingly */
322 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
324 /* Run the display filter so it goes in effect. */
325 if (action&MATCH_SELECTED_APPLY_NOW)
326 main_filter_packets(&cfile, new_filter, FALSE);
329 /* Free up the new filter text. */
334 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
338 if (cfile.finfo_selected) {
339 filter = proto_construct_match_selected_string(cfile.finfo_selected,
341 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
346 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
350 if (cfile.finfo_selected) {
351 filter = proto_construct_match_selected_string(cfile.finfo_selected,
353 if ((!filter) || (0 == strlen(filter))) {
354 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
355 "Could not acquire information to build a filter!\n"
356 "Try expanding or choosing another item.");
361 color_display_with_filter(filter);
364 color_filters_reset_tmp();
366 color_filters_set_tmp(filt_nr,filter, FALSE);
368 packet_list_colorize_packets();
374 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
376 gchar *selected_proto_url;
377 gchar *proto_abbrev = (gchar *)data;
382 if (cfile.finfo_selected) {
383 /* open wiki page using the protocol abbreviation */
384 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
385 browser_open_url(selected_proto_url);
386 g_free(selected_proto_url);
389 case(ESD_BTN_CANCEL):
392 g_assert_not_reached();
398 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
401 const gchar *proto_abbrev;
405 if (cfile.finfo_selected) {
406 /* convert selected field to protocol abbreviation */
407 /* XXX - could this conversion be simplified? */
408 field_id = cfile.finfo_selected->hfinfo->id;
409 /* if the selected field isn't a protocol, get its parent */
410 if(!proto_registrar_is_protocol(field_id)) {
411 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
414 proto_abbrev = proto_registrar_get_abbrev(field_id);
416 if (!proto_is_private(field_id)) {
417 /* ask the user if the wiki page really should be opened */
418 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
419 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
421 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
423 "The Wireshark Wiki is a collaborative approach to provide information "
424 "about Wireshark in several ways (not limited to protocol specifics).\n"
426 "This Wiki is new, so the page of the selected protocol "
427 "may not exist and/or may not contain valuable information.\n"
429 "As everyone can edit the Wiki and add new content (or extend existing), "
430 "you are encouraged to add information if you can.\n"
432 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
434 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
435 "which will save you a lot of editing and will give a consistent look over the pages.",
436 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
437 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
439 /* appologize to the user that the wiki page cannot be opened */
440 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
441 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
443 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
445 "Since this is a private protocol, such information is not available in "
446 "a public wiki. Therefore this wiki entry is blocked.\n"
448 "Sorry for the inconvenience.\n",
449 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
454 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
456 gchar *selected_proto_url;
457 gchar *proto_abbrev = (gchar *)data;
461 if (cfile.finfo_selected) {
462 /* open reference page using the protocol abbreviation */
463 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
464 browser_open_url(selected_proto_url);
465 g_free(selected_proto_url);
468 case(ESD_BTN_CANCEL):
471 g_assert_not_reached();
476 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
479 const gchar *proto_abbrev;
483 if (cfile.finfo_selected) {
484 /* convert selected field to protocol abbreviation */
485 /* XXX - could this conversion be simplified? */
486 field_id = cfile.finfo_selected->hfinfo->id;
487 /* if the selected field isn't a protocol, get its parent */
488 if(!proto_registrar_is_protocol(field_id)) {
489 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
492 proto_abbrev = proto_registrar_get_abbrev(field_id);
494 if (!proto_is_private(field_id)) {
495 /* ask the user if the wiki page really should be opened */
496 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
497 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
499 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
501 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
502 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
504 /* appologize to the user that the wiki page cannot be opened */
505 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
506 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
508 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
510 "Since this is a private protocol, such information is not available on "
511 "a public website. Therefore this filter entry is blocked.\n"
513 "Sorry for the inconvenience.\n",
514 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
520 is_address_column (gint column)
522 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
523 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
524 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
525 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
526 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
535 get_ip_address_list_from_packet_list_row(gpointer data)
537 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
538 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
541 GList *addr_list = NULL;
543 fdata = (frame_data *) packet_list_get_row_data(row);
548 if (!cf_read_frame (&cfile, fdata))
549 return NULL; /* error reading the frame */
551 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
552 col_custom_prime_edt(&edt, &cfile.cinfo);
554 epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
555 fdata, &cfile.cinfo);
556 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
558 /* First check selected column */
559 if (is_address_column (column)) {
560 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
563 for (col = 0; col < cfile.cinfo.num_cols; col++) {
564 /* Then check all columns except the selected */
565 if ((col != column) && (is_address_column (col))) {
566 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
570 epan_dissect_cleanup(&edt);
577 get_filter_from_packet_list_row_and_column(gpointer data)
579 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
580 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
584 fdata = (frame_data *) packet_list_get_row_data(row);
589 if (!cf_read_frame(&cfile, fdata))
590 return NULL; /* error reading the frame */
591 /* proto tree, visible. We need a proto tree if there's custom columns */
592 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
593 col_custom_prime_edt(&edt, &cfile.cinfo);
595 epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
596 fdata, &cfile.cinfo);
597 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
599 if ((cfile.cinfo.col_custom_occurrence[column]) ||
600 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
602 /* Only construct the filter when a single occurrence is displayed
603 * otherwise we might end up with a filter like "ip.proto==1,6".
605 * Or do we want to be able to filter on multiple occurrences so that
606 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
609 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
610 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
611 /* leak a little but safer than ep_ here */
612 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
613 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
614 if (hfi && hfi->parent == -1) {
616 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
617 } else if (hfi && hfi->type == FT_STRING) {
618 /* Custom string, add quotes */
619 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
620 cfile.cinfo.col_expr.col_expr_val[column]);
624 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
625 cfile.cinfo.col_expr.col_expr_val[column]);
630 epan_dissect_cleanup(&edt);
637 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
639 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
641 get_filter_from_packet_list_row_and_column((GtkWidget *)data));
644 /* This function allows users to right click in the details window and copy the text
645 * information to the operating systems clipboard.
647 * We first check to see if a string representation is setup in the tree and then
648 * read the string. If not available then we try to grab the value. If all else
649 * fails we display a message to the user to indicate the copy could not be completed.
652 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
654 GString *gtk_text_str = g_string_new("");
655 char labelstring[ITEM_LABEL_LENGTH];
656 char *stringpointer = labelstring;
660 case COPY_SELECTED_DESCRIPTION:
661 if (cfile.finfo_selected->rep &&
662 strlen (cfile.finfo_selected->rep->representation) > 0) {
663 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
666 case COPY_SELECTED_FIELDNAME:
667 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
668 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
671 case COPY_SELECTED_VALUE:
672 if (cfile.edt !=0 ) {
673 g_string_append(gtk_text_str,
674 get_node_field_value(cfile.finfo_selected, cfile.edt));
681 if (gtk_text_str->len == 0) {
682 /* If no representation then... Try to read the value */
683 proto_item_fill_label(cfile.finfo_selected, stringpointer);
684 g_string_append(gtk_text_str, stringpointer);
687 if (gtk_text_str->len == 0) {
688 /* Could not get item so display error msg */
689 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
691 /* Copy string to clipboard */
692 copy_to_clipboard(gtk_text_str);
694 g_string_free(gtk_text_str, TRUE); /* Free the memory */
698 /* mark as reference time frame */
700 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
704 frame->flags.ref_time=1;
705 cfile.ref_time_count++;
707 frame->flags.ref_time=0;
708 cfile.ref_time_count--;
710 cf_reftime_packets(&cfile);
711 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
712 packet_list_freeze();
713 cfile.displayed_count--;
714 packet_list_recreate_visible_rows();
717 packet_list_queue_draw();
721 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
725 timestamp_set_type(TS_RELATIVE);
726 recent.gui_time_format = TS_RELATIVE;
727 cf_timestamp_auto_precision(&cfile);
728 packet_list_queue_draw();
733 g_assert_not_reached();
736 if (cfile.current_frame) {
737 set_frame_reftime(!cfile.current_frame->flags.ref_time,
738 cfile.current_frame, cfile.current_row);
744 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
746 static GtkWidget *reftime_dialog = NULL;
750 if (cfile.current_frame) {
751 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
752 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
753 "%sSwitch to the appropriate Time Display Format?%s\n\n"
754 "Time References don't work well with the currently selected Time Display Format.\n\n"
755 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
756 simple_dialog_primary_start(), simple_dialog_primary_end());
757 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
759 set_frame_reftime(!cfile.current_frame->flags.ref_time,
760 cfile.current_frame, cfile.current_row);
764 case REFTIME_FIND_NEXT:
765 cf_find_packet_time_reference(&cfile, SD_FORWARD);
767 case REFTIME_FIND_PREV:
768 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
774 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
776 cf_find_packet_marked(&cfile, SD_FORWARD);
780 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
782 cf_find_packet_marked(&cfile, SD_BACKWARD);
786 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
789 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
791 gboolean has_blurb = FALSE;
792 guint length = 0, byte_len;
793 GtkWidget *byte_view;
794 const guint8 *byte_data;
799 /* if nothing is selected */
800 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
803 * Which byte view is displaying the current protocol tree
806 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
807 if (byte_view == NULL)
810 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
811 if (byte_data == NULL)
814 cf_unselect_field(&cfile);
815 packet_hex_print(byte_view, byte_data,
816 cfile.current_frame, NULL, byte_len);
817 proto_help_menu_modify(sel, &cfile);
820 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
823 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
825 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
826 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
827 g_assert(byte_data != NULL);
829 cfile.finfo_selected = finfo;
830 set_menus_for_selected_tree_row(&cfile);
833 if (finfo->hfinfo->blurb != NULL &&
834 finfo->hfinfo->blurb[0] != '\0') {
836 length = (guint) strlen(finfo->hfinfo->blurb);
838 length = (guint) strlen(finfo->hfinfo->name);
840 finfo_length = finfo->length + finfo->appendix_length;
842 if (finfo_length == 0) {
844 } else if (finfo_length == 1) {
845 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
847 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
849 statusbar_pop_field_msg(); /* get rid of current help msg */
851 statusbar_push_field_msg(" %s (%s)%s",
852 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
853 finfo->hfinfo->abbrev, len_str);
856 * Don't show anything if the field name is zero-length;
857 * the pseudo-field for "proto_tree_add_text()" is such
858 * a field, and we don't want "Text (text)" showing up
859 * on the status line if you've selected such a field.
861 * XXX - there are zero-length fields for which we *do*
862 * want to show the field name.
864 * XXX - perhaps the name and abbrev field should be null
865 * pointers rather than null strings for that pseudo-field,
866 * but we'd have to add checks for null pointers in some
867 * places if we did that.
869 * Or perhaps protocol tree items added with
870 * "proto_tree_add_text()" should have -1 as the field index,
871 * with no pseudo-field being used, but that might also
872 * require special checks for -1 to be added.
874 statusbar_push_field_msg("%s", "");
877 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
879 proto_help_menu_modify(sel, &cfile);
882 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
885 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
888 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
891 expand_all_tree(cfile.edt->tree, tree_view_gbl);
894 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
896 if (cfile.finfo_selected) {
897 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
898 cfile.finfo_selected->hfinfo->abbrev,0);
899 /* Recreate the packet list according to new preferences */
900 packet_list_recreate ();
901 if (!prefs.gui_use_pref_save) {
904 cfile.columns_changed = FALSE; /* Reset value */
908 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
912 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
914 /* the mouse position is at an entry, expand that one */
915 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
916 gtk_tree_path_free(path);
920 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
924 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
926 /* the mouse position is at an entry, expand that one */
928 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
929 gtk_tree_path_free(path);
933 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
935 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
937 if (cfile.edt->tree) {
938 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
942 /* Update main window items based on whether there's a capture in progress. */
944 main_set_for_capture_in_progress(gboolean capture_in_progress)
946 set_menus_for_capture_in_progress(capture_in_progress);
949 set_toolbar_for_capture_in_progress(capture_in_progress);
951 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
955 /* Update main window items based on whether we have a capture file. */
957 main_set_for_capture_file(gboolean have_capture_file_in)
959 have_capture_file = have_capture_file_in;
961 main_widgets_show_or_hide();
964 /* Update main window items based on whether we have captured packets. */
966 main_set_for_captured_packets(gboolean have_captured_packets)
968 set_menus_for_captured_packets(have_captured_packets);
969 set_toolbar_for_captured_packets(have_captured_packets);
972 /* Update main window items based on whether we have a packet history. */
974 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
976 set_menus_for_packet_history(back_history, forward_history);
977 set_toolbar_for_packet_history(back_history, forward_history);
983 /* get the current geometry, before writing it to disk */
984 main_save_window_geometry(top_level);
986 /* write user's recent file to disk
987 * It is no problem to write this file, even if we do not quit */
988 write_profile_recent();
991 /* XXX - should we check whether the capture file is an
992 unsaved temporary file for a live capture and, if so,
993 pop up a "do you want to exit without saving the capture
994 file?" dialog, and then just return, leaving said dialog
995 box to forcibly quit if the user clicks "OK"?
997 If so, note that this should be done in a subroutine that
998 returns TRUE if we do so, and FALSE otherwise, and if it
999 returns TRUE we should return TRUE without nuking anything.
1001 Note that, if we do that, we might also want to check if
1002 an "Update list of packets in real time" capture is in
1003 progress and, if so, ask whether they want to terminate
1004 the capture and discard it, and return TRUE, before nuking
1005 any child capture, if they say they don't want to do so. */
1008 /* Nuke any child capture in progress. */
1009 capture_kill_child(&global_capture_session);
1012 /* Are we in the middle of reading a capture? */
1013 if (cfile.state == FILE_READ_IN_PROGRESS) {
1014 /* Yes, so we can't just close the file and quit, as
1015 that may yank the rug out from under the read in
1016 progress; instead, just set the state to
1017 "FILE_READ_ABORTED" and return - the code doing the read
1018 will check for that and, if it sees that, will clean
1020 cfile.state = FILE_READ_ABORTED;
1022 /* Say that the window should *not* be deleted;
1023 that'll be done by the code that cleans up. */
1026 /* Close any capture file we have open; on some OSes, you
1027 can't unlink a temporary capture file if you have it
1029 "cf_close()" will unlink it after closing it if
1030 it's a temporary file.
1032 We do this here, rather than after the main loop returns,
1033 as, after the main loop returns, the main window may have
1034 been destroyed (if this is called due to a "destroy"
1035 even on the main window rather than due to the user
1036 selecting a menu item), and there may be a crash
1037 or other problem when "cf_close()" tries to
1038 clean up stuff in the main window.
1040 XXX - is there a better place to put this?
1041 Or should we have a routine that *just* closes the
1042 capture file, and doesn't do anything with the UI,
1043 which we'd call here, and another routine that
1044 calls that routine and also cleans up the UI, which
1045 we'd call elsewhere? */
1048 /* Exit by leaving the main loop, so that any quit functions
1049 we registered get called. */
1052 /* Say that the window should be deleted. */
1058 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1060 /* If we're in the middle of stopping a capture, don't do anything;
1061 the user can try deleting the window after the capture stops. */
1062 if (capture_stopping)
1065 /* If there's unsaved data, let the user save it first.
1066 If they cancel out of it, don't quit. */
1067 if (do_file_close(&cfile, TRUE, " before quitting"))
1068 return main_do_quit();
1070 return TRUE; /* will this keep the window from being deleted? */
1075 main_pane_load_window_geometry(void)
1077 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1078 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1079 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1080 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1086 main_load_window_geometry(GtkWidget *widget)
1088 window_geometry_t geom;
1090 geom.set_pos = prefs.gui_geometry_save_position;
1091 geom.x = recent.gui_geometry_main_x;
1092 geom.y = recent.gui_geometry_main_y;
1093 geom.set_size = prefs.gui_geometry_save_size;
1094 if (recent.gui_geometry_main_width > 0 &&
1095 recent.gui_geometry_main_height > 0) {
1096 geom.width = recent.gui_geometry_main_width;
1097 geom.height = recent.gui_geometry_main_height;
1098 geom.set_maximized = prefs.gui_geometry_save_maximized;
1100 /* We assume this means the width and height weren't set in
1101 the "recent" file (or that there is no "recent" file),
1102 and weren't set to a default value, so we don't set the
1103 size. (The "recent" file code rejects non-positive width
1104 and height values.) */
1105 geom.set_size = FALSE;
1107 geom.maximized = recent.gui_geometry_main_maximized;
1109 window_set_geometry(widget, &geom);
1111 main_pane_load_window_geometry();
1112 statusbar_load_window_geometry();
1117 main_save_window_geometry(GtkWidget *widget)
1119 window_geometry_t geom;
1121 window_get_geometry(widget, &geom);
1123 if (prefs.gui_geometry_save_position) {
1124 recent.gui_geometry_main_x = geom.x;
1125 recent.gui_geometry_main_y = geom.y;
1128 if (prefs.gui_geometry_save_size) {
1129 recent.gui_geometry_main_width = geom.width;
1130 recent.gui_geometry_main_height = geom.height;
1133 if(prefs.gui_geometry_save_maximized) {
1134 recent.gui_geometry_main_maximized = geom.maximized;
1137 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1138 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1139 statusbar_save_window_geometry();
1143 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1145 /* If there's unsaved data, let the user save it first. */
1146 if (do_file_close(&cfile, TRUE, " before quitting"))
1151 print_usage(gboolean print_ver) {
1161 fprintf(output, "Wireshark " VERSION "%s\n"
1162 "Interactively dump and analyze network traffic.\n"
1163 "See http://www.wireshark.org for more information.\n"
1166 wireshark_gitversion, get_copyright_info());
1170 fprintf(output, "\n");
1171 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1172 fprintf(output, "\n");
1175 fprintf(output, "Capture interface:\n");
1176 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1177 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1178 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1179 fprintf(output, " -p don't capture in promiscuous mode\n");
1180 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1181 fprintf(output, " -S update packet display when new packets are captured\n");
1182 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1183 #ifdef HAVE_PCAP_CREATE
1184 fprintf(output, " -I capture in monitor mode, if available\n");
1186 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1187 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1189 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1190 fprintf(output, " -D print list of interfaces and exit\n");
1191 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1192 fprintf(output, "\n");
1193 fprintf(output, "Capture stop conditions:\n");
1194 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1195 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1196 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1197 fprintf(output, " files:NUM - stop after NUM files\n");
1198 /*fprintf(output, "\n");*/
1199 fprintf(output, "Capture output:\n");
1200 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1201 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1202 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1203 #endif /* HAVE_LIBPCAP */
1204 #ifdef HAVE_PCAP_REMOTE
1205 fprintf(output, "RPCAP options:\n");
1206 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1208 /*fprintf(output, "\n");*/
1209 fprintf(output, "Input file:\n");
1210 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1212 fprintf(output, "\n");
1213 fprintf(output, "Processing:\n");
1214 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1215 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1216 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1218 fprintf(output, "\n");
1219 fprintf(output, "User interface:\n");
1220 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1221 fprintf(output, " -Y <display filter> start with the given display filter\n");
1222 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1223 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1224 fprintf(output, " filter\n");
1225 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1226 fprintf(output, " -m <font> set the font name used for most text\n");
1227 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
1228 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1229 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1230 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1232 fprintf(output, "\n");
1233 fprintf(output, "Output:\n");
1234 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1236 fprintf(output, "\n");
1237 fprintf(output, "Miscellaneous:\n");
1238 fprintf(output, " -h display this help and exit\n");
1239 fprintf(output, " -v display version info and exit\n");
1240 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1241 fprintf(output, " persdata:path - personal data files\n");
1242 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1243 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1245 fprintf(output, " --display=DISPLAY X display to use\n");
1256 printf(PACKAGE " " VERSION "%s\n"
1263 wireshark_gitversion, get_copyright_info(), comp_info_str->str,
1264 runtime_info_str->str);
1268 * Report an error in command-line arguments.
1269 * Creates a console on Windows.
1272 cmdarg_err(const char *fmt, ...)
1279 fprintf(stderr, "wireshark: ");
1281 vfprintf(stderr, fmt, ap);
1283 fprintf(stderr, "\n");
1287 * Report additional information for an error in command-line arguments.
1288 * Creates a console on Windows.
1289 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1290 * terminal isn't the standard error?
1293 cmdarg_err_cont(const char *fmt, ...)
1301 vfprintf(stderr, fmt, ap);
1302 fprintf(stderr, "\n");
1307 Once every 3 seconds we get a callback here which we use to update
1311 tap_update_cb(gpointer data _U_)
1313 draw_tap_listeners(FALSE);
1318 * Periodically process outstanding hostname lookups. If we have new items,
1319 * redraw the packet list and tree view.
1323 resolv_update_cb(gpointer data _U_)
1325 /* Anything new show up? */
1326 if (host_name_lookup_process()) {
1327 if (gtk_widget_get_window(pkt_scrollw))
1328 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1329 if (gtk_widget_get_window(tv_scrollw))
1330 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1333 /* Always check. Even if we don't do async lookups we could still get
1334 passive updates, e.g. from DNS packets. */
1339 /* Update various parts of the main window for a capture file "unsaved
1340 changes" change - update the title to reflect whether there are
1341 unsaved changes or not, and update the menus and toolbar to
1342 enable or disable the "Save" operation. */
1344 main_update_for_unsaved_changes(capture_file *cf)
1346 set_titlebar_for_capture_file(cf);
1347 set_menus_for_capture_file(cf);
1348 set_toolbar_for_capture_file(cf);
1353 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1355 /* Update menubar and toolbar */
1356 menu_auto_scroll_live_changed(auto_scroll_live_in);
1357 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1359 /* change auto scroll state */
1360 auto_scroll_live = auto_scroll_live_in;
1365 main_colorize_changed(gboolean packet_list_colorize)
1367 /* Update menubar and toolbar */
1368 menu_colorize_changed(packet_list_colorize);
1369 toolbar_colorize_changed(packet_list_colorize);
1371 /* change colorization */
1372 if(packet_list_colorize != recent.packet_list_colorize) {
1373 recent.packet_list_colorize = packet_list_colorize;
1374 color_filters_enable(packet_list_colorize);
1375 packet_list_colorize_packets();
1379 static GtkWidget *close_dlg = NULL;
1382 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1384 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1389 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1391 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1396 main_cf_cb_file_closing(capture_file *cf)
1398 /* if we have more than 10000 packets, show a splash screen while closing */
1399 /* XXX - don't know a better way to decide whether to show or not,
1400 * as most of the time is spend in various calls that destroy various
1401 * data structures, so it wouldn't be easy to use a progress bar,
1402 * rather than, say, a progress spinner, here! */
1403 if(cf->count > 10000) {
1404 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1405 "%sClosing file!%s\n\nPlease wait ...",
1406 simple_dialog_primary_start(),
1407 simple_dialog_primary_end());
1408 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1410 /* Clear maunally resolved addresses */
1411 manually_resolve_cleanup();
1412 /* Destroy all windows that refer to the
1413 capture file we're closing. */
1414 destroy_packet_wins();
1416 /* Update the titlebar to reflect the lack of a capture file. */
1417 set_titlebar_for_capture_file(NULL);
1419 /* Disable all menu and toolbar items that make sense only if
1420 you have a capture. */
1421 set_menus_for_capture_file(NULL);
1422 set_toolbar_for_capture_file(NULL);
1423 main_set_for_captured_packets(FALSE);
1424 set_menus_for_selected_packet(cf);
1425 main_set_for_capture_in_progress(FALSE);
1426 set_capture_if_dialog_for_capture_in_progress(FALSE);
1427 set_menus_for_selected_tree_row(cf);
1429 /* Set up main window for no capture file. */
1430 main_set_for_capture_file(FALSE);
1432 main_window_update();
1437 main_cf_cb_file_closed(capture_file *cf _U_)
1439 if(close_dlg != NULL) {
1440 splash_destroy(close_dlg);
1447 main_cf_cb_file_read_started(capture_file *cf _U_)
1449 tap_param_dlg_update();
1451 /* Set up main window for a capture file. */
1452 main_set_for_capture_file(TRUE);
1456 main_cf_cb_file_read_finished(capture_file *cf)
1460 if (!cf->is_tempfile && cf->filename) {
1461 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1462 add_menu_recent_capture_file(cf->filename);
1464 /* Remember folder for next Open dialog and save it in recent */
1465 dir_path = get_dirname(g_strdup(cf->filename));
1466 set_last_open_dir(dir_path);
1470 /* Update the appropriate parts of the main window. */
1471 main_update_for_unsaved_changes(cf);
1473 /* Enable menu items that make sense if you have some captured packets. */
1474 main_set_for_captured_packets(TRUE);
1478 main_cf_cb_file_rescan_finished(capture_file *cf)
1482 if (!cf->is_tempfile && cf->filename) {
1483 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1484 add_menu_recent_capture_file(cf->filename);
1486 /* Remember folder for next Open dialog and save it in recent */
1487 dir_path = get_dirname(g_strdup(cf->filename));
1488 set_last_open_dir(dir_path);
1492 /* Update the appropriate parts of the main window. */
1493 main_update_for_unsaved_changes(cf);
1497 static GList *icon_list_create(
1498 const guint8 *icon16_pb,
1499 const guint8 *icon32_pb,
1500 const guint8 *icon48_pb,
1501 const guint8 *icon64_pb)
1503 GList *icon_list = NULL;
1504 GdkPixbuf * pixbuf16;
1505 GdkPixbuf * pixbuf32;
1506 GdkPixbuf * pixbuf48;
1507 GdkPixbuf * pixbuf64;
1510 if(icon16_pb != NULL) {
1511 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1513 icon_list = g_list_append(icon_list, pixbuf16);
1516 if(icon32_pb != NULL) {
1517 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1519 icon_list = g_list_append(icon_list, pixbuf32);
1522 if(icon48_pb != NULL) {
1523 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1525 icon_list = g_list_append(icon_list, pixbuf48);
1528 if(icon64_pb != NULL) {
1529 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1531 icon_list = g_list_append(icon_list, pixbuf64);
1538 main_capture_cb_capture_prepared(capture_session *cap_session)
1540 static GList *icon_list = NULL;
1542 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1544 if(icon_list == NULL) {
1545 icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1547 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1549 /* Disable menu items that make no sense if you're currently running
1551 main_set_for_capture_in_progress(TRUE);
1552 set_capture_if_dialog_for_capture_in_progress(TRUE);
1554 /* Don't set up main window for a capture file. */
1555 main_set_for_capture_file(FALSE);
1559 main_capture_cb_capture_update_started(capture_session *cap_session)
1561 /* We've done this in "prepared" above, but it will be cleared while
1562 switching to the next multiple file. */
1563 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1565 main_set_for_capture_in_progress(TRUE);
1566 set_capture_if_dialog_for_capture_in_progress(TRUE);
1568 /* Enable menu items that make sense if you have some captured
1569 packets (yes, I know, we don't have any *yet*). */
1570 main_set_for_captured_packets(TRUE);
1572 /* Set up main window for a capture file. */
1573 main_set_for_capture_file(TRUE);
1577 main_capture_cb_capture_update_finished(capture_session *cap_session)
1579 capture_file *cf = (capture_file *)cap_session->cf;
1580 static GList *icon_list = NULL;
1582 /* The capture isn't stopping any more - it's stopped. */
1583 capture_stopping = FALSE;
1585 if (!cf->is_tempfile && cf->filename) {
1586 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1587 add_menu_recent_capture_file(cf->filename);
1590 /* Enable menu items that make sense if you're not currently running
1592 main_set_for_capture_in_progress(FALSE);
1593 set_capture_if_dialog_for_capture_in_progress(FALSE);
1595 /* Update the main window as appropriate. This has to occur AFTER
1596 * main_set_for_capture_in_progress() or else some of the menus are
1597 * incorrectly disabled (see bug
1598 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1599 main_update_for_unsaved_changes(cf);
1601 /* Set up main window for a capture file. */
1602 main_set_for_capture_file(TRUE);
1604 if(icon_list == NULL) {
1605 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1607 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1609 if(global_capture_opts.quit_after_cap) {
1610 /* command line asked us to quit after the capture */
1611 /* don't pop up a dialog to ask for unsaved files etc. */
1617 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1619 /* Don't set up main window for a capture file. */
1620 main_set_for_capture_file(FALSE);
1624 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1627 capture_file *cf = (capture_file *)cap_session->cf;
1629 static GList *icon_list = NULL;
1631 /* The capture isn't stopping any more - it's stopped. */
1632 capture_stopping = FALSE;
1634 /*set_titlebar_for_capture_file(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 /* Restore the standard title bar message */
1642 /* (just in case we have trouble opening the capture file). */
1643 set_titlebar_for_capture_file(NULL);
1645 if(icon_list == NULL) {
1646 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1648 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1650 /* We don't have loaded the capture file, this will be done later.
1651 * For now we still have simply a blank screen. */
1653 if(global_capture_opts.quit_after_cap) {
1654 /* command line asked us to quit after the capture */
1655 /* don't pop up a dialog to ask for unsaved files etc. */
1661 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1663 capture_stopping = TRUE;
1664 set_menus_for_capture_stopping();
1666 set_toolbar_for_capture_stopping();
1668 set_capture_if_dialog_for_capture_stopping();
1673 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1675 static GList *icon_list = NULL;
1677 /* Capture isn't stopping any more. */
1678 capture_stopping = FALSE;
1680 /* the capture failed before the first packet was captured
1681 reset title, menus and icon */
1682 set_titlebar_for_capture_file(NULL);
1684 main_set_for_capture_in_progress(FALSE);
1685 set_capture_if_dialog_for_capture_in_progress(FALSE);
1687 main_set_for_capture_file(FALSE);
1689 if(icon_list == NULL) {
1690 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1692 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1695 if(global_capture_opts.quit_after_cap) {
1696 /* command line asked us to quit after the capture */
1697 /* don't pop up a dialog to ask for unsaved files etc. */
1701 #endif /* HAVE_LIBPCAP */
1704 main_cf_cb_packet_selected(gpointer data)
1706 capture_file *cf = (capture_file *)data;
1708 /* Display the GUI protocol tree and packet bytes.
1709 XXX - why do we dump core if we call "proto_tree_draw()"
1710 before calling "add_byte_views()"? */
1711 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1712 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1714 /* Note: Both string and hex value searches in the packet data produce a non-zero
1715 search_pos if successful */
1716 if(cf->search_in_progress &&
1717 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1718 highlight_field(cf->edt->tvb, cf->search_pos,
1719 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1722 /* A packet is selected. */
1723 set_menus_for_selected_packet(cf);
1727 main_cf_cb_packet_unselected(capture_file *cf)
1729 /* No packet is being displayed; clear the hex dump pane by getting
1730 rid of all the byte views. */
1731 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1732 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1734 /* Add a placeholder byte view so that there's at least something
1735 displayed in the byte view notebook. */
1736 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1738 /* And clear the protocol tree display as well. */
1739 proto_tree_draw(NULL, tree_view_gbl);
1741 /* No packet is selected. */
1742 set_menus_for_selected_packet(cf);
1746 main_cf_cb_field_unselected(capture_file *cf)
1748 set_menus_for_selected_tree_row(cf);
1752 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1754 capture_file *cf = (capture_file *)data;
1756 case(cf_cb_file_opened):
1757 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1758 fileset_file_opened(cf);
1760 case(cf_cb_file_closing):
1761 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1762 main_cf_cb_file_closing(cf);
1764 case(cf_cb_file_closed):
1765 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1766 main_cf_cb_file_closed(cf);
1767 fileset_file_closed();
1769 case(cf_cb_file_read_started):
1770 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1771 main_cf_cb_file_read_started(cf);
1773 case(cf_cb_file_read_finished):
1774 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1775 main_cf_cb_file_read_finished(cf);
1777 case(cf_cb_file_reload_started):
1778 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1779 main_cf_cb_file_read_started(cf);
1781 case(cf_cb_file_reload_finished):
1782 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1783 main_cf_cb_file_read_finished(cf);
1785 case(cf_cb_file_rescan_started):
1786 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1788 case(cf_cb_file_rescan_finished):
1789 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1790 main_cf_cb_file_rescan_finished(cf);
1792 case(cf_cb_file_fast_save_finished):
1793 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1794 main_cf_cb_file_rescan_finished(cf);
1796 case(cf_cb_packet_selected):
1797 main_cf_cb_packet_selected(cf);
1799 case(cf_cb_packet_unselected):
1800 main_cf_cb_packet_unselected(cf);
1802 case(cf_cb_field_unselected):
1803 main_cf_cb_field_unselected(cf);
1805 case(cf_cb_file_save_started):
1806 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1808 case(cf_cb_file_save_finished):
1809 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1811 case(cf_cb_file_save_failed):
1812 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1814 case(cf_cb_file_save_stopped):
1815 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1817 case(cf_cb_file_export_specified_packets_started):
1818 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1820 case(cf_cb_file_export_specified_packets_finished):
1821 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1823 case(cf_cb_file_export_specified_packets_failed):
1824 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1826 case(cf_cb_file_export_specified_packets_stopped):
1827 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1830 g_warning("main_cf_callback: event %u unknown", event);
1831 g_assert_not_reached();
1837 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1839 #ifdef HAVE_GTKOSXAPPLICATION
1840 GtkosxApplication *theApp;
1843 case(capture_cb_capture_prepared):
1844 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1845 main_capture_cb_capture_prepared(cap_session);
1847 case(capture_cb_capture_update_started):
1848 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1849 main_capture_cb_capture_update_started(cap_session);
1850 #ifdef HAVE_GTKOSXAPPLICATION
1851 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1852 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1855 case(capture_cb_capture_update_continue):
1856 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1858 case(capture_cb_capture_update_finished):
1859 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1860 main_capture_cb_capture_update_finished(cap_session);
1862 case(capture_cb_capture_fixed_started):
1863 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1864 main_capture_cb_capture_fixed_started(cap_session);
1866 case(capture_cb_capture_fixed_continue):
1867 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1869 case(capture_cb_capture_fixed_finished):
1870 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1871 main_capture_cb_capture_fixed_finished(cap_session);
1873 case(capture_cb_capture_stopping):
1874 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1875 /* Beware: this state won't be called, if the capture child
1876 * closes the capturing on its own! */
1877 #ifdef HAVE_GTKOSXAPPLICATION
1878 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1879 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1881 main_capture_cb_capture_stopping(cap_session);
1883 case(capture_cb_capture_failed):
1884 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1885 main_capture_cb_capture_failed(cap_session);
1888 g_warning("main_capture_callback: event %u unknown", event);
1889 g_assert_not_reached();
1895 get_gtk_compiled_info(GString *str)
1897 g_string_append(str, "with ");
1898 g_string_append_printf(str,
1899 #ifdef GTK_MAJOR_VERSION
1900 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1903 "GTK+ (version unknown)");
1905 g_string_append(str, ", ");
1907 g_string_append(str, "with Cairo ");
1908 g_string_append(str, CAIRO_VERSION_STRING);
1909 g_string_append(str, ", ");
1912 g_string_append(str, "with Pango ");
1913 g_string_append(str, PANGO_VERSION_STRING);
1914 g_string_append(str, ", ");
1919 get_gui_compiled_info(GString *str)
1921 epan_get_compiled_version_info(str);
1923 g_string_append(str, ", ");
1924 #ifdef HAVE_LIBPORTAUDIO
1925 #ifdef PORTAUDIO_API_1
1926 g_string_append(str, "with PortAudio <= V18");
1927 #else /* PORTAUDIO_API_1 */
1928 g_string_append(str, "with ");
1929 g_string_append(str, Pa_GetVersionText());
1930 #endif /* PORTAUDIO_API_1 */
1931 #else /* HAVE_LIBPORTAUDIO */
1932 g_string_append(str, "without PortAudio");
1933 #endif /* HAVE_LIBPORTAUDIO */
1935 g_string_append(str, ", ");
1937 get_compiled_airpcap_version(str);
1939 g_string_append(str, "without AirPcap");
1944 get_gui_runtime_info(GString *str)
1946 epan_get_runtime_version_info(str);
1949 g_string_append(str, ", ");
1950 get_runtime_airpcap_version(str);
1954 g_string_append(str, ", ");
1955 u3_runtime_info(str);
1960 read_configuration_files(char **gdp_path, char **dp_path)
1962 int gpf_open_errno, gpf_read_errno;
1963 int cf_open_errno, df_open_errno;
1964 int gdp_open_errno, gdp_read_errno;
1965 int dp_open_errno, dp_read_errno;
1966 char *gpf_path, *pf_path;
1967 char *cf_path, *df_path;
1968 int pf_open_errno, pf_read_errno;
1971 /* load the decode as entries of this profile */
1972 load_decode_as_entries();
1974 /* Read the preference files. */
1975 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1976 &pf_open_errno, &pf_read_errno, &pf_path);
1978 if (gpf_path != NULL) {
1979 if (gpf_open_errno != 0) {
1980 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1981 "Could not open global preferences file\n\"%s\": %s.",
1982 gpf_path, g_strerror(gpf_open_errno));
1984 if (gpf_read_errno != 0) {
1985 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1986 "I/O error reading global preferences file\n\"%s\": %s.",
1987 gpf_path, g_strerror(gpf_read_errno));
1990 if (pf_path != NULL) {
1991 if (pf_open_errno != 0) {
1992 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1993 "Could not open your preferences file\n\"%s\": %s.",
1994 pf_path, g_strerror(pf_open_errno));
1996 if (pf_read_errno != 0) {
1997 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1998 "I/O error reading your preferences file\n\"%s\": %s.",
1999 pf_path, g_strerror(pf_read_errno));
2006 /* if the user wants a console to be always there, well, we should open one for him */
2007 if (prefs_p->gui_console_open == console_open_always) {
2012 /* Read the capture filter file. */
2013 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2014 if (cf_path != NULL) {
2015 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2016 "Could not open your capture filter file\n\"%s\": %s.",
2017 cf_path, g_strerror(cf_open_errno));
2021 /* Read the display filter file. */
2022 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2023 if (df_path != NULL) {
2024 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2025 "Could not open your display filter file\n\"%s\": %s.",
2026 df_path, g_strerror(df_open_errno));
2030 /* Read the disabled protocols file. */
2031 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2032 dp_path, &dp_open_errno, &dp_read_errno);
2033 if (*gdp_path != NULL) {
2034 if (gdp_open_errno != 0) {
2035 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2036 "Could not open global disabled protocols file\n\"%s\": %s.",
2037 *gdp_path, g_strerror(gdp_open_errno));
2039 if (gdp_read_errno != 0) {
2040 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2041 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2042 *gdp_path, g_strerror(gdp_read_errno));
2047 if (*dp_path != NULL) {
2048 if (dp_open_errno != 0) {
2049 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2050 "Could not open your disabled protocols file\n\"%s\": %s.",
2051 *dp_path, g_strerror(dp_open_errno));
2053 if (dp_read_errno != 0) {
2054 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2055 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2056 *dp_path, g_strerror(dp_read_errno));
2065 /* Check if there's something important to tell the user during startup.
2066 * We want to do this *after* showing the main window so that any windows
2067 * we pop up will be above the main window.
2071 check_and_warn_user_startup(gchar *cf_name)
2073 check_and_warn_user_startup(gchar *cf_name _U_)
2076 gchar *cur_user, *cur_group;
2077 gpointer priv_warning_dialog;
2079 /* Tell the user not to run as root. */
2080 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2081 cur_user = get_cur_username();
2082 cur_group = get_cur_groupname();
2083 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2084 "Running as user \"%s\" and group \"%s\".\n"
2085 "This could be dangerous.\n\n"
2086 "If you're running Wireshark this way in order to perform live capture, "
2087 "you may want to be aware that there is a better way documented at\n"
2088 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2091 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2092 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2096 /* Warn the user if npf.sys isn't loaded. */
2097 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2098 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2099 "The NPF driver isn't running. You may have trouble\n"
2100 "capturing or listing interfaces.");
2101 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2102 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2108 /* And now our feature presentation... [ fade to music ] */
2110 main(int argc, char *argv[])
2112 char *init_progfile_dir_error;
2115 gboolean arg_error = FALSE;
2117 extern int info_update_freq; /* Found in about_dlg.c. */
2118 const gchar *filter;
2126 char *gdp_path, *dp_path;
2129 gboolean start_capture = FALSE;
2130 gboolean list_link_layer_types = FALSE;
2135 gboolean capture_option_specified = FALSE;
2142 gint pl_size = 280, tv_size = 95, bv_size = 75;
2143 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2144 dfilter_t *rfcode = NULL;
2145 gboolean rfilter_parse_failed = FALSE;
2148 GtkWidget *splash_win = NULL;
2149 GLogLevelFlags log_flags;
2150 guint go_to_packet = 0;
2151 search_direction jump_backwards = SD_FORWARD;
2152 dfilter_t *jump_to_filter = NULL;
2154 #ifdef HAVE_GTKOSXAPPLICATION
2155 GtkosxApplication *theApp;
2159 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2160 #define OPTSTRING_B "B:"
2162 #define OPTSTRING_B ""
2163 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2164 #else /* HAVE_LIBPCAP */
2165 #define OPTSTRING_B ""
2166 #endif /* HAVE_LIBPCAP */
2167 #ifdef HAVE_PCAP_REMOTE
2168 #define OPTSTRING_A "A:"
2170 #define OPTSTRING_A ""
2172 #ifdef HAVE_PCAP_CREATE
2173 #define OPTSTRING_I "I"
2175 #define OPTSTRING_I ""
2178 #define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:Y:z:"
2180 static const char optstring[] = OPTSTRING;
2183 /* Set the C-language locale to the native environment. */
2184 setlocale(LC_ALL, "");
2186 arg_list_utf_16to8(argc, argv);
2187 create_app_running_mutex();
2191 * Get credential information for later use, and drop privileges
2192 * before doing anything else.
2193 * Let the user know if anything happened.
2195 init_process_policies();
2196 relinquish_special_privs_perm();
2199 * Attempt to get the pathname of the executable file.
2201 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2203 /* initialize the funnel mini-api */
2204 initialize_funnel_ops();
2206 AirPDcapInitContext(&airpdcap_ctx);
2209 /* Load wpcap if possible. Do this before collecting the run-time version information */
2212 /* ... and also load the packet.dll from wpcap */
2213 wpcap_packet_load();
2216 /* Load the airpcap.dll. This must also be done before collecting
2217 * run-time version information. */
2218 airpcap_dll_ret_val = load_airpcap();
2220 switch (airpcap_dll_ret_val) {
2221 case AIRPCAP_DLL_OK:
2222 /* load the airpcap interfaces */
2223 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2225 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2226 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2227 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2230 airpcap_if_active = NULL;
2234 /* select the first ad default (THIS SHOULD BE CHANGED) */
2235 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2240 * XXX - Maybe we need to warn the user if one of the following happens???
2242 case AIRPCAP_DLL_OLD:
2243 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2246 case AIRPCAP_DLL_ERROR:
2247 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2250 case AIRPCAP_DLL_NOT_FOUND:
2251 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2255 #endif /* HAVE_AIRPCAP */
2258 /* Assemble the compile-time version information string */
2259 comp_info_str = g_string_new("Compiled ");
2261 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2263 /* Assemble the run-time version information string */
2264 runtime_info_str = g_string_new("Running ");
2265 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2268 ws_add_crash_info(PACKAGE " " VERSION "%s\n"
2273 wireshark_gitversion, comp_info_str->str, runtime_info_str->str);
2275 /* Start windows sockets */
2276 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2279 profile_store_persconffiles (TRUE);
2281 /* Read the profile independent recent file. We have to do this here so we can */
2282 /* set the profile before it can be set from the command line parameterts */
2283 recent_read_static(&rf_path, &rf_open_errno);
2284 if (rf_path != NULL && rf_open_errno != 0) {
2285 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2286 "Could not open common recent file\n\"%s\": %s.",
2287 rf_path, g_strerror(rf_open_errno));
2290 /* "pre-scan" the command line parameters, if we have "console only"
2291 parameters. We do this so we don't start GTK+ if we're only showing
2292 command-line help or version information.
2294 XXX - this pre-scan is done before we start GTK+, so we haven't
2295 run gtk_init() on the arguments. That means that GTK+ arguments
2296 have not been removed from the argument list; those arguments
2297 begin with "--", and will be treated as an error by getopt().
2299 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2302 optind_initial = optind;
2303 while ((opt = getopt(argc, argv, optstring)) != -1) {
2305 case 'C': /* Configuration Profile */
2306 if (profile_exists (optarg, FALSE)) {
2307 set_profile_name (optarg);
2309 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2313 case 'D': /* Print a list of capture devices and exit */
2315 if_list = capture_interface_list(&err, &err_str,main_window_update);
2316 if (if_list == NULL) {
2318 case CANT_GET_INTERFACE_LIST:
2319 case DONT_HAVE_PCAP:
2320 cmdarg_err("%s", err_str);
2324 case NO_INTERFACES_FOUND:
2325 cmdarg_err("There are no interfaces on which a capture can be done");
2333 capture_opts_print_interfaces(if_list);
2334 free_interface_list(if_list);
2339 #else /* HAVE_LIBPCAP */
2340 capture_option_specified = TRUE;
2342 #endif /* HAVE_LIBPCAP */
2344 case 'h': /* Print help and exit */
2350 if (strcmp(optarg, "-") == 0)
2351 set_stdin_capture(TRUE);
2354 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
2355 if (!persfilepath_opt(opt, optarg)) {
2356 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2360 case 'v': /* Show version and exit */
2372 * Extension command line options have to be processed before
2373 * we call epan_init() as they are supposed to be used by dissectors
2374 * or taps very early in the registration process.
2378 case '?': /* Ignore errors - the "real" scan will catch them. */
2383 /* Init the "Open file" dialog directory */
2384 /* (do this after the path settings are processed) */
2386 /* Read the profile dependent (static part) of the recent file. */
2387 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2388 /* recent lists which is done in the dynamic part. */
2389 /* We have to do this already here, so command line parameters can overwrite these values. */
2390 recent_read_profile_static(&rf_path, &rf_open_errno);
2391 if (rf_path != NULL && rf_open_errno != 0) {
2392 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2393 "Could not open recent file\n\"%s\": %s.",
2394 rf_path, g_strerror(rf_open_errno));
2397 if (recent.gui_fileopen_remembered_dir &&
2398 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2399 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2401 set_last_open_dir(get_persdatafile_dir());
2404 /* Set getopt index back to initial value, so it will start with the
2405 first command line parameter again. Also reset opterr to 1, so that
2406 error messages are printed by getopt().
2408 XXX - this seems to work on most platforms, but time will tell.
2409 The Single UNIX Specification says "The getopt() function need
2410 not be reentrant", so this isn't guaranteed to work. The Mac
2411 OS X 10.4[.x] getopt() man page says
2413 In order to use getopt() to evaluate multiple sets of arguments, or to
2414 evaluate a single set of arguments multiple times, the variable optreset
2415 must be set to 1 before the second and each additional set of calls to
2416 getopt(), and the variable optind must be reinitialized.
2420 The optreset variable was added to make it possible to call the getopt()
2421 function multiple times. This is an extension to the IEEE Std 1003.2
2422 (``POSIX.2'') specification.
2424 which I think comes from one of the other BSDs.
2426 XXX - if we want to control all the command-line option errors, so
2427 that we can display them where we choose (e.g., in a window), we'd
2428 want to leave opterr as 0, and produce our own messages using optopt.
2429 We'd have to check the value of optopt to see if it's a valid option
2430 letter, in which case *presumably* the error is "this option requires
2431 an argument but none was specified", or not a valid option letter,
2432 in which case *presumably* the error is "this option isn't valid".
2433 Some versions of getopt() let you supply a option string beginning
2434 with ':', which means that getopt() will return ':' rather than '?'
2435 for "this option requires an argument but none was specified", but
2437 optind = optind_initial;
2440 #if !GLIB_CHECK_VERSION(2,31,0)
2441 g_thread_init(NULL);
2444 /* Set the current locale according to the program environment.
2445 * We haven't localized anything, but some GTK widgets are localized
2446 * (the file selection dialogue, for example).
2447 * This also sets the C-language locale to the native environment. */
2448 setlocale (LC_ALL, "");
2450 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2451 gtk_init (&argc, &argv);
2453 cf_callback_add(main_cf_callback, NULL);
2455 capture_callback_add(main_capture_callback, NULL);
2457 cf_callback_add(statusbar_cf_callback, NULL);
2459 capture_callback_add(statusbar_capture_callback, NULL);
2462 /* Arrange that if we have no console window, and a GLib message logging
2463 routine is called to log a message, we pop up a console window.
2465 We do that by inserting our own handler for all messages logged
2466 to the default domain; that handler pops up a console if necessary,
2467 and then calls the default handler. */
2469 /* We might want to have component specific log levels later ... */
2471 log_flags = (GLogLevelFlags)
2473 G_LOG_LEVEL_CRITICAL|
2474 G_LOG_LEVEL_WARNING|
2475 G_LOG_LEVEL_MESSAGE|
2479 G_LOG_FLAG_RECURSION);
2481 g_log_set_handler(NULL,
2483 console_log_handler, NULL /* user_data */);
2484 g_log_set_handler(LOG_DOMAIN_MAIN,
2486 console_log_handler, NULL /* user_data */);
2489 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2491 console_log_handler, NULL /* user_data */);
2492 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2494 console_log_handler, NULL /* user_data */);
2496 /* Set the initial values in the capture options. This might be overwritten
2497 by preference settings and then again by the command line parameters. */
2498 capture_opts_init(&global_capture_opts);
2500 capture_session_init(&global_capture_session, (void *)&cfile);
2503 init_report_err(failure_alert_box, open_failure_alert_box,
2504 read_failure_alert_box, write_failure_alert_box);
2506 /* Initialize whatever we need to allocate colors for GTK+ */
2509 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2510 filter = get_conn_cfilter();
2511 if ( *filter != '\0' ) {
2512 info_update_freq = 1000; /* Milliseconds */
2515 /* We won't come till here, if we had a "console only" command line parameter. */
2516 splash_win = splash_new("Loading Wireshark ...");
2517 if (init_progfile_dir_error != NULL) {
2518 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2519 "Can't get pathname of Wireshark: %s.\n"
2520 "It won't be possible to capture traffic.\n"
2521 "Report this to the Wireshark developers.",
2522 init_progfile_dir_error);
2523 g_free(init_progfile_dir_error);
2527 /* Register all the plugin types we have. */
2528 epan_register_plugin_types(); /* Types known to libwireshark */
2529 wtap_register_plugin_types(); /* Types known to libwiretap */
2530 codec_register_plugin_types(); /* Types known to libcodec */
2532 /* Scan for plugins. This does *not* call their registration routines;
2533 that's done later. */
2536 /* Register all libwiretap plugin modules. */
2537 register_all_wiretap_modules();
2539 /* Register all audio codec plugins. */
2540 register_all_codecs();
2543 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2545 /* Register all dissectors; we must do this before checking for the
2546 "-G" flag, as the "-G" flag dumps information registered by the
2547 dissectors, and we must do it before we read the preferences, in
2548 case any dissectors register preferences. */
2549 epan_init(register_all_protocols,register_all_protocol_handoffs,
2550 splash_update, (gpointer) splash_win);
2552 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2554 /* Register all tap listeners; we do this before we parse the arguments,
2555 as the "-z" argument can specify a registered tap. */
2557 /* we register the plugin taps before the other taps because
2558 stats_tree taps plugins will be registered as tap listeners
2559 by stats_tree_stat.c and need to registered before that */
2562 register_all_plugin_tap_listeners();
2565 register_all_tap_listeners();
2567 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2569 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2570 /* Removed thread code:
2571 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2574 /* this is to keep tap extensions updating once every 3 seconds */
2575 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2577 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2579 cap_file_init(&cfile);
2581 /* Fill in capture options with values from the preferences */
2582 prefs_to_capture_opts();
2584 /*#ifdef HAVE_LIBPCAP
2585 fill_in_local_interfaces();
2587 /* Now get our args */
2588 while ((opt = getopt(argc, argv, optstring)) != -1) {
2590 /*** capture option specific ***/
2591 case 'a': /* autostop criteria */
2592 case 'b': /* Ringbuffer option */
2593 case 'c': /* Capture xxx packets */
2594 case 'f': /* capture filter */
2595 case 'k': /* Start capture immediately */
2596 case 'H': /* Hide capture info dialog box */
2597 case 'p': /* Don't capture in promiscuous mode */
2598 case 'i': /* Use interface x */
2599 #ifdef HAVE_PCAP_CREATE
2600 case 'I': /* Capture in monitor mode, if available */
2602 #ifdef HAVE_PCAP_REMOTE
2603 case 'A': /* Authentication */
2605 case 's': /* Set the snapshot (capture) length */
2606 case 'S': /* "Sync" mode: used for following file ala tail -f */
2607 case 'w': /* Write to capture file xxx */
2608 case 'y': /* Set the pcap data link type */
2609 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2610 case 'B': /* Buffer size */
2611 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2613 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2619 capture_option_specified = TRUE;
2624 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2625 case 'K': /* Kerberos keytab file */
2626 read_keytab_file(optarg);
2630 /*** all non capture option specific ***/
2632 /* Configuration profile settings were already processed just ignore them this time*/
2634 case 'j': /* Search backwards for a matching packet from filter in option J */
2635 jump_backwards = SD_BACKWARD;
2637 case 'g': /* Go to packet with the given packet number */
2638 go_to_packet = get_positive_int(optarg, "go to packet");
2640 case 'J': /* Jump to the first packet which matches the filter criteria */
2643 case 'l': /* Automatic scrolling in live capture mode */
2645 auto_scroll_live = TRUE;
2647 capture_option_specified = TRUE;
2651 case 'L': /* Print list of link-layer types and exit */
2653 list_link_layer_types = TRUE;
2655 capture_option_specified = TRUE;
2659 case 'm': /* Fixed-width font for the display */
2660 g_free(prefs_p->gui_gtk2_font_name);
2661 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2663 case 'n': /* No name resolution */
2664 gbl_resolv_flags.mac_name = FALSE;
2665 gbl_resolv_flags.network_name = FALSE;
2666 gbl_resolv_flags.transport_name = FALSE;
2667 gbl_resolv_flags.concurrent_dns = FALSE;
2669 case 'N': /* Select what types of addresses/port #s to resolve */
2670 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2671 if (badopt != '\0') {
2672 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2677 case 'o': /* Override preference from command line */
2678 switch (prefs_set_pref(optarg)) {
2681 case PREFS_SET_SYNTAX_ERR:
2682 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2685 case PREFS_SET_NO_SUCH_PREF:
2686 /* not a preference, might be a recent setting */
2687 switch (recent_set_arg(optarg)) {
2690 case PREFS_SET_SYNTAX_ERR:
2691 /* shouldn't happen, checked already above */
2692 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2695 case PREFS_SET_NO_SUCH_PREF:
2696 case PREFS_SET_OBSOLETE:
2697 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2702 g_assert_not_reached();
2705 case PREFS_SET_OBSOLETE:
2706 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2711 g_assert_not_reached();
2715 /* Path settings were already processed just ignore them this time*/
2717 case 'r': /* Read capture file xxx */
2718 /* We may set "last_open_dir" to "cf_name", and if we change
2719 "last_open_dir" later, we free the old value, so we have to
2720 set "cf_name" to something that's been allocated. */
2721 cf_name = g_strdup(optarg);
2723 case 'R': /* Read file filter */
2726 case 't': /* Time stamp type */
2727 if (strcmp(optarg, "r") == 0)
2728 timestamp_set_type(TS_RELATIVE);
2729 else if (strcmp(optarg, "a") == 0)
2730 timestamp_set_type(TS_ABSOLUTE);
2731 else if (strcmp(optarg, "ad") == 0)
2732 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2733 else if (strcmp(optarg, "adoy") == 0)
2734 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
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_YMD);
2745 else if (strcmp(optarg, "udoy") == 0)
2746 timestamp_set_type(TS_UTC_WITH_YDOY);
2748 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2750 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2752 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2754 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2756 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2758 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2762 case 'u': /* Seconds type */
2763 if (strcmp(optarg, "s") == 0)
2764 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2765 else if (strcmp(optarg, "hms") == 0)
2766 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2768 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2770 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2775 /* ext ops were already processed just ignore them this time*/
2781 /* We won't call the init function for the stat this soon
2782 as it would disallow MATE's fields (which are registered
2783 by the preferences set callback) from being used as
2784 part of a tap filter. Instead, we just add the argument
2785 to a list of stat arguments. */
2786 if (!process_stat_cmd_arg(optarg)) {
2787 cmdarg_err("Invalid -z argument.");
2788 cmdarg_err_cont(" -z argument must be one of :");
2789 list_stat_cmd_args();
2794 case '?': /* Bad flag - print usage message */
2803 if (cf_name != NULL) {
2805 * Input file name specified with "-r" *and* specified as a regular
2806 * command-line argument.
2808 cmdarg_err("File name specified both with -r and regular argument");
2812 * Input file name not specified with "-r", and a command-line argument
2813 * was specified; treat it as the input file name.
2815 * Yes, this is different from tshark, where non-flag command-line
2816 * arguments are a filter, but this works better on GUI desktops
2817 * where a command can be specified to be run to open a particular
2818 * file - yes, you could have "-r" as the last part of the command,
2819 * but that's a bit ugly.
2821 #ifndef HAVE_GTKOSXAPPLICATION
2823 * For GTK+ Mac Integration, file name passed as free argument passed
2824 * through grag-and-drop and opened twice sometimes causing crashes.
2825 * Subject to report to GTK+ MAC.
2827 cf_name = g_strdup(argv[0]);
2836 * Extra command line arguments were specified; complain.
2838 cmdarg_err("Invalid argument: %s", argv[0]);
2844 #ifndef HAVE_LIBPCAP
2845 if (capture_option_specified) {
2846 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2854 fill_in_local_interfaces(main_window_update);
2855 if (start_capture && list_link_layer_types) {
2856 /* Specifying *both* is bogus. */
2857 cmdarg_err("You can't specify both -L and a live capture.");
2861 if (list_link_layer_types) {
2862 /* We're supposed to list the link-layer types for an interface;
2863 did the user also specify a capture file to be read? */
2865 /* Yes - that's bogus. */
2866 cmdarg_err("You can't specify -L and a capture file to be read.");
2869 /* No - did they specify a ring buffer option? */
2870 if (global_capture_opts.multi_files_on) {
2871 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2875 /* We're supposed to do a live capture; did the user also specify
2876 a capture file to be read? */
2877 if (start_capture && cf_name) {
2878 /* Yes - that's bogus. */
2879 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2883 /* No - was the ring buffer option specified and, if so, does it make
2885 if (global_capture_opts.multi_files_on) {
2886 /* Ring buffer works only under certain conditions:
2887 a) ring buffer does not work with temporary files;
2888 b) real_time_mode and multi_files_on are mutually exclusive -
2889 real_time_mode takes precedence;
2890 c) it makes no sense to enable the ring buffer if the maximum
2891 file size is set to "infinite". */
2892 if (global_capture_opts.save_file == NULL) {
2893 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2894 global_capture_opts.multi_files_on = FALSE;
2896 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2897 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2898 /* XXX - this must be redesigned as the conditions changed */
2903 if (start_capture || list_link_layer_types) {
2904 /* We're supposed to do a live capture or get a list of link-layer
2905 types for a live capture device; if the user didn't specify an
2906 interface to use, pick a default. */
2907 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2908 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2914 if (list_link_layer_types) {
2915 /* Get the list of link-layer types for the capture devices. */
2916 if_capabilities_t *caps;
2919 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2921 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2922 if (device.selected) {
2923 #if defined(HAVE_PCAP_CREATE)
2924 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str, main_window_update);
2926 caps = capture_get_if_capabilities(device.name, FALSE, &err_str,main_window_update);
2929 cmdarg_err("%s", err_str);
2933 if (caps->data_link_types == NULL) {
2934 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2940 #if defined(HAVE_PCAP_CREATE)
2941 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2943 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2948 free_if_capabilities(caps);
2953 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2954 capture_opts_trim_ring_num_files(&global_capture_opts);
2955 #endif /* HAVE_LIBPCAP */
2957 /* Notify all registered modules that have had any of their preferences
2958 changed either from one of the preferences file or from the command
2959 line that their preferences have changed. */
2963 if ((global_capture_opts.num_selected == 0) &&
2964 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2967 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2968 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2969 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2970 device.selected = TRUE;
2971 global_capture_opts.num_selected++;
2972 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2973 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2978 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2979 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2980 device.selected = TRUE;
2981 global_capture_opts.num_selected++;
2982 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2983 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2987 /* disabled protocols as per configuration file */
2988 if (gdp_path == NULL && dp_path == NULL) {
2989 set_disabled_protos_list();
2992 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2994 /* read in rc file from global and personal configuration paths. */
2995 rc_file = get_datafile_path(RC_FILE);
2996 #if GTK_CHECK_VERSION(3,0,0)
2997 /* XXX resolve later */
2999 gtk_rc_parse(rc_file);
3001 rc_file = get_persconffile_path(RC_FILE, FALSE);
3002 gtk_rc_parse(rc_file);
3012 /* close the splash screen, as we are going to open the main window now */
3013 splash_destroy(splash_win);
3015 /************************************************************************/
3016 /* Everything is prepared now, preferences and command line was read in */
3018 /* Pop up the main window. */
3019 create_main_window(pl_size, tv_size, bv_size, prefs_p);
3021 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3022 recent_read_dynamic(&rf_path, &rf_open_errno);
3023 if (rf_path != NULL && rf_open_errno != 0) {
3024 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3025 "Could not open recent file\n\"%s\": %s.",
3026 rf_path, g_strerror(rf_open_errno));
3029 color_filters_enable(recent.packet_list_colorize);
3031 /* rearrange all the widgets as we now have all recent settings ready for this */
3032 main_widgets_rearrange();
3034 /* Fill in column titles. This must be done after the top level window
3037 XXX - is that still true, with fixed-width columns? */
3039 menu_recent_read_finished();
3041 main_auto_scroll_live_changed(auto_scroll_live);
3044 switch (user_font_apply()) {
3047 case FA_FONT_NOT_RESIZEABLE:
3048 /* "user_font_apply()" popped up an alert box. */
3049 /* turn off zooming - font can't be resized */
3050 case FA_FONT_NOT_AVAILABLE:
3051 /* XXX - did we successfully load the un-zoomed version earlier?
3052 If so, this *probably* means the font is available, but not at
3053 this particular zoom level, but perhaps some other failure
3054 occurred; I'm not sure you can determine which is the case,
3056 /* turn off zooming - zoom level is unavailable */
3058 /* in any other case than FA_SUCCESS, turn off zooming */
3059 recent.gui_zoom_level = 0;
3060 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3063 dnd_init(top_level);
3065 color_filters_init();
3067 capture_filter_init();
3070 /* the window can be sized only, if it's not already shown, so do it now! */
3071 main_load_window_geometry(top_level);
3073 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3075 /* If we were given the name of a capture file, read it in now;
3076 we defer it until now, so that, if we can't open it, and pop
3077 up an alert box, the alert box is more likely to come up on
3078 top of the main window - but before the preference-file-error
3079 alert box, so, if we get one of those, it's more likely to come
3082 show_main_window(TRUE);
3083 check_and_warn_user_startup(cf_name);
3084 if (rfilter != NULL) {
3085 if (!dfilter_compile(rfilter, &rfcode)) {
3086 bad_dfilter_alert_box(top_level, rfilter);
3087 rfilter_parse_failed = TRUE;
3090 if (!rfilter_parse_failed) {
3091 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3092 /* "cf_open()" succeeded, so it closed the previous
3093 capture file, and thus destroyed any previous read filter
3094 attached to "cf". */
3096 cfile.rfcode = rfcode;
3097 /* Open stat windows; we do so after creating the main window,
3098 to avoid GTK warnings, and after successfully opening the
3099 capture file, so we know we have something to compute stats
3100 on, and after registering all dissectors, so that MATE will
3101 have registered its field array and we can have a tap filter
3102 with one of MATE's late-registered fields as part of the
3104 start_requested_stats();
3106 /* Read the capture file. */
3107 switch (cf_read(&cfile, FALSE)) {
3111 /* Just because we got an error, that doesn't mean we were unable
3112 to read any of the file; we handle what we could get from the
3114 /* if the user told us to jump to a specific packet, do it now */
3115 if(go_to_packet != 0) {
3116 /* Jump to the specified frame number, kept for backward
3118 cf_goto_frame(&cfile, go_to_packet);
3119 } else if (jfilter != NULL) {
3120 /* try to compile given filter */
3121 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3122 bad_dfilter_alert_box(top_level, jfilter);
3124 /* Filter ok, jump to the first packet matching the filter
3125 conditions. Default search direction is forward, but if
3126 option d was given, search backwards */
3127 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3132 case CF_READ_ABORTED:
3138 /* If the filename is not the absolute path, prepend the current dir. This happens
3139 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3140 if (!g_path_is_absolute(cf_name)) {
3141 char *old_cf_name = cf_name;
3142 char *pwd = g_get_current_dir();
3143 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3144 g_free(old_cf_name);
3148 /* Save the name of the containing directory specified in the
3149 path name, if any; we can write over cf_name, which is a
3150 good thing, given that "get_dirname()" does write over its
3152 s = get_dirname(cf_name);
3153 set_last_open_dir(s);
3158 dfilter_free(rfcode);
3159 cfile.rfcode = NULL;
3160 show_main_window(FALSE);
3161 /* Don't call check_and_warn_user_startup(): we did it above */
3162 main_set_for_capture_in_progress(FALSE);
3163 set_capture_if_dialog_for_capture_in_progress(FALSE);
3168 if (start_capture) {
3169 if (global_capture_opts.save_file != NULL) {
3170 /* Save the directory name for future file dialogs. */
3171 /* (get_dirname overwrites filename) */
3172 s = get_dirname(g_strdup(global_capture_opts.save_file));
3173 set_last_open_dir(s);
3176 /* "-k" was specified; start a capture. */
3177 show_main_window(FALSE);
3178 check_and_warn_user_startup(cf_name);
3180 /* If no user interfaces were specified on the command line,
3181 copy the list of selected interfaces to the set of interfaces
3182 to use for this capture. */
3183 if (global_capture_opts.ifaces->len == 0)
3184 collect_ifaces(&global_capture_opts);
3185 if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3186 /* The capture started. Open stat windows; we do so after creating
3187 the main window, to avoid GTK warnings, and after successfully
3188 opening the capture file, so we know we have something to compute
3189 stats on, and after registering all dissectors, so that MATE will
3190 have registered its field array and we can have a tap filter with
3191 one of MATE's late-registered fields as part of the filter. */
3192 start_requested_stats();
3195 show_main_window(FALSE);
3196 check_and_warn_user_startup(cf_name);
3197 main_set_for_capture_in_progress(FALSE);
3198 set_capture_if_dialog_for_capture_in_progress(FALSE);
3200 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3201 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3202 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3204 #else /* HAVE_LIBPCAP */
3205 show_main_window(FALSE);
3206 check_and_warn_user_startup(cf_name);
3207 main_set_for_capture_in_progress(FALSE);
3208 set_capture_if_dialog_for_capture_in_progress(FALSE);
3209 #endif /* HAVE_LIBPCAP */
3213 GtkWidget *filter_te;
3214 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3215 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3217 /* Run the display filter so it goes in effect. */
3218 main_filter_packets(&cfile, dfilter, FALSE);
3222 /* register our pid if we are being run from a U3 device */
3225 profile_store_persconffiles (FALSE);
3227 #ifdef HAVE_GTKOSXAPPLICATION
3228 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3229 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3230 gtkosx_application_ready(theApp);
3233 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3236 gtk_iface_mon_start();
3239 software_update_init();
3241 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3243 /* ... back from GTK, we're going down now! */
3246 gtk_iface_mon_stop();
3249 /* deregister our pid */
3250 u3_deregister_pid();
3254 AirPDcapDestroyContext(&airpdcap_ctx);
3257 /* hide the (unresponsive) main window, while asking the user to close the console window */
3258 gtk_widget_hide(top_level);
3260 #ifdef HAVE_GTKOSXAPPLICATION
3261 g_object_unref(theApp);
3264 software_update_cleanup();
3266 /* Shutdown windows sockets */
3269 /* For some unknown reason, the "atexit()" call in "create_console()"
3270 doesn't arrange that "destroy_console()" be called when we exit,
3271 so we call it here if a console was created. */
3280 /* We build this as a GUI subsystem application on Win32, so
3281 "WinMain()", not "main()", gets called.
3283 Hack shamelessly stolen from the Win32 port of the GIMP. */
3285 #define _stdcall __attribute__((stdcall))
3289 WinMain (struct HINSTANCE__ *hInstance,
3290 struct HINSTANCE__ *hPrevInstance,
3294 INITCOMMONCONTROLSEX comm_ctrl;
3297 * Initialize our DLL search path. MUST be called before LoadLibrary
3300 ws_init_dll_search_path();
3302 /* Initialize our controls. Required for native Windows file dialogs. */
3303 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3304 comm_ctrl.dwSize = sizeof(comm_ctrl);
3305 /* Includes the animate, header, hot key, list view, progress bar,
3306 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3309 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3310 InitCommonControlsEx(&comm_ctrl);
3312 /* RichEd20.DLL is needed for filter entries. */
3313 ws_load_library("riched20.dll");
3315 set_has_console(FALSE);
3316 set_console_wait(FALSE);
3317 return main (__argc, __argv);
3324 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3325 const char *message, gpointer user_data _U_)
3332 /* ignore log message, if log_level isn't interesting based
3333 upon the console log preferences.
3334 If the preferences haven't been loaded loaded yet, display the
3337 The default console_log_level preference value is such that only
3338 ERROR, CRITICAL and WARNING level messages are processed;
3339 MESSAGE, INFO and DEBUG level messages are ignored. */
3340 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3341 prefs.console_log_level != 0) {
3346 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3347 /* the user wants a console or the application will terminate immediately */
3350 if (get_has_console()) {
3351 /* For some unknown reason, the above doesn't appear to actually cause
3352 anything to be sent to the standard output, so we'll just splat the
3353 message out directly, just to make sure it gets out. */
3355 switch(log_level & G_LOG_LEVEL_MASK) {
3356 case G_LOG_LEVEL_ERROR:
3359 case G_LOG_LEVEL_CRITICAL:
3362 case G_LOG_LEVEL_WARNING:
3365 case G_LOG_LEVEL_MESSAGE:
3368 case G_LOG_LEVEL_INFO:
3371 case G_LOG_LEVEL_DEBUG:
3375 fprintf(stderr, "unknown log_level %u\n", log_level);
3377 g_assert_not_reached();
3380 /* create a "timestamp" */
3382 today = localtime(&curr);
3384 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3385 today->tm_hour, today->tm_min, today->tm_sec,
3386 log_domain != NULL ? log_domain : "",
3389 if(log_level & G_LOG_LEVEL_ERROR) {
3390 /* wait for a key press before the following error handler will terminate the program
3391 this way the user at least can read the error message */
3392 printf("\n\nPress any key to exit\n");
3396 /* XXX - on UN*X, should we just use g_log_default_handler()?
3397 We want the error messages to go to the standard output;
3398 on Mac OS X, that will cause them to show up in various
3399 per-user logs accessible through Console (details depend
3400 on whether you're running 10.0 through 10.4 or running
3401 10.5 and later), and, on other UN*X desktop environments,
3402 if they don't show up in some form of console log, that's
3403 a deficiency in that desktop environment. (Too bad
3404 Windows doesn't set the standard output and error for
3405 GUI apps to something that shows up in such a log.) */
3406 g_log_default_handler(log_domain, log_level, message, user_data);
3413 * Helper for main_widgets_rearrange()
3415 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3416 gtk_container_remove(GTK_CONTAINER(data), widget);
3419 static GtkWidget *main_widget_layout(gint layout_content)
3421 switch(layout_content) {
3422 case(layout_pane_content_none):
3424 case(layout_pane_content_plist):
3426 case(layout_pane_content_pdetails):
3428 case(layout_pane_content_pbytes):
3429 return byte_nb_ptr_gbl;
3431 g_assert_not_reached();
3438 * Rearrange the main window widgets
3440 void main_widgets_rearrange(void) {
3441 GtkWidget *first_pane_widget1, *first_pane_widget2;
3442 GtkWidget *second_pane_widget1, *second_pane_widget2;
3443 gboolean split_top_left = FALSE;
3445 /* be a bit faster */
3446 gtk_widget_hide(main_vbox);
3448 /* be sure we don't lose a widget while rearranging */
3449 g_object_ref(G_OBJECT(menubar));
3450 g_object_ref(G_OBJECT(main_tb));
3451 g_object_ref(G_OBJECT(filter_tb));
3452 g_object_ref(G_OBJECT(wireless_tb));
3453 g_object_ref(G_OBJECT(pkt_scrollw));
3454 g_object_ref(G_OBJECT(tv_scrollw));
3455 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3456 g_object_ref(G_OBJECT(statusbar));
3457 g_object_ref(G_OBJECT(main_pane_v1));
3458 g_object_ref(G_OBJECT(main_pane_v2));
3459 g_object_ref(G_OBJECT(main_pane_h1));
3460 g_object_ref(G_OBJECT(main_pane_h2));
3461 g_object_ref(G_OBJECT(welcome_pane));
3463 /* empty all containers participating */
3464 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3465 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3466 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3467 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3468 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3470 statusbar_widgets_emptying(statusbar);
3472 /* add the menubar always at the top */
3473 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3476 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3478 /* filter toolbar in toolbar area */
3479 if (!prefs.filter_toolbar_show_in_statusbar) {
3480 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3483 /* airpcap toolbar */
3484 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3486 /* fill the main layout panes */
3487 switch(prefs.gui_layout_type) {
3488 case(layout_type_5):
3489 main_first_pane = main_pane_v1;
3490 main_second_pane = main_pane_v2;
3491 split_top_left = FALSE;
3493 case(layout_type_2):
3494 main_first_pane = main_pane_v1;
3495 main_second_pane = main_pane_h1;
3496 split_top_left = FALSE;
3498 case(layout_type_1):
3499 main_first_pane = main_pane_v1;
3500 main_second_pane = main_pane_h1;
3501 split_top_left = TRUE;
3503 case(layout_type_4):
3504 main_first_pane = main_pane_h1;
3505 main_second_pane = main_pane_v1;
3506 split_top_left = FALSE;
3508 case(layout_type_3):
3509 main_first_pane = main_pane_h1;
3510 main_second_pane = main_pane_v1;
3511 split_top_left = TRUE;
3513 case(layout_type_6):
3514 main_first_pane = main_pane_h1;
3515 main_second_pane = main_pane_h2;
3516 split_top_left = FALSE;
3519 main_first_pane = NULL;
3520 main_second_pane = NULL;
3521 g_assert_not_reached();
3523 if (split_top_left) {
3524 first_pane_widget1 = main_second_pane;
3525 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3526 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3527 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3529 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3530 first_pane_widget2 = main_second_pane;
3531 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3532 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3534 if (first_pane_widget1 != NULL)
3535 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3536 if (first_pane_widget2 != NULL)
3537 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3538 if (second_pane_widget1 != NULL)
3539 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3540 if (second_pane_widget2 != NULL)
3541 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3543 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3546 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3549 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3551 /* filter toolbar in statusbar hbox */
3552 if (prefs.filter_toolbar_show_in_statusbar) {
3553 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3556 /* statusbar widgets */
3557 statusbar_widgets_pack(statusbar);
3559 /* hide widgets on users recent settings */
3560 main_widgets_show_or_hide();
3562 gtk_widget_show(main_vbox);
3566 is_widget_visible(GtkWidget *widget, gpointer data)
3568 gboolean *is_visible = ( gboolean *)data;
3571 if (gtk_widget_get_visible(widget))
3578 main_widgets_show_or_hide(void)
3580 gboolean main_second_pane_show;
3582 if (recent.main_toolbar_show) {
3583 gtk_widget_show(main_tb);
3585 gtk_widget_hide(main_tb);
3588 statusbar_widgets_show_or_hide(statusbar);
3590 if (recent.filter_toolbar_show) {
3591 gtk_widget_show(filter_tb);
3593 gtk_widget_hide(filter_tb);
3596 if (recent.wireless_toolbar_show) {
3597 gtk_widget_show(wireless_tb);
3599 gtk_widget_hide(wireless_tb);
3602 if (recent.packet_list_show && have_capture_file) {
3603 gtk_widget_show(pkt_scrollw);
3605 gtk_widget_hide(pkt_scrollw);
3608 if (recent.tree_view_show && have_capture_file) {
3609 gtk_widget_show(tv_scrollw);
3611 gtk_widget_hide(tv_scrollw);
3614 if (recent.byte_view_show && have_capture_file) {
3615 gtk_widget_show(byte_nb_ptr_gbl);
3617 gtk_widget_hide(byte_nb_ptr_gbl);
3620 if (have_capture_file) {
3621 gtk_widget_show(main_first_pane);
3623 gtk_widget_hide(main_first_pane);
3627 * Is anything in "main_second_pane" visible?
3628 * If so, show it, otherwise hide it.
3630 main_second_pane_show = FALSE;
3631 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3632 &main_second_pane_show);
3633 if (main_second_pane_show) {
3634 gtk_widget_show(main_second_pane);
3636 gtk_widget_hide(main_second_pane);
3639 if (!have_capture_file) {
3641 gtk_widget_show(welcome_pane);
3644 gtk_widget_hide(welcome_pane);
3649 /* called, when the window state changes (minimized, maximized, ...) */
3651 window_state_event_cb (GtkWidget *widget _U_,
3655 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3657 if( (event->type) == (GDK_WINDOW_STATE)) {
3658 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3659 /* we might have dialogs popped up while we where iconified,
3661 display_queued_messages();
3669 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3671 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3673 if (event->keyval == GDK_F8) {
3676 } else if (event->keyval == GDK_F7) {
3679 } else if (event->state & NO_SHIFT_MOD_MASK) {
3680 return FALSE; /* Skip control, alt, and other modifiers */
3682 * A comment in gdkkeysyms.h says that it's autogenerated from
3683 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3684 * don't explicitly say so, g_ascii_isprint() should work as expected
3687 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3688 /* Forward the keypress on to the display filter entry */
3689 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3690 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3691 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3699 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3700 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3705 GtkAccelGroup *accel;
3708 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3709 set_titlebar_for_capture_file(NULL);
3711 gtk_widget_set_name(top_level, "main window");
3712 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3714 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3715 G_CALLBACK(window_state_event_cb), NULL);
3716 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3717 G_CALLBACK(top_level_key_pressed_cb), NULL );
3719 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3720 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3722 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3723 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3724 gtk_widget_show(main_vbox);
3727 menubar = main_menu_new(&accel);
3729 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3730 /* Mac OS X native menus are created and displayed by main_menu_new() */
3731 if(!prefs_p->gui_macosx_style) {
3733 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3734 gtk_widget_show(menubar);
3735 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3737 gtk_widget_hide(menubar);
3742 main_tb = toolbar_new();
3743 gtk_widget_show (main_tb);
3745 /* Filter toolbar */
3746 filter_tb = filter_toolbar_new();
3749 pkt_scrollw = packet_list_create();
3750 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3751 gtk_widget_show_all(pkt_scrollw);
3754 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3755 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3756 gtk_widget_show(tv_scrollw);
3758 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3759 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3760 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3761 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3762 gtk_widget_show(tree_view_gbl);
3765 byte_nb_ptr_gbl = byte_view_new();
3766 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3767 gtk_widget_show(byte_nb_ptr_gbl);
3769 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3770 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3772 /* Panes for the packet list, tree, and byte view */
3773 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3774 gtk_widget_show(main_pane_v1);
3775 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3776 gtk_widget_show(main_pane_v2);
3777 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3778 gtk_widget_show(main_pane_h1);
3779 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3780 gtk_widget_show(main_pane_h2);
3782 wireless_tb = airpcap_toolbar_new();
3784 wireless_tb = ws80211_toolbar_new();
3786 gtk_widget_show(wireless_tb);
3789 statusbar = statusbar_new();
3790 gtk_widget_show(statusbar);
3792 /* Pane for the welcome screen */
3793 welcome_pane = welcome_new();
3794 gtk_widget_show(welcome_pane);
3798 show_main_window(gboolean doing_work)
3800 main_set_for_capture_file(doing_work);
3802 /*** we have finished all init things, show the main window ***/
3803 gtk_widget_show(top_level);
3805 /* the window can be maximized only, if it's visible, so do it after show! */
3806 main_load_window_geometry(top_level);
3808 /* process all pending GUI events before continue */
3809 while (gtk_events_pending()) gtk_main_iteration();
3811 /* Pop up any queued-up alert boxes. */
3812 display_queued_messages();
3814 /* Move the main window to the front, in case it isn't already there */
3815 gdk_window_raise(gtk_widget_get_window(top_level));
3818 airpcap_toolbar_show(wireless_tb);
3819 #endif /* HAVE_AIRPCAP */
3822 static void copy_global_profile (const gchar *profile_name)
3824 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3826 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3827 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3828 "Can't create directory\n\"%s\":\n%s.",
3829 pf_dir_path, g_strerror(errno));
3831 g_free(pf_dir_path);
3834 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3835 &pf_dir_path, &pf_dir_path2) == -1) {
3836 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3837 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3838 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3840 g_free(pf_filename);
3841 g_free(pf_dir_path);
3842 g_free(pf_dir_path2);
3846 /* Change configuration profile */
3847 void change_configuration_profile (const gchar *profile_name)
3849 char *gdp_path, *dp_path;
3853 /* First check if profile exists */
3854 if (!profile_exists(profile_name, FALSE)) {
3855 if (profile_exists(profile_name, TRUE)) {
3856 /* Copy from global profile */
3857 copy_global_profile (profile_name);
3859 /* No personal and no global profile exists */
3864 /* Then check if changing to another profile */
3865 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3869 /* Get the current geometry, before writing it to disk */
3870 main_save_window_geometry(top_level);
3872 if (profile_exists(get_profile_name(), FALSE)) {
3873 /* Write recent file for profile we are leaving, if it still exists */
3874 write_profile_recent();
3877 /* Set profile name and update the status bar */
3878 set_profile_name (profile_name);
3879 profile_bar_update ();
3880 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3882 /* Reset current preferences and apply the new */
3886 (void) read_configuration_files (&gdp_path, &dp_path);
3888 recent_read_profile_static(&rf_path, &rf_open_errno);
3889 if (rf_path != NULL && rf_open_errno != 0) {
3890 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3891 "Could not open common recent file\n\"%s\": %s.",
3892 rf_path, g_strerror(rf_open_errno));
3894 if (recent.gui_fileopen_remembered_dir &&
3895 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3896 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3898 timestamp_set_type (recent.gui_time_format);
3899 timestamp_set_seconds_type (recent.gui_seconds_format);
3900 color_filters_enable(recent.packet_list_colorize);
3902 prefs_to_capture_opts();
3904 macros_post_update();
3906 /* Update window view and redraw the toolbar */
3907 main_titlebar_update();
3908 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3909 toolbar_redraw_all();
3911 /* Enable all protocols and disable from the disabled list */
3913 if (gdp_path == NULL && dp_path == NULL) {
3914 set_disabled_protos_list();
3917 /* Reload color filters */
3918 color_filters_reload();
3920 /* Reload list of interfaces on welcome page */
3921 welcome_if_panel_reload();
3923 /* Recreate the packet list according to new preferences */
3924 packet_list_recreate ();
3925 cfile.columns_changed = FALSE; /* Reset value */
3928 /* Update menus with new recent values */
3929 menu_recent_read_finished();
3931 /* Reload pane geometry, must be done after recreating the list */
3932 main_pane_load_window_geometry();
3935 /** redissect packets and update UI */
3936 void redissect_packets(void)
3938 cf_redissect_packets(&cfile);
3939 status_expert_update();
3948 * indent-tabs-mode: nil
3951 * ex: set shiftwidth=4 tabstop=8 expandtab:
3952 * :indentSize=4:tabSize=8:noTabs=true: