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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/packet.h>
71 #include <epan/plugins.h>
72 #include <epan/dfilter/dfilter.h>
73 #include <epan/strutil.h>
74 #include <epan/addr_resolv.h>
75 #include <epan/emem.h>
76 #include <epan/ex-opt.h>
77 #include <epan/funnel.h>
78 #include <epan/expert.h>
79 #include <epan/frequency-utils.h>
80 #include <epan/prefs.h>
81 #include <epan/prefs-int.h>
83 #include <epan/stat_cmd_args.h>
85 #include <epan/column.h>
87 /* general (not GTK specific) */
89 #include "../summary.h"
90 #include "../filters.h"
91 #include "../disabled_protos.h"
93 #include "../color_filters.h"
95 #include "../simple_dialog.h"
96 #include "../main_statusbar.h"
97 #include "../register.h"
98 #include "../ringbuffer.h"
99 #include "../ui_util.h"
101 #include "../clopts_common.h"
102 #include "../console_io.h"
103 #include "../cmdarg_err.h"
104 #include "../version_info.h"
105 #include "../merge.h"
106 #include "../alert_box.h"
109 #include <wsutil/file_util.h>
112 #include "../capture_ui_utils.h"
113 #include "../capture-pcap-util.h"
114 #include "../capture_ifinfo.h"
115 #include "../capture.h"
116 #include "../capture_sync.h"
120 #include "../capture-wpcap.h"
121 #include "../capture_wpcap_packet.h"
122 #include <tchar.h> /* Needed for Unicode */
123 #include <wsutil/unicode-utils.h>
124 #include <commctrl.h>
125 #include <shellapi.h>
129 #include "gtk/file_dlg.h"
130 #include "gtk/gtkglobals.h"
131 #include "gtk/color_utils.h"
132 #include "gtk/gui_utils.h"
133 #include "gtk/color_dlg.h"
134 #include "gtk/filter_dlg.h"
135 #include "gtk/uat_gui.h"
136 #include "gtk/main.h"
137 #include "gtk/main_airpcap_toolbar.h"
138 #include "gtk/main_filter_toolbar.h"
139 #include "gtk/menus.h"
140 #include "gtk/macros_dlg.h"
141 #include "gtk/main_statusbar_private.h"
142 #include "gtk/main_toolbar.h"
143 #include "gtk/main_welcome.h"
144 #include "gtk/drag_and_drop.h"
145 #include "gtk/capture_file_dlg.h"
146 #include "gtk/main_proto_draw.h"
147 #include "gtk/keys.h"
148 #include "gtk/packet_win.h"
149 #include "gtk/stock_icons.h"
150 #include "gtk/find_dlg.h"
151 #include "gtk/recent.h"
152 #include "gtk/follow_tcp.h"
153 #include "gtk/font_utils.h"
154 #include "gtk/about_dlg.h"
155 #include "gtk/help_dlg.h"
156 #include "gtk/decode_as_dlg.h"
157 #include "gtk/webbrowser.h"
158 #include "gtk/capture_dlg.h"
159 #include "gtk/capture_if_dlg.h"
160 #include "gtk/tap_param_dlg.h"
161 #include "gtk/prefs_column.h"
162 #include "gtk/prefs_dlg.h"
163 #include "gtk/proto_help.h"
164 #include "gtk/new_packet_list.h"
165 #include "gtk/filter_expression_save_dlg.h"
167 #include "gtk/old-gtk-compat.h"
170 #include "../image/wsicon16.xpm"
171 #include "../image/wsicon32.xpm"
172 #include "../image/wsicon48.xpm"
173 #include "../image/wsicon64.xpm"
174 #include "../image/wsiconcap16.xpm"
175 #include "../image/wsiconcap32.xpm"
176 #include "../image/wsiconcap48.xpm"
181 #include "airpcap_loader.h"
182 #include "airpcap_dlg.h"
183 #include "airpcap_gui_utils.h"
186 #include <epan/crypt/airpdcap_ws.h>
189 #ifdef HAVE_GTKOSXAPPLICATION
190 #include <igemacintegration/gtkosxapplication.h>
194 * Files under personal and global preferences directories in which
195 * GTK settings for Wireshark are stored.
197 #define RC_FILE "gtkrc"
201 /* "exported" main widgets */
202 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
204 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
205 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
206 static GtkWidget *main_first_pane, *main_second_pane;
208 /* internally used widgets */
209 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
212 GtkWidget *airpcap_tb;
213 int airpcap_dll_ret_val = -1;
216 GString *comp_info_str, *runtime_info_str;
218 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
220 static guint tap_update_timer_id;
223 static gboolean has_console; /* TRUE if app has console */
224 static gboolean console_wait; /* "Press any key..." */
225 static void destroy_console(void);
226 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
228 static void console_log_handler(const char *log_domain,
229 GLogLevelFlags log_level, const char *message, gpointer user_data);
232 capture_options global_capture_opts;
236 static void create_main_window(gint, gint, gint, e_prefs*);
237 static void show_main_window(gboolean);
238 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
239 static void main_save_window_geometry(GtkWidget *widget);
242 /* Match selected byte pattern */
244 match_selected_cb_do(gpointer data, int action, gchar *text)
246 GtkWidget *filter_te;
247 char *cur_filter, *new_filter;
249 if ((!text) || (0 == strlen(text))) {
250 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
255 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
258 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
260 switch (action&MATCH_SELECTED_MASK) {
262 case MATCH_SELECTED_REPLACE:
263 new_filter = g_strdup(text);
266 case MATCH_SELECTED_AND:
267 if ((!cur_filter) || (0 == strlen(cur_filter)))
268 new_filter = g_strdup(text);
270 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
273 case MATCH_SELECTED_OR:
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_NOT:
281 new_filter = g_strconcat("!(", text, ")", NULL);
284 case MATCH_SELECTED_AND_NOT:
285 if ((!cur_filter) || (0 == strlen(cur_filter)))
286 new_filter = g_strconcat("!(", text, ")", NULL);
288 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
291 case MATCH_SELECTED_OR_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);
299 g_assert_not_reached();
304 /* Free up the copy we got of the old filter text. */
307 /* Don't change the current display filter if we only want to copy the filter */
308 if (action&MATCH_SELECTED_COPY_ONLY) {
309 GString *gtk_text_str = g_string_new("");
310 g_string_append(gtk_text_str, new_filter);
311 copy_to_clipboard(gtk_text_str);
312 g_string_free(gtk_text_str, TRUE);
314 /* create a new one and set the display filter entry accordingly */
315 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
317 /* Run the display filter so it goes in effect. */
318 if (action&MATCH_SELECTED_APPLY_NOW)
319 main_filter_packets(&cfile, new_filter, FALSE);
322 /* Free up the new filter text. */
327 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
331 if (cfile.finfo_selected) {
332 filter = proto_construct_match_selected_string(cfile.finfo_selected,
334 match_selected_cb_do((data ? data : w), action, filter);
339 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
343 if (cfile.finfo_selected) {
344 filter = proto_construct_match_selected_string(cfile.finfo_selected,
346 if ((!filter) || (0 == strlen(filter))) {
347 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
348 "Could not acquire information to build a filter!\n"
349 "Try expanding or choosing another item.");
354 color_display_with_filter(filter);
357 color_filters_reset_tmp();
359 color_filters_set_tmp(filt_nr,filter, FALSE);
361 new_packet_list_colorize_packets();
367 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
369 gchar *selected_proto_url;
370 gchar *proto_abbrev = data;
375 if (cfile.finfo_selected) {
376 /* open wiki page using the protocol abbreviation */
377 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
378 browser_open_url(selected_proto_url);
379 g_free(selected_proto_url);
382 case(ESD_BTN_CANCEL):
385 g_assert_not_reached();
391 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
394 const gchar *proto_abbrev;
398 if (cfile.finfo_selected) {
399 /* convert selected field to protocol abbreviation */
400 /* XXX - could this conversion be simplified? */
401 field_id = cfile.finfo_selected->hfinfo->id;
402 /* if the selected field isn't a protocol, get it's parent */
403 if(!proto_registrar_is_protocol(field_id)) {
404 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
407 proto_abbrev = proto_registrar_get_abbrev(field_id);
409 if (!proto_is_private(field_id)) {
410 /* ask the user if the wiki page really should be opened */
411 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
412 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
414 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
416 "The Wireshark Wiki is a collaborative approach to provide information "
417 "about Wireshark in several ways (not limited to protocol specifics).\n"
419 "This Wiki is new, so the page of the selected protocol "
420 "may not exist and/or may not contain valuable information.\n"
422 "As everyone can edit the Wiki and add new content (or extend existing), "
423 "you are encouraged to add information if you can.\n"
425 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
427 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
428 "which will save you a lot of editing and will give a consistent look over the pages.",
429 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
430 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
432 /* appologize to the user that the wiki page cannot be opened */
433 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
434 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
436 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
438 "Since this is a private protocol, such information is not available in "
439 "a public wiki. Therefore this wiki entry is blocked.\n"
441 "Sorry for the inconvenience.\n",
442 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
447 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
449 gchar *selected_proto_url;
450 gchar *proto_abbrev = data;
454 if (cfile.finfo_selected) {
455 /* open reference page using the protocol abbreviation */
456 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
457 browser_open_url(selected_proto_url);
458 g_free(selected_proto_url);
461 case(ESD_BTN_CANCEL):
464 g_assert_not_reached();
469 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
472 const gchar *proto_abbrev;
476 if (cfile.finfo_selected) {
477 /* convert selected field to protocol abbreviation */
478 /* XXX - could this conversion be simplified? */
479 field_id = cfile.finfo_selected->hfinfo->id;
480 /* if the selected field isn't a protocol, get it's parent */
481 if(!proto_registrar_is_protocol(field_id)) {
482 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
485 proto_abbrev = proto_registrar_get_abbrev(field_id);
487 if (!proto_is_private(field_id)) {
488 /* ask the user if the wiki page really should be opened */
489 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
490 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
492 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
494 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
495 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
497 /* appologize to the user that the wiki page cannot be opened */
498 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
499 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
501 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
503 "Since this is a private protocol, such information is not available on "
504 "a public website. Therefore this filter entry is blocked.\n"
506 "Sorry for the inconvenience.\n",
507 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
513 is_address_column (gint column)
515 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
516 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
517 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
518 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
519 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
528 get_ip_address_list_from_packet_list_row(gpointer data)
530 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
531 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
534 GList *addr_list = NULL;
536 fdata = (frame_data *) new_packet_list_get_row_data(row);
541 if (!cf_read_frame (&cfile, fdata))
542 return NULL; /* error reading the frame */
544 epan_dissect_init(&edt, FALSE, FALSE);
545 col_custom_prime_edt(&edt, &cfile.cinfo);
547 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
548 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
550 /* First check selected column */
551 if (is_address_column (column)) {
552 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
555 for (col = 0; col < cfile.cinfo.num_cols; col++) {
556 /* Then check all columns except the selected */
557 if ((col != column) && (is_address_column (col))) {
558 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
562 epan_dissect_cleanup(&edt);
569 get_filter_from_packet_list_row_and_column(gpointer data)
571 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
572 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
576 fdata = (frame_data *) new_packet_list_get_row_data(row);
581 if (!cf_read_frame(&cfile, fdata))
582 return NULL; /* error reading the frame */
583 /* proto tree, visible. We need a proto tree if there's custom columns */
584 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
585 col_custom_prime_edt(&edt, &cfile.cinfo);
587 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
589 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
591 if ((cfile.cinfo.col_custom_occurrence[column]) ||
592 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
594 /* Only construct the filter when a single occurrence is displayed
595 * otherwise we might end up with a filter like "ip.proto==1,6".
597 * Or do we want to be able to filter on multiple occurrences so that
598 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
601 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
602 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
603 /* leak a little but safer than ep_ here */
604 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
605 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
606 if (hfi->parent == -1) {
608 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
609 } else if (hfi->type == FT_STRING) {
610 /* Custom string, add quotes */
611 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
612 cfile.cinfo.col_expr.col_expr_val[column]);
616 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
617 cfile.cinfo.col_expr.col_expr_val[column]);
622 epan_dissect_cleanup(&edt);
629 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
631 match_selected_cb_do(data,
633 get_filter_from_packet_list_row_and_column(data));
636 /* This function allows users to right click in the details window and copy the text
637 * information to the operating systems clipboard.
639 * We first check to see if a string representation is setup in the tree and then
640 * read the string. If not available then we try to grab the value. If all else
641 * fails we display a message to the user to indicate the copy could not be completed.
644 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
646 GString *gtk_text_str = g_string_new("");
647 char labelstring[256];
648 char *stringpointer = labelstring;
652 case COPY_SELECTED_DESCRIPTION:
653 if (cfile.finfo_selected->rep &&
654 strlen (cfile.finfo_selected->rep->representation) > 0) {
655 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
658 case COPY_SELECTED_FIELDNAME:
659 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
660 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
663 case COPY_SELECTED_VALUE:
664 if (cfile.edt !=0 ) {
665 g_string_append(gtk_text_str,
666 get_node_field_value(cfile.finfo_selected, cfile.edt));
673 if (gtk_text_str->len == 0) {
674 /* If no representation then... Try to read the value */
675 proto_item_fill_label(cfile.finfo_selected, stringpointer);
676 g_string_append(gtk_text_str, stringpointer);
679 if (gtk_text_str->len == 0) {
680 /* Could not get item so display error msg */
681 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
683 /* Copy string to clipboard */
684 copy_to_clipboard(gtk_text_str);
686 g_string_free(gtk_text_str, TRUE); /* Free the memory */
690 /* mark as reference time frame */
692 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
696 frame->flags.ref_time=1;
697 cfile.ref_time_count++;
699 frame->flags.ref_time=0;
700 cfile.ref_time_count--;
702 cf_reftime_packets(&cfile);
703 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
704 new_packet_list_freeze();
705 cfile.displayed_count--;
706 new_packet_list_recreate_visible_rows();
707 new_packet_list_thaw();
709 new_packet_list_queue_draw();
713 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
717 timestamp_set_type(TS_RELATIVE);
718 recent.gui_time_format = TS_RELATIVE;
719 cf_timestamp_auto_precision(&cfile);
720 new_packet_list_queue_draw();
725 g_assert_not_reached();
728 if (cfile.current_frame) {
729 set_frame_reftime(!cfile.current_frame->flags.ref_time,
730 cfile.current_frame, cfile.current_row);
736 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
738 static GtkWidget *reftime_dialog = NULL;
742 if (cfile.current_frame) {
743 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
744 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
745 "%sSwitch to the appropriate Time Display Format?%s\n\n"
746 "Time References don't work well with the currently selected Time Display Format.\n\n"
747 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
748 simple_dialog_primary_start(), simple_dialog_primary_end());
749 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
751 set_frame_reftime(!cfile.current_frame->flags.ref_time,
752 cfile.current_frame, cfile.current_row);
756 case REFTIME_FIND_NEXT:
757 cf_find_packet_time_reference(&cfile, SD_FORWARD);
759 case REFTIME_FIND_PREV:
760 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
766 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
768 cf_find_packet_marked(&cfile, SD_FORWARD);
772 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
774 cf_find_packet_marked(&cfile, SD_BACKWARD);
778 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
781 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
783 gboolean has_blurb = FALSE;
784 guint length = 0, byte_len;
785 GtkWidget *byte_view;
786 const guint8 *byte_data;
791 /* if nothing is selected */
792 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
795 * Which byte view is displaying the current protocol tree
798 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
799 if (byte_view == NULL)
802 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
803 if (byte_data == NULL)
806 cf_unselect_field(&cfile);
807 packet_hex_print(byte_view, byte_data,
808 cfile.current_frame, NULL, byte_len);
809 proto_help_menu_modify(sel, &cfile);
812 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
815 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
817 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
818 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
819 g_assert(byte_data != NULL);
821 cfile.finfo_selected = finfo;
822 set_menus_for_selected_tree_row(&cfile);
825 if (finfo->hfinfo->blurb != NULL &&
826 finfo->hfinfo->blurb[0] != '\0') {
828 length = (guint) strlen(finfo->hfinfo->blurb);
830 length = (guint) strlen(finfo->hfinfo->name);
832 finfo_length = finfo->length + finfo->appendix_length;
834 if (finfo_length == 0) {
836 } else if (finfo_length == 1) {
837 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
839 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
841 statusbar_pop_field_msg(); /* get rid of current help msg */
843 statusbar_push_field_msg(" %s (%s)%s",
844 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
845 finfo->hfinfo->abbrev, len_str);
848 * Don't show anything if the field name is zero-length;
849 * the pseudo-field for "proto_tree_add_text()" is such
850 * a field, and we don't want "Text (text)" showing up
851 * on the status line if you've selected such a field.
853 * XXX - there are zero-length fields for which we *do*
854 * want to show the field name.
856 * XXX - perhaps the name and abbrev field should be null
857 * pointers rather than null strings for that pseudo-field,
858 * but we'd have to add checks for null pointers in some
859 * places if we did that.
861 * Or perhaps protocol tree items added with
862 * "proto_tree_add_text()" should have -1 as the field index,
863 * with no pseudo-field being used, but that might also
864 * require special checks for -1 to be added.
866 statusbar_push_field_msg("%s", "");
869 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
871 proto_help_menu_modify(sel, &cfile);
874 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
876 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
879 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
881 expand_all_tree(cfile.edt->tree, tree_view_gbl);
884 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
886 if (cfile.finfo_selected) {
887 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
888 cfile.finfo_selected->hfinfo->abbrev,0);
889 /* Recreate the packet list according to new preferences */
890 new_packet_list_recreate ();
891 if (!prefs.gui_use_pref_save) {
894 cfile.cinfo.columns_changed = FALSE; /* Reset value */
898 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
901 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
903 /* the mouse position is at an entry, expand that one */
904 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
905 gtk_tree_path_free(path);
909 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
910 if (cfile.edt->tree) {
911 guint32 tmp = gbl_resolv_flags;
912 gbl_resolv_flags = RESOLV_ALL;
913 proto_tree_draw(cfile.edt->tree, tree_view_gbl);
914 gbl_resolv_flags = tmp;
919 main_set_for_capture_file(gboolean have_capture_file_in)
921 have_capture_file = have_capture_file_in;
923 main_widgets_show_or_hide();
929 /* get the current geometry, before writing it to disk */
930 main_save_window_geometry(top_level);
932 /* write user's recent file to disk
933 * It is no problem to write this file, even if we do not quit */
934 write_profile_recent();
937 /* XXX - should we check whether the capture file is an
938 unsaved temporary file for a live capture and, if so,
939 pop up a "do you want to exit without saving the capture
940 file?" dialog, and then just return, leaving said dialog
941 box to forcibly quit if the user clicks "OK"?
943 If so, note that this should be done in a subroutine that
944 returns TRUE if we do so, and FALSE otherwise, and if it
945 returns TRUE we should return TRUE without nuking anything.
947 Note that, if we do that, we might also want to check if
948 an "Update list of packets in real time" capture is in
949 progress and, if so, ask whether they want to terminate
950 the capture and discard it, and return TRUE, before nuking
951 any child capture, if they say they don't want to do so. */
954 /* Nuke any child capture in progress. */
955 capture_kill_child(&global_capture_opts);
958 /* Are we in the middle of reading a capture? */
959 if (cfile.state == FILE_READ_IN_PROGRESS) {
960 /* Yes, so we can't just close the file and quit, as
961 that may yank the rug out from under the read in
962 progress; instead, just set the state to
963 "FILE_READ_ABORTED" and return - the code doing the read
964 will check for that and, if it sees that, will clean
966 cfile.state = FILE_READ_ABORTED;
968 /* Say that the window should *not* be deleted;
969 that'll be done by the code that cleans up. */
972 /* Close any capture file we have open; on some OSes, you
973 can't unlink a temporary capture file if you have it
975 "cf_close()" will unlink it after closing it if
976 it's a temporary file.
978 We do this here, rather than after the main loop returns,
979 as, after the main loop returns, the main window may have
980 been destroyed (if this is called due to a "destroy"
981 even on the main window rather than due to the user
982 selecting a menu item), and there may be a crash
983 or other problem when "cf_close()" tries to
984 clean up stuff in the main window.
986 XXX - is there a better place to put this?
987 Or should we have a routine that *just* closes the
988 capture file, and doesn't do anything with the UI,
989 which we'd call here, and another routine that
990 calls that routine and also cleans up the UI, which
991 we'd call elsewhere? */
994 /* Exit by leaving the main loop, so that any quit functions
995 we registered get called. */
998 /* Say that the window should be deleted. */
1004 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1008 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1009 gtk_window_present(GTK_WINDOW(top_level));
1010 /* user didn't saved his current file, ask him */
1011 dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
1012 ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
1013 "%sSave capture file before program quit?%s\n\n"
1014 "If you quit the program without saving, your capture data will be discarded.",
1015 simple_dialog_primary_start(), simple_dialog_primary_end());
1016 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1019 /* unchanged file, just exit */
1020 /* "main_do_quit()" indicates whether the main window should be deleted. */
1021 return main_do_quit();
1027 main_pane_load_window_geometry(void)
1029 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1030 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1031 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1032 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1038 main_load_window_geometry(GtkWidget *widget)
1040 window_geometry_t geom;
1042 geom.set_pos = prefs.gui_geometry_save_position;
1043 geom.x = recent.gui_geometry_main_x;
1044 geom.y = recent.gui_geometry_main_y;
1045 geom.set_size = prefs.gui_geometry_save_size;
1046 if (recent.gui_geometry_main_width > 0 &&
1047 recent.gui_geometry_main_height > 0) {
1048 geom.width = recent.gui_geometry_main_width;
1049 geom.height = recent.gui_geometry_main_height;
1050 geom.set_maximized = prefs.gui_geometry_save_maximized;
1052 /* We assume this means the width and height weren't set in
1053 the "recent" file (or that there is no "recent" file),
1054 and weren't set to a default value, so we don't set the
1055 size. (The "recent" file code rejects non-positive width
1056 and height values.) */
1057 geom.set_size = FALSE;
1059 geom.maximized = recent.gui_geometry_main_maximized;
1061 window_set_geometry(widget, &geom);
1063 main_pane_load_window_geometry();
1064 statusbar_load_window_geometry();
1069 main_save_window_geometry(GtkWidget *widget)
1071 window_geometry_t geom;
1073 window_get_geometry(widget, &geom);
1075 if (prefs.gui_geometry_save_position) {
1076 recent.gui_geometry_main_x = geom.x;
1077 recent.gui_geometry_main_y = geom.y;
1080 if (prefs.gui_geometry_save_size) {
1081 recent.gui_geometry_main_width = geom.width;
1082 recent.gui_geometry_main_height = geom.height;
1085 if(prefs.gui_geometry_save_maximized) {
1086 recent.gui_geometry_main_maximized = geom.maximized;
1089 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1090 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1091 statusbar_save_window_geometry();
1094 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1098 /* save file first */
1099 file_save_as_cmd(after_save_exit, NULL, FALSE);
1101 case(ESD_BTN_QUIT_DONT_SAVE):
1104 case(ESD_BTN_CANCEL):
1107 g_assert_not_reached();
1112 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1116 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1117 /* user didn't saved his current file, ask him */
1118 dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
1119 ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
1120 "%sSave capture file before program quit?%s\n\n"
1121 "If you quit the program without saving, your capture data will be discarded.",
1122 simple_dialog_primary_start(), simple_dialog_primary_end());
1123 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1125 /* unchanged file, just exit */
1131 print_usage(gboolean print_ver) {
1141 fprintf(output, "Wireshark " VERSION "%s\n"
1142 "Interactively dump and analyze network traffic.\n"
1143 "See http://www.wireshark.org for more information.\n"
1146 wireshark_svnversion, get_copyright_info());
1150 fprintf(output, "\n");
1151 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1152 fprintf(output, "\n");
1155 fprintf(output, "Capture interface:\n");
1156 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1157 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1158 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1159 fprintf(output, " -p don't capture in promiscuous mode\n");
1160 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1161 fprintf(output, " -S update packet display when new packets are captured\n");
1162 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1163 #ifdef HAVE_PCAP_CREATE
1164 fprintf(output, " -I capture in monitor mode, if available\n");
1166 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1167 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1169 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1170 fprintf(output, " -D print list of interfaces and exit\n");
1171 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1172 fprintf(output, "\n");
1173 fprintf(output, "Capture stop conditions:\n");
1174 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1175 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1176 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1177 fprintf(output, " files:NUM - stop after NUM files\n");
1178 /*fprintf(output, "\n");*/
1179 fprintf(output, "Capture output:\n");
1180 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1181 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1182 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1183 #endif /* HAVE_LIBPCAP */
1185 /*fprintf(output, "\n");*/
1186 fprintf(output, "Input file:\n");
1187 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1189 fprintf(output, "\n");
1190 fprintf(output, "Processing:\n");
1191 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1192 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1193 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1195 fprintf(output, "\n");
1196 fprintf(output, "User interface:\n");
1197 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1198 fprintf(output, " -d <display filter> start with the given display filter\n");
1199 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1200 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1201 fprintf(output, " filter\n");
1202 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1203 fprintf(output, " -m <font> set the font name used for most text\n");
1204 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1205 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1206 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1207 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1209 fprintf(output, "\n");
1210 fprintf(output, "Output:\n");
1211 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1213 fprintf(output, "\n");
1214 fprintf(output, "Miscellaneous:\n");
1215 fprintf(output, " -h display this help and exit\n");
1216 fprintf(output, " -v display version info and exit\n");
1217 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1218 fprintf(output, " persdata:path - personal data files\n");
1219 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1220 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1222 fprintf(output, " --display=DISPLAY X display to use\n");
1237 printf(PACKAGE " " VERSION "%s\n"
1244 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1245 runtime_info_str->str);
1253 * Print to the standard error. On Windows, create a console for the
1254 * standard error to show up on, if necessary.
1255 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1256 * terminal isn't the standard error?
1259 vfprintf_stderr(const char *fmt, va_list ap)
1264 vfprintf(stderr, fmt, ap);
1268 fprintf_stderr(const char *fmt, ...)
1273 vfprintf_stderr(fmt, ap);
1278 * Report an error in command-line arguments.
1279 * Creates a console on Windows.
1282 cmdarg_err(const char *fmt, ...)
1286 fprintf_stderr("wireshark: ");
1288 vfprintf_stderr(fmt, ap);
1290 fprintf_stderr("\n");
1294 * Report additional information for an error in command-line arguments.
1295 * Creates a console on Windows.
1296 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1297 * terminal isn't the standard error?
1300 cmdarg_err_cont(const char *fmt, ...)
1305 vfprintf_stderr(fmt, ap);
1306 fprintf_stderr("\n");
1311 Once every 3 seconds we get a callback here which we use to update
1315 tap_update_cb(gpointer data _U_)
1317 draw_tap_listeners(FALSE);
1321 /* Restart the tap update display timer with new configured interval */
1322 void reset_tap_update_timer(void)
1324 g_source_remove(tap_update_timer_id);
1325 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1329 protect_thread_critical_region(void)
1331 /* Threading support for TAP:s removed
1332 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1333 * See the commit for removed code:
1334 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
1338 unprotect_thread_critical_region(void)
1340 /* Threading support for TAP:s removed
1341 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1347 * Periodically process outstanding hostname lookups. If we have new items,
1348 * redraw the packet list and tree view.
1352 resolv_update_cb(gpointer data _U_)
1354 /* Anything new show up? */
1355 if (host_name_lookup_process(NULL)) {
1356 if (gtk_widget_get_window(pkt_scrollw))
1357 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1358 if (gtk_widget_get_window(tv_scrollw))
1359 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1362 /* Always check. Even if we don't do async lookups we could still get
1363 passive updates, e.g. from DNS packets. */
1368 /* Set main_window_name and it's icon title to the capture filename */
1370 set_display_filename(capture_file *cf)
1375 window_name = g_strdup_printf("%s", cf_get_display_name(cf));
1376 set_main_window_name(window_name);
1377 g_free(window_name);
1379 set_main_window_name("The Wireshark Network Analyzer");
1383 static GtkWidget *close_dlg = NULL;
1386 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1388 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1393 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1395 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1400 main_cf_cb_file_closing(capture_file *cf)
1403 /* if we have more than 10000 packets, show a splash screen while closing */
1404 /* XXX - don't know a better way to decide whether to show or not,
1405 * as most of the time is spend in a single eth_clist_clear function,
1406 * so we can't use a progress bar here! */
1407 if(cf->count > 10000) {
1408 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1409 "%sClosing file!%s\n\nPlease wait ...",
1410 simple_dialog_primary_start(),
1411 simple_dialog_primary_end());
1412 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1415 /* Destroy all windows, which refer to the
1416 capture file we're closing. */
1417 destroy_packet_wins();
1418 file_save_as_destroy();
1420 /* Restore the standard title bar message. */
1421 set_main_window_name("The Wireshark Network Analyzer");
1423 /* Disable all menu items that make sense only if you have a capture. */
1424 set_menus_for_capture_file(NULL);
1425 set_menus_for_captured_packets(FALSE);
1426 set_menus_for_selected_packet(cf);
1427 set_menus_for_capture_in_progress(FALSE);
1428 set_capture_if_dialog_for_capture_in_progress(FALSE);
1429 set_menus_for_selected_tree_row(cf);
1431 /* Set up main window for no capture file. */
1432 main_set_for_capture_file(FALSE);
1434 main_window_update();
1438 main_cf_cb_file_closed(capture_file *cf _U_)
1440 if(close_dlg != NULL) {
1441 splash_destroy(close_dlg);
1448 main_cf_cb_file_read_started(capture_file *cf _U_)
1450 tap_param_dlg_update();
1452 /* Set up main window for a capture file. */
1453 main_set_for_capture_file(TRUE);
1457 main_cf_cb_file_read_finished(capture_file *cf)
1461 if (!cf->is_tempfile && cf->filename) {
1462 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1463 add_menu_recent_capture_file(cf->filename);
1465 /* Remember folder for next Open dialog and save it in recent */
1466 dir_path = get_dirname(g_strdup(cf->filename));
1467 set_last_open_dir(dir_path);
1470 set_display_filename(cf);
1472 /* Enable menu items that make sense if you have a capture file you've
1473 finished reading. */
1474 set_menus_for_capture_file(cf);
1476 /* Enable menu items that make sense if you have some captured packets. */
1477 set_menus_for_captured_packets(TRUE);
1481 static GList *icon_list_create(
1482 const char **icon16_xpm,
1483 const char **icon32_xpm,
1484 const char **icon48_xpm,
1485 const char **icon64_xpm)
1487 GList *icon_list = NULL;
1488 GdkPixbuf * pixbuf16;
1489 GdkPixbuf * pixbuf32;
1490 GdkPixbuf * pixbuf48;
1491 GdkPixbuf * pixbuf64;
1494 if(icon16_xpm != NULL) {
1495 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1497 icon_list = g_list_append(icon_list, pixbuf16);
1500 if(icon32_xpm != NULL) {
1501 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1503 icon_list = g_list_append(icon_list, pixbuf32);
1506 if(icon48_xpm != NULL) {
1507 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1509 icon_list = g_list_append(icon_list, pixbuf48);
1512 if(icon64_xpm != NULL) {
1513 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1515 icon_list = g_list_append(icon_list, pixbuf64);
1522 main_capture_set_main_window_title(capture_options *capture_opts)
1524 GString *title = g_string_new("");
1526 g_string_append(title, "Capturing ");
1527 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1528 set_main_window_name(title->str);
1529 g_string_free(title, TRUE);
1533 main_capture_cb_capture_prepared(capture_options *capture_opts)
1535 static GList *icon_list = NULL;
1537 main_capture_set_main_window_title(capture_opts);
1539 if(icon_list == NULL) {
1540 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1542 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1544 /* Disable menu items that make no sense if you're currently running
1546 set_menus_for_capture_in_progress(TRUE);
1547 set_capture_if_dialog_for_capture_in_progress(TRUE);
1549 /* Don't set up main window for a capture file. */
1550 main_set_for_capture_file(FALSE);
1554 main_capture_cb_capture_update_started(capture_options *capture_opts)
1556 /* We've done this in "prepared" above, but it will be cleared while
1557 switching to the next multiple file. */
1558 main_capture_set_main_window_title(capture_opts);
1560 set_menus_for_capture_in_progress(TRUE);
1561 set_capture_if_dialog_for_capture_in_progress(TRUE);
1563 /* Enable menu items that make sense if you have some captured
1564 packets (yes, I know, we don't have any *yet*). */
1565 set_menus_for_captured_packets(TRUE);
1567 /* Set up main window for a capture file. */
1568 main_set_for_capture_file(TRUE);
1572 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1574 capture_file *cf = capture_opts->cf;
1575 static GList *icon_list = NULL;
1577 if (!cf->is_tempfile && cf->filename) {
1578 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1579 add_menu_recent_capture_file(cf->filename);
1581 set_display_filename(cf);
1583 /* Enable menu items that make sense if you're not currently running
1585 set_menus_for_capture_in_progress(FALSE);
1586 set_capture_if_dialog_for_capture_in_progress(FALSE);
1588 /* Enable menu items that make sense if you have a capture file
1589 you've finished reading. */
1590 set_menus_for_capture_file(cf);
1592 /* Set up main window for a capture file. */
1593 main_set_for_capture_file(TRUE);
1595 if(icon_list == NULL) {
1596 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1598 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1600 if(global_capture_opts.quit_after_cap) {
1601 /* command line asked us to quit after the capture */
1602 /* don't pop up a dialog to ask for unsaved files etc. */
1608 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1610 /* Don't set up main window for a capture file. */
1611 main_set_for_capture_file(FALSE);
1615 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1618 capture_file *cf = capture_opts->cf;
1620 static GList *icon_list = NULL;
1622 /*set_display_filename(cf);*/
1624 /* Enable menu items that make sense if you're not currently running
1626 set_menus_for_capture_in_progress(FALSE);
1627 set_capture_if_dialog_for_capture_in_progress(FALSE);
1629 /* Restore the standard title bar message */
1630 /* (just in case we have trouble opening the capture file). */
1631 set_main_window_name("The Wireshark Network Analyzer");
1633 if(icon_list == NULL) {
1634 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1636 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1638 /* We don't have loaded the capture file, this will be done later.
1639 * For now we still have simply a blank screen. */
1641 if(global_capture_opts.quit_after_cap) {
1642 /* command line asked us to quit after the capture */
1643 /* don't pop up a dialog to ask for unsaved files etc. */
1648 #endif /* HAVE_LIBPCAP */
1651 main_cf_cb_packet_selected(gpointer data)
1653 capture_file *cf = data;
1655 /* Display the GUI protocol tree and packet bytes.
1656 XXX - why do we dump core if we call "proto_tree_draw()"
1657 before calling "add_byte_views()"? */
1658 add_main_byte_views(cf->edt);
1659 main_proto_tree_draw(cf->edt->tree);
1661 /* Note: Both string and hex value searches in the packet data produce a non-zero
1662 search_pos if successful */
1663 if(cf->search_in_progress &&
1664 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1665 highlight_field(cf->edt->tvb, cf->search_pos,
1666 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1669 /* A packet is selected. */
1670 set_menus_for_selected_packet(cf);
1674 main_cf_cb_packet_unselected(capture_file *cf)
1676 /* Clear out the display of that packet. */
1677 clear_tree_and_hex_views();
1679 /* No packet is selected. */
1680 set_menus_for_selected_packet(cf);
1684 main_cf_cb_field_unselected(capture_file *cf)
1686 set_menus_for_selected_tree_row(cf);
1690 main_cf_cb_file_save_reload_finished(gpointer data _U_)
1692 set_display_filename(&cfile);
1693 set_menus_for_capture_file(&cfile);
1697 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1700 case(cf_cb_file_closing):
1701 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1702 main_cf_cb_file_closing(data);
1704 case(cf_cb_file_closed):
1705 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1706 main_cf_cb_file_closed(data);
1708 case(cf_cb_file_read_started):
1709 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1710 main_cf_cb_file_read_started(data);
1712 case(cf_cb_file_read_finished):
1713 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1714 main_cf_cb_file_read_finished(data);
1716 case(cf_cb_packet_selected):
1717 main_cf_cb_packet_selected(data);
1719 case(cf_cb_packet_unselected):
1720 main_cf_cb_packet_unselected(data);
1722 case(cf_cb_field_unselected):
1723 main_cf_cb_field_unselected(data);
1725 case(cf_cb_file_save_started):
1726 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1728 case(cf_cb_file_save_finished):
1729 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1731 case(cf_cb_file_save_reload_finished):
1732 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1733 main_cf_cb_file_save_reload_finished(data);
1735 case(cf_cb_file_save_failed):
1736 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1739 g_warning("main_cf_callback: event %u unknown", event);
1740 g_assert_not_reached();
1746 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1748 #ifdef HAVE_GTKOSXAPPLICATION
1749 GtkOSXApplication *theApp;
1752 case(capture_cb_capture_prepared):
1753 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1754 main_capture_cb_capture_prepared(capture_opts);
1756 case(capture_cb_capture_update_started):
1757 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1758 main_capture_cb_capture_update_started(capture_opts);
1759 #ifdef HAVE_GTKOSXAPPLICATION
1760 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1761 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1764 case(capture_cb_capture_update_continue):
1765 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1767 case(capture_cb_capture_update_finished):
1768 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1769 main_capture_cb_capture_update_finished(capture_opts);
1771 case(capture_cb_capture_fixed_started):
1772 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1773 main_capture_cb_capture_fixed_started(capture_opts);
1775 case(capture_cb_capture_fixed_continue):
1776 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1778 case(capture_cb_capture_fixed_finished):
1779 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1780 main_capture_cb_capture_fixed_finished(capture_opts);
1782 case(capture_cb_capture_stopping):
1783 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1784 /* Beware: this state won't be called, if the capture child
1785 * closes the capturing on it's own! */
1786 #ifdef HAVE_GTKOSXAPPLICATION
1787 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1788 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1792 g_warning("main_capture_callback: event %u unknown", event);
1793 g_assert_not_reached();
1799 get_gtk_compiled_info(GString *str)
1801 g_string_append(str, "with ");
1802 g_string_append_printf(str,
1803 #ifdef GTK_MAJOR_VERSION
1804 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1807 "GTK+ (version unknown)");
1809 g_string_append(str, ", ");
1811 g_string_append(str, "with Cairo ");
1812 g_string_append(str, CAIRO_VERSION_STRING);
1813 g_string_append(str, ", ");
1816 g_string_append(str, "with Pango ");
1817 g_string_append(str, PANGO_VERSION_STRING);
1818 g_string_append(str, ", ");
1824 get_gui_compiled_info(GString *str)
1826 epan_get_compiled_version_info(str);
1828 g_string_append(str, ", ");
1829 #ifdef HAVE_LIBPORTAUDIO
1830 #ifdef PORTAUDIO_API_1
1831 g_string_append(str, "with PortAudio <= V18");
1832 #else /* PORTAUDIO_API_1 */
1833 g_string_append(str, "with ");
1834 g_string_append(str, Pa_GetVersionText());
1835 #endif /* PORTAUDIO_API_1 */
1836 #else /* HAVE_LIBPORTAUDIO */
1837 g_string_append(str, "without PortAudio");
1838 #endif /* HAVE_LIBPORTAUDIO */
1840 g_string_append(str, ", ");
1842 get_compiled_airpcap_version(str);
1844 g_string_append(str, "without AirPcap");
1849 get_gui_runtime_info(GString *str)
1851 epan_get_runtime_version_info(str);
1854 g_string_append(str, ", ");
1855 get_runtime_airpcap_version(str);
1859 g_string_append(str, ", ");
1860 u3_runtime_info(str);
1865 read_configuration_files(char **gdp_path, char **dp_path)
1867 int gpf_open_errno, gpf_read_errno;
1868 int cf_open_errno, df_open_errno;
1869 int gdp_open_errno, gdp_read_errno;
1870 int dp_open_errno, dp_read_errno;
1871 char *gpf_path, *pf_path;
1872 char *cf_path, *df_path;
1873 int pf_open_errno, pf_read_errno;
1876 /* load the decode as entries of this profile */
1877 load_decode_as_entries();
1879 /* Read the preference files. */
1880 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1881 &pf_open_errno, &pf_read_errno, &pf_path);
1883 if (gpf_path != NULL) {
1884 if (gpf_open_errno != 0) {
1885 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1886 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1887 g_strerror(gpf_open_errno));
1889 if (gpf_read_errno != 0) {
1890 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1891 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1892 g_strerror(gpf_read_errno));
1895 if (pf_path != NULL) {
1896 if (pf_open_errno != 0) {
1897 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1898 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1899 g_strerror(pf_open_errno));
1901 if (pf_read_errno != 0) {
1902 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1903 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1904 g_strerror(pf_read_errno));
1911 /* if the user wants a console to be always there, well, we should open one for him */
1912 if (prefs_p->gui_console_open == console_open_always) {
1917 /* Read the capture filter file. */
1918 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1919 if (cf_path != NULL) {
1920 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1921 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1922 g_strerror(cf_open_errno));
1926 /* Read the display filter file. */
1927 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1928 if (df_path != NULL) {
1929 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1930 "Could not open your display filter file\n\"%s\": %s.", df_path,
1931 g_strerror(df_open_errno));
1935 /* Read the disabled protocols file. */
1936 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1937 dp_path, &dp_open_errno, &dp_read_errno);
1938 if (*gdp_path != NULL) {
1939 if (gdp_open_errno != 0) {
1940 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1941 "Could not open global disabled protocols file\n\"%s\": %s.",
1942 *gdp_path, g_strerror(gdp_open_errno));
1944 if (gdp_read_errno != 0) {
1945 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1946 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1947 *gdp_path, g_strerror(gdp_read_errno));
1952 if (*dp_path != NULL) {
1953 if (dp_open_errno != 0) {
1954 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1955 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1956 g_strerror(dp_open_errno));
1958 if (dp_read_errno != 0) {
1959 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1960 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1961 g_strerror(dp_read_errno));
1970 /* Check if there's something important to tell the user during startup.
1971 * We want to do this *after* showing the main window so that any windows
1972 * we pop up will be above the main window.
1976 check_and_warn_user_startup(gchar *cf_name)
1978 check_and_warn_user_startup(gchar *cf_name _U_)
1981 gchar *cur_user, *cur_group;
1982 gpointer priv_warning_dialog;
1984 /* Tell the user not to run as root. */
1985 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
1986 cur_user = get_cur_username();
1987 cur_group = get_cur_groupname();
1988 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1989 "Running as user \"%s\" and group \"%s\".\n"
1990 "This could be dangerous.\n\n"
1991 "If you're running Wireshark this way in order to perform live capture, "
1992 "you may want to be aware that there is a better way documented at\n"
1993 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
1996 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
1997 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2001 /* Warn the user if npf.sys isn't loaded. */
2002 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2003 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2004 "The NPF driver isn't running. You may have trouble\n"
2005 "capturing or listing interfaces.");
2006 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2007 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2014 /* And now our feature presentation... [ fade to music ] */
2016 main(int argc, char *argv[])
2018 char *init_progfile_dir_error;
2021 gboolean arg_error = FALSE;
2023 extern int info_update_freq; /* Found in about_dlg.c. */
2024 const gchar *filter;
2032 char *gdp_path, *dp_path;
2035 gboolean start_capture = FALSE;
2036 gboolean list_link_layer_types = FALSE;
2040 gboolean capture_option_specified = FALSE;
2047 gint pl_size = 280, tv_size = 95, bv_size = 75;
2048 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2049 dfilter_t *rfcode = NULL;
2050 gboolean rfilter_parse_failed = FALSE;
2053 GtkWidget *splash_win = NULL;
2054 GLogLevelFlags log_flags;
2055 guint go_to_packet = 0;
2056 gboolean jump_backwards = FALSE;
2057 dfilter_t *jump_to_filter = NULL;
2060 #ifdef HAVE_GTKOSXAPPLICATION
2061 GtkOSXApplication *theApp;
2065 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2066 #define OPTSTRING_B "B:"
2068 #define OPTSTRING_B ""
2069 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2070 #else /* HAVE_LIBPCAP */
2071 #define OPTSTRING_B ""
2072 #endif /* HAVE_LIBPCAP */
2074 #ifdef HAVE_PCAP_CREATE
2075 #define OPTSTRING_I "I"
2077 #define OPTSTRING_I ""
2080 #define OPTSTRING "a:b:" OPTSTRING_B "c:C:d:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:z:"
2082 static const char optstring[] = OPTSTRING;
2084 /* Set the C-language locale to the native environment. */
2085 setlocale(LC_ALL, "");
2087 arg_list_utf_16to8(argc, argv);
2091 * Get credential information for later use, and drop privileges
2092 * before doing anything else.
2093 * Let the user know if anything happened.
2095 init_process_policies();
2096 relinquish_special_privs_perm();
2099 * Attempt to get the pathname of the executable file.
2101 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2103 /* initialize the funnel mini-api */
2104 initialize_funnel_ops();
2106 AirPDcapInitContext(&airpdcap_ctx);
2109 /* Load wpcap if possible. Do this before collecting the run-time version information */
2112 /* ... and also load the packet.dll from wpcap */
2113 wpcap_packet_load();
2116 /* Load the airpcap.dll. This must also be done before collecting
2117 * run-time version information. */
2118 airpcap_dll_ret_val = load_airpcap();
2120 switch (airpcap_dll_ret_val) {
2121 case AIRPCAP_DLL_OK:
2122 /* load the airpcap interfaces */
2123 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2125 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2126 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2127 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2130 airpcap_if_active = NULL;
2134 /* select the first ad default (THIS SHOULD BE CHANGED) */
2135 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2140 * XXX - Maybe we need to warn the user if one of the following happens???
2142 case AIRPCAP_DLL_OLD:
2143 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2146 case AIRPCAP_DLL_ERROR:
2147 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2150 case AIRPCAP_DLL_NOT_FOUND:
2151 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2155 #endif /* HAVE_AIRPCAP */
2157 /* Start windows sockets */
2158 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2161 profile_store_persconffiles (TRUE);
2163 /* Assemble the compile-time version information string */
2164 comp_info_str = g_string_new("Compiled ");
2166 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2168 /* Assemble the run-time version information string */
2169 runtime_info_str = g_string_new("Running ");
2170 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2172 /* Read the profile independent recent file. We have to do this here so we can */
2173 /* set the profile before it can be set from the command line parameterts */
2174 recent_read_static(&rf_path, &rf_open_errno);
2175 if (rf_path != NULL && rf_open_errno != 0) {
2176 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2177 "Could not open common recent file\n\"%s\": %s.",
2178 rf_path, g_strerror(rf_open_errno));
2181 /* "pre-scan" the command line parameters, if we have "console only"
2182 parameters. We do this so we don't start GTK+ if we're only showing
2183 command-line help or version information.
2185 XXX - this pre-scan is done before we start GTK+, so we haven't
2186 run gtk_init() on the arguments. That means that GTK+ arguments
2187 have not been removed from the argument list; those arguments
2188 begin with "--", and will be treated as an error by getopt().
2190 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2193 optind_initial = optind;
2194 while ((opt = getopt(argc, argv, optstring)) != -1) {
2196 case 'C': /* Configuration Profile */
2197 if (profile_exists (optarg, FALSE)) {
2198 set_profile_name (optarg);
2200 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2204 case 'D': /* Print a list of capture devices and exit */
2206 if_list = capture_interface_list(&err, &err_str);
2207 if (if_list == NULL) {
2209 case CANT_GET_INTERFACE_LIST:
2210 cmdarg_err("%s", err_str);
2214 case NO_INTERFACES_FOUND:
2215 cmdarg_err("There are no interfaces on which a capture can be done");
2220 capture_opts_print_interfaces(if_list);
2221 free_interface_list(if_list);
2224 capture_option_specified = TRUE;
2228 case 'h': /* Print help and exit */
2234 if (strcmp(optarg, "-") == 0)
2235 stdin_capture = TRUE;
2238 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2239 status = filesystem_opt(opt, optarg);
2241 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2245 case 'v': /* Show version and exit */
2251 * Extension command line options have to be processed before
2252 * we call epan_init() as they are supposed to be used by dissectors
2253 * or taps very early in the registration process.
2257 case '?': /* Ignore errors - the "real" scan will catch them. */
2262 /* Init the "Open file" dialog directory */
2263 /* (do this after the path settings are processed) */
2265 /* Read the profile dependent (static part) of the recent file. */
2266 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2267 /* recent lists which is done in the dynamic part. */
2268 /* We have to do this already here, so command line parameters can overwrite these values. */
2269 recent_read_profile_static(&rf_path, &rf_open_errno);
2270 if (rf_path != NULL && rf_open_errno != 0) {
2271 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2272 "Could not open recent file\n\"%s\": %s.",
2273 rf_path, g_strerror(rf_open_errno));
2276 if (recent.gui_fileopen_remembered_dir &&
2277 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2278 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2280 set_last_open_dir(get_persdatafile_dir());
2283 /* Set getopt index back to initial value, so it will start with the
2284 first command line parameter again. Also reset opterr to 1, so that
2285 error messages are printed by getopt().
2287 XXX - this seems to work on most platforms, but time will tell.
2288 The Single UNIX Specification says "The getopt() function need
2289 not be reentrant", so this isn't guaranteed to work. The Mac
2290 OS X 10.4[.x] getopt() man page says
2292 In order to use getopt() to evaluate multiple sets of arguments, or to
2293 evaluate a single set of arguments multiple times, the variable optreset
2294 must be set to 1 before the second and each additional set of calls to
2295 getopt(), and the variable optind must be reinitialized.
2299 The optreset variable was added to make it possible to call the getopt()
2300 function multiple times. This is an extension to the IEEE Std 1003.2
2301 (``POSIX.2'') specification.
2303 which I think comes from one of the other BSDs.
2305 XXX - if we want to control all the command-line option errors, so
2306 that we can display them where we choose (e.g., in a window), we'd
2307 want to leave opterr as 0, and produce our own messages using optopt.
2308 We'd have to check the value of optopt to see if it's a valid option
2309 letter, in which case *presumably* the error is "this option requires
2310 an argument but none was specified", or not a valid option letter,
2311 in which case *presumably* the error is "this option isn't valid".
2312 Some versions of getopt() let you supply a option string beginning
2313 with ':', which means that getopt() will return ':' rather than '?'
2314 for "this option requires an argument but none was specified", but
2316 optind = optind_initial;
2320 g_thread_init(NULL);
2323 /* Set the current locale according to the program environment.
2324 * We haven't localized anything, but some GTK widgets are localized
2325 * (the file selection dialogue, for example).
2326 * This also sets the C-language locale to the native environment. */
2327 setlocale (LC_ALL, "");
2329 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2330 gtk_init (&argc, &argv);
2332 cf_callback_add(main_cf_callback, NULL);
2334 capture_callback_add(main_capture_callback, NULL);
2336 cf_callback_add(statusbar_cf_callback, NULL);
2338 capture_callback_add(statusbar_capture_callback, NULL);
2341 /* Arrange that if we have no console window, and a GLib message logging
2342 routine is called to log a message, we pop up a console window.
2344 We do that by inserting our own handler for all messages logged
2345 to the default domain; that handler pops up a console if necessary,
2346 and then calls the default handler. */
2348 /* We might want to have component specific log levels later ... */
2352 G_LOG_LEVEL_CRITICAL|
2353 G_LOG_LEVEL_WARNING|
2354 G_LOG_LEVEL_MESSAGE|
2357 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2359 g_log_set_handler(NULL,
2361 console_log_handler, NULL /* user_data */);
2362 g_log_set_handler(LOG_DOMAIN_MAIN,
2364 console_log_handler, NULL /* user_data */);
2367 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2369 console_log_handler, NULL /* user_data */);
2370 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2372 console_log_handler, NULL /* user_data */);
2374 /* Set the initial values in the capture options. This might be overwritten
2375 by preference settings and then again by the command line parameters. */
2376 capture_opts_init(&global_capture_opts, &cfile);
2379 /* Initialize whatever we need to allocate colors for GTK+ */
2382 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2383 filter = get_conn_cfilter();
2384 if ( *filter != '\0' ) {
2385 info_update_freq = 1000; /* Milliseconds */
2388 /* We won't come till here, if we had a "console only" command line parameter. */
2389 splash_win = splash_new("Loading Wireshark ...");
2390 if (init_progfile_dir_error != NULL) {
2391 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2392 "Can't get pathname of Wireshark: %s.\n"
2393 "It won't be possible to capture traffic.\n"
2394 "Report this to the Wireshark developers.",
2395 init_progfile_dir_error);
2396 g_free(init_progfile_dir_error);
2399 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2401 /* Register all dissectors; we must do this before checking for the
2402 "-G" flag, as the "-G" flag dumps information registered by the
2403 dissectors, and we must do it before we read the preferences, in
2404 case any dissectors register preferences. */
2405 epan_init(register_all_protocols,register_all_protocol_handoffs,
2406 splash_update, (gpointer) splash_win,
2407 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2408 write_failure_alert_box);
2410 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2412 /* Register all tap listeners; we do this before we parse the arguments,
2413 as the "-z" argument can specify a registered tap. */
2415 /* we register the plugin taps before the other taps because
2416 stats_tree taps plugins will be registered as tap listeners
2417 by stats_tree_stat.c and need to registered before that */
2420 register_all_plugin_tap_listeners();
2423 register_all_tap_listeners();
2425 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2427 /* Now register the preferences for any non-dissector modules.
2428 We must do that before we read the preferences as well. */
2429 prefs_register_modules();
2431 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2432 /* Removed thread code:
2433 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2436 /* this is to keep tap extensions updating once every 3 seconds */
2437 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2439 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2441 cap_file_init(&cfile);
2443 /* Fill in capture options with values from the preferences */
2444 prefs_to_capture_opts();
2446 /* Now get our args */
2447 while ((opt = getopt(argc, argv, optstring)) != -1) {
2449 /*** capture option specific ***/
2450 case 'a': /* autostop criteria */
2451 case 'b': /* Ringbuffer option */
2452 case 'c': /* Capture xxx packets */
2453 case 'f': /* capture filter */
2454 case 'k': /* Start capture immediately */
2455 case 'H': /* Hide capture info dialog box */
2456 case 'i': /* Use interface xxx */
2457 case 'p': /* Don't capture in promiscuous mode */
2458 #ifdef HAVE_PCAP_CREATE
2459 case 'I': /* Capture in monitor mode, if available */
2461 case 's': /* Set the snapshot (capture) length */
2462 case 'S': /* "Sync" mode: used for following file ala tail -f */
2463 case 'w': /* Write to capture file xxx */
2464 case 'y': /* Set the pcap data link type */
2465 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2466 case 'B': /* Buffer size */
2467 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2469 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2475 capture_option_specified = TRUE;
2480 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2481 case 'K': /* Kerberos keytab file */
2482 read_keytab_file(optarg);
2486 /*** all non capture option specific ***/
2488 /* Configuration profile settings were already processed just ignore them this time*/
2493 case 'j': /* Search backwards for a matching packet from filter in option J */
2494 jump_backwards = TRUE;
2496 case 'g': /* Go to packet with the given packet number */
2497 go_to_packet = get_positive_int(optarg, "go to packet");
2499 case 'J': /* Jump to the first packet which matches the filter criteria */
2502 case 'l': /* Automatic scrolling in live capture mode */
2504 auto_scroll_live = TRUE;
2506 capture_option_specified = TRUE;
2510 case 'L': /* Print list of link-layer types and exit */
2512 list_link_layer_types = TRUE;
2514 capture_option_specified = TRUE;
2518 case 'm': /* Fixed-width font for the display */
2519 g_free(prefs_p->gui_font_name);
2520 prefs_p->gui_font_name = g_strdup(optarg);
2522 case 'n': /* No name resolution */
2523 gbl_resolv_flags = RESOLV_NONE;
2525 case 'N': /* Select what types of addresses/port #s to resolve */
2526 if (gbl_resolv_flags == RESOLV_ALL)
2527 gbl_resolv_flags = RESOLV_NONE;
2528 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2529 if (badopt != '\0') {
2530 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2535 case 'o': /* Override preference from command line */
2536 switch (prefs_set_pref(optarg)) {
2539 case PREFS_SET_SYNTAX_ERR:
2540 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2543 case PREFS_SET_NO_SUCH_PREF:
2544 /* not a preference, might be a recent setting */
2545 switch (recent_set_arg(optarg)) {
2548 case PREFS_SET_SYNTAX_ERR:
2549 /* shouldn't happen, checked already above */
2550 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2553 case PREFS_SET_NO_SUCH_PREF:
2554 case PREFS_SET_OBSOLETE:
2555 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2560 g_assert_not_reached();
2563 case PREFS_SET_OBSOLETE:
2564 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2569 g_assert_not_reached();
2573 /* Path settings were already processed just ignore them this time*/
2575 case 'r': /* Read capture file xxx */
2576 /* We may set "last_open_dir" to "cf_name", and if we change
2577 "last_open_dir" later, we free the old value, so we have to
2578 set "cf_name" to something that's been allocated. */
2579 cf_name = g_strdup(optarg);
2581 case 'R': /* Read file filter */
2584 case 't': /* Time stamp type */
2585 if (strcmp(optarg, "r") == 0)
2586 timestamp_set_type(TS_RELATIVE);
2587 else if (strcmp(optarg, "a") == 0)
2588 timestamp_set_type(TS_ABSOLUTE);
2589 else if (strcmp(optarg, "ad") == 0)
2590 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2591 else if (strcmp(optarg, "d") == 0)
2592 timestamp_set_type(TS_DELTA);
2593 else if (strcmp(optarg, "dd") == 0)
2594 timestamp_set_type(TS_DELTA_DIS);
2595 else if (strcmp(optarg, "e") == 0)
2596 timestamp_set_type(TS_EPOCH);
2597 else if (strcmp(optarg, "u") == 0)
2598 timestamp_set_type(TS_UTC);
2599 else if (strcmp(optarg, "ud") == 0)
2600 timestamp_set_type(TS_UTC_WITH_DATE);
2602 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2603 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2604 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2608 case 'u': /* Seconds type */
2609 if (strcmp(optarg, "s") == 0)
2610 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2611 else if (strcmp(optarg, "hms") == 0)
2612 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2614 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2615 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2620 /* ext ops were already processed just ignore them this time*/
2623 /* We won't call the init function for the stat this soon
2624 as it would disallow MATE's fields (which are registered
2625 by the preferences set callback) from being used as
2626 part of a tap filter. Instead, we just add the argument
2627 to a list of stat arguments. */
2628 if (!process_stat_cmd_arg(optarg)) {
2629 cmdarg_err("Invalid -z argument.");
2630 cmdarg_err_cont(" -z argument must be one of :");
2631 list_stat_cmd_args();
2636 case '?': /* Bad flag - print usage message */
2645 if (cf_name != NULL) {
2647 * Input file name specified with "-r" *and* specified as a regular
2648 * command-line argument.
2650 cmdarg_err("File name specified both with -r and regular argument");
2654 * Input file name not specified with "-r", and a command-line argument
2655 * was specified; treat it as the input file name.
2657 * Yes, this is different from tshark, where non-flag command-line
2658 * arguments are a filter, but this works better on GUI desktops
2659 * where a command can be specified to be run to open a particular
2660 * file - yes, you could have "-r" as the last part of the command,
2661 * but that's a bit ugly.
2663 cf_name = g_strdup(argv[0]);
2671 * Extra command line arguments were specified; complain.
2673 cmdarg_err("Invalid argument: %s", argv[0]);
2678 #ifndef HAVE_LIBPCAP
2679 if (capture_option_specified) {
2680 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2688 if (start_capture && list_link_layer_types) {
2689 /* Specifying *both* is bogus. */
2690 cmdarg_err("You can't specify both -L and a live capture.");
2694 if (list_link_layer_types) {
2695 /* We're supposed to list the link-layer types for an interface;
2696 did the user also specify a capture file to be read? */
2698 /* Yes - that's bogus. */
2699 cmdarg_err("You can't specify -L and a capture file to be read.");
2702 /* No - did they specify a ring buffer option? */
2703 if (global_capture_opts.multi_files_on) {
2704 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2708 /* We're supposed to do a live capture; did the user also specify
2709 a capture file to be read? */
2710 if (start_capture && cf_name) {
2711 /* Yes - that's bogus. */
2712 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2716 /* No - was the ring buffer option specified and, if so, does it make
2718 if (global_capture_opts.multi_files_on) {
2719 /* Ring buffer works only under certain conditions:
2720 a) ring buffer does not work with temporary files;
2721 b) real_time_mode and multi_files_on are mutually exclusive -
2722 real_time_mode takes precedence;
2723 c) it makes no sense to enable the ring buffer if the maximum
2724 file size is set to "infinite". */
2725 if (global_capture_opts.save_file == NULL) {
2726 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2727 global_capture_opts.multi_files_on = FALSE;
2729 /* if (global_capture_opts.real_time_mode) {
2730 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2731 global_capture_opts.multi_files_on = FALSE;
2733 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2734 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2735 /* XXX - this must be redesigned as the conditions changed */
2736 /* global_capture_opts.multi_files_on = FALSE;*/
2741 if (start_capture || list_link_layer_types) {
2742 /* Did the user specify an interface to use? */
2743 if (!capture_opts_trim_iface(&global_capture_opts,
2744 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2749 if (list_link_layer_types) {
2750 /* Get the list of link-layer types for the capture devices. */
2751 if_capabilities_t *caps;
2753 interface_options interface_opts;
2755 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2757 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
2758 caps = capture_get_if_capabilities(interface_opts.name, interface_opts.monitor_mode, &err_str);
2760 cmdarg_err("%s", err_str);
2764 if (caps->data_link_types == NULL) {
2765 cmdarg_err("The capture device \"%s\" has no data link types.", interface_opts.name);
2768 capture_opts_print_if_capabilities(caps, interface_opts.name, interface_opts.monitor_mode);
2769 free_if_capabilities(caps);
2774 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2775 capture_opts_trim_ring_num_files(&global_capture_opts);
2776 #endif /* HAVE_LIBPCAP */
2778 /* Notify all registered modules that have had any of their preferences
2779 changed either from one of the preferences file or from the command
2780 line that their preferences have changed. */
2785 if ((global_capture_opts.ifaces->len > 1) && start_capture) {
2786 cmdarg_err("You specified multiple interfaces for capturing which this version of Wireshark doesn't support.");
2790 if ((global_capture_opts.ifaces->len == 0) &&
2791 (prefs.capture_device != NULL)) {
2792 GList *curr, *combo_list;
2793 gboolean found = FALSE;
2795 if_list = capture_interface_list(&err, NULL);
2796 if (g_list_length(if_list) > 0) {
2797 combo_list = build_capture_combo_list(if_list, FALSE);
2798 free_interface_list(if_list);
2799 for (curr = combo_list; curr; curr = g_list_next(curr)) {
2800 if (strcmp(curr->data, prefs.capture_device) == 0) {
2807 interface_options interface_opts;
2809 interface_opts.name = g_strdup(get_if_name(prefs.capture_device));
2810 interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
2811 interface_opts.monitor_mode = prefs_capture_device_monitor_mode(interface_opts.name);
2812 interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name);
2813 interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
2814 interface_opts.snaplen = global_capture_opts.default_options.snaplen;
2815 interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen;
2816 interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode;
2817 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2818 interface_opts.buffer_size = global_capture_opts.default_options.buffer_size;
2820 #ifdef HAVE_PCAP_REMOTE
2821 interface_opts.src_type = global_capture_opts.default_options.src_type;
2822 interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
2823 interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
2824 interface_opts.auth_type = global_capture_opts.default_options.auth_type;
2825 interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
2826 interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
2827 interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
2828 interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
2829 interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
2831 #ifdef HAVE_PCAP_SETSAMPLING
2832 interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
2833 interface_opts.sampling_param = global_capture_opts.default_options.sampling_param;
2835 g_array_insert_val(global_capture_opts.ifaces, 0, interface_opts);
2840 /* disabled protocols as per configuration file */
2841 if (gdp_path == NULL && dp_path == NULL) {
2842 set_disabled_protos_list();
2845 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2847 /* read in rc file from global and personal configuration paths. */
2848 rc_file = get_datafile_path(RC_FILE);
2849 #if GTK_CHECK_VERSION(3,0,0)
2850 /* XXX resolve later */
2852 gtk_rc_parse(rc_file);
2854 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2855 gtk_rc_parse(rc_file);
2865 /* close the splash screen, as we are going to open the main window now */
2866 splash_destroy(splash_win);
2868 /************************************************************************/
2869 /* Everything is prepared now, preferences and command line was read in */
2871 /* Pop up the main window. */
2872 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2874 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2875 recent_read_dynamic(&rf_path, &rf_open_errno);
2876 if (rf_path != NULL && rf_open_errno != 0) {
2877 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2878 "Could not open recent file\n\"%s\": %s.",
2879 rf_path, g_strerror(rf_open_errno));
2882 color_filters_enable(recent.packet_list_colorize);
2884 /* rearrange all the widgets as we now have all recent settings ready for this */
2885 main_widgets_rearrange();
2887 /* Fill in column titles. This must be done after the top level window
2890 XXX - is that still true, with fixed-width columns? */
2892 menu_recent_read_finished();
2894 menu_auto_scroll_live_changed(auto_scroll_live);
2897 switch (user_font_apply()) {
2900 case FA_FONT_NOT_RESIZEABLE:
2901 /* "user_font_apply()" popped up an alert box. */
2902 /* turn off zooming - font can't be resized */
2903 case FA_FONT_NOT_AVAILABLE:
2904 /* XXX - did we successfully load the un-zoomed version earlier?
2905 If so, this *probably* means the font is available, but not at
2906 this particular zoom level, but perhaps some other failure
2907 occurred; I'm not sure you can determine which is the case,
2909 /* turn off zooming - zoom level is unavailable */
2911 /* in any other case than FA_SUCCESS, turn off zooming */
2912 recent.gui_zoom_level = 0;
2913 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2916 dnd_init(top_level);
2918 color_filters_init();
2921 capture_filter_init();
2924 /* the window can be sized only, if it's not already shown, so do it now! */
2925 main_load_window_geometry(top_level);
2927 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2930 GtkWidget *filter_te;
2931 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
2932 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
2934 /* Run the display filter so it goes in effect. */
2935 main_filter_packets(&cfile, dfilter, FALSE);
2938 /* If we were given the name of a capture file, read it in now;
2939 we defer it until now, so that, if we can't open it, and pop
2940 up an alert box, the alert box is more likely to come up on
2941 top of the main window - but before the preference-file-error
2942 alert box, so, if we get one of those, it's more likely to come
2945 show_main_window(TRUE);
2946 check_and_warn_user_startup(cf_name);
2947 if (rfilter != NULL) {
2948 if (!dfilter_compile(rfilter, &rfcode)) {
2949 bad_dfilter_alert_box(rfilter);
2950 rfilter_parse_failed = TRUE;
2953 if (!rfilter_parse_failed) {
2954 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2955 /* "cf_open()" succeeded, so it closed the previous
2956 capture file, and thus destroyed any previous read filter
2957 attached to "cf". */
2959 cfile.rfcode = rfcode;
2960 /* Open stat windows; we do so after creating the main window,
2961 to avoid GTK warnings, and after successfully opening the
2962 capture file, so we know we have something to compute stats
2963 on, and after registering all dissectors, so that MATE will
2964 have registered its field array and we can have a tap filter
2965 with one of MATE's late-registered fields as part of the
2967 start_requested_stats();
2969 /* Read the capture file. */
2970 switch (cf_read(&cfile, FALSE)) {
2974 /* Just because we got an error, that doesn't mean we were unable
2975 to read any of the file; we handle what we could get from the
2977 /* if the user told us to jump to a specific packet, do it now */
2978 if(go_to_packet != 0) {
2979 /* Jump to the specified frame number, kept for backward
2981 cf_goto_frame(&cfile, go_to_packet);
2982 } else if (jfilter != NULL) {
2983 /* try to compile given filter */
2984 if (!dfilter_compile(jfilter, &jump_to_filter)) {
2985 bad_dfilter_alert_box(jfilter);
2987 /* Filter ok, jump to the first packet matching the filter
2988 conditions. Default search direction is forward, but if
2989 option d was given, search backwards */
2990 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
2995 case CF_READ_ABORTED:
3001 /* If the filename is not the absolute path, prepend the current dir. This happens
3002 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3003 if (!g_path_is_absolute(cf_name)) {
3004 char *old_cf_name = cf_name;
3005 char *pwd = g_get_current_dir();
3006 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3007 g_free(old_cf_name);
3011 /* Save the name of the containing directory specified in the
3012 path name, if any; we can write over cf_name, which is a
3013 good thing, given that "get_dirname()" does write over its
3015 s = get_dirname(cf_name);
3016 set_last_open_dir(s);
3021 dfilter_free(rfcode);
3022 cfile.rfcode = NULL;
3023 show_main_window(FALSE);
3024 /* Don't call check_and_warn_user_startup(): we did it above */
3025 set_menus_for_capture_in_progress(FALSE);
3026 set_capture_if_dialog_for_capture_in_progress(FALSE);
3031 if (start_capture) {
3032 if (global_capture_opts.save_file != NULL) {
3033 /* Save the directory name for future file dialogs. */
3034 /* (get_dirname overwrites filename) */
3035 s = get_dirname(g_strdup(global_capture_opts.save_file));
3036 set_last_open_dir(s);
3039 /* "-k" was specified; start a capture. */
3040 show_main_window(TRUE);
3041 check_and_warn_user_startup(cf_name);
3042 if (capture_start(&global_capture_opts)) {
3043 /* The capture started. Open stat windows; we do so after creating
3044 the main window, to avoid GTK warnings, and after successfully
3045 opening the capture file, so we know we have something to compute
3046 stats on, and after registering all dissectors, so that MATE will
3047 have registered its field array and we can have a tap filter with
3048 one of MATE's late-registered fields as part of the filter. */
3049 start_requested_stats();
3052 show_main_window(FALSE);
3053 check_and_warn_user_startup(cf_name);
3054 set_menus_for_capture_in_progress(FALSE);
3055 set_capture_if_dialog_for_capture_in_progress(FALSE);
3058 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3059 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3060 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3062 #else /* HAVE_LIBPCAP */
3063 show_main_window(FALSE);
3064 check_and_warn_user_startup(cf_name);
3065 set_menus_for_capture_in_progress(FALSE);
3066 set_capture_if_dialog_for_capture_in_progress(FALSE);
3067 #endif /* HAVE_LIBPCAP */
3070 /* register our pid if we are being run from a U3 device */
3073 profile_store_persconffiles (FALSE);
3075 #ifdef HAVE_GTKOSXAPPLICATION
3076 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3077 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3078 gtk_osxapplication_ready(theApp);
3081 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3083 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3085 /* ... back from GTK, we're going down now! */
3087 /* deregister our pid */
3088 u3_deregister_pid();
3092 AirPDcapDestroyContext(&airpdcap_ctx);
3095 /* hide the (unresponsive) main window, while asking the user to close the console window */
3096 gtk_widget_hide(top_level);
3098 #ifdef HAVE_GTKOSXAPPLICATION
3099 g_object_unref(theApp);
3102 /* Shutdown windows sockets */
3105 /* For some unknown reason, the "atexit()" call in "create_console()"
3106 doesn't arrange that "destroy_console()" be called when we exit,
3107 so we call it here if a console was created. */
3116 /* We build this as a GUI subsystem application on Win32, so
3117 "WinMain()", not "main()", gets called.
3119 Hack shamelessly stolen from the Win32 port of the GIMP. */
3121 #define _stdcall __attribute__((stdcall))
3125 WinMain (struct HINSTANCE__ *hInstance,
3126 struct HINSTANCE__ *hPrevInstance,
3130 INITCOMMONCONTROLSEX comm_ctrl;
3133 * Initialize our DLL search path. MUST be called before LoadLibrary
3136 ws_init_dll_search_path();
3138 /* Initialize our controls. Required for native Windows file dialogs. */
3139 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3140 comm_ctrl.dwSize = sizeof(comm_ctrl);
3141 /* Includes the animate, header, hot key, list view, progress bar,
3142 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3145 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3146 InitCommonControlsEx(&comm_ctrl);
3148 /* RichEd20.DLL is needed for filter entries. */
3149 ws_load_library("riched20.dll");
3151 has_console = FALSE;
3152 console_wait = FALSE;
3153 return main (__argc, __argv);
3156 /* The code to create and desstroy console windows should not be necessary,
3157 at least as I read the GLib source code, as it looks as if GLib is, on
3158 Win32, *supposed* to create a console window into which to display its
3161 That doesn't happen, however. I suspect there's something completely
3162 broken about that code in GLib-for-Win32, and that it may be related
3163 to the breakage that forces us to just call "printf()" on the message
3164 rather than passing the message on to "g_log_default_handler()"
3165 (which is the routine that does the aforementioned non-functional
3166 console window creation). */
3169 * If this application has no console window to which its standard output
3170 * would go, create one.
3173 create_console(void)
3175 if (stdin_capture) {
3176 /* We've been handed "-i -". Don't mess with stdio. */
3181 /* We have no console to which to print the version string, so
3182 create one and make it the standard input, output, and error. */
3185 * See if we have an existing console (i.e. we were run from a
3188 if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3189 if (AllocConsole()) {
3190 console_wait = TRUE;
3191 SetConsoleTitle(_T("Wireshark Debug Console"));
3193 return; /* couldn't create console */
3197 ws_freopen("CONIN$", "r", stdin);
3198 ws_freopen("CONOUT$", "w", stdout);
3199 ws_freopen("CONOUT$", "w", stderr);
3200 fprintf(stdout, "\n");
3201 fprintf(stderr, "\n");
3203 /* Now register "destroy_console()" as a routine to be called just
3204 before the application exits, so that we can destroy the console
3205 after the user has typed a key (so that the console doesn't just
3206 disappear out from under them, giving the user no chance to see
3207 the message(s) we put in there). */
3208 atexit(destroy_console);
3210 /* Well, we have a console now. */
3216 destroy_console(void)
3219 printf("\n\nPress any key to exit\n");
3228 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3229 const char *message, gpointer user_data _U_)
3236 /* ignore log message, if log_level isn't interesting based
3237 upon the console log preferences.
3238 If the preferences haven't been loaded loaded yet, display the
3241 The default console_log_level preference value is such that only
3242 ERROR, CRITICAL and WARNING level messages are processed;
3243 MESSAGE, INFO and DEBUG level messages are ignored. */
3244 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3245 prefs.console_log_level != 0) {
3250 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3251 /* the user wants a console or the application will terminate immediately */
3255 /* For some unknown reason, the above doesn't appear to actually cause
3256 anything to be sent to the standard output, so we'll just splat the
3257 message out directly, just to make sure it gets out. */
3259 switch(log_level & G_LOG_LEVEL_MASK) {
3260 case G_LOG_LEVEL_ERROR:
3263 case G_LOG_LEVEL_CRITICAL:
3266 case G_LOG_LEVEL_WARNING:
3269 case G_LOG_LEVEL_MESSAGE:
3272 case G_LOG_LEVEL_INFO:
3275 case G_LOG_LEVEL_DEBUG:
3279 fprintf(stderr, "unknown log_level %u\n", log_level);
3281 g_assert_not_reached();
3284 /* create a "timestamp" */
3286 today = localtime(&curr);
3288 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3289 today->tm_hour, today->tm_min, today->tm_sec,
3290 log_domain != NULL ? log_domain : "",
3293 if(log_level & G_LOG_LEVEL_ERROR) {
3294 /* wait for a key press before the following error handler will terminate the program
3295 this way the user at least can read the error message */
3296 printf("\n\nPress any key to exit\n");
3300 /* XXX - on UN*X, should we just use g_log_default_handler()?
3301 We want the error messages to go to the standard output;
3302 on Mac OS X, that will cause them to show up in various
3303 per-user logs accessible through Console (details depend
3304 on whether you're running 10.0 through 10.4 or running
3305 10.5 and later), and, on other UN*X desktop environments,
3306 if they don't show up in some form of console log, that's
3307 a deficiency in that desktop environment. (Too bad
3308 Windows doesn't set the standard output and error for
3309 GUI apps to something that shows up in such a log.) */
3310 g_log_default_handler(log_domain, log_level, message, user_data);
3317 * Helper for main_widgets_rearrange()
3319 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3320 gtk_container_remove(GTK_CONTAINER(data), widget);
3323 static GtkWidget *main_widget_layout(gint layout_content)
3325 switch(layout_content) {
3326 case(layout_pane_content_none):
3328 case(layout_pane_content_plist):
3330 case(layout_pane_content_pdetails):
3332 case(layout_pane_content_pbytes):
3333 return byte_nb_ptr_gbl;
3335 g_assert_not_reached();
3342 * Rearrange the main window widgets
3344 void main_widgets_rearrange(void) {
3345 GtkWidget *first_pane_widget1, *first_pane_widget2;
3346 GtkWidget *second_pane_widget1, *second_pane_widget2;
3347 gboolean split_top_left;
3349 /* be a bit faster */
3350 gtk_widget_hide(main_vbox);
3352 /* be sure we don't lose a widget while rearranging */
3353 g_object_ref(G_OBJECT(menubar));
3354 g_object_ref(G_OBJECT(main_tb));
3355 g_object_ref(G_OBJECT(filter_tb));
3357 g_object_ref(G_OBJECT(airpcap_tb));
3359 g_object_ref(G_OBJECT(pkt_scrollw));
3360 g_object_ref(G_OBJECT(tv_scrollw));
3361 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3362 g_object_ref(G_OBJECT(statusbar));
3363 g_object_ref(G_OBJECT(main_pane_v1));
3364 g_object_ref(G_OBJECT(main_pane_v2));
3365 g_object_ref(G_OBJECT(main_pane_h1));
3366 g_object_ref(G_OBJECT(main_pane_h2));
3367 g_object_ref(G_OBJECT(welcome_pane));
3369 /* empty all containers participating */
3370 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3371 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3372 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3373 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3374 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3376 statusbar_widgets_emptying(statusbar);
3378 /* add the menubar always at the top */
3379 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3382 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3384 /* filter toolbar in toolbar area */
3385 if (!prefs.filter_toolbar_show_in_statusbar) {
3386 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3390 /* airpcap toolbar */
3391 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3394 /* fill the main layout panes */
3395 switch(prefs.gui_layout_type) {
3396 case(layout_type_5):
3397 main_first_pane = main_pane_v1;
3398 main_second_pane = main_pane_v2;
3399 split_top_left = FALSE;
3401 case(layout_type_2):
3402 main_first_pane = main_pane_v1;
3403 main_second_pane = main_pane_h1;
3404 split_top_left = FALSE;
3406 case(layout_type_1):
3407 main_first_pane = main_pane_v1;
3408 main_second_pane = main_pane_h1;
3409 split_top_left = TRUE;
3411 case(layout_type_4):
3412 main_first_pane = main_pane_h1;
3413 main_second_pane = main_pane_v1;
3414 split_top_left = FALSE;
3416 case(layout_type_3):
3417 main_first_pane = main_pane_h1;
3418 main_second_pane = main_pane_v1;
3419 split_top_left = TRUE;
3421 case(layout_type_6):
3422 main_first_pane = main_pane_h1;
3423 main_second_pane = main_pane_h2;
3424 split_top_left = FALSE;
3427 main_first_pane = NULL;
3428 main_second_pane = NULL;
3429 split_top_left = FALSE;
3430 g_assert_not_reached();
3432 if (split_top_left) {
3433 first_pane_widget1 = main_second_pane;
3434 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3435 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3436 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3438 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3439 first_pane_widget2 = main_second_pane;
3440 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3441 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3443 if (first_pane_widget1 != NULL)
3444 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3445 if (first_pane_widget2 != NULL)
3446 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3447 if (second_pane_widget1 != NULL)
3448 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3449 if (second_pane_widget2 != NULL)
3450 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3452 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3455 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3458 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3460 /* filter toolbar in statusbar hbox */
3461 if (prefs.filter_toolbar_show_in_statusbar) {
3462 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3465 /* statusbar widgets */
3466 statusbar_widgets_pack(statusbar);
3468 /* hide widgets on users recent settings */
3469 main_widgets_show_or_hide();
3471 gtk_widget_show(main_vbox);
3475 is_widget_visible(GtkWidget *widget, gpointer data)
3477 gboolean *is_visible = data;
3480 if (gtk_widget_get_visible(widget))
3487 main_widgets_show_or_hide(void)
3489 gboolean main_second_pane_show;
3491 if (recent.main_toolbar_show) {
3492 gtk_widget_show(main_tb);
3494 gtk_widget_hide(main_tb);
3497 statusbar_widgets_show_or_hide(statusbar);
3499 if (recent.filter_toolbar_show) {
3500 gtk_widget_show(filter_tb);
3502 gtk_widget_hide(filter_tb);
3506 if (recent.airpcap_toolbar_show) {
3507 gtk_widget_show(airpcap_tb);
3509 gtk_widget_hide(airpcap_tb);
3513 if (recent.packet_list_show && have_capture_file) {
3514 gtk_widget_show(pkt_scrollw);
3516 gtk_widget_hide(pkt_scrollw);
3519 if (recent.tree_view_show && have_capture_file) {
3520 gtk_widget_show(tv_scrollw);
3522 gtk_widget_hide(tv_scrollw);
3525 if (recent.byte_view_show && have_capture_file) {
3526 gtk_widget_show(byte_nb_ptr_gbl);
3528 gtk_widget_hide(byte_nb_ptr_gbl);
3531 if (have_capture_file) {
3532 gtk_widget_show(main_first_pane);
3534 gtk_widget_hide(main_first_pane);
3538 * Is anything in "main_second_pane" visible?
3539 * If so, show it, otherwise hide it.
3541 main_second_pane_show = FALSE;
3542 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3543 &main_second_pane_show);
3544 if (main_second_pane_show) {
3545 gtk_widget_show(main_second_pane);
3547 gtk_widget_hide(main_second_pane);
3550 if (!have_capture_file) {
3552 gtk_widget_show(welcome_pane);
3556 gtk_widget_hide(welcome_pane);
3561 /* called, when the window state changes (minimized, maximized, ...) */
3563 window_state_event_cb (GtkWidget *widget _U_,
3567 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3569 if( (event->type) == (GDK_WINDOW_STATE)) {
3570 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3571 /* we might have dialogs popped up while we where iconified,
3573 display_queued_messages();
3581 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3583 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3585 if (event->keyval == GDK_F8) {
3586 new_packet_list_next();
3588 } else if (event->keyval == GDK_F7) {
3589 new_packet_list_prev();
3591 } else if (event->state & NO_SHIFT_MOD_MASK) {
3592 return FALSE; /* Skip control, alt, and other modifiers */
3594 * A comment in gdkkeysyms.h says that it's autogenerated from
3595 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3596 * don't explicitly say so, isprint() should work as expected
3599 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3600 /* Forward the keypress on to the display filter entry */
3601 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3602 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3603 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3611 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3613 GtkAccelGroup *accel;
3616 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3617 set_main_window_name("The Wireshark Network Analyzer");
3619 gtk_widget_set_name(top_level, "main window");
3620 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3622 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3623 G_CALLBACK(window_state_event_cb), NULL);
3624 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3625 G_CALLBACK(top_level_key_pressed_cb), NULL );
3627 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3628 main_vbox = gtk_vbox_new(FALSE, 1);
3629 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3630 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3631 gtk_widget_show(main_vbox);
3634 menubar = main_menu_new(&accel);
3636 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3637 /* Mac OS X native menus are created and displayed by main_menu_new() */
3638 if(!prefs_p->gui_macosx_style) {
3640 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3641 gtk_widget_show(menubar);
3642 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3647 main_tb = toolbar_new();
3648 gtk_widget_show (main_tb);
3650 /* Filter toolbar */
3651 filter_tb = filter_toolbar_new();
3654 pkt_scrollw = new_packet_list_create();
3655 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3656 gtk_widget_show_all(pkt_scrollw);
3659 tv_scrollw = main_tree_view_new(prefs_p, &tree_view_gbl);
3660 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3661 gtk_widget_show(tv_scrollw);
3663 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3664 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3665 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3666 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3667 gtk_widget_show(tree_view_gbl);
3670 byte_nb_ptr_gbl = byte_view_new();
3671 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3672 gtk_widget_show(byte_nb_ptr_gbl);
3674 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3675 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3677 /* Panes for the packet list, tree, and byte view */
3678 main_pane_v1 = gtk_vpaned_new();
3679 gtk_widget_show(main_pane_v1);
3680 main_pane_v2 = gtk_vpaned_new();
3681 gtk_widget_show(main_pane_v2);
3682 main_pane_h1 = gtk_hpaned_new();
3683 gtk_widget_show(main_pane_h1);
3684 main_pane_h2 = gtk_hpaned_new();
3685 gtk_widget_show(main_pane_h2);
3687 airpcap_tb = airpcap_toolbar_new();
3688 gtk_widget_show(airpcap_tb);
3691 statusbar = statusbar_new();
3692 gtk_widget_show(statusbar);
3694 /* Pane for the welcome screen */
3695 welcome_pane = welcome_new();
3696 gtk_widget_show(welcome_pane);
3700 show_main_window(gboolean doing_work)
3702 main_set_for_capture_file(doing_work);
3704 /*** we have finished all init things, show the main window ***/
3705 gtk_widget_show(top_level);
3707 /* the window can be maximized only, if it's visible, so do it after show! */
3708 main_load_window_geometry(top_level);
3710 /* process all pending GUI events before continue */
3711 while (gtk_events_pending()) gtk_main_iteration();
3713 /* Pop up any queued-up alert boxes. */
3714 display_queued_messages();
3716 /* Move the main window to the front, in case it isn't already there */
3717 gdk_window_raise(gtk_widget_get_window(top_level));
3720 airpcap_toolbar_show(airpcap_tb);
3721 #endif /* HAVE_AIRPCAP */
3724 /* Fill in capture options with values from the preferences */
3726 prefs_to_capture_opts(void)
3729 /* Set promiscuous mode from the preferences setting. */
3730 /* the same applies to other preferences settings as well. */
3731 global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
3732 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3733 global_capture_opts.show_info = prefs.capture_show_info;
3734 global_capture_opts.real_time_mode = prefs.capture_real_time;
3735 auto_scroll_live = prefs.capture_auto_scroll;
3736 #endif /* HAVE_LIBPCAP */
3738 /* Set the name resolution code's flags from the preferences. */
3739 gbl_resolv_flags = prefs.name_resolve;
3742 static void copy_global_profile (const gchar *profile_name)
3744 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3746 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3747 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3748 "Can't create directory\n\"%s\":\n%s.",
3749 pf_dir_path, g_strerror(errno));
3751 g_free(pf_dir_path);
3754 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3755 &pf_dir_path, &pf_dir_path2) == -1) {
3756 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3757 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3758 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3760 g_free(pf_filename);
3761 g_free(pf_dir_path);
3762 g_free(pf_dir_path2);
3766 /* Change configuration profile */
3767 void change_configuration_profile (const gchar *profile_name)
3769 char *gdp_path, *dp_path;
3773 /* First check if profile exists */
3774 if (!profile_exists(profile_name, FALSE)) {
3775 if (profile_exists(profile_name, TRUE)) {
3776 /* Copy from global profile */
3777 copy_global_profile (profile_name);
3779 /* No personal and no global profile exists */
3784 /* Then check if changing to another profile */
3785 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3789 /* Get the current geometry, before writing it to disk */
3790 main_save_window_geometry(top_level);
3792 if (profile_exists(get_profile_name(), FALSE)) {
3793 /* Write recent file for profile we are leaving, if it still exists */
3794 write_profile_recent();
3797 /* Set profile name and update the status bar */
3798 set_profile_name (profile_name);
3799 profile_bar_update ();
3800 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3802 /* Reset current preferences and apply the new */
3806 (void) read_configuration_files (&gdp_path, &dp_path);
3808 recent_read_profile_static(&rf_path, &rf_open_errno);
3809 if (rf_path != NULL && rf_open_errno != 0) {
3810 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3811 "Could not open common recent file\n\"%s\": %s.",
3812 rf_path, g_strerror(rf_open_errno));
3814 if (recent.gui_fileopen_remembered_dir &&
3815 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3816 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3818 timestamp_set_type (recent.gui_time_format);
3819 timestamp_set_seconds_type (recent.gui_seconds_format);
3820 color_filters_enable(recent.packet_list_colorize);
3822 prefs_to_capture_opts();
3824 macros_post_update();
3826 /* Update window view and redraw the toolbar */
3827 update_main_window_title();
3828 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3829 toolbar_redraw_all();
3831 /* Enable all protocols and disable from the disabled list */
3833 if (gdp_path == NULL && dp_path == NULL) {
3834 set_disabled_protos_list();
3837 /* Reload color filters */
3838 color_filters_reload();
3840 /* Reload list of interfaces on welcome page */
3841 welcome_if_panel_reload();
3843 /* Recreate the packet list according to new preferences */
3844 new_packet_list_recreate ();
3845 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3848 /* Update menus with new recent values */
3849 menu_recent_read_finished();
3851 /* Reload pane geometry, must be done after recreating the list */
3852 main_pane_load_window_geometry();
3855 /** redissect packets and update UI */
3856 void redissect_packets(void)
3858 cf_redissect_packets(&cfile);
3859 status_expert_update();