5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10 * needed by dissect routines
11 * Jeff Foster, 2001/03/12, added support tabbed hex display windowss
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include <gdk/gdkkeysyms.h>
35 #if GTK_CHECK_VERSION(3,0,0)
36 # include <gdk/gdkkeysyms-compat.h>
49 #include "wsutil/wsgetopt.h"
52 #ifdef _WIN32 /* Needed for console I/O */
54 /* AttachConsole() needs this #define! */
55 #define _WIN32_WINNT 0x0501
61 #ifdef HAVE_LIBPORTAUDIO
62 #include <portaudio.h>
63 #endif /* HAVE_LIBPORTAUDIO */
65 #include <epan/epan.h>
66 #include <epan/filesystem.h>
67 #include <wsutil/privileges.h>
68 #include <epan/epan_dissect.h>
69 #include <epan/timestamp.h>
70 #include <epan/plugins.h>
71 #include <epan/dfilter/dfilter.h>
72 #include <epan/strutil.h>
73 #include <epan/addr_resolv.h>
74 #include <epan/emem.h>
75 #include <epan/ex-opt.h>
76 #include <epan/funnel.h>
77 #include <epan/expert.h>
78 #include <epan/frequency-utils.h>
79 #include <epan/prefs.h>
80 #include <epan/prefs-int.h>
82 #include <epan/stat_cmd_args.h>
84 #include <epan/column.h>
86 /* general (not GTK specific) */
88 #include "../summary.h"
89 #include "../filters.h"
90 #include "../disabled_protos.h"
92 #include "../color_filters.h"
94 #include "../register.h"
95 #include "../ringbuffer.h"
97 #include "../clopts_common.h"
98 #include "../console_io.h"
99 #include "../cmdarg_err.h"
100 #include "../version_info.h"
101 #include "../merge.h"
105 #include "gtk_iface_monitor.h"
107 #include "ui/alert_box.h"
108 #include "ui/main_statusbar.h"
109 #include "ui/recent.h"
110 #include "ui/recent_utils.h"
111 #include "ui/simple_dialog.h"
112 #include "ui/ui_util.h"
115 #include "ui/capture_globals.h"
116 #include "ui/iface_lists.h"
119 #include <wsutil/file_util.h>
122 #include "capture_ui_utils.h"
123 #include "capture-pcap-util.h"
124 #include "capture_ifinfo.h"
126 #include "capture_sync.h"
130 #include "capture-wpcap.h"
131 #include "capture_wpcap_packet.h"
132 #include <tchar.h> /* Needed for Unicode */
133 #include <wsutil/unicode-utils.h>
134 #include <commctrl.h>
135 #include <shellapi.h>
139 #include "ui/gtk/file_dlg.h"
140 #include "ui/gtk/gtkglobals.h"
141 #include "ui/gtk/color_utils.h"
142 #include "ui/gtk/gui_utils.h"
143 #include "ui/gtk/color_dlg.h"
144 #include "ui/gtk/filter_dlg.h"
145 #include "ui/gtk/uat_gui.h"
146 #include "ui/gtk/main.h"
147 #include "ui/gtk/main_80211_toolbar.h"
148 #include "ui/gtk/main_airpcap_toolbar.h"
149 #include "ui/gtk/main_filter_toolbar.h"
150 #include "ui/gtk/main_titlebar.h"
151 #include "ui/gtk/menus.h"
152 #include "ui/gtk/main_menubar_private.h"
153 #include "ui/gtk/macros_dlg.h"
154 #include "ui/gtk/main_statusbar_private.h"
155 #include "ui/gtk/main_toolbar.h"
156 #include "ui/gtk/main_toolbar_private.h"
157 #include "ui/gtk/main_welcome.h"
158 #include "ui/gtk/drag_and_drop.h"
159 #include "ui/gtk/capture_file_dlg.h"
160 #include "ui/gtk/packet_panes.h"
161 #include "ui/gtk/keys.h"
162 #include "ui/gtk/packet_win.h"
163 #include "ui/gtk/stock_icons.h"
164 #include "ui/gtk/find_dlg.h"
165 #include "ui/gtk/follow_tcp.h"
166 #include "ui/gtk/font_utils.h"
167 #include "ui/gtk/about_dlg.h"
168 #include "ui/gtk/help_dlg.h"
169 #include "ui/gtk/decode_as_dlg.h"
170 #include "ui/gtk/webbrowser.h"
171 #include "ui/gtk/capture_dlg.h"
172 #include "ui/gtk/capture_if_dlg.h"
173 #include "ui/gtk/tap_param_dlg.h"
174 #include "ui/gtk/prefs_column.h"
175 #include "ui/gtk/prefs_dlg.h"
176 #include "ui/gtk/proto_help.h"
177 #include "ui/gtk/new_packet_list.h"
178 #include "ui/gtk/filter_expression_save_dlg.h"
180 #include "ui/gtk/old-gtk-compat.h"
183 #include "../../image/wsicon16.xpm"
184 #include "../../image/wsicon32.xpm"
185 #include "../../image/wsicon48.xpm"
186 #include "../../image/wsicon64.xpm"
187 #include "../../image/wsiconcap16.xpm"
188 #include "../../image/wsiconcap32.xpm"
189 #include "../../image/wsiconcap48.xpm"
194 #include "airpcap_loader.h"
195 #include "airpcap_dlg.h"
196 #include "airpcap_gui_utils.h"
199 #include <epan/crypt/airpdcap_ws.h>
202 #ifdef HAVE_GTKOSXAPPLICATION
203 #include <igemacintegration/gtkosxapplication.h>
207 * Files under personal and global preferences directories in which
208 * GTK settings for Wireshark are stored.
210 #define RC_FILE "gtkrc"
214 static gboolean capture_stopping;
216 /* "exported" main widgets */
217 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
219 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
220 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
221 static GtkWidget *main_first_pane, *main_second_pane;
223 /* internally used widgets */
224 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
226 GtkWidget *wireless_tb;
228 int airpcap_dll_ret_val = -1;
231 GString *comp_info_str, *runtime_info_str;
233 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
235 static guint tap_update_timer_id;
238 static gboolean has_console; /* TRUE if app has console */
239 static gboolean console_wait; /* "Press any key..." */
240 static void destroy_console(void);
241 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
243 static void console_log_handler(const char *log_domain,
244 GLogLevelFlags log_level, const char *message, gpointer user_data);
246 static void create_main_window(gint, gint, gint, e_prefs*);
247 static void show_main_window(gboolean);
248 static void main_save_window_geometry(GtkWidget *widget);
251 /* Match selected byte pattern */
253 match_selected_cb_do(GtkWidget *filter_te, gpointer data, int action, gchar *text)
255 char *cur_filter, *new_filter;
257 if ((!text) || (0 == strlen(text))) {
258 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
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(g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),data, 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 new_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 = 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 it's 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 = 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 it's 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 = new_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 *) new_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, FALSE, FALSE);
552 col_custom_prime_edt(&edt, &cfile.cinfo);
554 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
555 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
557 /* First check selected column */
558 if (is_address_column (column)) {
559 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
562 for (col = 0; col < cfile.cinfo.num_cols; col++) {
563 /* Then check all columns except the selected */
564 if ((col != column) && (is_address_column (col))) {
565 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
569 epan_dissect_cleanup(&edt);
576 get_filter_from_packet_list_row_and_column(gpointer data)
578 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
579 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
583 fdata = (frame_data *) new_packet_list_get_row_data(row);
588 if (!cf_read_frame(&cfile, fdata))
589 return NULL; /* error reading the frame */
590 /* proto tree, visible. We need a proto tree if there's custom columns */
591 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
592 col_custom_prime_edt(&edt, &cfile.cinfo);
594 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
596 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
598 if ((cfile.cinfo.col_custom_occurrence[column]) ||
599 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
601 /* Only construct the filter when a single occurrence is displayed
602 * otherwise we might end up with a filter like "ip.proto==1,6".
604 * Or do we want to be able to filter on multiple occurrences so that
605 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
608 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
609 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
610 /* leak a little but safer than ep_ here */
611 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
612 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
613 if (hfi->parent == -1) {
615 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
616 } else if (hfi->type == FT_STRING) {
617 /* Custom string, add quotes */
618 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
619 cfile.cinfo.col_expr.col_expr_val[column]);
623 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
624 cfile.cinfo.col_expr.col_expr_val[column]);
629 epan_dissect_cleanup(&edt);
636 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
638 match_selected_cb_do(g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
641 get_filter_from_packet_list_row_and_column(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[256];
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 new_packet_list_freeze();
713 cfile.displayed_count--;
714 new_packet_list_recreate_visible_rows();
715 new_packet_list_thaw();
717 new_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 new_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 = 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_) {
884 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
887 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
889 expand_all_tree(cfile.edt->tree, tree_view_gbl);
892 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
894 if (cfile.finfo_selected) {
895 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
896 cfile.finfo_selected->hfinfo->abbrev,0);
897 /* Recreate the packet list according to new preferences */
898 new_packet_list_recreate ();
899 if (!prefs.gui_use_pref_save) {
902 cfile.cinfo.columns_changed = FALSE; /* Reset value */
906 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
909 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
911 /* the mouse position is at an entry, expand that one */
912 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
913 gtk_tree_path_free(path);
917 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
918 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
920 if (cfile.edt->tree) {
921 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
925 /* Update main window items based on whether there's a capture in progress. */
927 main_set_for_capture_in_progress(gboolean capture_in_progress)
929 set_menus_for_capture_in_progress(capture_in_progress);
932 set_toolbar_for_capture_in_progress(capture_in_progress);
934 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
938 /* Update main window items based on whether we have a capture file. */
940 main_set_for_capture_file(gboolean have_capture_file_in)
942 have_capture_file = have_capture_file_in;
944 main_widgets_show_or_hide();
947 /* Update main window items based on whether we have captured packets. */
949 main_set_for_captured_packets(gboolean have_captured_packets)
951 set_menus_for_captured_packets(have_captured_packets);
952 set_toolbar_for_captured_packets(have_captured_packets);
955 /* Update main window items based on whether we have a packet history. */
957 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
959 set_menus_for_packet_history(back_history, forward_history);
960 set_toolbar_for_packet_history(back_history, forward_history);
966 /* get the current geometry, before writing it to disk */
967 main_save_window_geometry(top_level);
969 /* write user's recent file to disk
970 * It is no problem to write this file, even if we do not quit */
971 write_profile_recent();
974 /* XXX - should we check whether the capture file is an
975 unsaved temporary file for a live capture and, if so,
976 pop up a "do you want to exit without saving the capture
977 file?" dialog, and then just return, leaving said dialog
978 box to forcibly quit if the user clicks "OK"?
980 If so, note that this should be done in a subroutine that
981 returns TRUE if we do so, and FALSE otherwise, and if it
982 returns TRUE we should return TRUE without nuking anything.
984 Note that, if we do that, we might also want to check if
985 an "Update list of packets in real time" capture is in
986 progress and, if so, ask whether they want to terminate
987 the capture and discard it, and return TRUE, before nuking
988 any child capture, if they say they don't want to do so. */
991 /* Nuke any child capture in progress. */
992 capture_kill_child(&global_capture_opts);
995 /* Are we in the middle of reading a capture? */
996 if (cfile.state == FILE_READ_IN_PROGRESS) {
997 /* Yes, so we can't just close the file and quit, as
998 that may yank the rug out from under the read in
999 progress; instead, just set the state to
1000 "FILE_READ_ABORTED" and return - the code doing the read
1001 will check for that and, if it sees that, will clean
1003 cfile.state = FILE_READ_ABORTED;
1005 /* Say that the window should *not* be deleted;
1006 that'll be done by the code that cleans up. */
1009 /* Close any capture file we have open; on some OSes, you
1010 can't unlink a temporary capture file if you have it
1012 "cf_close()" will unlink it after closing it if
1013 it's a temporary file.
1015 We do this here, rather than after the main loop returns,
1016 as, after the main loop returns, the main window may have
1017 been destroyed (if this is called due to a "destroy"
1018 even on the main window rather than due to the user
1019 selecting a menu item), and there may be a crash
1020 or other problem when "cf_close()" tries to
1021 clean up stuff in the main window.
1023 XXX - is there a better place to put this?
1024 Or should we have a routine that *just* closes the
1025 capture file, and doesn't do anything with the UI,
1026 which we'd call here, and another routine that
1027 calls that routine and also cleans up the UI, which
1028 we'd call elsewhere? */
1031 /* Exit by leaving the main loop, so that any quit functions
1032 we registered get called. */
1035 /* Say that the window should be deleted. */
1041 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1043 /* If we're in the middle of stopping a capture, don't do anything;
1044 the user can try deleting the window after the capture stops. */
1045 if (capture_stopping)
1048 /* If there's unsaved data, let the user save it first.
1049 If they cancel out of it, don't quit. */
1050 if (do_file_close(&cfile, TRUE, " before quitting"))
1051 return main_do_quit();
1053 return TRUE; /* will this keep the window from being deleted? */
1058 main_pane_load_window_geometry(void)
1060 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1061 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1062 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1063 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1069 main_load_window_geometry(GtkWidget *widget)
1071 window_geometry_t geom;
1073 geom.set_pos = prefs.gui_geometry_save_position;
1074 geom.x = recent.gui_geometry_main_x;
1075 geom.y = recent.gui_geometry_main_y;
1076 geom.set_size = prefs.gui_geometry_save_size;
1077 if (recent.gui_geometry_main_width > 0 &&
1078 recent.gui_geometry_main_height > 0) {
1079 geom.width = recent.gui_geometry_main_width;
1080 geom.height = recent.gui_geometry_main_height;
1081 geom.set_maximized = prefs.gui_geometry_save_maximized;
1083 /* We assume this means the width and height weren't set in
1084 the "recent" file (or that there is no "recent" file),
1085 and weren't set to a default value, so we don't set the
1086 size. (The "recent" file code rejects non-positive width
1087 and height values.) */
1088 geom.set_size = FALSE;
1090 geom.maximized = recent.gui_geometry_main_maximized;
1092 window_set_geometry(widget, &geom);
1094 main_pane_load_window_geometry();
1095 statusbar_load_window_geometry();
1100 main_save_window_geometry(GtkWidget *widget)
1102 window_geometry_t geom;
1104 window_get_geometry(widget, &geom);
1106 if (prefs.gui_geometry_save_position) {
1107 recent.gui_geometry_main_x = geom.x;
1108 recent.gui_geometry_main_y = geom.y;
1111 if (prefs.gui_geometry_save_size) {
1112 recent.gui_geometry_main_width = geom.width;
1113 recent.gui_geometry_main_height = geom.height;
1116 if(prefs.gui_geometry_save_maximized) {
1117 recent.gui_geometry_main_maximized = geom.maximized;
1120 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1121 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1122 statusbar_save_window_geometry();
1126 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1128 /* If there's unsaved data, let the user save it first. */
1129 if (do_file_close(&cfile, TRUE, " before quitting"))
1134 print_usage(gboolean print_ver) {
1144 fprintf(output, "Wireshark " VERSION "%s\n"
1145 "Interactively dump and analyze network traffic.\n"
1146 "See http://www.wireshark.org for more information.\n"
1149 wireshark_svnversion, get_copyright_info());
1153 fprintf(output, "\n");
1154 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1155 fprintf(output, "\n");
1158 fprintf(output, "Capture interface:\n");
1159 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1160 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1161 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1162 fprintf(output, " -p don't capture in promiscuous mode\n");
1163 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1164 fprintf(output, " -S update packet display when new packets are captured\n");
1165 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1166 #ifdef HAVE_PCAP_CREATE
1167 fprintf(output, " -I capture in monitor mode, if available\n");
1169 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1170 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1172 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1173 fprintf(output, " -D print list of interfaces and exit\n");
1174 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1175 fprintf(output, "\n");
1176 fprintf(output, "Capture stop conditions:\n");
1177 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1178 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1179 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1180 fprintf(output, " files:NUM - stop after NUM files\n");
1181 /*fprintf(output, "\n");*/
1182 fprintf(output, "Capture output:\n");
1183 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1184 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1185 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1186 #endif /* HAVE_LIBPCAP */
1188 /*fprintf(output, "\n");*/
1189 fprintf(output, "Input file:\n");
1190 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1192 fprintf(output, "\n");
1193 fprintf(output, "Processing:\n");
1194 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1195 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1196 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1198 fprintf(output, "\n");
1199 fprintf(output, "User interface:\n");
1200 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1201 fprintf(output, " -d <display filter> start with the given display filter\n");
1202 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1203 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1204 fprintf(output, " filter\n");
1205 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1206 fprintf(output, " -m <font> set the font name used for most text\n");
1207 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1208 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1209 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1210 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1212 fprintf(output, "\n");
1213 fprintf(output, "Output:\n");
1214 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1216 fprintf(output, "\n");
1217 fprintf(output, "Miscellaneous:\n");
1218 fprintf(output, " -h display this help and exit\n");
1219 fprintf(output, " -v display version info and exit\n");
1220 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1221 fprintf(output, " persdata:path - personal data files\n");
1222 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1223 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1225 fprintf(output, " --display=DISPLAY X display to use\n");
1240 printf(PACKAGE " " VERSION "%s\n"
1247 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1248 runtime_info_str->str);
1256 * Print to the standard error. On Windows, create a console for the
1257 * standard error to show up on, if necessary.
1258 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1259 * terminal isn't the standard error?
1262 vfprintf_stderr(const char *fmt, va_list ap)
1267 vfprintf(stderr, fmt, ap);
1271 fprintf_stderr(const char *fmt, ...)
1276 vfprintf_stderr(fmt, ap);
1281 * Report an error in command-line arguments.
1282 * Creates a console on Windows.
1285 cmdarg_err(const char *fmt, ...)
1289 fprintf_stderr("wireshark: ");
1291 vfprintf_stderr(fmt, ap);
1293 fprintf_stderr("\n");
1297 * Report additional information for an error in command-line arguments.
1298 * Creates a console on Windows.
1299 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1300 * terminal isn't the standard error?
1303 cmdarg_err_cont(const char *fmt, ...)
1308 vfprintf_stderr(fmt, ap);
1309 fprintf_stderr("\n");
1314 Once every 3 seconds we get a callback here which we use to update
1318 tap_update_cb(gpointer data _U_)
1320 draw_tap_listeners(FALSE);
1324 /* Restart the tap update display timer with new configured interval */
1325 void reset_tap_update_timer(void)
1327 g_source_remove(tap_update_timer_id);
1328 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1332 protect_thread_critical_region(void)
1334 /* Threading support for TAP:s removed
1335 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1336 * See the commit for removed code:
1337 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
1341 unprotect_thread_critical_region(void)
1343 /* Threading support for TAP:s removed
1344 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1350 * Periodically process outstanding hostname lookups. If we have new items,
1351 * redraw the packet list and tree view.
1355 resolv_update_cb(gpointer data _U_)
1357 /* Anything new show up? */
1358 if (host_name_lookup_process(NULL)) {
1359 if (gtk_widget_get_window(pkt_scrollw))
1360 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1361 if (gtk_widget_get_window(tv_scrollw))
1362 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1365 /* Always check. Even if we don't do async lookups we could still get
1366 passive updates, e.g. from DNS packets. */
1371 /* Set main_window_name and it's icon title to the capture filename */
1373 set_display_filename(capture_file *cf)
1375 gchar *display_name;
1379 display_name = cf_get_display_name(cf);
1380 window_name = g_strdup_printf("%s%s", cf->unsaved_changes ? "*" : "",
1382 g_free(display_name);
1383 main_set_window_name(window_name);
1384 g_free(window_name);
1386 main_set_window_name("The Wireshark Network Analyzer");
1390 /* Update various parts of the main window for a capture file "unsaved
1391 changes" change - update the title to reflect whether there are
1392 unsaved changes or not, and update the menus and toolbar to
1393 enable or disable the "Save" operation. */
1395 main_update_for_unsaved_changes(capture_file *cf)
1397 set_display_filename(cf);
1398 set_menus_for_capture_file(cf);
1399 set_toolbar_for_capture_file(cf);
1404 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1406 /* Update menubar and toolbar */
1407 menu_auto_scroll_live_changed(auto_scroll_live_in);
1408 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1410 /* change auto scroll state */
1411 auto_scroll_live = auto_scroll_live_in;
1416 main_colorize_changed(gboolean packet_list_colorize)
1418 /* Update menubar and toolbar */
1419 menu_colorize_changed(packet_list_colorize);
1420 toolbar_colorize_changed(packet_list_colorize);
1422 /* change colorization */
1423 if(packet_list_colorize != recent.packet_list_colorize) {
1424 recent.packet_list_colorize = packet_list_colorize;
1425 color_filters_enable(packet_list_colorize);
1426 new_packet_list_colorize_packets();
1430 static GtkWidget *close_dlg = NULL;
1433 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1435 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1440 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1442 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1447 main_cf_cb_file_closing(capture_file *cf)
1449 /* if we have more than 10000 packets, show a splash screen while closing */
1450 /* XXX - don't know a better way to decide whether to show or not,
1451 * as most of the time is spend in various calls that destroy various
1452 * data structures, so it wouldn't be easy to use a progress bar,
1453 * rather than, say, a progress spinner, here! */
1454 if(cf->count > 10000) {
1455 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1456 "%sClosing file!%s\n\nPlease wait ...",
1457 simple_dialog_primary_start(),
1458 simple_dialog_primary_end());
1459 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1462 /* Destroy all windows that refer to the
1463 capture file we're closing. */
1464 destroy_packet_wins();
1466 /* Restore the standard title bar message. */
1467 main_set_window_name("The Wireshark Network Analyzer");
1469 /* Disable all menu items that make sense only if you have a capture. */
1470 set_menus_for_capture_file(NULL);
1471 set_toolbar_for_capture_file(NULL);
1472 main_set_for_captured_packets(FALSE);
1473 set_menus_for_selected_packet(cf);
1474 main_set_for_capture_in_progress(FALSE);
1475 set_capture_if_dialog_for_capture_in_progress(FALSE);
1476 set_menus_for_selected_tree_row(cf);
1478 /* Set up main window for no capture file. */
1479 main_set_for_capture_file(FALSE);
1481 main_window_update();
1485 main_cf_cb_file_closed(capture_file *cf _U_)
1487 if(close_dlg != NULL) {
1488 splash_destroy(close_dlg);
1495 main_cf_cb_file_read_started(capture_file *cf _U_)
1497 tap_param_dlg_update();
1499 /* Set up main window for a capture file. */
1500 main_set_for_capture_file(TRUE);
1504 main_cf_cb_file_read_finished(capture_file *cf)
1508 if (!cf->is_tempfile && cf->filename) {
1509 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1510 add_menu_recent_capture_file(cf->filename);
1512 /* Remember folder for next Open dialog and save it in recent */
1513 dir_path = get_dirname(g_strdup(cf->filename));
1514 set_last_open_dir(dir_path);
1518 /* Update the appropriate parts of the main window. */
1519 main_update_for_unsaved_changes(cf);
1521 /* Enable menu items that make sense if you have some captured packets. */
1522 main_set_for_captured_packets(TRUE);
1526 main_cf_cb_file_rescan_finished(capture_file *cf)
1530 if (!cf->is_tempfile && cf->filename) {
1531 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1532 add_menu_recent_capture_file(cf->filename);
1534 /* Remember folder for next Open dialog and save it in recent */
1535 dir_path = get_dirname(g_strdup(cf->filename));
1536 set_last_open_dir(dir_path);
1540 /* Update the appropriate parts of the main window. */
1541 main_update_for_unsaved_changes(cf);
1545 static GList *icon_list_create(
1546 const char **icon16_xpm,
1547 const char **icon32_xpm,
1548 const char **icon48_xpm,
1549 const char **icon64_xpm)
1551 GList *icon_list = NULL;
1552 GdkPixbuf * pixbuf16;
1553 GdkPixbuf * pixbuf32;
1554 GdkPixbuf * pixbuf48;
1555 GdkPixbuf * pixbuf64;
1558 if(icon16_xpm != NULL) {
1559 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1561 icon_list = g_list_append(icon_list, pixbuf16);
1564 if(icon32_xpm != NULL) {
1565 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1567 icon_list = g_list_append(icon_list, pixbuf32);
1570 if(icon48_xpm != NULL) {
1571 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1573 icon_list = g_list_append(icon_list, pixbuf48);
1576 if(icon64_xpm != NULL) {
1577 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1579 icon_list = g_list_append(icon_list, pixbuf64);
1586 main_capture_set_main_window_title(capture_options *capture_opts)
1588 GString *title = g_string_new("");
1590 g_string_append(title, "Capturing ");
1591 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1592 main_set_window_name(title->str);
1593 g_string_free(title, TRUE);
1597 main_capture_cb_capture_prepared(capture_options *capture_opts)
1599 static GList *icon_list = NULL;
1601 main_capture_set_main_window_title(capture_opts);
1603 if(icon_list == NULL) {
1604 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1606 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1608 /* Disable menu items that make no sense if you're currently running
1610 main_set_for_capture_in_progress(TRUE);
1611 set_capture_if_dialog_for_capture_in_progress(TRUE);
1613 /* Don't set up main window for a capture file. */
1614 main_set_for_capture_file(FALSE);
1618 main_capture_cb_capture_update_started(capture_options *capture_opts)
1620 /* We've done this in "prepared" above, but it will be cleared while
1621 switching to the next multiple file. */
1622 main_capture_set_main_window_title(capture_opts);
1624 main_set_for_capture_in_progress(TRUE);
1625 set_capture_if_dialog_for_capture_in_progress(TRUE);
1627 /* Enable menu items that make sense if you have some captured
1628 packets (yes, I know, we don't have any *yet*). */
1629 main_set_for_captured_packets(TRUE);
1631 /* Set up main window for a capture file. */
1632 main_set_for_capture_file(TRUE);
1636 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1638 capture_file *cf = capture_opts->cf;
1639 static GList *icon_list = NULL;
1641 /* The capture isn't stopping any more - it's stopped. */
1642 capture_stopping = FALSE;
1644 if (!cf->is_tempfile && cf->filename) {
1645 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1646 add_menu_recent_capture_file(cf->filename);
1649 /* Update the main window as appropriate */
1650 main_update_for_unsaved_changes(cf);
1652 /* Enable menu items that make sense if you're not currently running
1654 main_set_for_capture_in_progress(FALSE);
1655 set_capture_if_dialog_for_capture_in_progress(FALSE);
1657 /* Set up main window for a capture file. */
1658 main_set_for_capture_file(TRUE);
1660 if(icon_list == NULL) {
1661 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1663 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1665 if(global_capture_opts.quit_after_cap) {
1666 /* command line asked us to quit after the capture */
1667 /* don't pop up a dialog to ask for unsaved files etc. */
1673 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1675 /* Don't set up main window for a capture file. */
1676 main_set_for_capture_file(FALSE);
1680 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1683 capture_file *cf = capture_opts->cf;
1685 static GList *icon_list = NULL;
1687 /* The capture isn't stopping any more - it's stopped. */
1688 capture_stopping = FALSE;
1690 /*set_display_filename(cf);*/
1692 /* Enable menu items that make sense if you're not currently running
1694 main_set_for_capture_in_progress(FALSE);
1695 set_capture_if_dialog_for_capture_in_progress(FALSE);
1697 /* Restore the standard title bar message */
1698 /* (just in case we have trouble opening the capture file). */
1699 main_set_window_name("The Wireshark Network Analyzer");
1701 if(icon_list == NULL) {
1702 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1704 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1706 /* We don't have loaded the capture file, this will be done later.
1707 * For now we still have simply a blank screen. */
1709 if(global_capture_opts.quit_after_cap) {
1710 /* command line asked us to quit after the capture */
1711 /* don't pop up a dialog to ask for unsaved files etc. */
1717 main_capture_cb_capture_stopping(capture_options *capture_opts _U_)
1719 capture_stopping = TRUE;
1720 set_menus_for_capture_stopping();
1722 set_toolbar_for_capture_stopping();
1724 set_capture_if_dialog_for_capture_stopping();
1729 main_capture_cb_capture_failed(capture_options *capture_opts _U_)
1731 static GList *icon_list = NULL;
1733 /* Capture isn't stopping any more. */
1734 capture_stopping = FALSE;
1736 /* the capture failed before the first packet was captured
1737 reset title, menus and icon */
1739 main_set_window_name("The Wireshark Network Analyzer");
1741 main_set_for_capture_in_progress(FALSE);
1742 set_capture_if_dialog_for_capture_in_progress(FALSE);
1744 main_set_for_capture_file(FALSE);
1746 if(icon_list == NULL) {
1747 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1749 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1752 if(global_capture_opts.quit_after_cap) {
1753 /* command line asked us to quit after the capture */
1754 /* don't pop up a dialog to ask for unsaved files etc. */
1758 #endif /* HAVE_LIBPCAP */
1761 main_cf_cb_packet_selected(gpointer data)
1763 capture_file *cf = data;
1765 /* Display the GUI protocol tree and packet bytes.
1766 XXX - why do we dump core if we call "proto_tree_draw()"
1767 before calling "add_byte_views()"? */
1768 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1769 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1771 /* Note: Both string and hex value searches in the packet data produce a non-zero
1772 search_pos if successful */
1773 if(cf->search_in_progress &&
1774 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1775 highlight_field(cf->edt->tvb, cf->search_pos,
1776 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1779 /* A packet is selected. */
1780 set_menus_for_selected_packet(cf);
1784 main_cf_cb_packet_unselected(capture_file *cf)
1786 /* No packet is being displayed; clear the hex dump pane by getting
1787 rid of all the byte views. */
1788 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1789 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1791 /* Add a placeholder byte view so that there's at least something
1792 displayed in the byte view notebook. */
1793 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1795 /* And clear the protocol tree display as well. */
1796 proto_tree_draw(NULL, tree_view_gbl);
1798 /* No packet is selected. */
1799 set_menus_for_selected_packet(cf);
1803 main_cf_cb_field_unselected(capture_file *cf)
1805 set_menus_for_selected_tree_row(cf);
1809 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1812 case(cf_cb_file_closing):
1813 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1814 main_cf_cb_file_closing(data);
1816 case(cf_cb_file_closed):
1817 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1818 main_cf_cb_file_closed(data);
1820 case(cf_cb_file_read_started):
1821 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1822 main_cf_cb_file_read_started(data);
1824 case(cf_cb_file_read_finished):
1825 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1826 main_cf_cb_file_read_finished(data);
1828 case(cf_cb_file_reload_started):
1829 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1830 main_cf_cb_file_read_started(data);
1832 case(cf_cb_file_reload_finished):
1833 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1834 main_cf_cb_file_read_finished(data);
1836 case(cf_cb_file_rescan_started):
1837 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1839 case(cf_cb_file_rescan_finished):
1840 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1841 main_cf_cb_file_rescan_finished(data);
1843 case(cf_cb_file_fast_save_finished):
1844 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1845 main_cf_cb_file_rescan_finished(data);
1847 case(cf_cb_packet_selected):
1848 main_cf_cb_packet_selected(data);
1850 case(cf_cb_packet_unselected):
1851 main_cf_cb_packet_unselected(data);
1853 case(cf_cb_field_unselected):
1854 main_cf_cb_field_unselected(data);
1856 case(cf_cb_file_save_started):
1857 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1859 case(cf_cb_file_save_finished):
1860 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1862 case(cf_cb_file_save_failed):
1863 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1865 case(cf_cb_file_save_stopped):
1866 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1868 case(cf_cb_file_export_specified_packets_started):
1869 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1871 case(cf_cb_file_export_specified_packets_finished):
1872 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1874 case(cf_cb_file_export_specified_packets_failed):
1875 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1877 case(cf_cb_file_export_specified_packets_stopped):
1878 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1881 g_warning("main_cf_callback: event %u unknown", event);
1882 g_assert_not_reached();
1888 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1890 #ifdef HAVE_GTKOSXAPPLICATION
1891 GtkOSXApplication *theApp;
1894 case(capture_cb_capture_prepared):
1895 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1896 main_capture_cb_capture_prepared(capture_opts);
1898 case(capture_cb_capture_update_started):
1899 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1900 main_capture_cb_capture_update_started(capture_opts);
1901 #ifdef HAVE_GTKOSXAPPLICATION
1902 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1903 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1906 case(capture_cb_capture_update_continue):
1907 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1909 case(capture_cb_capture_update_finished):
1910 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1911 main_capture_cb_capture_update_finished(capture_opts);
1913 case(capture_cb_capture_fixed_started):
1914 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1915 main_capture_cb_capture_fixed_started(capture_opts);
1917 case(capture_cb_capture_fixed_continue):
1918 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1920 case(capture_cb_capture_fixed_finished):
1921 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1922 main_capture_cb_capture_fixed_finished(capture_opts);
1924 case(capture_cb_capture_stopping):
1925 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1926 /* Beware: this state won't be called, if the capture child
1927 * closes the capturing on it's own! */
1928 #ifdef HAVE_GTKOSXAPPLICATION
1929 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1930 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1932 main_capture_cb_capture_stopping(capture_opts);
1934 case(capture_cb_capture_failed):
1935 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1936 main_capture_cb_capture_failed(capture_opts);
1939 g_warning("main_capture_callback: event %u unknown", event);
1940 g_assert_not_reached();
1946 get_gtk_compiled_info(GString *str)
1948 g_string_append(str, "with ");
1949 g_string_append_printf(str,
1950 #ifdef GTK_MAJOR_VERSION
1951 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1954 "GTK+ (version unknown)");
1956 g_string_append(str, ", ");
1958 g_string_append(str, "with Cairo ");
1959 g_string_append(str, CAIRO_VERSION_STRING);
1960 g_string_append(str, ", ");
1963 g_string_append(str, "with Pango ");
1964 g_string_append(str, PANGO_VERSION_STRING);
1965 g_string_append(str, ", ");
1971 get_gui_compiled_info(GString *str)
1973 epan_get_compiled_version_info(str);
1975 g_string_append(str, ", ");
1976 #ifdef HAVE_LIBPORTAUDIO
1977 #ifdef PORTAUDIO_API_1
1978 g_string_append(str, "with PortAudio <= V18");
1979 #else /* PORTAUDIO_API_1 */
1980 g_string_append(str, "with ");
1981 g_string_append(str, Pa_GetVersionText());
1982 #endif /* PORTAUDIO_API_1 */
1983 #else /* HAVE_LIBPORTAUDIO */
1984 g_string_append(str, "without PortAudio");
1985 #endif /* HAVE_LIBPORTAUDIO */
1987 g_string_append(str, ", ");
1989 get_compiled_airpcap_version(str);
1991 g_string_append(str, "without AirPcap");
1996 get_gui_runtime_info(GString *str)
1998 epan_get_runtime_version_info(str);
2001 g_string_append(str, ", ");
2002 get_runtime_airpcap_version(str);
2006 g_string_append(str, ", ");
2007 u3_runtime_info(str);
2012 read_configuration_files(char **gdp_path, char **dp_path)
2014 int gpf_open_errno, gpf_read_errno;
2015 int cf_open_errno, df_open_errno;
2016 int gdp_open_errno, gdp_read_errno;
2017 int dp_open_errno, dp_read_errno;
2018 char *gpf_path, *pf_path;
2019 char *cf_path, *df_path;
2020 int pf_open_errno, pf_read_errno;
2023 /* load the decode as entries of this profile */
2024 load_decode_as_entries();
2026 /* Read the preference files. */
2027 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2028 &pf_open_errno, &pf_read_errno, &pf_path);
2030 if (gpf_path != NULL) {
2031 if (gpf_open_errno != 0) {
2032 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2033 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2034 g_strerror(gpf_open_errno));
2036 if (gpf_read_errno != 0) {
2037 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2038 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2039 g_strerror(gpf_read_errno));
2042 if (pf_path != NULL) {
2043 if (pf_open_errno != 0) {
2044 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2045 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2046 g_strerror(pf_open_errno));
2048 if (pf_read_errno != 0) {
2049 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2050 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2051 g_strerror(pf_read_errno));
2058 /* if the user wants a console to be always there, well, we should open one for him */
2059 if (prefs_p->gui_console_open == console_open_always) {
2064 /* Read the capture filter file. */
2065 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2066 if (cf_path != NULL) {
2067 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2068 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2069 g_strerror(cf_open_errno));
2073 /* Read the display filter file. */
2074 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2075 if (df_path != NULL) {
2076 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2077 "Could not open your display filter file\n\"%s\": %s.", df_path,
2078 g_strerror(df_open_errno));
2082 /* Read the disabled protocols file. */
2083 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2084 dp_path, &dp_open_errno, &dp_read_errno);
2085 if (*gdp_path != NULL) {
2086 if (gdp_open_errno != 0) {
2087 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2088 "Could not open global disabled protocols file\n\"%s\": %s.",
2089 *gdp_path, g_strerror(gdp_open_errno));
2091 if (gdp_read_errno != 0) {
2092 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2093 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2094 *gdp_path, g_strerror(gdp_read_errno));
2099 if (*dp_path != NULL) {
2100 if (dp_open_errno != 0) {
2101 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2102 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2103 g_strerror(dp_open_errno));
2105 if (dp_read_errno != 0) {
2106 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2107 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2108 g_strerror(dp_read_errno));
2117 /* Check if there's something important to tell the user during startup.
2118 * We want to do this *after* showing the main window so that any windows
2119 * we pop up will be above the main window.
2123 check_and_warn_user_startup(gchar *cf_name)
2125 check_and_warn_user_startup(gchar *cf_name _U_)
2128 gchar *cur_user, *cur_group;
2129 gpointer priv_warning_dialog;
2131 /* Tell the user not to run as root. */
2132 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2133 cur_user = get_cur_username();
2134 cur_group = get_cur_groupname();
2135 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2136 "Running as user \"%s\" and group \"%s\".\n"
2137 "This could be dangerous.\n\n"
2138 "If you're running Wireshark this way in order to perform live capture, "
2139 "you may want to be aware that there is a better way documented at\n"
2140 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2143 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2144 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2148 /* Warn the user if npf.sys isn't loaded. */
2149 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2150 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2151 "The NPF driver isn't running. You may have trouble\n"
2152 "capturing or listing interfaces.");
2153 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2154 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2161 /* And now our feature presentation... [ fade to music ] */
2163 main(int argc, char *argv[])
2165 char *init_progfile_dir_error;
2168 gboolean arg_error = FALSE;
2170 extern int info_update_freq; /* Found in about_dlg.c. */
2171 const gchar *filter;
2179 char *gdp_path, *dp_path;
2182 gboolean start_capture = FALSE;
2183 gboolean list_link_layer_types = FALSE;
2187 gboolean capture_option_specified = FALSE;
2194 gint pl_size = 280, tv_size = 95, bv_size = 75;
2195 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2196 dfilter_t *rfcode = NULL;
2197 gboolean rfilter_parse_failed = FALSE;
2200 GtkWidget *splash_win = NULL;
2201 GLogLevelFlags log_flags;
2202 guint go_to_packet = 0;
2203 gboolean jump_backwards = FALSE;
2204 dfilter_t *jump_to_filter = NULL;
2207 #ifdef HAVE_GTKOSXAPPLICATION
2208 GtkOSXApplication *theApp;
2212 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2213 #define OPTSTRING_B "B:"
2215 #define OPTSTRING_B ""
2216 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2217 #else /* HAVE_LIBPCAP */
2218 #define OPTSTRING_B ""
2219 #endif /* HAVE_LIBPCAP */
2221 #ifdef HAVE_PCAP_CREATE
2222 #define OPTSTRING_I "I"
2224 #define OPTSTRING_I ""
2227 #define OPTSTRING "a:b:" OPTSTRING_B "c:C:d:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:z:"
2229 static const char optstring[] = OPTSTRING;
2231 /* Set the C-language locale to the native environment. */
2232 setlocale(LC_ALL, "");
2234 arg_list_utf_16to8(argc, argv);
2238 * Get credential information for later use, and drop privileges
2239 * before doing anything else.
2240 * Let the user know if anything happened.
2242 init_process_policies();
2243 relinquish_special_privs_perm();
2246 * Attempt to get the pathname of the executable file.
2248 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2250 /* initialize the funnel mini-api */
2251 initialize_funnel_ops();
2253 AirPDcapInitContext(&airpdcap_ctx);
2256 /* Load wpcap if possible. Do this before collecting the run-time version information */
2259 /* ... and also load the packet.dll from wpcap */
2260 wpcap_packet_load();
2263 /* Load the airpcap.dll. This must also be done before collecting
2264 * run-time version information. */
2265 airpcap_dll_ret_val = load_airpcap();
2267 switch (airpcap_dll_ret_val) {
2268 case AIRPCAP_DLL_OK:
2269 /* load the airpcap interfaces */
2270 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2272 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2273 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2274 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2277 airpcap_if_active = NULL;
2281 /* select the first ad default (THIS SHOULD BE CHANGED) */
2282 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2287 * XXX - Maybe we need to warn the user if one of the following happens???
2289 case AIRPCAP_DLL_OLD:
2290 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2293 case AIRPCAP_DLL_ERROR:
2294 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2297 case AIRPCAP_DLL_NOT_FOUND:
2298 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2302 #endif /* HAVE_AIRPCAP */
2304 /* Start windows sockets */
2305 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2308 profile_store_persconffiles (TRUE);
2310 /* Assemble the compile-time version information string */
2311 comp_info_str = g_string_new("Compiled ");
2313 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2315 /* Assemble the run-time version information string */
2316 runtime_info_str = g_string_new("Running ");
2317 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2319 /* Read the profile independent recent file. We have to do this here so we can */
2320 /* set the profile before it can be set from the command line parameterts */
2321 recent_read_static(&rf_path, &rf_open_errno);
2322 if (rf_path != NULL && rf_open_errno != 0) {
2323 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2324 "Could not open common recent file\n\"%s\": %s.",
2325 rf_path, g_strerror(rf_open_errno));
2328 /* "pre-scan" the command line parameters, if we have "console only"
2329 parameters. We do this so we don't start GTK+ if we're only showing
2330 command-line help or version information.
2332 XXX - this pre-scan is done before we start GTK+, so we haven't
2333 run gtk_init() on the arguments. That means that GTK+ arguments
2334 have not been removed from the argument list; those arguments
2335 begin with "--", and will be treated as an error by getopt().
2337 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2340 optind_initial = optind;
2341 while ((opt = getopt(argc, argv, optstring)) != -1) {
2343 case 'C': /* Configuration Profile */
2344 if (profile_exists (optarg, FALSE)) {
2345 set_profile_name (optarg);
2347 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2351 case 'D': /* Print a list of capture devices and exit */
2353 if_list = capture_interface_list(&err, &err_str);
2354 if (if_list == NULL) {
2356 case CANT_GET_INTERFACE_LIST:
2357 case DONT_HAVE_PCAP:
2358 cmdarg_err("%s", err_str);
2362 case NO_INTERFACES_FOUND:
2363 cmdarg_err("There are no interfaces on which a capture can be done");
2368 capture_opts_print_interfaces(if_list);
2369 free_interface_list(if_list);
2372 capture_option_specified = TRUE;
2376 case 'h': /* Print help and exit */
2382 if (strcmp(optarg, "-") == 0)
2383 stdin_capture = TRUE;
2386 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2387 status = filesystem_opt(opt, optarg);
2389 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2393 case 'v': /* Show version and exit */
2399 * Extension command line options have to be processed before
2400 * we call epan_init() as they are supposed to be used by dissectors
2401 * or taps very early in the registration process.
2405 case '?': /* Ignore errors - the "real" scan will catch them. */
2410 /* Init the "Open file" dialog directory */
2411 /* (do this after the path settings are processed) */
2413 /* Read the profile dependent (static part) of the recent file. */
2414 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2415 /* recent lists which is done in the dynamic part. */
2416 /* We have to do this already here, so command line parameters can overwrite these values. */
2417 recent_read_profile_static(&rf_path, &rf_open_errno);
2418 if (rf_path != NULL && rf_open_errno != 0) {
2419 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2420 "Could not open recent file\n\"%s\": %s.",
2421 rf_path, g_strerror(rf_open_errno));
2424 if (recent.gui_fileopen_remembered_dir &&
2425 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2426 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2428 set_last_open_dir(get_persdatafile_dir());
2431 /* Set getopt index back to initial value, so it will start with the
2432 first command line parameter again. Also reset opterr to 1, so that
2433 error messages are printed by getopt().
2435 XXX - this seems to work on most platforms, but time will tell.
2436 The Single UNIX Specification says "The getopt() function need
2437 not be reentrant", so this isn't guaranteed to work. The Mac
2438 OS X 10.4[.x] getopt() man page says
2440 In order to use getopt() to evaluate multiple sets of arguments, or to
2441 evaluate a single set of arguments multiple times, the variable optreset
2442 must be set to 1 before the second and each additional set of calls to
2443 getopt(), and the variable optind must be reinitialized.
2447 The optreset variable was added to make it possible to call the getopt()
2448 function multiple times. This is an extension to the IEEE Std 1003.2
2449 (``POSIX.2'') specification.
2451 which I think comes from one of the other BSDs.
2453 XXX - if we want to control all the command-line option errors, so
2454 that we can display them where we choose (e.g., in a window), we'd
2455 want to leave opterr as 0, and produce our own messages using optopt.
2456 We'd have to check the value of optopt to see if it's a valid option
2457 letter, in which case *presumably* the error is "this option requires
2458 an argument but none was specified", or not a valid option letter,
2459 in which case *presumably* the error is "this option isn't valid".
2460 Some versions of getopt() let you supply a option string beginning
2461 with ':', which means that getopt() will return ':' rather than '?'
2462 for "this option requires an argument but none was specified", but
2464 optind = optind_initial;
2467 #if !GLIB_CHECK_VERSION(2,31,0)
2468 g_thread_init(NULL);
2471 /* Set the current locale according to the program environment.
2472 * We haven't localized anything, but some GTK widgets are localized
2473 * (the file selection dialogue, for example).
2474 * This also sets the C-language locale to the native environment. */
2475 setlocale (LC_ALL, "");
2477 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2478 gtk_init (&argc, &argv);
2480 cf_callback_add(main_cf_callback, NULL);
2482 capture_callback_add(main_capture_callback, NULL);
2484 cf_callback_add(statusbar_cf_callback, NULL);
2486 capture_callback_add(statusbar_capture_callback, NULL);
2489 /* Arrange that if we have no console window, and a GLib message logging
2490 routine is called to log a message, we pop up a console window.
2492 We do that by inserting our own handler for all messages logged
2493 to the default domain; that handler pops up a console if necessary,
2494 and then calls the default handler. */
2496 /* We might want to have component specific log levels later ... */
2500 G_LOG_LEVEL_CRITICAL|
2501 G_LOG_LEVEL_WARNING|
2502 G_LOG_LEVEL_MESSAGE|
2505 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2507 g_log_set_handler(NULL,
2509 console_log_handler, NULL /* user_data */);
2510 g_log_set_handler(LOG_DOMAIN_MAIN,
2512 console_log_handler, NULL /* user_data */);
2515 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2517 console_log_handler, NULL /* user_data */);
2518 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2520 console_log_handler, NULL /* user_data */);
2522 /* Set the initial values in the capture options. This might be overwritten
2523 by preference settings and then again by the command line parameters. */
2524 capture_opts_init(&global_capture_opts, &cfile);
2527 /* Initialize whatever we need to allocate colors for GTK+ */
2530 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2531 filter = get_conn_cfilter();
2532 if ( *filter != '\0' ) {
2533 info_update_freq = 1000; /* Milliseconds */
2536 /* We won't come till here, if we had a "console only" command line parameter. */
2537 splash_win = splash_new("Loading Wireshark ...");
2538 if (init_progfile_dir_error != NULL) {
2539 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2540 "Can't get pathname of Wireshark: %s.\n"
2541 "It won't be possible to capture traffic.\n"
2542 "Report this to the Wireshark developers.",
2543 init_progfile_dir_error);
2544 g_free(init_progfile_dir_error);
2547 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2549 /* Register all dissectors; we must do this before checking for the
2550 "-G" flag, as the "-G" flag dumps information registered by the
2551 dissectors, and we must do it before we read the preferences, in
2552 case any dissectors register preferences. */
2553 epan_init(register_all_protocols,register_all_protocol_handoffs,
2554 splash_update, (gpointer) splash_win,
2555 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2556 write_failure_alert_box);
2558 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2560 /* Register all tap listeners; we do this before we parse the arguments,
2561 as the "-z" argument can specify a registered tap. */
2563 /* we register the plugin taps before the other taps because
2564 stats_tree taps plugins will be registered as tap listeners
2565 by stats_tree_stat.c and need to registered before that */
2568 register_all_plugin_tap_listeners();
2571 register_all_tap_listeners();
2573 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2575 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2576 /* Removed thread code:
2577 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2580 /* this is to keep tap extensions updating once every 3 seconds */
2581 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2583 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2585 cap_file_init(&cfile);
2587 /* Fill in capture options with values from the preferences */
2588 prefs_to_capture_opts();
2590 /*#ifdef HAVE_LIBPCAP
2591 fill_in_local_interfaces();
2593 /* Now get our args */
2594 while ((opt = getopt(argc, argv, optstring)) != -1) {
2596 /*** capture option specific ***/
2597 case 'a': /* autostop criteria */
2598 case 'b': /* Ringbuffer option */
2599 case 'c': /* Capture xxx packets */
2600 case 'f': /* capture filter */
2601 case 'k': /* Start capture immediately */
2602 case 'H': /* Hide capture info dialog box */
2603 case 'p': /* Don't capture in promiscuous mode */
2604 case 'i': /* Use interface x */
2605 #ifdef HAVE_PCAP_CREATE
2606 case 'I': /* Capture in monitor mode, if available */
2608 case 's': /* Set the snapshot (capture) length */
2609 case 'S': /* "Sync" mode: used for following file ala tail -f */
2610 case 'w': /* Write to capture file xxx */
2611 case 'y': /* Set the pcap data link type */
2612 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2613 case 'B': /* Buffer size */
2614 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2616 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2622 capture_option_specified = TRUE;
2627 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2628 case 'K': /* Kerberos keytab file */
2629 read_keytab_file(optarg);
2633 /*** all non capture option specific ***/
2635 /* Configuration profile settings were already processed just ignore them this time*/
2640 case 'j': /* Search backwards for a matching packet from filter in option J */
2641 jump_backwards = TRUE;
2643 case 'g': /* Go to packet with the given packet number */
2644 go_to_packet = get_positive_int(optarg, "go to packet");
2646 case 'J': /* Jump to the first packet which matches the filter criteria */
2649 case 'l': /* Automatic scrolling in live capture mode */
2651 auto_scroll_live = TRUE;
2653 capture_option_specified = TRUE;
2657 case 'L': /* Print list of link-layer types and exit */
2659 list_link_layer_types = TRUE;
2661 capture_option_specified = TRUE;
2665 case 'm': /* Fixed-width font for the display */
2666 g_free(prefs_p->gui_font_name);
2667 prefs_p->gui_font_name = g_strdup(optarg);
2669 case 'n': /* No name resolution */
2670 gbl_resolv_flags.mac_name = FALSE;
2671 gbl_resolv_flags.network_name = FALSE;
2672 gbl_resolv_flags.transport_name = FALSE;
2673 gbl_resolv_flags.concurrent_dns = FALSE;
2675 case 'N': /* Select what types of addresses/port #s to resolve */
2676 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2677 if (badopt != '\0') {
2678 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2683 case 'o': /* Override preference from command line */
2684 switch (prefs_set_pref(optarg)) {
2687 case PREFS_SET_SYNTAX_ERR:
2688 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2691 case PREFS_SET_NO_SUCH_PREF:
2692 /* not a preference, might be a recent setting */
2693 switch (recent_set_arg(optarg)) {
2696 case PREFS_SET_SYNTAX_ERR:
2697 /* shouldn't happen, checked already above */
2698 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2701 case PREFS_SET_NO_SUCH_PREF:
2702 case PREFS_SET_OBSOLETE:
2703 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2708 g_assert_not_reached();
2711 case PREFS_SET_OBSOLETE:
2712 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2717 g_assert_not_reached();
2721 /* Path settings were already processed just ignore them this time*/
2723 case 'r': /* Read capture file xxx */
2724 /* We may set "last_open_dir" to "cf_name", and if we change
2725 "last_open_dir" later, we free the old value, so we have to
2726 set "cf_name" to something that's been allocated. */
2727 cf_name = g_strdup(optarg);
2729 case 'R': /* Read file filter */
2732 case 't': /* Time stamp type */
2733 if (strcmp(optarg, "r") == 0)
2734 timestamp_set_type(TS_RELATIVE);
2735 else if (strcmp(optarg, "a") == 0)
2736 timestamp_set_type(TS_ABSOLUTE);
2737 else if (strcmp(optarg, "ad") == 0)
2738 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2739 else if (strcmp(optarg, "d") == 0)
2740 timestamp_set_type(TS_DELTA);
2741 else if (strcmp(optarg, "dd") == 0)
2742 timestamp_set_type(TS_DELTA_DIS);
2743 else if (strcmp(optarg, "e") == 0)
2744 timestamp_set_type(TS_EPOCH);
2745 else if (strcmp(optarg, "u") == 0)
2746 timestamp_set_type(TS_UTC);
2747 else if (strcmp(optarg, "ud") == 0)
2748 timestamp_set_type(TS_UTC_WITH_DATE);
2750 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2751 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2752 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2756 case 'u': /* Seconds type */
2757 if (strcmp(optarg, "s") == 0)
2758 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2759 else if (strcmp(optarg, "hms") == 0)
2760 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2762 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2763 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2768 /* ext ops were already processed just ignore them this time*/
2771 /* We won't call the init function for the stat this soon
2772 as it would disallow MATE's fields (which are registered
2773 by the preferences set callback) from being used as
2774 part of a tap filter. Instead, we just add the argument
2775 to a list of stat arguments. */
2776 if (!process_stat_cmd_arg(optarg)) {
2777 cmdarg_err("Invalid -z argument.");
2778 cmdarg_err_cont(" -z argument must be one of :");
2779 list_stat_cmd_args();
2784 case '?': /* Bad flag - print usage message */
2793 if (cf_name != NULL) {
2795 * Input file name specified with "-r" *and* specified as a regular
2796 * command-line argument.
2798 cmdarg_err("File name specified both with -r and regular argument");
2802 * Input file name not specified with "-r", and a command-line argument
2803 * was specified; treat it as the input file name.
2805 * Yes, this is different from tshark, where non-flag command-line
2806 * arguments are a filter, but this works better on GUI desktops
2807 * where a command can be specified to be run to open a particular
2808 * file - yes, you could have "-r" as the last part of the command,
2809 * but that's a bit ugly.
2811 cf_name = g_strdup(argv[0]);
2819 * Extra command line arguments were specified; complain.
2821 cmdarg_err("Invalid argument: %s", argv[0]);
2826 #ifndef HAVE_LIBPCAP
2827 if (capture_option_specified) {
2828 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2836 fill_in_local_interfaces();
2837 if (start_capture && list_link_layer_types) {
2838 /* Specifying *both* is bogus. */
2839 cmdarg_err("You can't specify both -L and a live capture.");
2843 if (list_link_layer_types) {
2844 /* We're supposed to list the link-layer types for an interface;
2845 did the user also specify a capture file to be read? */
2847 /* Yes - that's bogus. */
2848 cmdarg_err("You can't specify -L and a capture file to be read.");
2851 /* No - did they specify a ring buffer option? */
2852 if (global_capture_opts.multi_files_on) {
2853 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2857 /* We're supposed to do a live capture; did the user also specify
2858 a capture file to be read? */
2859 if (start_capture && cf_name) {
2860 /* Yes - that's bogus. */
2861 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2865 /* No - was the ring buffer option specified and, if so, does it make
2867 if (global_capture_opts.multi_files_on) {
2868 /* Ring buffer works only under certain conditions:
2869 a) ring buffer does not work with temporary files;
2870 b) real_time_mode and multi_files_on are mutually exclusive -
2871 real_time_mode takes precedence;
2872 c) it makes no sense to enable the ring buffer if the maximum
2873 file size is set to "infinite". */
2874 if (global_capture_opts.save_file == NULL) {
2875 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2876 global_capture_opts.multi_files_on = FALSE;
2878 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2879 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2880 /* XXX - this must be redesigned as the conditions changed */
2885 if (start_capture || list_link_layer_types) {
2886 /* Did the user specify an interface to use? */
2887 if (!capture_opts_trim_iface(&global_capture_opts,
2888 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2893 if (list_link_layer_types) {
2894 /* Get the list of link-layer types for the capture devices. */
2895 if_capabilities_t *caps;
2898 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2900 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2901 if (device.selected) {
2902 #if defined(HAVE_PCAP_CREATE)
2903 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2905 caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2908 cmdarg_err("%s", err_str);
2912 if (caps->data_link_types == NULL) {
2913 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2916 #if defined(HAVE_PCAP_CREATE)
2917 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2919 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2921 free_if_capabilities(caps);
2927 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2928 capture_opts_trim_ring_num_files(&global_capture_opts);
2929 #endif /* HAVE_LIBPCAP */
2931 /* Notify all registered modules that have had any of their preferences
2932 changed either from one of the preferences file or from the command
2933 line that their preferences have changed. */
2937 if ((global_capture_opts.num_selected == 0) &&
2938 (prefs.capture_device != NULL)) {
2941 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2942 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2943 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2944 device.selected = TRUE;
2945 global_capture_opts.num_selected++;
2946 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2947 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2954 /* disabled protocols as per configuration file */
2955 if (gdp_path == NULL && dp_path == NULL) {
2956 set_disabled_protos_list();
2959 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2961 /* read in rc file from global and personal configuration paths. */
2962 rc_file = get_datafile_path(RC_FILE);
2963 #if GTK_CHECK_VERSION(3,0,0)
2964 /* XXX resolve later */
2966 gtk_rc_parse(rc_file);
2968 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2969 gtk_rc_parse(rc_file);
2979 /* close the splash screen, as we are going to open the main window now */
2980 splash_destroy(splash_win);
2982 /************************************************************************/
2983 /* Everything is prepared now, preferences and command line was read in */
2985 /* Pop up the main window. */
2986 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2988 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2989 recent_read_dynamic(&rf_path, &rf_open_errno);
2990 if (rf_path != NULL && rf_open_errno != 0) {
2991 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2992 "Could not open recent file\n\"%s\": %s.",
2993 rf_path, g_strerror(rf_open_errno));
2996 color_filters_enable(recent.packet_list_colorize);
2998 /* rearrange all the widgets as we now have all recent settings ready for this */
2999 main_widgets_rearrange();
3001 /* Fill in column titles. This must be done after the top level window
3004 XXX - is that still true, with fixed-width columns? */
3006 menu_recent_read_finished();
3008 main_auto_scroll_live_changed(auto_scroll_live);
3011 switch (user_font_apply()) {
3014 case FA_FONT_NOT_RESIZEABLE:
3015 /* "user_font_apply()" popped up an alert box. */
3016 /* turn off zooming - font can't be resized */
3017 case FA_FONT_NOT_AVAILABLE:
3018 /* XXX - did we successfully load the un-zoomed version earlier?
3019 If so, this *probably* means the font is available, but not at
3020 this particular zoom level, but perhaps some other failure
3021 occurred; I'm not sure you can determine which is the case,
3023 /* turn off zooming - zoom level is unavailable */
3025 /* in any other case than FA_SUCCESS, turn off zooming */
3026 recent.gui_zoom_level = 0;
3027 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3030 dnd_init(top_level);
3032 color_filters_init();
3035 capture_filter_init();
3038 /* the window can be sized only, if it's not already shown, so do it now! */
3039 main_load_window_geometry(top_level);
3041 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3044 GtkWidget *filter_te;
3045 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3046 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3048 /* Run the display filter so it goes in effect. */
3049 main_filter_packets(&cfile, dfilter, FALSE);
3052 /* If we were given the name of a capture file, read it in now;
3053 we defer it until now, so that, if we can't open it, and pop
3054 up an alert box, the alert box is more likely to come up on
3055 top of the main window - but before the preference-file-error
3056 alert box, so, if we get one of those, it's more likely to come
3059 show_main_window(TRUE);
3060 check_and_warn_user_startup(cf_name);
3061 if (rfilter != NULL) {
3062 if (!dfilter_compile(rfilter, &rfcode)) {
3063 bad_dfilter_alert_box(top_level, rfilter);
3064 rfilter_parse_failed = TRUE;
3067 if (!rfilter_parse_failed) {
3068 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3069 /* "cf_open()" succeeded, so it closed the previous
3070 capture file, and thus destroyed any previous read filter
3071 attached to "cf". */
3073 cfile.rfcode = rfcode;
3074 /* Open stat windows; we do so after creating the main window,
3075 to avoid GTK warnings, and after successfully opening the
3076 capture file, so we know we have something to compute stats
3077 on, and after registering all dissectors, so that MATE will
3078 have registered its field array and we can have a tap filter
3079 with one of MATE's late-registered fields as part of the
3081 start_requested_stats();
3083 /* Read the capture file. */
3084 switch (cf_read(&cfile, FALSE)) {
3088 /* Just because we got an error, that doesn't mean we were unable
3089 to read any of the file; we handle what we could get from the
3091 /* if the user told us to jump to a specific packet, do it now */
3092 if(go_to_packet != 0) {
3093 /* Jump to the specified frame number, kept for backward
3095 cf_goto_frame(&cfile, go_to_packet);
3096 } else if (jfilter != NULL) {
3097 /* try to compile given filter */
3098 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3099 bad_dfilter_alert_box(top_level, jfilter);
3101 /* Filter ok, jump to the first packet matching the filter
3102 conditions. Default search direction is forward, but if
3103 option d was given, search backwards */
3104 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3109 case CF_READ_ABORTED:
3115 /* If the filename is not the absolute path, prepend the current dir. This happens
3116 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3117 if (!g_path_is_absolute(cf_name)) {
3118 char *old_cf_name = cf_name;
3119 char *pwd = g_get_current_dir();
3120 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3121 g_free(old_cf_name);
3125 /* Save the name of the containing directory specified in the
3126 path name, if any; we can write over cf_name, which is a
3127 good thing, given that "get_dirname()" does write over its
3129 s = get_dirname(cf_name);
3130 set_last_open_dir(s);
3135 dfilter_free(rfcode);
3136 cfile.rfcode = NULL;
3137 show_main_window(FALSE);
3138 /* Don't call check_and_warn_user_startup(): we did it above */
3139 main_set_for_capture_in_progress(FALSE);
3140 set_capture_if_dialog_for_capture_in_progress(FALSE);
3145 if (start_capture) {
3146 if (global_capture_opts.save_file != NULL) {
3147 /* Save the directory name for future file dialogs. */
3148 /* (get_dirname overwrites filename) */
3149 s = get_dirname(g_strdup(global_capture_opts.save_file));
3150 set_last_open_dir(s);
3153 /* "-k" was specified; start a capture. */
3154 show_main_window(FALSE);
3155 check_and_warn_user_startup(cf_name);
3157 /* If no user interfaces were specified on the command line,
3158 copy the list of selected interfaces to the set of interfaces
3159 to use for this capture. */
3160 if (global_capture_opts.ifaces->len == 0)
3161 collect_ifaces(&global_capture_opts);
3162 if (capture_start(&global_capture_opts)) {
3163 /* The capture started. Open stat windows; we do so after creating
3164 the main window, to avoid GTK warnings, and after successfully
3165 opening the capture file, so we know we have something to compute
3166 stats on, and after registering all dissectors, so that MATE will
3167 have registered its field array and we can have a tap filter with
3168 one of MATE's late-registered fields as part of the filter. */
3169 start_requested_stats();
3172 show_main_window(FALSE);
3173 check_and_warn_user_startup(cf_name);
3174 main_set_for_capture_in_progress(FALSE);
3175 set_capture_if_dialog_for_capture_in_progress(FALSE);
3178 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3179 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3180 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3182 #else /* HAVE_LIBPCAP */
3183 show_main_window(FALSE);
3184 check_and_warn_user_startup(cf_name);
3185 main_set_for_capture_in_progress(FALSE);
3186 set_capture_if_dialog_for_capture_in_progress(FALSE);
3187 #endif /* HAVE_LIBPCAP */
3190 /* register our pid if we are being run from a U3 device */
3193 profile_store_persconffiles (FALSE);
3195 #ifdef HAVE_GTKOSXAPPLICATION
3196 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3197 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3198 gtk_osxapplication_ready(theApp);
3201 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3204 gtk_iface_mon_start();
3207 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3209 /* ... back from GTK, we're going down now! */
3212 gtk_iface_mon_stop();
3215 /* deregister our pid */
3216 u3_deregister_pid();
3220 AirPDcapDestroyContext(&airpdcap_ctx);
3223 /* hide the (unresponsive) main window, while asking the user to close the console window */
3224 gtk_widget_hide(top_level);
3226 #ifdef HAVE_GTKOSXAPPLICATION
3227 g_object_unref(theApp);
3230 /* Shutdown windows sockets */
3233 /* For some unknown reason, the "atexit()" call in "create_console()"
3234 doesn't arrange that "destroy_console()" be called when we exit,
3235 so we call it here if a console was created. */
3244 /* We build this as a GUI subsystem application on Win32, so
3245 "WinMain()", not "main()", gets called.
3247 Hack shamelessly stolen from the Win32 port of the GIMP. */
3249 #define _stdcall __attribute__((stdcall))
3253 WinMain (struct HINSTANCE__ *hInstance,
3254 struct HINSTANCE__ *hPrevInstance,
3258 INITCOMMONCONTROLSEX comm_ctrl;
3261 * Initialize our DLL search path. MUST be called before LoadLibrary
3264 ws_init_dll_search_path();
3266 /* Initialize our controls. Required for native Windows file dialogs. */
3267 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3268 comm_ctrl.dwSize = sizeof(comm_ctrl);
3269 /* Includes the animate, header, hot key, list view, progress bar,
3270 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3273 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3274 InitCommonControlsEx(&comm_ctrl);
3276 /* RichEd20.DLL is needed for filter entries. */
3277 ws_load_library("riched20.dll");
3279 has_console = FALSE;
3280 console_wait = FALSE;
3281 return main (__argc, __argv);
3284 /* The code to create and desstroy console windows should not be necessary,
3285 at least as I read the GLib source code, as it looks as if GLib is, on
3286 Win32, *supposed* to create a console window into which to display its
3289 That doesn't happen, however. I suspect there's something completely
3290 broken about that code in GLib-for-Win32, and that it may be related
3291 to the breakage that forces us to just call "printf()" on the message
3292 rather than passing the message on to "g_log_default_handler()"
3293 (which is the routine that does the aforementioned non-functional
3294 console window creation). */
3297 * If this application has no console window to which its standard output
3298 * would go, create one.
3301 create_console(void)
3303 if (stdin_capture) {
3304 /* We've been handed "-i -". Don't mess with stdio. */
3309 /* We have no console to which to print the version string, so
3310 create one and make it the standard input, output, and error. */
3313 * See if we have an existing console (i.e. we were run from a
3316 if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3317 if (AllocConsole()) {
3318 console_wait = TRUE;
3319 SetConsoleTitle(_T("Wireshark Debug Console"));
3321 return; /* couldn't create console */
3325 ws_freopen("CONIN$", "r", stdin);
3326 ws_freopen("CONOUT$", "w", stdout);
3327 ws_freopen("CONOUT$", "w", stderr);
3328 fprintf(stdout, "\n");
3329 fprintf(stderr, "\n");
3331 /* Now register "destroy_console()" as a routine to be called just
3332 before the application exits, so that we can destroy the console
3333 after the user has typed a key (so that the console doesn't just
3334 disappear out from under them, giving the user no chance to see
3335 the message(s) we put in there). */
3336 atexit(destroy_console);
3338 /* Well, we have a console now. */
3344 destroy_console(void)
3347 printf("\n\nPress any key to exit\n");
3356 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3357 const char *message, gpointer user_data _U_)
3364 /* ignore log message, if log_level isn't interesting based
3365 upon the console log preferences.
3366 If the preferences haven't been loaded loaded yet, display the
3369 The default console_log_level preference value is such that only
3370 ERROR, CRITICAL and WARNING level messages are processed;
3371 MESSAGE, INFO and DEBUG level messages are ignored. */
3372 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3373 prefs.console_log_level != 0) {
3378 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3379 /* the user wants a console or the application will terminate immediately */
3383 /* For some unknown reason, the above doesn't appear to actually cause
3384 anything to be sent to the standard output, so we'll just splat the
3385 message out directly, just to make sure it gets out. */
3387 switch(log_level & G_LOG_LEVEL_MASK) {
3388 case G_LOG_LEVEL_ERROR:
3391 case G_LOG_LEVEL_CRITICAL:
3394 case G_LOG_LEVEL_WARNING:
3397 case G_LOG_LEVEL_MESSAGE:
3400 case G_LOG_LEVEL_INFO:
3403 case G_LOG_LEVEL_DEBUG:
3407 fprintf(stderr, "unknown log_level %u\n", log_level);
3409 g_assert_not_reached();
3412 /* create a "timestamp" */
3414 today = localtime(&curr);
3416 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3417 today->tm_hour, today->tm_min, today->tm_sec,
3418 log_domain != NULL ? log_domain : "",
3421 if(log_level & G_LOG_LEVEL_ERROR) {
3422 /* wait for a key press before the following error handler will terminate the program
3423 this way the user at least can read the error message */
3424 printf("\n\nPress any key to exit\n");
3428 /* XXX - on UN*X, should we just use g_log_default_handler()?
3429 We want the error messages to go to the standard output;
3430 on Mac OS X, that will cause them to show up in various
3431 per-user logs accessible through Console (details depend
3432 on whether you're running 10.0 through 10.4 or running
3433 10.5 and later), and, on other UN*X desktop environments,
3434 if they don't show up in some form of console log, that's
3435 a deficiency in that desktop environment. (Too bad
3436 Windows doesn't set the standard output and error for
3437 GUI apps to something that shows up in such a log.) */
3438 g_log_default_handler(log_domain, log_level, message, user_data);
3445 * Helper for main_widgets_rearrange()
3447 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3448 gtk_container_remove(GTK_CONTAINER(data), widget);
3451 static GtkWidget *main_widget_layout(gint layout_content)
3453 switch(layout_content) {
3454 case(layout_pane_content_none):
3456 case(layout_pane_content_plist):
3458 case(layout_pane_content_pdetails):
3460 case(layout_pane_content_pbytes):
3461 return byte_nb_ptr_gbl;
3463 g_assert_not_reached();
3470 * Rearrange the main window widgets
3472 void main_widgets_rearrange(void) {
3473 GtkWidget *first_pane_widget1, *first_pane_widget2;
3474 GtkWidget *second_pane_widget1, *second_pane_widget2;
3475 gboolean split_top_left = FALSE;
3477 /* be a bit faster */
3478 gtk_widget_hide(main_vbox);
3480 /* be sure we don't lose a widget while rearranging */
3481 g_object_ref(G_OBJECT(menubar));
3482 g_object_ref(G_OBJECT(main_tb));
3483 g_object_ref(G_OBJECT(filter_tb));
3484 g_object_ref(G_OBJECT(wireless_tb));
3485 g_object_ref(G_OBJECT(pkt_scrollw));
3486 g_object_ref(G_OBJECT(tv_scrollw));
3487 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3488 g_object_ref(G_OBJECT(statusbar));
3489 g_object_ref(G_OBJECT(main_pane_v1));
3490 g_object_ref(G_OBJECT(main_pane_v2));
3491 g_object_ref(G_OBJECT(main_pane_h1));
3492 g_object_ref(G_OBJECT(main_pane_h2));
3493 g_object_ref(G_OBJECT(welcome_pane));
3495 /* empty all containers participating */
3496 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3497 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3498 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3499 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3500 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3502 statusbar_widgets_emptying(statusbar);
3504 /* add the menubar always at the top */
3505 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3508 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3510 /* filter toolbar in toolbar area */
3511 if (!prefs.filter_toolbar_show_in_statusbar) {
3512 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3515 /* airpcap toolbar */
3516 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3518 /* fill the main layout panes */
3519 switch(prefs.gui_layout_type) {
3520 case(layout_type_5):
3521 main_first_pane = main_pane_v1;
3522 main_second_pane = main_pane_v2;
3523 split_top_left = FALSE;
3525 case(layout_type_2):
3526 main_first_pane = main_pane_v1;
3527 main_second_pane = main_pane_h1;
3528 split_top_left = FALSE;
3530 case(layout_type_1):
3531 main_first_pane = main_pane_v1;
3532 main_second_pane = main_pane_h1;
3533 split_top_left = TRUE;
3535 case(layout_type_4):
3536 main_first_pane = main_pane_h1;
3537 main_second_pane = main_pane_v1;
3538 split_top_left = FALSE;
3540 case(layout_type_3):
3541 main_first_pane = main_pane_h1;
3542 main_second_pane = main_pane_v1;
3543 split_top_left = TRUE;
3545 case(layout_type_6):
3546 main_first_pane = main_pane_h1;
3547 main_second_pane = main_pane_h2;
3548 split_top_left = FALSE;
3551 main_first_pane = NULL;
3552 main_second_pane = NULL;
3553 g_assert_not_reached();
3555 if (split_top_left) {
3556 first_pane_widget1 = main_second_pane;
3557 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3558 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3559 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3561 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3562 first_pane_widget2 = main_second_pane;
3563 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3564 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3566 if (first_pane_widget1 != NULL)
3567 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3568 if (first_pane_widget2 != NULL)
3569 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3570 if (second_pane_widget1 != NULL)
3571 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3572 if (second_pane_widget2 != NULL)
3573 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3575 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3578 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3581 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3583 /* filter toolbar in statusbar hbox */
3584 if (prefs.filter_toolbar_show_in_statusbar) {
3585 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3588 /* statusbar widgets */
3589 statusbar_widgets_pack(statusbar);
3591 /* hide widgets on users recent settings */
3592 main_widgets_show_or_hide();
3594 gtk_widget_show(main_vbox);
3598 is_widget_visible(GtkWidget *widget, gpointer data)
3600 gboolean *is_visible = data;
3603 if (gtk_widget_get_visible(widget))
3610 main_widgets_show_or_hide(void)
3612 gboolean main_second_pane_show;
3614 if (recent.main_toolbar_show) {
3615 gtk_widget_show(main_tb);
3617 gtk_widget_hide(main_tb);
3620 statusbar_widgets_show_or_hide(statusbar);
3622 if (recent.filter_toolbar_show) {
3623 gtk_widget_show(filter_tb);
3625 gtk_widget_hide(filter_tb);
3628 if (recent.wireless_toolbar_show) {
3629 gtk_widget_show(wireless_tb);
3631 gtk_widget_hide(wireless_tb);
3634 if (recent.packet_list_show && have_capture_file) {
3635 gtk_widget_show(pkt_scrollw);
3637 gtk_widget_hide(pkt_scrollw);
3640 if (recent.tree_view_show && have_capture_file) {
3641 gtk_widget_show(tv_scrollw);
3643 gtk_widget_hide(tv_scrollw);
3646 if (recent.byte_view_show && have_capture_file) {
3647 gtk_widget_show(byte_nb_ptr_gbl);
3649 gtk_widget_hide(byte_nb_ptr_gbl);
3652 if (have_capture_file) {
3653 gtk_widget_show(main_first_pane);
3655 gtk_widget_hide(main_first_pane);
3659 * Is anything in "main_second_pane" visible?
3660 * If so, show it, otherwise hide it.
3662 main_second_pane_show = FALSE;
3663 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3664 &main_second_pane_show);
3665 if (main_second_pane_show) {
3666 gtk_widget_show(main_second_pane);
3668 gtk_widget_hide(main_second_pane);
3671 if (!have_capture_file) {
3673 gtk_widget_show(welcome_pane);
3676 gtk_widget_hide(welcome_pane);
3681 /* called, when the window state changes (minimized, maximized, ...) */
3683 window_state_event_cb (GtkWidget *widget _U_,
3687 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3689 if( (event->type) == (GDK_WINDOW_STATE)) {
3690 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3691 /* we might have dialogs popped up while we where iconified,
3693 display_queued_messages();
3701 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3703 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3705 if (event->keyval == GDK_F8) {
3706 new_packet_list_next();
3708 } else if (event->keyval == GDK_F7) {
3709 new_packet_list_prev();
3711 } else if (event->state & NO_SHIFT_MOD_MASK) {
3712 return FALSE; /* Skip control, alt, and other modifiers */
3714 * A comment in gdkkeysyms.h says that it's autogenerated from
3715 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3716 * don't explicitly say so, isprint() should work as expected
3719 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3720 /* Forward the keypress on to the display filter entry */
3721 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3722 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3723 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3731 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3733 GtkAccelGroup *accel;
3736 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3737 main_set_window_name("The Wireshark Network Analyzer");
3739 gtk_widget_set_name(top_level, "main window");
3740 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3742 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3743 G_CALLBACK(window_state_event_cb), NULL);
3744 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3745 G_CALLBACK(top_level_key_pressed_cb), NULL );
3747 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3748 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3750 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3751 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3752 gtk_widget_show(main_vbox);
3755 menubar = main_menu_new(&accel);
3757 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3758 /* Mac OS X native menus are created and displayed by main_menu_new() */
3759 if(!prefs_p->gui_macosx_style) {
3761 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3762 gtk_widget_show(menubar);
3763 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3768 main_tb = toolbar_new();
3769 gtk_widget_show (main_tb);
3771 /* Filter toolbar */
3772 filter_tb = filter_toolbar_new();
3775 pkt_scrollw = new_packet_list_create();
3776 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3777 gtk_widget_show_all(pkt_scrollw);
3780 tv_scrollw = proto_tree_view_new(prefs_p, &tree_view_gbl);
3781 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3782 gtk_widget_show(tv_scrollw);
3784 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3785 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3786 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3787 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3788 gtk_widget_show(tree_view_gbl);
3791 byte_nb_ptr_gbl = byte_view_new();
3792 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3793 gtk_widget_show(byte_nb_ptr_gbl);
3795 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3796 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3798 /* Panes for the packet list, tree, and byte view */
3799 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3800 gtk_widget_show(main_pane_v1);
3801 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3802 gtk_widget_show(main_pane_v2);
3803 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3804 gtk_widget_show(main_pane_h1);
3805 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3806 gtk_widget_show(main_pane_h2);
3808 wireless_tb = airpcap_toolbar_new();
3810 wireless_tb = ws80211_toolbar_new();
3812 gtk_widget_show(wireless_tb);
3815 statusbar = statusbar_new();
3816 gtk_widget_show(statusbar);
3818 /* Pane for the welcome screen */
3819 welcome_pane = welcome_new();
3820 gtk_widget_show(welcome_pane);
3824 show_main_window(gboolean doing_work)
3826 main_set_for_capture_file(doing_work);
3828 /*** we have finished all init things, show the main window ***/
3829 gtk_widget_show(top_level);
3831 /* the window can be maximized only, if it's visible, so do it after show! */
3832 main_load_window_geometry(top_level);
3834 /* process all pending GUI events before continue */
3835 while (gtk_events_pending()) gtk_main_iteration();
3837 /* Pop up any queued-up alert boxes. */
3838 display_queued_messages();
3840 /* Move the main window to the front, in case it isn't already there */
3841 gdk_window_raise(gtk_widget_get_window(top_level));
3844 airpcap_toolbar_show(wireless_tb);
3845 #endif /* HAVE_AIRPCAP */
3848 /* Fill in capture options with values from the preferences */
3850 prefs_to_capture_opts(void)
3853 /* Set promiscuous mode from the preferences setting. */
3854 /* the same applies to other preferences settings as well. */
3855 global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
3856 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3857 global_capture_opts.show_info = prefs.capture_show_info;
3858 global_capture_opts.real_time_mode = prefs.capture_real_time;
3859 auto_scroll_live = prefs.capture_auto_scroll;
3860 #endif /* HAVE_LIBPCAP */
3863 static void copy_global_profile (const gchar *profile_name)
3865 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3867 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3868 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3869 "Can't create directory\n\"%s\":\n%s.",
3870 pf_dir_path, g_strerror(errno));
3872 g_free(pf_dir_path);
3875 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3876 &pf_dir_path, &pf_dir_path2) == -1) {
3877 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3878 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3879 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3881 g_free(pf_filename);
3882 g_free(pf_dir_path);
3883 g_free(pf_dir_path2);
3887 /* Change configuration profile */
3888 void change_configuration_profile (const gchar *profile_name)
3890 char *gdp_path, *dp_path;
3894 /* First check if profile exists */
3895 if (!profile_exists(profile_name, FALSE)) {
3896 if (profile_exists(profile_name, TRUE)) {
3897 /* Copy from global profile */
3898 copy_global_profile (profile_name);
3900 /* No personal and no global profile exists */
3905 /* Then check if changing to another profile */
3906 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3910 /* Get the current geometry, before writing it to disk */
3911 main_save_window_geometry(top_level);
3913 if (profile_exists(get_profile_name(), FALSE)) {
3914 /* Write recent file for profile we are leaving, if it still exists */
3915 write_profile_recent();
3918 /* Set profile name and update the status bar */
3919 set_profile_name (profile_name);
3920 profile_bar_update ();
3921 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3923 /* Reset current preferences and apply the new */
3927 (void) read_configuration_files (&gdp_path, &dp_path);
3929 recent_read_profile_static(&rf_path, &rf_open_errno);
3930 if (rf_path != NULL && rf_open_errno != 0) {
3931 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3932 "Could not open common recent file\n\"%s\": %s.",
3933 rf_path, g_strerror(rf_open_errno));
3935 if (recent.gui_fileopen_remembered_dir &&
3936 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3937 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3939 timestamp_set_type (recent.gui_time_format);
3940 timestamp_set_seconds_type (recent.gui_seconds_format);
3941 color_filters_enable(recent.packet_list_colorize);
3943 prefs_to_capture_opts();
3945 macros_post_update();
3947 /* Update window view and redraw the toolbar */
3948 main_titlebar_update();
3949 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3950 toolbar_redraw_all();
3952 /* Enable all protocols and disable from the disabled list */
3954 if (gdp_path == NULL && dp_path == NULL) {
3955 set_disabled_protos_list();
3958 /* Reload color filters */
3959 color_filters_reload();
3961 /* Reload list of interfaces on welcome page */
3962 welcome_if_panel_reload();
3964 /* Recreate the packet list according to new preferences */
3965 new_packet_list_recreate ();
3966 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3969 /* Update menus with new recent values */
3970 menu_recent_read_finished();
3972 /* Reload pane geometry, must be done after recreating the list */
3973 main_pane_load_window_geometry();
3976 /** redissect packets and update UI */
3977 void redissect_packets(void)
3979 cf_redissect_packets(&cfile);
3980 status_expert_update();