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.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 */
1187 #ifdef HAVE_PCAP_REMOTE
1188 fprintf(output, "RPCAP options:\n");
1189 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1191 /*fprintf(output, "\n");*/
1192 fprintf(output, "Input file:\n");
1193 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1195 fprintf(output, "\n");
1196 fprintf(output, "Processing:\n");
1197 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1198 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1199 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1201 fprintf(output, "\n");
1202 fprintf(output, "User interface:\n");
1203 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1204 fprintf(output, " -d <display filter> start with the given display filter\n");
1205 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1206 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1207 fprintf(output, " filter\n");
1208 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1209 fprintf(output, " -m <font> set the font name used for most text\n");
1210 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1211 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1212 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1213 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1215 fprintf(output, "\n");
1216 fprintf(output, "Output:\n");
1217 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1219 fprintf(output, "\n");
1220 fprintf(output, "Miscellaneous:\n");
1221 fprintf(output, " -h display this help and exit\n");
1222 fprintf(output, " -v display version info and exit\n");
1223 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1224 fprintf(output, " persdata:path - personal data files\n");
1225 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1226 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1228 fprintf(output, " --display=DISPLAY X display to use\n");
1243 printf(PACKAGE " " VERSION "%s\n"
1250 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1251 runtime_info_str->str);
1259 * Print to the standard error. On Windows, create a console for the
1260 * standard error to show up on, if necessary.
1261 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1262 * terminal isn't the standard error?
1265 vfprintf_stderr(const char *fmt, va_list ap)
1270 vfprintf(stderr, fmt, ap);
1274 fprintf_stderr(const char *fmt, ...)
1279 vfprintf_stderr(fmt, ap);
1284 * Report an error in command-line arguments.
1285 * Creates a console on Windows.
1288 cmdarg_err(const char *fmt, ...)
1292 fprintf_stderr("wireshark: ");
1294 vfprintf_stderr(fmt, ap);
1296 fprintf_stderr("\n");
1300 * Report additional information for an error in command-line arguments.
1301 * Creates a console on Windows.
1302 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1303 * terminal isn't the standard error?
1306 cmdarg_err_cont(const char *fmt, ...)
1311 vfprintf_stderr(fmt, ap);
1312 fprintf_stderr("\n");
1317 Once every 3 seconds we get a callback here which we use to update
1321 tap_update_cb(gpointer data _U_)
1323 draw_tap_listeners(FALSE);
1327 /* Restart the tap update display timer with new configured interval */
1328 void reset_tap_update_timer(void)
1330 g_source_remove(tap_update_timer_id);
1331 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1335 protect_thread_critical_region(void)
1337 /* Threading support for TAP:s removed
1338 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1339 * See the commit for removed code:
1340 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
1344 unprotect_thread_critical_region(void)
1346 /* Threading support for TAP:s removed
1347 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1353 * Periodically process outstanding hostname lookups. If we have new items,
1354 * redraw the packet list and tree view.
1358 resolv_update_cb(gpointer data _U_)
1360 /* Anything new show up? */
1361 if (host_name_lookup_process(NULL)) {
1362 if (gtk_widget_get_window(pkt_scrollw))
1363 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1364 if (gtk_widget_get_window(tv_scrollw))
1365 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1368 /* Always check. Even if we don't do async lookups we could still get
1369 passive updates, e.g. from DNS packets. */
1374 /* Set main_window_name and it's icon title to the capture filename */
1376 set_display_filename(capture_file *cf)
1378 gchar *display_name;
1382 display_name = cf_get_display_name(cf);
1383 window_name = g_strdup_printf("%s%s", cf->unsaved_changes ? "*" : "",
1385 g_free(display_name);
1386 main_set_window_name(window_name);
1387 g_free(window_name);
1389 main_set_window_name("The Wireshark Network Analyzer");
1393 /* Update various parts of the main window for a capture file "unsaved
1394 changes" change - update the title to reflect whether there are
1395 unsaved changes or not, and update the menus and toolbar to
1396 enable or disable the "Save" operation. */
1398 main_update_for_unsaved_changes(capture_file *cf)
1400 set_display_filename(cf);
1401 set_menus_for_capture_file(cf);
1402 set_toolbar_for_capture_file(cf);
1407 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1409 /* Update menubar and toolbar */
1410 menu_auto_scroll_live_changed(auto_scroll_live_in);
1411 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1413 /* change auto scroll state */
1414 auto_scroll_live = auto_scroll_live_in;
1419 main_colorize_changed(gboolean packet_list_colorize)
1421 /* Update menubar and toolbar */
1422 menu_colorize_changed(packet_list_colorize);
1423 toolbar_colorize_changed(packet_list_colorize);
1425 /* change colorization */
1426 if(packet_list_colorize != recent.packet_list_colorize) {
1427 recent.packet_list_colorize = packet_list_colorize;
1428 color_filters_enable(packet_list_colorize);
1429 new_packet_list_colorize_packets();
1433 static GtkWidget *close_dlg = NULL;
1436 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1438 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1443 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1445 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1450 main_cf_cb_file_closing(capture_file *cf)
1452 /* if we have more than 10000 packets, show a splash screen while closing */
1453 /* XXX - don't know a better way to decide whether to show or not,
1454 * as most of the time is spend in various calls that destroy various
1455 * data structures, so it wouldn't be easy to use a progress bar,
1456 * rather than, say, a progress spinner, here! */
1457 if(cf->count > 10000) {
1458 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1459 "%sClosing file!%s\n\nPlease wait ...",
1460 simple_dialog_primary_start(),
1461 simple_dialog_primary_end());
1462 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1465 /* Destroy all windows that refer to the
1466 capture file we're closing. */
1467 destroy_packet_wins();
1469 /* Restore the standard title bar message. */
1470 main_set_window_name("The Wireshark Network Analyzer");
1472 /* Disable all menu items that make sense only if you have a capture. */
1473 set_menus_for_capture_file(NULL);
1474 set_toolbar_for_capture_file(NULL);
1475 main_set_for_captured_packets(FALSE);
1476 set_menus_for_selected_packet(cf);
1477 main_set_for_capture_in_progress(FALSE);
1478 set_capture_if_dialog_for_capture_in_progress(FALSE);
1479 set_menus_for_selected_tree_row(cf);
1481 /* Set up main window for no capture file. */
1482 main_set_for_capture_file(FALSE);
1484 main_window_update();
1488 main_cf_cb_file_closed(capture_file *cf _U_)
1490 if(close_dlg != NULL) {
1491 splash_destroy(close_dlg);
1498 main_cf_cb_file_read_started(capture_file *cf _U_)
1500 tap_param_dlg_update();
1502 /* Set up main window for a capture file. */
1503 main_set_for_capture_file(TRUE);
1507 main_cf_cb_file_read_finished(capture_file *cf)
1511 if (!cf->is_tempfile && cf->filename) {
1512 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1513 add_menu_recent_capture_file(cf->filename);
1515 /* Remember folder for next Open dialog and save it in recent */
1516 dir_path = get_dirname(g_strdup(cf->filename));
1517 set_last_open_dir(dir_path);
1521 /* Update the appropriate parts of the main window. */
1522 main_update_for_unsaved_changes(cf);
1524 /* Enable menu items that make sense if you have some captured packets. */
1525 main_set_for_captured_packets(TRUE);
1529 main_cf_cb_file_rescan_finished(capture_file *cf)
1533 if (!cf->is_tempfile && cf->filename) {
1534 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1535 add_menu_recent_capture_file(cf->filename);
1537 /* Remember folder for next Open dialog and save it in recent */
1538 dir_path = get_dirname(g_strdup(cf->filename));
1539 set_last_open_dir(dir_path);
1543 /* Update the appropriate parts of the main window. */
1544 main_update_for_unsaved_changes(cf);
1548 static GList *icon_list_create(
1549 const char **icon16_xpm,
1550 const char **icon32_xpm,
1551 const char **icon48_xpm,
1552 const char **icon64_xpm)
1554 GList *icon_list = NULL;
1555 GdkPixbuf * pixbuf16;
1556 GdkPixbuf * pixbuf32;
1557 GdkPixbuf * pixbuf48;
1558 GdkPixbuf * pixbuf64;
1561 if(icon16_xpm != NULL) {
1562 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1564 icon_list = g_list_append(icon_list, pixbuf16);
1567 if(icon32_xpm != NULL) {
1568 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1570 icon_list = g_list_append(icon_list, pixbuf32);
1573 if(icon48_xpm != NULL) {
1574 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1576 icon_list = g_list_append(icon_list, pixbuf48);
1579 if(icon64_xpm != NULL) {
1580 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1582 icon_list = g_list_append(icon_list, pixbuf64);
1589 main_capture_set_main_window_title(capture_options *capture_opts)
1591 GString *title = g_string_new("");
1593 g_string_append(title, "Capturing ");
1594 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1595 main_set_window_name(title->str);
1596 g_string_free(title, TRUE);
1600 main_capture_cb_capture_prepared(capture_options *capture_opts)
1602 static GList *icon_list = NULL;
1604 main_capture_set_main_window_title(capture_opts);
1606 if(icon_list == NULL) {
1607 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1609 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1611 /* Disable menu items that make no sense if you're currently running
1613 main_set_for_capture_in_progress(TRUE);
1614 set_capture_if_dialog_for_capture_in_progress(TRUE);
1616 /* Don't set up main window for a capture file. */
1617 main_set_for_capture_file(FALSE);
1621 main_capture_cb_capture_update_started(capture_options *capture_opts)
1623 /* We've done this in "prepared" above, but it will be cleared while
1624 switching to the next multiple file. */
1625 main_capture_set_main_window_title(capture_opts);
1627 main_set_for_capture_in_progress(TRUE);
1628 set_capture_if_dialog_for_capture_in_progress(TRUE);
1630 /* Enable menu items that make sense if you have some captured
1631 packets (yes, I know, we don't have any *yet*). */
1632 main_set_for_captured_packets(TRUE);
1634 /* Set up main window for a capture file. */
1635 main_set_for_capture_file(TRUE);
1639 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1641 capture_file *cf = capture_opts->cf;
1642 static GList *icon_list = NULL;
1644 /* The capture isn't stopping any more - it's stopped. */
1645 capture_stopping = FALSE;
1647 if (!cf->is_tempfile && cf->filename) {
1648 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1649 add_menu_recent_capture_file(cf->filename);
1652 /* Update the main window as appropriate */
1653 main_update_for_unsaved_changes(cf);
1655 /* Enable menu items that make sense if you're not currently running
1657 main_set_for_capture_in_progress(FALSE);
1658 set_capture_if_dialog_for_capture_in_progress(FALSE);
1660 /* Set up main window for a capture file. */
1661 main_set_for_capture_file(TRUE);
1663 if(icon_list == NULL) {
1664 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1666 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1668 if(global_capture_opts.quit_after_cap) {
1669 /* command line asked us to quit after the capture */
1670 /* don't pop up a dialog to ask for unsaved files etc. */
1676 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1678 /* Don't set up main window for a capture file. */
1679 main_set_for_capture_file(FALSE);
1683 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1686 capture_file *cf = capture_opts->cf;
1688 static GList *icon_list = NULL;
1690 /* The capture isn't stopping any more - it's stopped. */
1691 capture_stopping = FALSE;
1693 /*set_display_filename(cf);*/
1695 /* Enable menu items that make sense if you're not currently running
1697 main_set_for_capture_in_progress(FALSE);
1698 set_capture_if_dialog_for_capture_in_progress(FALSE);
1700 /* Restore the standard title bar message */
1701 /* (just in case we have trouble opening the capture file). */
1702 main_set_window_name("The Wireshark Network Analyzer");
1704 if(icon_list == NULL) {
1705 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1707 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1709 /* We don't have loaded the capture file, this will be done later.
1710 * For now we still have simply a blank screen. */
1712 if(global_capture_opts.quit_after_cap) {
1713 /* command line asked us to quit after the capture */
1714 /* don't pop up a dialog to ask for unsaved files etc. */
1720 main_capture_cb_capture_stopping(capture_options *capture_opts _U_)
1722 capture_stopping = TRUE;
1723 set_menus_for_capture_stopping();
1725 set_toolbar_for_capture_stopping();
1727 set_capture_if_dialog_for_capture_stopping();
1732 main_capture_cb_capture_failed(capture_options *capture_opts _U_)
1734 static GList *icon_list = NULL;
1736 /* Capture isn't stopping any more. */
1737 capture_stopping = FALSE;
1739 /* the capture failed before the first packet was captured
1740 reset title, menus and icon */
1742 main_set_window_name("The Wireshark Network Analyzer");
1744 main_set_for_capture_in_progress(FALSE);
1745 set_capture_if_dialog_for_capture_in_progress(FALSE);
1747 main_set_for_capture_file(FALSE);
1749 if(icon_list == NULL) {
1750 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1752 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1755 if(global_capture_opts.quit_after_cap) {
1756 /* command line asked us to quit after the capture */
1757 /* don't pop up a dialog to ask for unsaved files etc. */
1761 #endif /* HAVE_LIBPCAP */
1764 main_cf_cb_packet_selected(gpointer data)
1766 capture_file *cf = data;
1768 /* Display the GUI protocol tree and packet bytes.
1769 XXX - why do we dump core if we call "proto_tree_draw()"
1770 before calling "add_byte_views()"? */
1771 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1772 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1774 /* Note: Both string and hex value searches in the packet data produce a non-zero
1775 search_pos if successful */
1776 if(cf->search_in_progress &&
1777 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1778 highlight_field(cf->edt->tvb, cf->search_pos,
1779 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1782 /* A packet is selected. */
1783 set_menus_for_selected_packet(cf);
1787 main_cf_cb_packet_unselected(capture_file *cf)
1789 /* No packet is being displayed; clear the hex dump pane by getting
1790 rid of all the byte views. */
1791 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1792 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1794 /* Add a placeholder byte view so that there's at least something
1795 displayed in the byte view notebook. */
1796 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1798 /* And clear the protocol tree display as well. */
1799 proto_tree_draw(NULL, tree_view_gbl);
1801 /* No packet is selected. */
1802 set_menus_for_selected_packet(cf);
1806 main_cf_cb_field_unselected(capture_file *cf)
1808 set_menus_for_selected_tree_row(cf);
1812 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1815 case(cf_cb_file_closing):
1816 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1817 main_cf_cb_file_closing(data);
1819 case(cf_cb_file_closed):
1820 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1821 main_cf_cb_file_closed(data);
1823 case(cf_cb_file_read_started):
1824 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1825 main_cf_cb_file_read_started(data);
1827 case(cf_cb_file_read_finished):
1828 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1829 main_cf_cb_file_read_finished(data);
1831 case(cf_cb_file_reload_started):
1832 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1833 main_cf_cb_file_read_started(data);
1835 case(cf_cb_file_reload_finished):
1836 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1837 main_cf_cb_file_read_finished(data);
1839 case(cf_cb_file_rescan_started):
1840 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1842 case(cf_cb_file_rescan_finished):
1843 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1844 main_cf_cb_file_rescan_finished(data);
1846 case(cf_cb_file_fast_save_finished):
1847 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1848 main_cf_cb_file_rescan_finished(data);
1850 case(cf_cb_packet_selected):
1851 main_cf_cb_packet_selected(data);
1853 case(cf_cb_packet_unselected):
1854 main_cf_cb_packet_unselected(data);
1856 case(cf_cb_field_unselected):
1857 main_cf_cb_field_unselected(data);
1859 case(cf_cb_file_save_started):
1860 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1862 case(cf_cb_file_save_finished):
1863 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1865 case(cf_cb_file_save_failed):
1866 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1868 case(cf_cb_file_save_stopped):
1869 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1871 case(cf_cb_file_export_specified_packets_started):
1872 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1874 case(cf_cb_file_export_specified_packets_finished):
1875 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1877 case(cf_cb_file_export_specified_packets_failed):
1878 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1880 case(cf_cb_file_export_specified_packets_stopped):
1881 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1884 g_warning("main_cf_callback: event %u unknown", event);
1885 g_assert_not_reached();
1891 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1893 #ifdef HAVE_GTKOSXAPPLICATION
1894 GtkOSXApplication *theApp;
1897 case(capture_cb_capture_prepared):
1898 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1899 main_capture_cb_capture_prepared(capture_opts);
1901 case(capture_cb_capture_update_started):
1902 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1903 main_capture_cb_capture_update_started(capture_opts);
1904 #ifdef HAVE_GTKOSXAPPLICATION
1905 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1906 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1909 case(capture_cb_capture_update_continue):
1910 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1912 case(capture_cb_capture_update_finished):
1913 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1914 main_capture_cb_capture_update_finished(capture_opts);
1916 case(capture_cb_capture_fixed_started):
1917 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1918 main_capture_cb_capture_fixed_started(capture_opts);
1920 case(capture_cb_capture_fixed_continue):
1921 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1923 case(capture_cb_capture_fixed_finished):
1924 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1925 main_capture_cb_capture_fixed_finished(capture_opts);
1927 case(capture_cb_capture_stopping):
1928 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1929 /* Beware: this state won't be called, if the capture child
1930 * closes the capturing on it's own! */
1931 #ifdef HAVE_GTKOSXAPPLICATION
1932 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1933 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1935 main_capture_cb_capture_stopping(capture_opts);
1937 case(capture_cb_capture_failed):
1938 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1939 main_capture_cb_capture_failed(capture_opts);
1942 g_warning("main_capture_callback: event %u unknown", event);
1943 g_assert_not_reached();
1949 get_gtk_compiled_info(GString *str)
1951 g_string_append(str, "with ");
1952 g_string_append_printf(str,
1953 #ifdef GTK_MAJOR_VERSION
1954 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1957 "GTK+ (version unknown)");
1959 g_string_append(str, ", ");
1961 g_string_append(str, "with Cairo ");
1962 g_string_append(str, CAIRO_VERSION_STRING);
1963 g_string_append(str, ", ");
1966 g_string_append(str, "with Pango ");
1967 g_string_append(str, PANGO_VERSION_STRING);
1968 g_string_append(str, ", ");
1974 get_gui_compiled_info(GString *str)
1976 epan_get_compiled_version_info(str);
1978 g_string_append(str, ", ");
1979 #ifdef HAVE_LIBPORTAUDIO
1980 #ifdef PORTAUDIO_API_1
1981 g_string_append(str, "with PortAudio <= V18");
1982 #else /* PORTAUDIO_API_1 */
1983 g_string_append(str, "with ");
1984 g_string_append(str, Pa_GetVersionText());
1985 #endif /* PORTAUDIO_API_1 */
1986 #else /* HAVE_LIBPORTAUDIO */
1987 g_string_append(str, "without PortAudio");
1988 #endif /* HAVE_LIBPORTAUDIO */
1990 g_string_append(str, ", ");
1992 get_compiled_airpcap_version(str);
1994 g_string_append(str, "without AirPcap");
1999 get_gui_runtime_info(GString *str)
2001 epan_get_runtime_version_info(str);
2004 g_string_append(str, ", ");
2005 get_runtime_airpcap_version(str);
2009 g_string_append(str, ", ");
2010 u3_runtime_info(str);
2015 read_configuration_files(char **gdp_path, char **dp_path)
2017 int gpf_open_errno, gpf_read_errno;
2018 int cf_open_errno, df_open_errno;
2019 int gdp_open_errno, gdp_read_errno;
2020 int dp_open_errno, dp_read_errno;
2021 char *gpf_path, *pf_path;
2022 char *cf_path, *df_path;
2023 int pf_open_errno, pf_read_errno;
2026 /* load the decode as entries of this profile */
2027 load_decode_as_entries();
2029 /* Read the preference files. */
2030 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2031 &pf_open_errno, &pf_read_errno, &pf_path);
2033 if (gpf_path != NULL) {
2034 if (gpf_open_errno != 0) {
2035 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2036 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2037 g_strerror(gpf_open_errno));
2039 if (gpf_read_errno != 0) {
2040 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2041 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2042 g_strerror(gpf_read_errno));
2045 if (pf_path != NULL) {
2046 if (pf_open_errno != 0) {
2047 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2048 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2049 g_strerror(pf_open_errno));
2051 if (pf_read_errno != 0) {
2052 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2053 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2054 g_strerror(pf_read_errno));
2061 /* if the user wants a console to be always there, well, we should open one for him */
2062 if (prefs_p->gui_console_open == console_open_always) {
2067 /* Read the capture filter file. */
2068 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2069 if (cf_path != NULL) {
2070 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2071 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2072 g_strerror(cf_open_errno));
2076 /* Read the display filter file. */
2077 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2078 if (df_path != NULL) {
2079 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2080 "Could not open your display filter file\n\"%s\": %s.", df_path,
2081 g_strerror(df_open_errno));
2085 /* Read the disabled protocols file. */
2086 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2087 dp_path, &dp_open_errno, &dp_read_errno);
2088 if (*gdp_path != NULL) {
2089 if (gdp_open_errno != 0) {
2090 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2091 "Could not open global disabled protocols file\n\"%s\": %s.",
2092 *gdp_path, g_strerror(gdp_open_errno));
2094 if (gdp_read_errno != 0) {
2095 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2096 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2097 *gdp_path, g_strerror(gdp_read_errno));
2102 if (*dp_path != NULL) {
2103 if (dp_open_errno != 0) {
2104 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2105 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2106 g_strerror(dp_open_errno));
2108 if (dp_read_errno != 0) {
2109 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2110 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2111 g_strerror(dp_read_errno));
2120 /* Check if there's something important to tell the user during startup.
2121 * We want to do this *after* showing the main window so that any windows
2122 * we pop up will be above the main window.
2126 check_and_warn_user_startup(gchar *cf_name)
2128 check_and_warn_user_startup(gchar *cf_name _U_)
2131 gchar *cur_user, *cur_group;
2132 gpointer priv_warning_dialog;
2134 /* Tell the user not to run as root. */
2135 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2136 cur_user = get_cur_username();
2137 cur_group = get_cur_groupname();
2138 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2139 "Running as user \"%s\" and group \"%s\".\n"
2140 "This could be dangerous.\n\n"
2141 "If you're running Wireshark this way in order to perform live capture, "
2142 "you may want to be aware that there is a better way documented at\n"
2143 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2146 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2147 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2151 /* Warn the user if npf.sys isn't loaded. */
2152 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2153 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2154 "The NPF driver isn't running. You may have trouble\n"
2155 "capturing or listing interfaces.");
2156 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2157 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2164 /* And now our feature presentation... [ fade to music ] */
2166 main(int argc, char *argv[])
2168 char *init_progfile_dir_error;
2171 gboolean arg_error = FALSE;
2173 extern int info_update_freq; /* Found in about_dlg.c. */
2174 const gchar *filter;
2182 char *gdp_path, *dp_path;
2185 gboolean start_capture = FALSE;
2186 gboolean list_link_layer_types = FALSE;
2190 gboolean capture_option_specified = FALSE;
2197 gint pl_size = 280, tv_size = 95, bv_size = 75;
2198 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2199 dfilter_t *rfcode = NULL;
2200 gboolean rfilter_parse_failed = FALSE;
2203 GtkWidget *splash_win = NULL;
2204 GLogLevelFlags log_flags;
2205 guint go_to_packet = 0;
2206 gboolean jump_backwards = FALSE;
2207 dfilter_t *jump_to_filter = NULL;
2210 #ifdef HAVE_GTKOSXAPPLICATION
2211 GtkOSXApplication *theApp;
2215 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2216 #define OPTSTRING_B "B:"
2218 #define OPTSTRING_B ""
2219 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2220 #else /* HAVE_LIBPCAP */
2221 #define OPTSTRING_B ""
2222 #endif /* HAVE_LIBPCAP */
2223 #ifdef HAVE_PCAP_REMOTE
2224 #define OPTSTRING_A "A:"
2226 #define OPTSTRING_A ""
2228 #ifdef HAVE_PCAP_CREATE
2229 #define OPTSTRING_I "I"
2231 #define OPTSTRING_I ""
2234 #define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:d:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:z:"
2236 static const char optstring[] = OPTSTRING;
2238 /* Set the C-language locale to the native environment. */
2239 setlocale(LC_ALL, "");
2241 arg_list_utf_16to8(argc, argv);
2245 * Get credential information for later use, and drop privileges
2246 * before doing anything else.
2247 * Let the user know if anything happened.
2249 init_process_policies();
2250 relinquish_special_privs_perm();
2253 * Attempt to get the pathname of the executable file.
2255 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2257 /* initialize the funnel mini-api */
2258 initialize_funnel_ops();
2260 AirPDcapInitContext(&airpdcap_ctx);
2263 /* Load wpcap if possible. Do this before collecting the run-time version information */
2266 /* ... and also load the packet.dll from wpcap */
2267 wpcap_packet_load();
2270 /* Load the airpcap.dll. This must also be done before collecting
2271 * run-time version information. */
2272 airpcap_dll_ret_val = load_airpcap();
2274 switch (airpcap_dll_ret_val) {
2275 case AIRPCAP_DLL_OK:
2276 /* load the airpcap interfaces */
2277 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2279 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2280 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2281 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2284 airpcap_if_active = NULL;
2288 /* select the first ad default (THIS SHOULD BE CHANGED) */
2289 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2294 * XXX - Maybe we need to warn the user if one of the following happens???
2296 case AIRPCAP_DLL_OLD:
2297 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2300 case AIRPCAP_DLL_ERROR:
2301 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2304 case AIRPCAP_DLL_NOT_FOUND:
2305 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2309 #endif /* HAVE_AIRPCAP */
2311 /* Start windows sockets */
2312 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2315 profile_store_persconffiles (TRUE);
2317 /* Assemble the compile-time version information string */
2318 comp_info_str = g_string_new("Compiled ");
2320 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2322 /* Assemble the run-time version information string */
2323 runtime_info_str = g_string_new("Running ");
2324 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2326 /* Read the profile independent recent file. We have to do this here so we can */
2327 /* set the profile before it can be set from the command line parameterts */
2328 recent_read_static(&rf_path, &rf_open_errno);
2329 if (rf_path != NULL && rf_open_errno != 0) {
2330 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2331 "Could not open common recent file\n\"%s\": %s.",
2332 rf_path, g_strerror(rf_open_errno));
2335 /* "pre-scan" the command line parameters, if we have "console only"
2336 parameters. We do this so we don't start GTK+ if we're only showing
2337 command-line help or version information.
2339 XXX - this pre-scan is done before we start GTK+, so we haven't
2340 run gtk_init() on the arguments. That means that GTK+ arguments
2341 have not been removed from the argument list; those arguments
2342 begin with "--", and will be treated as an error by getopt().
2344 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2347 optind_initial = optind;
2348 while ((opt = getopt(argc, argv, optstring)) != -1) {
2350 case 'C': /* Configuration Profile */
2351 if (profile_exists (optarg, FALSE)) {
2352 set_profile_name (optarg);
2354 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2358 case 'D': /* Print a list of capture devices and exit */
2360 if_list = capture_interface_list(&err, &err_str);
2361 if (if_list == NULL) {
2363 case CANT_GET_INTERFACE_LIST:
2364 case DONT_HAVE_PCAP:
2365 cmdarg_err("%s", err_str);
2369 case NO_INTERFACES_FOUND:
2370 cmdarg_err("There are no interfaces on which a capture can be done");
2375 capture_opts_print_interfaces(if_list);
2376 free_interface_list(if_list);
2379 capture_option_specified = TRUE;
2383 case 'h': /* Print help and exit */
2389 if (strcmp(optarg, "-") == 0)
2390 stdin_capture = TRUE;
2393 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2394 status = filesystem_opt(opt, optarg);
2396 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2400 case 'v': /* Show version and exit */
2406 * Extension command line options have to be processed before
2407 * we call epan_init() as they are supposed to be used by dissectors
2408 * or taps very early in the registration process.
2412 case '?': /* Ignore errors - the "real" scan will catch them. */
2417 /* Init the "Open file" dialog directory */
2418 /* (do this after the path settings are processed) */
2420 /* Read the profile dependent (static part) of the recent file. */
2421 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2422 /* recent lists which is done in the dynamic part. */
2423 /* We have to do this already here, so command line parameters can overwrite these values. */
2424 recent_read_profile_static(&rf_path, &rf_open_errno);
2425 if (rf_path != NULL && rf_open_errno != 0) {
2426 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2427 "Could not open recent file\n\"%s\": %s.",
2428 rf_path, g_strerror(rf_open_errno));
2431 if (recent.gui_fileopen_remembered_dir &&
2432 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2433 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2435 set_last_open_dir(get_persdatafile_dir());
2438 /* Set getopt index back to initial value, so it will start with the
2439 first command line parameter again. Also reset opterr to 1, so that
2440 error messages are printed by getopt().
2442 XXX - this seems to work on most platforms, but time will tell.
2443 The Single UNIX Specification says "The getopt() function need
2444 not be reentrant", so this isn't guaranteed to work. The Mac
2445 OS X 10.4[.x] getopt() man page says
2447 In order to use getopt() to evaluate multiple sets of arguments, or to
2448 evaluate a single set of arguments multiple times, the variable optreset
2449 must be set to 1 before the second and each additional set of calls to
2450 getopt(), and the variable optind must be reinitialized.
2454 The optreset variable was added to make it possible to call the getopt()
2455 function multiple times. This is an extension to the IEEE Std 1003.2
2456 (``POSIX.2'') specification.
2458 which I think comes from one of the other BSDs.
2460 XXX - if we want to control all the command-line option errors, so
2461 that we can display them where we choose (e.g., in a window), we'd
2462 want to leave opterr as 0, and produce our own messages using optopt.
2463 We'd have to check the value of optopt to see if it's a valid option
2464 letter, in which case *presumably* the error is "this option requires
2465 an argument but none was specified", or not a valid option letter,
2466 in which case *presumably* the error is "this option isn't valid".
2467 Some versions of getopt() let you supply a option string beginning
2468 with ':', which means that getopt() will return ':' rather than '?'
2469 for "this option requires an argument but none was specified", but
2471 optind = optind_initial;
2474 #if !GLIB_CHECK_VERSION(2,31,0)
2475 g_thread_init(NULL);
2478 /* Set the current locale according to the program environment.
2479 * We haven't localized anything, but some GTK widgets are localized
2480 * (the file selection dialogue, for example).
2481 * This also sets the C-language locale to the native environment. */
2482 setlocale (LC_ALL, "");
2484 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2485 gtk_init (&argc, &argv);
2487 cf_callback_add(main_cf_callback, NULL);
2489 capture_callback_add(main_capture_callback, NULL);
2491 cf_callback_add(statusbar_cf_callback, NULL);
2493 capture_callback_add(statusbar_capture_callback, NULL);
2496 /* Arrange that if we have no console window, and a GLib message logging
2497 routine is called to log a message, we pop up a console window.
2499 We do that by inserting our own handler for all messages logged
2500 to the default domain; that handler pops up a console if necessary,
2501 and then calls the default handler. */
2503 /* We might want to have component specific log levels later ... */
2507 G_LOG_LEVEL_CRITICAL|
2508 G_LOG_LEVEL_WARNING|
2509 G_LOG_LEVEL_MESSAGE|
2512 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2514 g_log_set_handler(NULL,
2516 console_log_handler, NULL /* user_data */);
2517 g_log_set_handler(LOG_DOMAIN_MAIN,
2519 console_log_handler, NULL /* user_data */);
2522 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2524 console_log_handler, NULL /* user_data */);
2525 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2527 console_log_handler, NULL /* user_data */);
2529 /* Set the initial values in the capture options. This might be overwritten
2530 by preference settings and then again by the command line parameters. */
2531 capture_opts_init(&global_capture_opts, &cfile);
2534 /* Initialize whatever we need to allocate colors for GTK+ */
2537 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2538 filter = get_conn_cfilter();
2539 if ( *filter != '\0' ) {
2540 info_update_freq = 1000; /* Milliseconds */
2543 /* We won't come till here, if we had a "console only" command line parameter. */
2544 splash_win = splash_new("Loading Wireshark ...");
2545 if (init_progfile_dir_error != NULL) {
2546 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2547 "Can't get pathname of Wireshark: %s.\n"
2548 "It won't be possible to capture traffic.\n"
2549 "Report this to the Wireshark developers.",
2550 init_progfile_dir_error);
2551 g_free(init_progfile_dir_error);
2554 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2556 /* Register all dissectors; we must do this before checking for the
2557 "-G" flag, as the "-G" flag dumps information registered by the
2558 dissectors, and we must do it before we read the preferences, in
2559 case any dissectors register preferences. */
2560 epan_init(register_all_protocols,register_all_protocol_handoffs,
2561 splash_update, (gpointer) splash_win,
2562 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2563 write_failure_alert_box);
2565 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2567 /* Register all tap listeners; we do this before we parse the arguments,
2568 as the "-z" argument can specify a registered tap. */
2570 /* we register the plugin taps before the other taps because
2571 stats_tree taps plugins will be registered as tap listeners
2572 by stats_tree_stat.c and need to registered before that */
2575 register_all_plugin_tap_listeners();
2578 register_all_tap_listeners();
2580 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2582 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2583 /* Removed thread code:
2584 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2587 /* this is to keep tap extensions updating once every 3 seconds */
2588 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2590 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2592 cap_file_init(&cfile);
2594 /* Fill in capture options with values from the preferences */
2595 prefs_to_capture_opts();
2597 /*#ifdef HAVE_LIBPCAP
2598 fill_in_local_interfaces();
2600 /* Now get our args */
2601 while ((opt = getopt(argc, argv, optstring)) != -1) {
2603 /*** capture option specific ***/
2604 case 'a': /* autostop criteria */
2605 case 'b': /* Ringbuffer option */
2606 case 'c': /* Capture xxx packets */
2607 case 'f': /* capture filter */
2608 case 'k': /* Start capture immediately */
2609 case 'H': /* Hide capture info dialog box */
2610 case 'p': /* Don't capture in promiscuous mode */
2611 case 'i': /* Use interface x */
2612 #ifdef HAVE_PCAP_CREATE
2613 case 'I': /* Capture in monitor mode, if available */
2615 #ifdef HAVE_PCAP_REMOTE
2616 case 'A': /* Authentication */
2618 case 's': /* Set the snapshot (capture) length */
2619 case 'S': /* "Sync" mode: used for following file ala tail -f */
2620 case 'w': /* Write to capture file xxx */
2621 case 'y': /* Set the pcap data link type */
2622 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2623 case 'B': /* Buffer size */
2624 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2626 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2632 capture_option_specified = TRUE;
2637 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2638 case 'K': /* Kerberos keytab file */
2639 read_keytab_file(optarg);
2643 /*** all non capture option specific ***/
2645 /* Configuration profile settings were already processed just ignore them this time*/
2650 case 'j': /* Search backwards for a matching packet from filter in option J */
2651 jump_backwards = TRUE;
2653 case 'g': /* Go to packet with the given packet number */
2654 go_to_packet = get_positive_int(optarg, "go to packet");
2656 case 'J': /* Jump to the first packet which matches the filter criteria */
2659 case 'l': /* Automatic scrolling in live capture mode */
2661 auto_scroll_live = TRUE;
2663 capture_option_specified = TRUE;
2667 case 'L': /* Print list of link-layer types and exit */
2669 list_link_layer_types = TRUE;
2671 capture_option_specified = TRUE;
2675 case 'm': /* Fixed-width font for the display */
2676 g_free(prefs_p->gui_font_name);
2677 prefs_p->gui_font_name = g_strdup(optarg);
2679 case 'n': /* No name resolution */
2680 gbl_resolv_flags.mac_name = FALSE;
2681 gbl_resolv_flags.network_name = FALSE;
2682 gbl_resolv_flags.transport_name = FALSE;
2683 gbl_resolv_flags.concurrent_dns = FALSE;
2685 case 'N': /* Select what types of addresses/port #s to resolve */
2686 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2687 if (badopt != '\0') {
2688 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2693 case 'o': /* Override preference from command line */
2694 switch (prefs_set_pref(optarg)) {
2697 case PREFS_SET_SYNTAX_ERR:
2698 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2701 case PREFS_SET_NO_SUCH_PREF:
2702 /* not a preference, might be a recent setting */
2703 switch (recent_set_arg(optarg)) {
2706 case PREFS_SET_SYNTAX_ERR:
2707 /* shouldn't happen, checked already above */
2708 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2711 case PREFS_SET_NO_SUCH_PREF:
2712 case PREFS_SET_OBSOLETE:
2713 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2718 g_assert_not_reached();
2721 case PREFS_SET_OBSOLETE:
2722 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2727 g_assert_not_reached();
2731 /* Path settings were already processed just ignore them this time*/
2733 case 'r': /* Read capture file xxx */
2734 /* We may set "last_open_dir" to "cf_name", and if we change
2735 "last_open_dir" later, we free the old value, so we have to
2736 set "cf_name" to something that's been allocated. */
2737 cf_name = g_strdup(optarg);
2739 case 'R': /* Read file filter */
2742 case 't': /* Time stamp type */
2743 if (strcmp(optarg, "r") == 0)
2744 timestamp_set_type(TS_RELATIVE);
2745 else if (strcmp(optarg, "a") == 0)
2746 timestamp_set_type(TS_ABSOLUTE);
2747 else if (strcmp(optarg, "ad") == 0)
2748 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2749 else if (strcmp(optarg, "d") == 0)
2750 timestamp_set_type(TS_DELTA);
2751 else if (strcmp(optarg, "dd") == 0)
2752 timestamp_set_type(TS_DELTA_DIS);
2753 else if (strcmp(optarg, "e") == 0)
2754 timestamp_set_type(TS_EPOCH);
2755 else if (strcmp(optarg, "u") == 0)
2756 timestamp_set_type(TS_UTC);
2757 else if (strcmp(optarg, "ud") == 0)
2758 timestamp_set_type(TS_UTC_WITH_DATE);
2760 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2761 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2762 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2766 case 'u': /* Seconds type */
2767 if (strcmp(optarg, "s") == 0)
2768 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2769 else if (strcmp(optarg, "hms") == 0)
2770 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2772 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2773 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2778 /* ext ops were already processed just ignore them this time*/
2781 /* We won't call the init function for the stat this soon
2782 as it would disallow MATE's fields (which are registered
2783 by the preferences set callback) from being used as
2784 part of a tap filter. Instead, we just add the argument
2785 to a list of stat arguments. */
2786 if (!process_stat_cmd_arg(optarg)) {
2787 cmdarg_err("Invalid -z argument.");
2788 cmdarg_err_cont(" -z argument must be one of :");
2789 list_stat_cmd_args();
2794 case '?': /* Bad flag - print usage message */
2803 if (cf_name != NULL) {
2805 * Input file name specified with "-r" *and* specified as a regular
2806 * command-line argument.
2808 cmdarg_err("File name specified both with -r and regular argument");
2812 * Input file name not specified with "-r", and a command-line argument
2813 * was specified; treat it as the input file name.
2815 * Yes, this is different from tshark, where non-flag command-line
2816 * arguments are a filter, but this works better on GUI desktops
2817 * where a command can be specified to be run to open a particular
2818 * file - yes, you could have "-r" as the last part of the command,
2819 * but that's a bit ugly.
2821 cf_name = g_strdup(argv[0]);
2829 * Extra command line arguments were specified; complain.
2831 cmdarg_err("Invalid argument: %s", argv[0]);
2836 #ifndef HAVE_LIBPCAP
2837 if (capture_option_specified) {
2838 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2846 fill_in_local_interfaces();
2847 if (start_capture && list_link_layer_types) {
2848 /* Specifying *both* is bogus. */
2849 cmdarg_err("You can't specify both -L and a live capture.");
2853 if (list_link_layer_types) {
2854 /* We're supposed to list the link-layer types for an interface;
2855 did the user also specify a capture file to be read? */
2857 /* Yes - that's bogus. */
2858 cmdarg_err("You can't specify -L and a capture file to be read.");
2861 /* No - did they specify a ring buffer option? */
2862 if (global_capture_opts.multi_files_on) {
2863 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2867 /* We're supposed to do a live capture; did the user also specify
2868 a capture file to be read? */
2869 if (start_capture && cf_name) {
2870 /* Yes - that's bogus. */
2871 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2875 /* No - was the ring buffer option specified and, if so, does it make
2877 if (global_capture_opts.multi_files_on) {
2878 /* Ring buffer works only under certain conditions:
2879 a) ring buffer does not work with temporary files;
2880 b) real_time_mode and multi_files_on are mutually exclusive -
2881 real_time_mode takes precedence;
2882 c) it makes no sense to enable the ring buffer if the maximum
2883 file size is set to "infinite". */
2884 if (global_capture_opts.save_file == NULL) {
2885 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2886 global_capture_opts.multi_files_on = FALSE;
2888 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2889 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2890 /* XXX - this must be redesigned as the conditions changed */
2895 if (start_capture || list_link_layer_types) {
2896 /* Did the user specify an interface to use? */
2897 if (!capture_opts_trim_iface(&global_capture_opts,
2898 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL)) {
2903 if (list_link_layer_types) {
2904 /* Get the list of link-layer types for the capture devices. */
2905 if_capabilities_t *caps;
2908 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2910 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2911 if (device.selected) {
2912 #if defined(HAVE_PCAP_CREATE)
2913 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2915 caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2918 cmdarg_err("%s", err_str);
2922 if (caps->data_link_types == NULL) {
2923 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2926 #if defined(HAVE_PCAP_CREATE)
2927 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2929 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2931 free_if_capabilities(caps);
2937 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2938 capture_opts_trim_ring_num_files(&global_capture_opts);
2939 #endif /* HAVE_LIBPCAP */
2941 /* Notify all registered modules that have had any of their preferences
2942 changed either from one of the preferences file or from the command
2943 line that their preferences have changed. */
2947 if ((global_capture_opts.num_selected == 0) &&
2948 (prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0')) {
2951 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2952 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2953 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2954 device.selected = TRUE;
2955 global_capture_opts.num_selected++;
2956 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2957 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2964 /* disabled protocols as per configuration file */
2965 if (gdp_path == NULL && dp_path == NULL) {
2966 set_disabled_protos_list();
2969 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2971 /* read in rc file from global and personal configuration paths. */
2972 rc_file = get_datafile_path(RC_FILE);
2973 #if GTK_CHECK_VERSION(3,0,0)
2974 /* XXX resolve later */
2976 gtk_rc_parse(rc_file);
2978 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2979 gtk_rc_parse(rc_file);
2989 /* close the splash screen, as we are going to open the main window now */
2990 splash_destroy(splash_win);
2992 /************************************************************************/
2993 /* Everything is prepared now, preferences and command line was read in */
2995 /* Pop up the main window. */
2996 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2998 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2999 recent_read_dynamic(&rf_path, &rf_open_errno);
3000 if (rf_path != NULL && rf_open_errno != 0) {
3001 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3002 "Could not open recent file\n\"%s\": %s.",
3003 rf_path, g_strerror(rf_open_errno));
3006 color_filters_enable(recent.packet_list_colorize);
3008 /* rearrange all the widgets as we now have all recent settings ready for this */
3009 main_widgets_rearrange();
3011 /* Fill in column titles. This must be done after the top level window
3014 XXX - is that still true, with fixed-width columns? */
3016 menu_recent_read_finished();
3018 main_auto_scroll_live_changed(auto_scroll_live);
3021 switch (user_font_apply()) {
3024 case FA_FONT_NOT_RESIZEABLE:
3025 /* "user_font_apply()" popped up an alert box. */
3026 /* turn off zooming - font can't be resized */
3027 case FA_FONT_NOT_AVAILABLE:
3028 /* XXX - did we successfully load the un-zoomed version earlier?
3029 If so, this *probably* means the font is available, but not at
3030 this particular zoom level, but perhaps some other failure
3031 occurred; I'm not sure you can determine which is the case,
3033 /* turn off zooming - zoom level is unavailable */
3035 /* in any other case than FA_SUCCESS, turn off zooming */
3036 recent.gui_zoom_level = 0;
3037 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3040 dnd_init(top_level);
3042 color_filters_init();
3045 capture_filter_init();
3048 /* the window can be sized only, if it's not already shown, so do it now! */
3049 main_load_window_geometry(top_level);
3051 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3054 GtkWidget *filter_te;
3055 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3056 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3058 /* Run the display filter so it goes in effect. */
3059 main_filter_packets(&cfile, dfilter, FALSE);
3062 /* If we were given the name of a capture file, read it in now;
3063 we defer it until now, so that, if we can't open it, and pop
3064 up an alert box, the alert box is more likely to come up on
3065 top of the main window - but before the preference-file-error
3066 alert box, so, if we get one of those, it's more likely to come
3069 show_main_window(TRUE);
3070 check_and_warn_user_startup(cf_name);
3071 if (rfilter != NULL) {
3072 if (!dfilter_compile(rfilter, &rfcode)) {
3073 bad_dfilter_alert_box(top_level, rfilter);
3074 rfilter_parse_failed = TRUE;
3077 if (!rfilter_parse_failed) {
3078 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3079 /* "cf_open()" succeeded, so it closed the previous
3080 capture file, and thus destroyed any previous read filter
3081 attached to "cf". */
3083 cfile.rfcode = rfcode;
3084 /* Open stat windows; we do so after creating the main window,
3085 to avoid GTK warnings, and after successfully opening the
3086 capture file, so we know we have something to compute stats
3087 on, and after registering all dissectors, so that MATE will
3088 have registered its field array and we can have a tap filter
3089 with one of MATE's late-registered fields as part of the
3091 start_requested_stats();
3093 /* Read the capture file. */
3094 switch (cf_read(&cfile, FALSE)) {
3098 /* Just because we got an error, that doesn't mean we were unable
3099 to read any of the file; we handle what we could get from the
3101 /* if the user told us to jump to a specific packet, do it now */
3102 if(go_to_packet != 0) {
3103 /* Jump to the specified frame number, kept for backward
3105 cf_goto_frame(&cfile, go_to_packet);
3106 } else if (jfilter != NULL) {
3107 /* try to compile given filter */
3108 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3109 bad_dfilter_alert_box(top_level, jfilter);
3111 /* Filter ok, jump to the first packet matching the filter
3112 conditions. Default search direction is forward, but if
3113 option d was given, search backwards */
3114 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3119 case CF_READ_ABORTED:
3125 /* If the filename is not the absolute path, prepend the current dir. This happens
3126 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3127 if (!g_path_is_absolute(cf_name)) {
3128 char *old_cf_name = cf_name;
3129 char *pwd = g_get_current_dir();
3130 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3131 g_free(old_cf_name);
3135 /* Save the name of the containing directory specified in the
3136 path name, if any; we can write over cf_name, which is a
3137 good thing, given that "get_dirname()" does write over its
3139 s = get_dirname(cf_name);
3140 set_last_open_dir(s);
3145 dfilter_free(rfcode);
3146 cfile.rfcode = NULL;
3147 show_main_window(FALSE);
3148 /* Don't call check_and_warn_user_startup(): we did it above */
3149 main_set_for_capture_in_progress(FALSE);
3150 set_capture_if_dialog_for_capture_in_progress(FALSE);
3155 if (start_capture) {
3156 if (global_capture_opts.save_file != NULL) {
3157 /* Save the directory name for future file dialogs. */
3158 /* (get_dirname overwrites filename) */
3159 s = get_dirname(g_strdup(global_capture_opts.save_file));
3160 set_last_open_dir(s);
3163 /* "-k" was specified; start a capture. */
3164 show_main_window(FALSE);
3165 check_and_warn_user_startup(cf_name);
3167 /* If no user interfaces were specified on the command line,
3168 copy the list of selected interfaces to the set of interfaces
3169 to use for this capture. */
3170 if (global_capture_opts.ifaces->len == 0)
3171 collect_ifaces(&global_capture_opts);
3172 if (capture_start(&global_capture_opts)) {
3173 /* The capture started. Open stat windows; we do so after creating
3174 the main window, to avoid GTK warnings, and after successfully
3175 opening the capture file, so we know we have something to compute
3176 stats on, and after registering all dissectors, so that MATE will
3177 have registered its field array and we can have a tap filter with
3178 one of MATE's late-registered fields as part of the filter. */
3179 start_requested_stats();
3182 show_main_window(FALSE);
3183 check_and_warn_user_startup(cf_name);
3184 main_set_for_capture_in_progress(FALSE);
3185 set_capture_if_dialog_for_capture_in_progress(FALSE);
3188 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3189 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3190 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3192 #else /* HAVE_LIBPCAP */
3193 show_main_window(FALSE);
3194 check_and_warn_user_startup(cf_name);
3195 main_set_for_capture_in_progress(FALSE);
3196 set_capture_if_dialog_for_capture_in_progress(FALSE);
3197 #endif /* HAVE_LIBPCAP */
3200 /* register our pid if we are being run from a U3 device */
3203 profile_store_persconffiles (FALSE);
3205 #ifdef HAVE_GTKOSXAPPLICATION
3206 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3207 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3208 gtk_osxapplication_ready(theApp);
3211 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3214 gtk_iface_mon_start();
3217 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3219 /* ... back from GTK, we're going down now! */
3222 gtk_iface_mon_stop();
3225 /* deregister our pid */
3226 u3_deregister_pid();
3230 AirPDcapDestroyContext(&airpdcap_ctx);
3233 /* hide the (unresponsive) main window, while asking the user to close the console window */
3234 gtk_widget_hide(top_level);
3236 #ifdef HAVE_GTKOSXAPPLICATION
3237 g_object_unref(theApp);
3240 /* Shutdown windows sockets */
3243 /* For some unknown reason, the "atexit()" call in "create_console()"
3244 doesn't arrange that "destroy_console()" be called when we exit,
3245 so we call it here if a console was created. */
3254 /* We build this as a GUI subsystem application on Win32, so
3255 "WinMain()", not "main()", gets called.
3257 Hack shamelessly stolen from the Win32 port of the GIMP. */
3259 #define _stdcall __attribute__((stdcall))
3263 WinMain (struct HINSTANCE__ *hInstance,
3264 struct HINSTANCE__ *hPrevInstance,
3268 INITCOMMONCONTROLSEX comm_ctrl;
3271 * Initialize our DLL search path. MUST be called before LoadLibrary
3274 ws_init_dll_search_path();
3276 /* Initialize our controls. Required for native Windows file dialogs. */
3277 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3278 comm_ctrl.dwSize = sizeof(comm_ctrl);
3279 /* Includes the animate, header, hot key, list view, progress bar,
3280 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3283 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3284 InitCommonControlsEx(&comm_ctrl);
3286 /* RichEd20.DLL is needed for filter entries. */
3287 ws_load_library("riched20.dll");
3289 has_console = FALSE;
3290 console_wait = FALSE;
3291 return main (__argc, __argv);
3294 /* The code to create and desstroy console windows should not be necessary,
3295 at least as I read the GLib source code, as it looks as if GLib is, on
3296 Win32, *supposed* to create a console window into which to display its
3299 That doesn't happen, however. I suspect there's something completely
3300 broken about that code in GLib-for-Win32, and that it may be related
3301 to the breakage that forces us to just call "printf()" on the message
3302 rather than passing the message on to "g_log_default_handler()"
3303 (which is the routine that does the aforementioned non-functional
3304 console window creation). */
3307 * If this application has no console window to which its standard output
3308 * would go, create one.
3311 create_console(void)
3313 if (stdin_capture) {
3314 /* We've been handed "-i -". Don't mess with stdio. */
3319 /* We have no console to which to print the version string, so
3320 create one and make it the standard input, output, and error. */
3323 * See if we have an existing console (i.e. we were run from a
3326 if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3327 if (AllocConsole()) {
3328 console_wait = TRUE;
3329 SetConsoleTitle(_T("Wireshark Debug Console"));
3331 return; /* couldn't create console */
3335 ws_freopen("CONIN$", "r", stdin);
3336 ws_freopen("CONOUT$", "w", stdout);
3337 ws_freopen("CONOUT$", "w", stderr);
3338 fprintf(stdout, "\n");
3339 fprintf(stderr, "\n");
3341 /* Now register "destroy_console()" as a routine to be called just
3342 before the application exits, so that we can destroy the console
3343 after the user has typed a key (so that the console doesn't just
3344 disappear out from under them, giving the user no chance to see
3345 the message(s) we put in there). */
3346 atexit(destroy_console);
3348 /* Well, we have a console now. */
3354 destroy_console(void)
3357 printf("\n\nPress any key to exit\n");
3366 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3367 const char *message, gpointer user_data _U_)
3374 /* ignore log message, if log_level isn't interesting based
3375 upon the console log preferences.
3376 If the preferences haven't been loaded loaded yet, display the
3379 The default console_log_level preference value is such that only
3380 ERROR, CRITICAL and WARNING level messages are processed;
3381 MESSAGE, INFO and DEBUG level messages are ignored. */
3382 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3383 prefs.console_log_level != 0) {
3388 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3389 /* the user wants a console or the application will terminate immediately */
3393 /* For some unknown reason, the above doesn't appear to actually cause
3394 anything to be sent to the standard output, so we'll just splat the
3395 message out directly, just to make sure it gets out. */
3397 switch(log_level & G_LOG_LEVEL_MASK) {
3398 case G_LOG_LEVEL_ERROR:
3401 case G_LOG_LEVEL_CRITICAL:
3404 case G_LOG_LEVEL_WARNING:
3407 case G_LOG_LEVEL_MESSAGE:
3410 case G_LOG_LEVEL_INFO:
3413 case G_LOG_LEVEL_DEBUG:
3417 fprintf(stderr, "unknown log_level %u\n", log_level);
3419 g_assert_not_reached();
3422 /* create a "timestamp" */
3424 today = localtime(&curr);
3426 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3427 today->tm_hour, today->tm_min, today->tm_sec,
3428 log_domain != NULL ? log_domain : "",
3431 if(log_level & G_LOG_LEVEL_ERROR) {
3432 /* wait for a key press before the following error handler will terminate the program
3433 this way the user at least can read the error message */
3434 printf("\n\nPress any key to exit\n");
3438 /* XXX - on UN*X, should we just use g_log_default_handler()?
3439 We want the error messages to go to the standard output;
3440 on Mac OS X, that will cause them to show up in various
3441 per-user logs accessible through Console (details depend
3442 on whether you're running 10.0 through 10.4 or running
3443 10.5 and later), and, on other UN*X desktop environments,
3444 if they don't show up in some form of console log, that's
3445 a deficiency in that desktop environment. (Too bad
3446 Windows doesn't set the standard output and error for
3447 GUI apps to something that shows up in such a log.) */
3448 g_log_default_handler(log_domain, log_level, message, user_data);
3455 * Helper for main_widgets_rearrange()
3457 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3458 gtk_container_remove(GTK_CONTAINER(data), widget);
3461 static GtkWidget *main_widget_layout(gint layout_content)
3463 switch(layout_content) {
3464 case(layout_pane_content_none):
3466 case(layout_pane_content_plist):
3468 case(layout_pane_content_pdetails):
3470 case(layout_pane_content_pbytes):
3471 return byte_nb_ptr_gbl;
3473 g_assert_not_reached();
3480 * Rearrange the main window widgets
3482 void main_widgets_rearrange(void) {
3483 GtkWidget *first_pane_widget1, *first_pane_widget2;
3484 GtkWidget *second_pane_widget1, *second_pane_widget2;
3485 gboolean split_top_left = FALSE;
3487 /* be a bit faster */
3488 gtk_widget_hide(main_vbox);
3490 /* be sure we don't lose a widget while rearranging */
3491 g_object_ref(G_OBJECT(menubar));
3492 g_object_ref(G_OBJECT(main_tb));
3493 g_object_ref(G_OBJECT(filter_tb));
3494 g_object_ref(G_OBJECT(wireless_tb));
3495 g_object_ref(G_OBJECT(pkt_scrollw));
3496 g_object_ref(G_OBJECT(tv_scrollw));
3497 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3498 g_object_ref(G_OBJECT(statusbar));
3499 g_object_ref(G_OBJECT(main_pane_v1));
3500 g_object_ref(G_OBJECT(main_pane_v2));
3501 g_object_ref(G_OBJECT(main_pane_h1));
3502 g_object_ref(G_OBJECT(main_pane_h2));
3503 g_object_ref(G_OBJECT(welcome_pane));
3505 /* empty all containers participating */
3506 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3507 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3508 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3509 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3510 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3512 statusbar_widgets_emptying(statusbar);
3514 /* add the menubar always at the top */
3515 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3518 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3520 /* filter toolbar in toolbar area */
3521 if (!prefs.filter_toolbar_show_in_statusbar) {
3522 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3525 /* airpcap toolbar */
3526 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3528 /* fill the main layout panes */
3529 switch(prefs.gui_layout_type) {
3530 case(layout_type_5):
3531 main_first_pane = main_pane_v1;
3532 main_second_pane = main_pane_v2;
3533 split_top_left = FALSE;
3535 case(layout_type_2):
3536 main_first_pane = main_pane_v1;
3537 main_second_pane = main_pane_h1;
3538 split_top_left = FALSE;
3540 case(layout_type_1):
3541 main_first_pane = main_pane_v1;
3542 main_second_pane = main_pane_h1;
3543 split_top_left = TRUE;
3545 case(layout_type_4):
3546 main_first_pane = main_pane_h1;
3547 main_second_pane = main_pane_v1;
3548 split_top_left = FALSE;
3550 case(layout_type_3):
3551 main_first_pane = main_pane_h1;
3552 main_second_pane = main_pane_v1;
3553 split_top_left = TRUE;
3555 case(layout_type_6):
3556 main_first_pane = main_pane_h1;
3557 main_second_pane = main_pane_h2;
3558 split_top_left = FALSE;
3561 main_first_pane = NULL;
3562 main_second_pane = NULL;
3563 g_assert_not_reached();
3565 if (split_top_left) {
3566 first_pane_widget1 = main_second_pane;
3567 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3568 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3569 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3571 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3572 first_pane_widget2 = main_second_pane;
3573 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3574 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3576 if (first_pane_widget1 != NULL)
3577 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3578 if (first_pane_widget2 != NULL)
3579 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3580 if (second_pane_widget1 != NULL)
3581 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3582 if (second_pane_widget2 != NULL)
3583 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3585 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3588 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3591 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3593 /* filter toolbar in statusbar hbox */
3594 if (prefs.filter_toolbar_show_in_statusbar) {
3595 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3598 /* statusbar widgets */
3599 statusbar_widgets_pack(statusbar);
3601 /* hide widgets on users recent settings */
3602 main_widgets_show_or_hide();
3604 gtk_widget_show(main_vbox);
3608 is_widget_visible(GtkWidget *widget, gpointer data)
3610 gboolean *is_visible = data;
3613 if (gtk_widget_get_visible(widget))
3620 main_widgets_show_or_hide(void)
3622 gboolean main_second_pane_show;
3624 if (recent.main_toolbar_show) {
3625 gtk_widget_show(main_tb);
3627 gtk_widget_hide(main_tb);
3630 statusbar_widgets_show_or_hide(statusbar);
3632 if (recent.filter_toolbar_show) {
3633 gtk_widget_show(filter_tb);
3635 gtk_widget_hide(filter_tb);
3638 if (recent.wireless_toolbar_show) {
3639 gtk_widget_show(wireless_tb);
3641 gtk_widget_hide(wireless_tb);
3644 if (recent.packet_list_show && have_capture_file) {
3645 gtk_widget_show(pkt_scrollw);
3647 gtk_widget_hide(pkt_scrollw);
3650 if (recent.tree_view_show && have_capture_file) {
3651 gtk_widget_show(tv_scrollw);
3653 gtk_widget_hide(tv_scrollw);
3656 if (recent.byte_view_show && have_capture_file) {
3657 gtk_widget_show(byte_nb_ptr_gbl);
3659 gtk_widget_hide(byte_nb_ptr_gbl);
3662 if (have_capture_file) {
3663 gtk_widget_show(main_first_pane);
3665 gtk_widget_hide(main_first_pane);
3669 * Is anything in "main_second_pane" visible?
3670 * If so, show it, otherwise hide it.
3672 main_second_pane_show = FALSE;
3673 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3674 &main_second_pane_show);
3675 if (main_second_pane_show) {
3676 gtk_widget_show(main_second_pane);
3678 gtk_widget_hide(main_second_pane);
3681 if (!have_capture_file) {
3683 gtk_widget_show(welcome_pane);
3686 gtk_widget_hide(welcome_pane);
3691 /* called, when the window state changes (minimized, maximized, ...) */
3693 window_state_event_cb (GtkWidget *widget _U_,
3697 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3699 if( (event->type) == (GDK_WINDOW_STATE)) {
3700 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3701 /* we might have dialogs popped up while we where iconified,
3703 display_queued_messages();
3711 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3713 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3715 if (event->keyval == GDK_F8) {
3716 new_packet_list_next();
3718 } else if (event->keyval == GDK_F7) {
3719 new_packet_list_prev();
3721 } else if (event->state & NO_SHIFT_MOD_MASK) {
3722 return FALSE; /* Skip control, alt, and other modifiers */
3724 * A comment in gdkkeysyms.h says that it's autogenerated from
3725 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3726 * don't explicitly say so, isprint() should work as expected
3729 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3730 /* Forward the keypress on to the display filter entry */
3731 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3732 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3733 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3741 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3743 GtkAccelGroup *accel;
3746 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3747 main_set_window_name("The Wireshark Network Analyzer");
3749 gtk_widget_set_name(top_level, "main window");
3750 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3752 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3753 G_CALLBACK(window_state_event_cb), NULL);
3754 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3755 G_CALLBACK(top_level_key_pressed_cb), NULL );
3757 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3758 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3760 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3761 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3762 gtk_widget_show(main_vbox);
3765 menubar = main_menu_new(&accel);
3767 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3768 /* Mac OS X native menus are created and displayed by main_menu_new() */
3769 if(!prefs_p->gui_macosx_style) {
3771 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3772 gtk_widget_show(menubar);
3773 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3778 main_tb = toolbar_new();
3779 gtk_widget_show (main_tb);
3781 /* Filter toolbar */
3782 filter_tb = filter_toolbar_new();
3785 pkt_scrollw = new_packet_list_create();
3786 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3787 gtk_widget_show_all(pkt_scrollw);
3790 tv_scrollw = proto_tree_view_new(prefs_p, &tree_view_gbl);
3791 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3792 gtk_widget_show(tv_scrollw);
3794 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3795 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3796 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3797 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3798 gtk_widget_show(tree_view_gbl);
3801 byte_nb_ptr_gbl = byte_view_new();
3802 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3803 gtk_widget_show(byte_nb_ptr_gbl);
3805 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3806 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3808 /* Panes for the packet list, tree, and byte view */
3809 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3810 gtk_widget_show(main_pane_v1);
3811 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3812 gtk_widget_show(main_pane_v2);
3813 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3814 gtk_widget_show(main_pane_h1);
3815 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3816 gtk_widget_show(main_pane_h2);
3818 wireless_tb = airpcap_toolbar_new();
3820 wireless_tb = ws80211_toolbar_new();
3822 gtk_widget_show(wireless_tb);
3825 statusbar = statusbar_new();
3826 gtk_widget_show(statusbar);
3828 /* Pane for the welcome screen */
3829 welcome_pane = welcome_new();
3830 gtk_widget_show(welcome_pane);
3834 show_main_window(gboolean doing_work)
3836 main_set_for_capture_file(doing_work);
3838 /*** we have finished all init things, show the main window ***/
3839 gtk_widget_show(top_level);
3841 /* the window can be maximized only, if it's visible, so do it after show! */
3842 main_load_window_geometry(top_level);
3844 /* process all pending GUI events before continue */
3845 while (gtk_events_pending()) gtk_main_iteration();
3847 /* Pop up any queued-up alert boxes. */
3848 display_queued_messages();
3850 /* Move the main window to the front, in case it isn't already there */
3851 gdk_window_raise(gtk_widget_get_window(top_level));
3854 airpcap_toolbar_show(wireless_tb);
3855 #endif /* HAVE_AIRPCAP */
3858 /* Fill in capture options with values from the preferences */
3860 prefs_to_capture_opts(void)
3863 /* Set promiscuous mode from the preferences setting. */
3864 /* the same applies to other preferences settings as well. */
3865 global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
3866 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3867 global_capture_opts.show_info = prefs.capture_show_info;
3868 global_capture_opts.real_time_mode = prefs.capture_real_time;
3869 auto_scroll_live = prefs.capture_auto_scroll;
3870 #endif /* HAVE_LIBPCAP */
3873 static void copy_global_profile (const gchar *profile_name)
3875 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3877 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3878 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3879 "Can't create directory\n\"%s\":\n%s.",
3880 pf_dir_path, g_strerror(errno));
3882 g_free(pf_dir_path);
3885 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3886 &pf_dir_path, &pf_dir_path2) == -1) {
3887 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3888 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3889 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3891 g_free(pf_filename);
3892 g_free(pf_dir_path);
3893 g_free(pf_dir_path2);
3897 /* Change configuration profile */
3898 void change_configuration_profile (const gchar *profile_name)
3900 char *gdp_path, *dp_path;
3904 /* First check if profile exists */
3905 if (!profile_exists(profile_name, FALSE)) {
3906 if (profile_exists(profile_name, TRUE)) {
3907 /* Copy from global profile */
3908 copy_global_profile (profile_name);
3910 /* No personal and no global profile exists */
3915 /* Then check if changing to another profile */
3916 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3920 /* Get the current geometry, before writing it to disk */
3921 main_save_window_geometry(top_level);
3923 if (profile_exists(get_profile_name(), FALSE)) {
3924 /* Write recent file for profile we are leaving, if it still exists */
3925 write_profile_recent();
3928 /* Set profile name and update the status bar */
3929 set_profile_name (profile_name);
3930 profile_bar_update ();
3931 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3933 /* Reset current preferences and apply the new */
3937 (void) read_configuration_files (&gdp_path, &dp_path);
3939 recent_read_profile_static(&rf_path, &rf_open_errno);
3940 if (rf_path != NULL && rf_open_errno != 0) {
3941 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3942 "Could not open common recent file\n\"%s\": %s.",
3943 rf_path, g_strerror(rf_open_errno));
3945 if (recent.gui_fileopen_remembered_dir &&
3946 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3947 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3949 timestamp_set_type (recent.gui_time_format);
3950 timestamp_set_seconds_type (recent.gui_seconds_format);
3951 color_filters_enable(recent.packet_list_colorize);
3953 prefs_to_capture_opts();
3955 macros_post_update();
3957 /* Update window view and redraw the toolbar */
3958 main_titlebar_update();
3959 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3960 toolbar_redraw_all();
3962 /* Enable all protocols and disable from the disabled list */
3964 if (gdp_path == NULL && dp_path == NULL) {
3965 set_disabled_protos_list();
3968 /* Reload color filters */
3969 color_filters_reload();
3971 /* Reload list of interfaces on welcome page */
3972 welcome_if_panel_reload();
3974 /* Recreate the packet list according to new preferences */
3975 new_packet_list_recreate ();
3976 cfile.columns_changed = FALSE; /* Reset value */
3979 /* Update menus with new recent values */
3980 menu_recent_read_finished();
3982 /* Reload pane geometry, must be done after recreating the list */
3983 main_pane_load_window_geometry();
3986 /** redissect packets and update UI */
3987 void redissect_packets(void)
3989 cf_redissect_packets(&cfile);
3990 status_expert_update();