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"
166 #include "gtk/old-gtk-compat.h"
169 #include "../image/wsicon16.xpm"
170 #include "../image/wsicon32.xpm"
171 #include "../image/wsicon48.xpm"
172 #include "../image/wsicon64.xpm"
173 #include "../image/wsiconcap16.xpm"
174 #include "../image/wsiconcap32.xpm"
175 #include "../image/wsiconcap48.xpm"
180 #include "airpcap_loader.h"
181 #include "airpcap_dlg.h"
182 #include "airpcap_gui_utils.h"
185 #include <epan/crypt/airpdcap_ws.h>
188 #ifdef HAVE_GTKOSXAPPLICATION
189 #include <igemacintegration/gtkosxapplication.h>
193 * Files under personal and global preferences directories in which
194 * GTK settings for Wireshark are stored.
196 #define RC_FILE "gtkrc"
200 /* "exported" main widgets */
201 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
203 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
204 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
205 static GtkWidget *main_first_pane, *main_second_pane;
207 /* internally used widgets */
208 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
211 GtkWidget *airpcap_tb;
212 int airpcap_dll_ret_val = -1;
215 GString *comp_info_str, *runtime_info_str;
217 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
219 static guint tap_update_timer_id;
222 static gboolean has_console; /* TRUE if app has console */
223 static gboolean console_wait; /* "Press any key..." */
224 static void destroy_console(void);
225 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
227 static void console_log_handler(const char *log_domain,
228 GLogLevelFlags log_level, const char *message, gpointer user_data);
231 capture_options global_capture_opts;
235 static void create_main_window(gint, gint, gint, e_prefs*);
236 static void show_main_window(gboolean);
237 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
238 static void main_save_window_geometry(GtkWidget *widget);
241 /* Match selected byte pattern */
243 match_selected_cb_do(gpointer data, int action, gchar *text)
245 GtkWidget *filter_te;
246 char *cur_filter, *new_filter;
248 if ((!text) || (0 == strlen(text))) {
249 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
254 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
257 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
259 switch (action&MATCH_SELECTED_MASK) {
261 case MATCH_SELECTED_REPLACE:
262 new_filter = g_strdup(text);
265 case MATCH_SELECTED_AND:
266 if ((!cur_filter) || (0 == strlen(cur_filter)))
267 new_filter = g_strdup(text);
269 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
272 case MATCH_SELECTED_OR:
273 if ((!cur_filter) || (0 == strlen(cur_filter)))
274 new_filter = g_strdup(text);
276 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
279 case MATCH_SELECTED_NOT:
280 new_filter = g_strconcat("!(", text, ")", NULL);
283 case MATCH_SELECTED_AND_NOT:
284 if ((!cur_filter) || (0 == strlen(cur_filter)))
285 new_filter = g_strconcat("!(", text, ")", NULL);
287 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
290 case MATCH_SELECTED_OR_NOT:
291 if ((!cur_filter) || (0 == strlen(cur_filter)))
292 new_filter = g_strconcat("!(", text, ")", NULL);
294 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
298 g_assert_not_reached();
303 /* Free up the copy we got of the old filter text. */
306 /* Don't change the current display filter if we only want to copy the filter */
307 if (action&MATCH_SELECTED_COPY_ONLY) {
308 GString *gtk_text_str = g_string_new("");
309 g_string_append(gtk_text_str, new_filter);
310 copy_to_clipboard(gtk_text_str);
311 g_string_free(gtk_text_str, TRUE);
313 /* create a new one and set the display filter entry accordingly */
314 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
316 /* Run the display filter so it goes in effect. */
317 if (action&MATCH_SELECTED_APPLY_NOW)
318 main_filter_packets(&cfile, new_filter, FALSE);
321 /* Free up the new filter text. */
326 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
330 if (cfile.finfo_selected) {
331 filter = proto_construct_match_selected_string(cfile.finfo_selected,
333 match_selected_cb_do((data ? data : w), action, filter);
338 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
342 if (cfile.finfo_selected) {
343 filter = proto_construct_match_selected_string(cfile.finfo_selected,
345 if ((!filter) || (0 == strlen(filter))) {
346 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
347 "Could not acquire information to build a filter!\n"
348 "Try expanding or choosing another item.");
353 color_display_with_filter(filter);
356 color_filters_reset_tmp();
358 color_filters_set_tmp(filt_nr,filter, FALSE);
360 new_packet_list_colorize_packets();
366 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
368 gchar *selected_proto_url;
369 gchar *proto_abbrev = data;
374 if (cfile.finfo_selected) {
375 /* open wiki page using the protocol abbreviation */
376 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
377 browser_open_url(selected_proto_url);
378 g_free(selected_proto_url);
381 case(ESD_BTN_CANCEL):
384 g_assert_not_reached();
390 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
393 const gchar *proto_abbrev;
397 if (cfile.finfo_selected) {
398 /* convert selected field to protocol abbreviation */
399 /* XXX - could this conversion be simplified? */
400 field_id = cfile.finfo_selected->hfinfo->id;
401 /* if the selected field isn't a protocol, get it's parent */
402 if(!proto_registrar_is_protocol(field_id)) {
403 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
406 proto_abbrev = proto_registrar_get_abbrev(field_id);
408 if (!proto_is_private(field_id)) {
409 /* ask the user if the wiki page really should be opened */
410 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
411 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
413 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
415 "The Wireshark Wiki is a collaborative approach to provide information "
416 "about Wireshark in several ways (not limited to protocol specifics).\n"
418 "This Wiki is new, so the page of the selected protocol "
419 "may not exist and/or may not contain valuable information.\n"
421 "As everyone can edit the Wiki and add new content (or extend existing), "
422 "you are encouraged to add information if you can.\n"
424 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
426 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
427 "which will save you a lot of editing and will give a consistent look over the pages.",
428 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
429 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
431 /* appologize to the user that the wiki page cannot be opened */
432 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
433 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
435 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
437 "Since this is a private protocol, such information is not available in "
438 "a public wiki. Therefore this wiki entry is blocked.\n"
440 "Sorry for the inconvenience.\n",
441 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
446 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
448 gchar *selected_proto_url;
449 gchar *proto_abbrev = data;
453 if (cfile.finfo_selected) {
454 /* open reference page using the protocol abbreviation */
455 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
456 browser_open_url(selected_proto_url);
457 g_free(selected_proto_url);
460 case(ESD_BTN_CANCEL):
463 g_assert_not_reached();
468 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
471 const gchar *proto_abbrev;
475 if (cfile.finfo_selected) {
476 /* convert selected field to protocol abbreviation */
477 /* XXX - could this conversion be simplified? */
478 field_id = cfile.finfo_selected->hfinfo->id;
479 /* if the selected field isn't a protocol, get it's parent */
480 if(!proto_registrar_is_protocol(field_id)) {
481 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
484 proto_abbrev = proto_registrar_get_abbrev(field_id);
486 if (!proto_is_private(field_id)) {
487 /* ask the user if the wiki page really should be opened */
488 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
489 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
491 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
493 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
494 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
496 /* appologize to the user that the wiki page cannot be opened */
497 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
498 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
500 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
502 "Since this is a private protocol, such information is not available on "
503 "a public website. Therefore this filter entry is blocked.\n"
505 "Sorry for the inconvenience.\n",
506 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
512 is_address_column (gint column)
514 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
515 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
516 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
517 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
518 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
527 get_ip_address_list_from_packet_list_row(gpointer data)
529 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
530 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
533 GList *addr_list = NULL;
535 fdata = (frame_data *) new_packet_list_get_row_data(row);
540 if (!cf_read_frame (&cfile, fdata))
541 return NULL; /* error reading the frame */
543 epan_dissect_init(&edt, FALSE, FALSE);
544 col_custom_prime_edt(&edt, &cfile.cinfo);
546 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
547 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
549 /* First check selected column */
550 if (is_address_column (column)) {
551 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
554 for (col = 0; col < cfile.cinfo.num_cols; col++) {
555 /* Then check all columns except the selected */
556 if ((col != column) && (is_address_column (col))) {
557 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
561 epan_dissect_cleanup(&edt);
568 get_filter_from_packet_list_row_and_column(gpointer data)
570 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
571 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
575 fdata = (frame_data *) new_packet_list_get_row_data(row);
580 if (!cf_read_frame(&cfile, fdata))
581 return NULL; /* error reading the frame */
582 /* proto tree, visible. We need a proto tree if there's custom columns */
583 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
584 col_custom_prime_edt(&edt, &cfile.cinfo);
586 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
588 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
590 if ((cfile.cinfo.col_custom_occurrence[column]) ||
591 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
593 /* Only construct the filter when a single occurrence is displayed
594 * otherwise we might end up with a filter like "ip.proto==1,6".
596 * Or do we want to be able to filter on multiple occurrences so that
597 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
600 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
601 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
602 /* leak a little but safer than ep_ here */
603 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
604 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
605 if (hfi->parent == -1) {
607 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
608 } else if (hfi->type == FT_STRING) {
609 /* Custom string, add quotes */
610 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
611 cfile.cinfo.col_expr.col_expr_val[column]);
615 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
616 cfile.cinfo.col_expr.col_expr_val[column]);
621 epan_dissect_cleanup(&edt);
628 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
630 match_selected_cb_do(data,
632 get_filter_from_packet_list_row_and_column(data));
635 /* This function allows users to right click in the details window and copy the text
636 * information to the operating systems clipboard.
638 * We first check to see if a string representation is setup in the tree and then
639 * read the string. If not available then we try to grab the value. If all else
640 * fails we display a message to the user to indicate the copy could not be completed.
643 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
645 GString *gtk_text_str = g_string_new("");
646 char labelstring[256];
647 char *stringpointer = labelstring;
651 case COPY_SELECTED_DESCRIPTION:
652 if (cfile.finfo_selected->rep &&
653 strlen (cfile.finfo_selected->rep->representation) > 0) {
654 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
657 case COPY_SELECTED_FIELDNAME:
658 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
659 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
662 case COPY_SELECTED_VALUE:
663 if (cfile.edt !=0 ) {
664 g_string_append(gtk_text_str,
665 get_node_field_value(cfile.finfo_selected, cfile.edt));
672 if (gtk_text_str->len == 0) {
673 /* If no representation then... Try to read the value */
674 proto_item_fill_label(cfile.finfo_selected, stringpointer);
675 g_string_append(gtk_text_str, stringpointer);
678 if (gtk_text_str->len == 0) {
679 /* Could not get item so display error msg */
680 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
682 /* Copy string to clipboard */
683 copy_to_clipboard(gtk_text_str);
685 g_string_free(gtk_text_str, TRUE); /* Free the memory */
689 /* mark as reference time frame */
691 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
695 frame->flags.ref_time=1;
696 cfile.ref_time_count++;
698 frame->flags.ref_time=0;
699 cfile.ref_time_count--;
701 cf_reftime_packets(&cfile);
702 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
703 new_packet_list_freeze();
704 cfile.displayed_count--;
705 new_packet_list_recreate_visible_rows();
706 new_packet_list_thaw();
708 new_packet_list_queue_draw();
712 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
716 timestamp_set_type(TS_RELATIVE);
717 recent.gui_time_format = TS_RELATIVE;
718 cf_timestamp_auto_precision(&cfile);
719 new_packet_list_queue_draw();
724 g_assert_not_reached();
727 if (cfile.current_frame) {
728 set_frame_reftime(!cfile.current_frame->flags.ref_time,
729 cfile.current_frame, cfile.current_row);
735 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
737 static GtkWidget *reftime_dialog = NULL;
741 if (cfile.current_frame) {
742 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
743 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
744 "%sSwitch to the appropriate Time Display Format?%s\n\n"
745 "Time References don't work well with the currently selected Time Display Format.\n\n"
746 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
747 simple_dialog_primary_start(), simple_dialog_primary_end());
748 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
750 set_frame_reftime(!cfile.current_frame->flags.ref_time,
751 cfile.current_frame, cfile.current_row);
755 case REFTIME_FIND_NEXT:
756 cf_find_packet_time_reference(&cfile, SD_FORWARD);
758 case REFTIME_FIND_PREV:
759 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
765 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
767 cf_find_packet_marked(&cfile, SD_FORWARD);
771 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
773 cf_find_packet_marked(&cfile, SD_BACKWARD);
777 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
780 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
782 gboolean has_blurb = FALSE;
783 guint length = 0, byte_len;
784 GtkWidget *byte_view;
785 const guint8 *byte_data;
790 /* if nothing is selected */
791 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
794 * Which byte view is displaying the current protocol tree
797 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
798 if (byte_view == NULL)
801 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
802 if (byte_data == NULL)
805 cf_unselect_field(&cfile);
806 packet_hex_print(byte_view, byte_data,
807 cfile.current_frame, NULL, byte_len);
808 proto_help_menu_modify(sel, &cfile);
811 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
814 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
816 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
817 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
818 g_assert(byte_data != NULL);
820 cfile.finfo_selected = finfo;
821 set_menus_for_selected_tree_row(&cfile);
824 if (finfo->hfinfo->blurb != NULL &&
825 finfo->hfinfo->blurb[0] != '\0') {
827 length = (guint) strlen(finfo->hfinfo->blurb);
829 length = (guint) strlen(finfo->hfinfo->name);
831 finfo_length = finfo->length + finfo->appendix_length;
833 if (finfo_length == 0) {
835 } else if (finfo_length == 1) {
836 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
838 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
840 statusbar_pop_field_msg(); /* get rid of current help msg */
842 statusbar_push_field_msg(" %s (%s)%s",
843 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
844 finfo->hfinfo->abbrev, len_str);
847 * Don't show anything if the field name is zero-length;
848 * the pseudo-field for "proto_tree_add_text()" is such
849 * a field, and we don't want "Text (text)" showing up
850 * on the status line if you've selected such a field.
852 * XXX - there are zero-length fields for which we *do*
853 * want to show the field name.
855 * XXX - perhaps the name and abbrev field should be null
856 * pointers rather than null strings for that pseudo-field,
857 * but we'd have to add checks for null pointers in some
858 * places if we did that.
860 * Or perhaps protocol tree items added with
861 * "proto_tree_add_text()" should have -1 as the field index,
862 * with no pseudo-field being used, but that might also
863 * require special checks for -1 to be added.
865 statusbar_push_field_msg("%s", "");
868 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
870 proto_help_menu_modify(sel, &cfile);
873 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
875 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
878 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
880 expand_all_tree(cfile.edt->tree, tree_view_gbl);
883 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
885 if (cfile.finfo_selected) {
886 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
887 cfile.finfo_selected->hfinfo->abbrev,0);
888 /* Recreate the packet list according to new preferences */
889 new_packet_list_recreate ();
890 if (!prefs.gui_use_pref_save) {
893 cfile.cinfo.columns_changed = FALSE; /* Reset value */
897 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
900 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
902 /* the mouse position is at an entry, expand that one */
903 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
904 gtk_tree_path_free(path);
908 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
909 if (cfile.edt->tree) {
910 guint32 tmp = gbl_resolv_flags;
911 gbl_resolv_flags = RESOLV_ALL;
912 proto_tree_draw(cfile.edt->tree, tree_view_gbl);
913 gbl_resolv_flags = tmp;
918 main_set_for_capture_file(gboolean have_capture_file_in)
920 have_capture_file = have_capture_file_in;
922 main_widgets_show_or_hide();
928 /* get the current geometry, before writing it to disk */
929 main_save_window_geometry(top_level);
931 /* write user's recent file to disk
932 * It is no problem to write this file, even if we do not quit */
933 write_profile_recent();
936 /* XXX - should we check whether the capture file is an
937 unsaved temporary file for a live capture and, if so,
938 pop up a "do you want to exit without saving the capture
939 file?" dialog, and then just return, leaving said dialog
940 box to forcibly quit if the user clicks "OK"?
942 If so, note that this should be done in a subroutine that
943 returns TRUE if we do so, and FALSE otherwise, and if it
944 returns TRUE we should return TRUE without nuking anything.
946 Note that, if we do that, we might also want to check if
947 an "Update list of packets in real time" capture is in
948 progress and, if so, ask whether they want to terminate
949 the capture and discard it, and return TRUE, before nuking
950 any child capture, if they say they don't want to do so. */
953 /* Nuke any child capture in progress. */
954 capture_kill_child(&global_capture_opts);
957 /* Are we in the middle of reading a capture? */
958 if (cfile.state == FILE_READ_IN_PROGRESS) {
959 /* Yes, so we can't just close the file and quit, as
960 that may yank the rug out from under the read in
961 progress; instead, just set the state to
962 "FILE_READ_ABORTED" and return - the code doing the read
963 will check for that and, if it sees that, will clean
965 cfile.state = FILE_READ_ABORTED;
967 /* Say that the window should *not* be deleted;
968 that'll be done by the code that cleans up. */
971 /* Close any capture file we have open; on some OSes, you
972 can't unlink a temporary capture file if you have it
974 "cf_close()" will unlink it after closing it if
975 it's a temporary file.
977 We do this here, rather than after the main loop returns,
978 as, after the main loop returns, the main window may have
979 been destroyed (if this is called due to a "destroy"
980 even on the main window rather than due to the user
981 selecting a menu item), and there may be a crash
982 or other problem when "cf_close()" tries to
983 clean up stuff in the main window.
985 XXX - is there a better place to put this?
986 Or should we have a routine that *just* closes the
987 capture file, and doesn't do anything with the UI,
988 which we'd call here, and another routine that
989 calls that routine and also cleans up the UI, which
990 we'd call elsewhere? */
993 /* Exit by leaving the main loop, so that any quit functions
994 we registered get called. */
997 /* Say that the window should be deleted. */
1003 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1007 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1008 gtk_window_present(GTK_WINDOW(top_level));
1009 /* user didn't saved his current file, ask him */
1010 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1011 "%sSave capture file before program quit?%s\n\n"
1012 "If you quit the program without saving, your capture data will be discarded.",
1013 simple_dialog_primary_start(), simple_dialog_primary_end());
1014 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1017 /* unchanged file, just exit */
1018 /* "main_do_quit()" indicates whether the main window should be deleted. */
1019 return main_do_quit();
1025 main_pane_load_window_geometry(void)
1027 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1028 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1029 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1030 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1036 main_load_window_geometry(GtkWidget *widget)
1038 window_geometry_t geom;
1040 geom.set_pos = prefs.gui_geometry_save_position;
1041 geom.x = recent.gui_geometry_main_x;
1042 geom.y = recent.gui_geometry_main_y;
1043 geom.set_size = prefs.gui_geometry_save_size;
1044 if (recent.gui_geometry_main_width > 0 &&
1045 recent.gui_geometry_main_height > 0) {
1046 geom.width = recent.gui_geometry_main_width;
1047 geom.height = recent.gui_geometry_main_height;
1048 geom.set_maximized = prefs.gui_geometry_save_maximized;
1050 /* We assume this means the width and height weren't set in
1051 the "recent" file (or that there is no "recent" file),
1052 and weren't set to a default value, so we don't set the
1053 size. (The "recent" file code rejects non-positive width
1054 and height values.) */
1055 geom.set_size = FALSE;
1057 geom.maximized = recent.gui_geometry_main_maximized;
1059 window_set_geometry(widget, &geom);
1061 main_pane_load_window_geometry();
1062 statusbar_load_window_geometry();
1067 main_save_window_geometry(GtkWidget *widget)
1069 window_geometry_t geom;
1071 window_get_geometry(widget, &geom);
1073 if (prefs.gui_geometry_save_position) {
1074 recent.gui_geometry_main_x = geom.x;
1075 recent.gui_geometry_main_y = geom.y;
1078 if (prefs.gui_geometry_save_size) {
1079 recent.gui_geometry_main_width = geom.width;
1080 recent.gui_geometry_main_height = geom.height;
1083 if(prefs.gui_geometry_save_maximized) {
1084 recent.gui_geometry_main_maximized = geom.maximized;
1087 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1088 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1089 statusbar_save_window_geometry();
1092 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1096 /* save file first */
1097 file_save_as_cmd(after_save_exit, NULL);
1099 case(ESD_BTN_QUIT_DONT_SAVE):
1102 case(ESD_BTN_CANCEL):
1105 g_assert_not_reached();
1110 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1114 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1115 /* user didn't saved his current file, ask him */
1116 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL,
1117 "%sSave capture file before program quit?%s\n\n"
1118 "If you quit the program without saving, your capture data will be discarded.",
1119 simple_dialog_primary_start(), simple_dialog_primary_end());
1120 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1122 /* unchanged file, just exit */
1128 print_usage(gboolean print_ver) {
1138 fprintf(output, "Wireshark " VERSION "%s\n"
1139 "Interactively dump and analyze network traffic.\n"
1140 "See http://www.wireshark.org for more information.\n"
1143 wireshark_svnversion, get_copyright_info());
1147 fprintf(output, "\n");
1148 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1149 fprintf(output, "\n");
1152 fprintf(output, "Capture interface:\n");
1153 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1154 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1155 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1156 fprintf(output, " -p don't capture in promiscuous mode\n");
1157 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1158 fprintf(output, " -Q quit Wireshark after capturing\n");
1159 fprintf(output, " -S update packet display when new packets are captured\n");
1160 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1161 #ifdef HAVE_PCAP_CREATE
1162 fprintf(output, " -I capture in monitor mode, if available\n");
1164 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1165 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1167 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1168 fprintf(output, " -D print list of interfaces and exit\n");
1169 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1170 fprintf(output, "\n");
1171 fprintf(output, "Capture stop conditions:\n");
1172 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1173 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1174 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1175 fprintf(output, " files:NUM - stop after NUM files\n");
1176 /*fprintf(output, "\n");*/
1177 fprintf(output, "Capture output:\n");
1178 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1179 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1180 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1181 #endif /* HAVE_LIBPCAP */
1183 /*fprintf(output, "\n");*/
1184 fprintf(output, "Input file:\n");
1185 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1187 fprintf(output, "\n");
1188 fprintf(output, "Processing:\n");
1189 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1190 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1191 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1193 fprintf(output, "\n");
1194 fprintf(output, "User interface:\n");
1195 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1196 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1197 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1198 fprintf(output, " filter\n");
1199 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1200 fprintf(output, " -m <font> set the font name used for most text\n");
1201 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1202 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1203 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1204 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1206 fprintf(output, "\n");
1207 fprintf(output, "Output:\n");
1208 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1210 fprintf(output, "\n");
1211 fprintf(output, "Miscellaneous:\n");
1212 fprintf(output, " -h display this help and exit\n");
1213 fprintf(output, " -v display version info and exit\n");
1214 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1215 fprintf(output, " persdata:path - personal data files\n");
1216 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1217 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1219 fprintf(output, " --display=DISPLAY X display to use\n");
1234 printf(PACKAGE " " VERSION "%s\n"
1241 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1242 runtime_info_str->str);
1250 * Print to the standard error. On Windows, create a console for the
1251 * standard error to show up on, if necessary.
1252 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1253 * terminal isn't the standard error?
1256 vfprintf_stderr(const char *fmt, va_list ap)
1261 vfprintf(stderr, fmt, ap);
1265 fprintf_stderr(const char *fmt, ...)
1270 vfprintf_stderr(fmt, ap);
1275 * Report an error in command-line arguments.
1276 * Creates a console on Windows.
1279 cmdarg_err(const char *fmt, ...)
1283 fprintf_stderr("wireshark: ");
1285 vfprintf_stderr(fmt, ap);
1287 fprintf_stderr("\n");
1291 * Report additional information for an error in command-line arguments.
1292 * Creates a console on Windows.
1293 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1294 * terminal isn't the standard error?
1297 cmdarg_err_cont(const char *fmt, ...)
1302 vfprintf_stderr(fmt, ap);
1303 fprintf_stderr("\n");
1308 Once every 3 seconds we get a callback here which we use to update
1312 tap_update_cb(gpointer data _U_)
1314 draw_tap_listeners(FALSE);
1318 /* Restart the tap update display timer with new configured interval */
1319 void reset_tap_update_timer(void)
1321 g_source_remove(tap_update_timer_id);
1322 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1326 protect_thread_critical_region(void)
1328 /* Threading support for TAP:s removed
1329 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1330 * See the commit for removed code:
1331 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
1335 unprotect_thread_critical_region(void)
1337 /* Threading support for TAP:s removed
1338 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1344 * Periodically process outstanding hostname lookups. If we have new items,
1345 * redraw the packet list and tree view.
1349 resolv_update_cb(gpointer data _U_)
1351 /* Anything new show up? */
1352 if (host_name_lookup_process(NULL)) {
1353 if (gtk_widget_get_window(pkt_scrollw))
1354 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1355 if (gtk_widget_get_window(tv_scrollw))
1356 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1359 /* Always check. Even if we don't do async lookups we could still get
1360 passive updates, e.g. from DNS packets. */
1365 /* Set main_window_name and it's icon title to the capture filename */
1367 set_display_filename(capture_file *cf)
1372 window_name = g_strdup_printf("%s", cf_get_display_name(cf));
1373 set_main_window_name(window_name);
1374 g_free(window_name);
1376 set_main_window_name("The Wireshark Network Analyzer");
1380 static GtkWidget *close_dlg = NULL;
1383 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1385 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1390 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1392 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1397 main_cf_cb_file_closing(capture_file *cf)
1400 /* if we have more than 10000 packets, show a splash screen while closing */
1401 /* XXX - don't know a better way to decide whether to show or not,
1402 * as most of the time is spend in a single eth_clist_clear function,
1403 * so we can't use a progress bar here! */
1404 if(cf->count > 10000) {
1405 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1406 "%sClosing file!%s\n\nPlease wait ...",
1407 simple_dialog_primary_start(),
1408 simple_dialog_primary_end());
1409 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1412 /* Destroy all windows, which refer to the
1413 capture file we're closing. */
1414 destroy_packet_wins();
1415 file_save_as_destroy();
1417 /* Restore the standard title bar message. */
1418 set_main_window_name("The Wireshark Network Analyzer");
1420 /* Disable all menu items that make sense only if you have a capture. */
1421 set_menus_for_capture_file(NULL);
1422 set_menus_for_captured_packets(FALSE);
1423 set_menus_for_selected_packet(cf);
1424 set_menus_for_capture_in_progress(FALSE);
1425 set_capture_if_dialog_for_capture_in_progress(FALSE);
1426 set_menus_for_selected_tree_row(cf);
1428 /* Set up main window for no capture file. */
1429 main_set_for_capture_file(FALSE);
1431 main_window_update();
1435 main_cf_cb_file_closed(capture_file *cf _U_)
1437 if(close_dlg != NULL) {
1438 splash_destroy(close_dlg);
1445 main_cf_cb_file_read_started(capture_file *cf _U_)
1447 tap_param_dlg_update();
1449 /* Set up main window for a capture file. */
1450 main_set_for_capture_file(TRUE);
1454 main_cf_cb_file_read_finished(capture_file *cf)
1458 if (!cf->is_tempfile && cf->filename) {
1459 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1460 add_menu_recent_capture_file(cf->filename);
1462 /* Remember folder for next Open dialog and save it in recent */
1463 dir_path = get_dirname(g_strdup(cf->filename));
1464 set_last_open_dir(dir_path);
1467 set_display_filename(cf);
1469 /* Enable menu items that make sense if you have a capture file you've
1470 finished reading. */
1471 set_menus_for_capture_file(cf);
1473 /* Enable menu items that make sense if you have some captured packets. */
1474 set_menus_for_captured_packets(TRUE);
1478 static GList *icon_list_create(
1479 const char **icon16_xpm,
1480 const char **icon32_xpm,
1481 const char **icon48_xpm,
1482 const char **icon64_xpm)
1484 GList *icon_list = NULL;
1485 GdkPixbuf * pixbuf16;
1486 GdkPixbuf * pixbuf32;
1487 GdkPixbuf * pixbuf48;
1488 GdkPixbuf * pixbuf64;
1491 if(icon16_xpm != NULL) {
1492 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1494 icon_list = g_list_append(icon_list, pixbuf16);
1497 if(icon32_xpm != NULL) {
1498 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1500 icon_list = g_list_append(icon_list, pixbuf32);
1503 if(icon48_xpm != NULL) {
1504 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1506 icon_list = g_list_append(icon_list, pixbuf48);
1509 if(icon64_xpm != NULL) {
1510 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1512 icon_list = g_list_append(icon_list, pixbuf64);
1519 main_capture_set_main_window_title(capture_options *capture_opts)
1521 GString *title = g_string_new("");
1523 g_string_append(title, "Capturing ");
1524 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1525 set_main_window_name(title->str);
1526 g_string_free(title, TRUE);
1530 main_capture_cb_capture_prepared(capture_options *capture_opts)
1532 static GList *icon_list = NULL;
1534 main_capture_set_main_window_title(capture_opts);
1536 if(icon_list == NULL) {
1537 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1539 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1541 /* Disable menu items that make no sense if you're currently running
1543 set_menus_for_capture_in_progress(TRUE);
1544 set_capture_if_dialog_for_capture_in_progress(TRUE);
1546 /* Don't set up main window for a capture file. */
1547 main_set_for_capture_file(FALSE);
1551 main_capture_cb_capture_update_started(capture_options *capture_opts)
1553 /* We've done this in "prepared" above, but it will be cleared while
1554 switching to the next multiple file. */
1555 main_capture_set_main_window_title(capture_opts);
1557 set_menus_for_capture_in_progress(TRUE);
1558 set_capture_if_dialog_for_capture_in_progress(TRUE);
1560 /* Enable menu items that make sense if you have some captured
1561 packets (yes, I know, we don't have any *yet*). */
1562 set_menus_for_captured_packets(TRUE);
1564 /* Set up main window for a capture file. */
1565 main_set_for_capture_file(TRUE);
1569 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1571 capture_file *cf = capture_opts->cf;
1572 static GList *icon_list = NULL;
1574 if (!cf->is_tempfile && cf->filename) {
1575 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1576 add_menu_recent_capture_file(cf->filename);
1578 set_display_filename(cf);
1580 /* Enable menu items that make sense if you're not currently running
1582 set_menus_for_capture_in_progress(FALSE);
1583 set_capture_if_dialog_for_capture_in_progress(FALSE);
1585 /* Enable menu items that make sense if you have a capture file
1586 you've finished reading. */
1587 set_menus_for_capture_file(cf);
1589 /* Set up main window for a capture file. */
1590 main_set_for_capture_file(TRUE);
1592 if(icon_list == NULL) {
1593 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1595 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1597 if(global_capture_opts.quit_after_cap) {
1598 /* command line asked us to quit after the capture */
1599 /* don't pop up a dialog to ask for unsaved files etc. */
1605 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1607 /* Don't set up main window for a capture file. */
1608 main_set_for_capture_file(FALSE);
1612 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1615 capture_file *cf = capture_opts->cf;
1617 static GList *icon_list = NULL;
1619 /*set_display_filename(cf);*/
1621 /* Enable menu items that make sense if you're not currently running
1623 set_menus_for_capture_in_progress(FALSE);
1624 set_capture_if_dialog_for_capture_in_progress(FALSE);
1626 /* Restore the standard title bar message */
1627 /* (just in case we have trouble opening the capture file). */
1628 set_main_window_name("The Wireshark Network Analyzer");
1630 if(icon_list == NULL) {
1631 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1633 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1635 /* We don't have loaded the capture file, this will be done later.
1636 * For now we still have simply a blank screen. */
1638 if(global_capture_opts.quit_after_cap) {
1639 /* command line asked us to quit after the capture */
1640 /* don't pop up a dialog to ask for unsaved files etc. */
1645 #endif /* HAVE_LIBPCAP */
1648 main_cf_cb_packet_selected(gpointer data)
1650 capture_file *cf = data;
1652 /* Display the GUI protocol tree and packet bytes.
1653 XXX - why do we dump core if we call "proto_tree_draw()"
1654 before calling "add_byte_views()"? */
1655 add_main_byte_views(cf->edt);
1656 main_proto_tree_draw(cf->edt->tree);
1658 /* Note: Both string and hex value searches in the packet data produce a non-zero
1659 search_pos if successful */
1660 if(cf->search_in_progress &&
1661 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1662 highlight_field(cf->edt->tvb, cf->search_pos,
1663 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1666 /* A packet is selected. */
1667 set_menus_for_selected_packet(cf);
1671 main_cf_cb_packet_unselected(capture_file *cf)
1673 /* Clear out the display of that packet. */
1674 clear_tree_and_hex_views();
1676 /* No packet is selected. */
1677 set_menus_for_selected_packet(cf);
1681 main_cf_cb_field_unselected(capture_file *cf)
1683 set_menus_for_selected_tree_row(cf);
1687 main_cf_cb_file_save_reload_finished(gpointer data _U_)
1689 set_display_filename(&cfile);
1690 set_menus_for_capture_file(&cfile);
1694 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1697 case(cf_cb_file_closing):
1698 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1699 main_cf_cb_file_closing(data);
1701 case(cf_cb_file_closed):
1702 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1703 main_cf_cb_file_closed(data);
1705 case(cf_cb_file_read_started):
1706 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1707 main_cf_cb_file_read_started(data);
1709 case(cf_cb_file_read_finished):
1710 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1711 main_cf_cb_file_read_finished(data);
1713 case(cf_cb_packet_selected):
1714 main_cf_cb_packet_selected(data);
1716 case(cf_cb_packet_unselected):
1717 main_cf_cb_packet_unselected(data);
1719 case(cf_cb_field_unselected):
1720 main_cf_cb_field_unselected(data);
1722 case(cf_cb_file_save_started):
1723 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1725 case(cf_cb_file_save_finished):
1726 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1728 case(cf_cb_file_save_reload_finished):
1729 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1730 main_cf_cb_file_save_reload_finished(data);
1732 case(cf_cb_file_save_failed):
1733 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1736 g_warning("main_cf_callback: event %u unknown", event);
1737 g_assert_not_reached();
1743 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1745 #ifdef HAVE_GTKOSXAPPLICATION
1746 GtkOSXApplication *theApp;
1749 case(capture_cb_capture_prepared):
1750 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1751 main_capture_cb_capture_prepared(capture_opts);
1753 case(capture_cb_capture_update_started):
1754 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1755 main_capture_cb_capture_update_started(capture_opts);
1756 #ifdef HAVE_GTKOSXAPPLICATION
1757 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1758 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1761 case(capture_cb_capture_update_continue):
1762 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1764 case(capture_cb_capture_update_finished):
1765 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1766 main_capture_cb_capture_update_finished(capture_opts);
1768 case(capture_cb_capture_fixed_started):
1769 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1770 main_capture_cb_capture_fixed_started(capture_opts);
1772 case(capture_cb_capture_fixed_continue):
1773 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1775 case(capture_cb_capture_fixed_finished):
1776 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1777 main_capture_cb_capture_fixed_finished(capture_opts);
1779 case(capture_cb_capture_stopping):
1780 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1781 /* Beware: this state won't be called, if the capture child
1782 * closes the capturing on it's own! */
1783 #ifdef HAVE_GTKOSXAPPLICATION
1784 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1785 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1789 g_warning("main_capture_callback: event %u unknown", event);
1790 g_assert_not_reached();
1796 get_gtk_compiled_info(GString *str)
1798 g_string_append(str, "with ");
1799 g_string_append_printf(str,
1800 #ifdef GTK_MAJOR_VERSION
1801 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1804 "GTK+ (version unknown)");
1806 g_string_append(str, ", ");
1808 g_string_append(str, "with Cairo ");
1809 g_string_append(str, CAIRO_VERSION_STRING);
1810 g_string_append(str, ", ");
1813 g_string_append(str, "with Pango ");
1814 g_string_append(str, PANGO_VERSION_STRING);
1815 g_string_append(str, ", ");
1821 get_gui_compiled_info(GString *str)
1823 epan_get_compiled_version_info(str);
1825 g_string_append(str, ", ");
1826 #ifdef HAVE_LIBPORTAUDIO
1827 #ifdef PORTAUDIO_API_1
1828 g_string_append(str, "with PortAudio <= V18");
1829 #else /* PORTAUDIO_API_1 */
1830 g_string_append(str, "with ");
1831 g_string_append(str, Pa_GetVersionText());
1832 #endif /* PORTAUDIO_API_1 */
1833 #else /* HAVE_LIBPORTAUDIO */
1834 g_string_append(str, "without PortAudio");
1835 #endif /* HAVE_LIBPORTAUDIO */
1837 g_string_append(str, ", ");
1839 get_compiled_airpcap_version(str);
1841 g_string_append(str, "without AirPcap");
1846 get_gui_runtime_info(GString *str)
1848 epan_get_runtime_version_info(str);
1851 g_string_append(str, ", ");
1852 get_runtime_airpcap_version(str);
1856 g_string_append(str, ", ");
1857 u3_runtime_info(str);
1862 read_configuration_files(char **gdp_path, char **dp_path)
1864 int gpf_open_errno, gpf_read_errno;
1865 int cf_open_errno, df_open_errno;
1866 int gdp_open_errno, gdp_read_errno;
1867 int dp_open_errno, dp_read_errno;
1868 char *gpf_path, *pf_path;
1869 char *cf_path, *df_path;
1870 int pf_open_errno, pf_read_errno;
1873 /* Read the preference files. */
1874 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1875 &pf_open_errno, &pf_read_errno, &pf_path);
1877 if (gpf_path != NULL) {
1878 if (gpf_open_errno != 0) {
1879 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1880 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1881 g_strerror(gpf_open_errno));
1883 if (gpf_read_errno != 0) {
1884 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1885 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1886 g_strerror(gpf_read_errno));
1889 if (pf_path != NULL) {
1890 if (pf_open_errno != 0) {
1891 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1892 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1893 g_strerror(pf_open_errno));
1895 if (pf_read_errno != 0) {
1896 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1897 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1898 g_strerror(pf_read_errno));
1905 /* if the user wants a console to be always there, well, we should open one for him */
1906 if (prefs_p->gui_console_open == console_open_always) {
1911 /* Read the capture filter file. */
1912 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1913 if (cf_path != NULL) {
1914 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1915 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1916 g_strerror(cf_open_errno));
1920 /* Read the display filter file. */
1921 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1922 if (df_path != NULL) {
1923 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1924 "Could not open your display filter file\n\"%s\": %s.", df_path,
1925 g_strerror(df_open_errno));
1929 /* Read the disabled protocols file. */
1930 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1931 dp_path, &dp_open_errno, &dp_read_errno);
1932 if (*gdp_path != NULL) {
1933 if (gdp_open_errno != 0) {
1934 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1935 "Could not open global disabled protocols file\n\"%s\": %s.",
1936 *gdp_path, g_strerror(gdp_open_errno));
1938 if (gdp_read_errno != 0) {
1939 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1940 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1941 *gdp_path, g_strerror(gdp_read_errno));
1946 if (*dp_path != NULL) {
1947 if (dp_open_errno != 0) {
1948 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1949 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1950 g_strerror(dp_open_errno));
1952 if (dp_read_errno != 0) {
1953 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1954 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1955 g_strerror(dp_read_errno));
1964 /* Check if there's something important to tell the user during startup.
1965 * We want to do this *after* showing the main window so that any windows
1966 * we pop up will be above the main window.
1970 check_and_warn_user_startup(gchar *cf_name)
1972 check_and_warn_user_startup(gchar *cf_name _U_)
1975 gchar *cur_user, *cur_group;
1976 gpointer priv_warning_dialog;
1978 /* Tell the user not to run as root. */
1979 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
1980 cur_user = get_cur_username();
1981 cur_group = get_cur_groupname();
1982 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1983 "Running as user \"%s\" and group \"%s\".\n"
1984 "This could be dangerous.\n\n"
1985 "If you're running Wireshark this way in order to perform live capture, "
1986 "you may want to be aware that there is a better way documented at\n"
1987 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
1990 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
1991 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
1995 /* Warn the user if npf.sys isn't loaded. */
1996 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
1997 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1998 "The NPF driver isn't running. You may have trouble\n"
1999 "capturing or listing interfaces.");
2000 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2001 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2008 /* And now our feature presentation... [ fade to music ] */
2010 main(int argc, char *argv[])
2012 char *init_progfile_dir_error;
2015 gboolean arg_error = FALSE;
2017 extern int info_update_freq; /* Found in about_dlg.c. */
2018 const gchar *filter;
2026 char *gdp_path, *dp_path;
2029 gboolean start_capture = FALSE;
2030 gboolean list_link_layer_types = FALSE;
2034 gboolean capture_option_specified = FALSE;
2041 gint pl_size = 280, tv_size = 95, bv_size = 75;
2042 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *jfilter = NULL;
2043 dfilter_t *rfcode = NULL;
2044 gboolean rfilter_parse_failed = FALSE;
2047 GtkWidget *splash_win = NULL;
2048 GLogLevelFlags log_flags;
2049 guint go_to_packet = 0;
2050 gboolean jump_backwards = FALSE;
2051 dfilter_t *jump_to_filter = NULL;
2054 #ifdef HAVE_GTKOSXAPPLICATION
2055 GtkOSXApplication *theApp;
2059 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2060 #define OPTSTRING_B "B:"
2062 #define OPTSTRING_B ""
2063 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2064 #else /* HAVE_LIBPCAP */
2065 #define OPTSTRING_B ""
2066 #endif /* HAVE_LIBPCAP */
2068 #ifdef HAVE_PCAP_CREATE
2069 #define OPTSTRING_I "I"
2071 #define OPTSTRING_I ""
2074 #define OPTSTRING "a:b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pQr:R:Ss:t:u:vw:X:y:z:"
2076 static const char optstring[] = OPTSTRING;
2078 /* Set the C-language locale to the native environment. */
2079 setlocale(LC_ALL, "");
2081 arg_list_utf_16to8(argc, argv);
2085 * Get credential information for later use, and drop privileges
2086 * before doing anything else.
2087 * Let the user know if anything happened.
2089 init_process_policies();
2090 relinquish_special_privs_perm();
2093 * Attempt to get the pathname of the executable file.
2095 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2097 /* initialize the funnel mini-api */
2098 initialize_funnel_ops();
2100 AirPDcapInitContext(&airpdcap_ctx);
2103 /* Load wpcap if possible. Do this before collecting the run-time version information */
2106 /* ... and also load the packet.dll from wpcap */
2107 wpcap_packet_load();
2110 /* Load the airpcap.dll. This must also be done before collecting
2111 * run-time version information. */
2112 airpcap_dll_ret_val = load_airpcap();
2114 switch (airpcap_dll_ret_val) {
2115 case AIRPCAP_DLL_OK:
2116 /* load the airpcap interfaces */
2117 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2119 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2120 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2121 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2124 airpcap_if_active = NULL;
2128 /* select the first ad default (THIS SHOULD BE CHANGED) */
2129 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2134 * XXX - Maybe we need to warn the user if one of the following happens???
2136 case AIRPCAP_DLL_OLD:
2137 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2140 case AIRPCAP_DLL_ERROR:
2141 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2144 case AIRPCAP_DLL_NOT_FOUND:
2145 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2149 #endif /* HAVE_AIRPCAP */
2151 /* Start windows sockets */
2152 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2155 profile_store_persconffiles (TRUE);
2157 /* Assemble the compile-time version information string */
2158 comp_info_str = g_string_new("Compiled ");
2160 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2162 /* Assemble the run-time version information string */
2163 runtime_info_str = g_string_new("Running ");
2164 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2166 /* Read the profile independent recent file. We have to do this here so we can */
2167 /* set the profile before it can be set from the command line parameterts */
2168 recent_read_static(&rf_path, &rf_open_errno);
2169 if (rf_path != NULL && rf_open_errno != 0) {
2170 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2171 "Could not open common recent file\n\"%s\": %s.",
2172 rf_path, g_strerror(rf_open_errno));
2175 /* "pre-scan" the command line parameters, if we have "console only"
2176 parameters. We do this so we don't start GTK+ if we're only showing
2177 command-line help or version information.
2179 XXX - this pre-scan is done before we start GTK+, so we haven't
2180 run gtk_init() on the arguments. That means that GTK+ arguments
2181 have not been removed from the argument list; those arguments
2182 begin with "--", and will be treated as an error by getopt().
2184 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2187 optind_initial = optind;
2188 while ((opt = getopt(argc, argv, optstring)) != -1) {
2190 case 'C': /* Configuration Profile */
2191 if (profile_exists (optarg, FALSE)) {
2192 set_profile_name (optarg);
2194 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2198 case 'D': /* Print a list of capture devices and exit */
2200 if_list = capture_interface_list(&err, &err_str);
2201 if (if_list == NULL) {
2203 case CANT_GET_INTERFACE_LIST:
2204 cmdarg_err("%s", err_str);
2208 case NO_INTERFACES_FOUND:
2209 cmdarg_err("There are no interfaces on which a capture can be done");
2214 capture_opts_print_interfaces(if_list);
2215 free_interface_list(if_list);
2218 capture_option_specified = TRUE;
2222 case 'h': /* Print help and exit */
2228 if (strcmp(optarg, "-") == 0)
2229 stdin_capture = TRUE;
2232 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2233 status = filesystem_opt(opt, optarg);
2235 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2239 case 'v': /* Show version and exit */
2245 * Extension command line options have to be processed before
2246 * we call epan_init() as they are supposed to be used by dissectors
2247 * or taps very early in the registration process.
2251 case '?': /* Ignore errors - the "real" scan will catch them. */
2256 /* Init the "Open file" dialog directory */
2257 /* (do this after the path settings are processed) */
2259 /* Read the profile dependent (static part) of the recent file. */
2260 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2261 /* recent lists which is done in the dynamic part. */
2262 /* We have to do this already here, so command line parameters can overwrite these values. */
2263 recent_read_profile_static(&rf_path, &rf_open_errno);
2264 if (rf_path != NULL && rf_open_errno != 0) {
2265 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2266 "Could not open recent file\n\"%s\": %s.",
2267 rf_path, g_strerror(rf_open_errno));
2270 if (recent.gui_fileopen_remembered_dir &&
2271 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2272 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2274 set_last_open_dir(get_persdatafile_dir());
2277 /* Set getopt index back to initial value, so it will start with the
2278 first command line parameter again. Also reset opterr to 1, so that
2279 error messages are printed by getopt().
2281 XXX - this seems to work on most platforms, but time will tell.
2282 The Single UNIX Specification says "The getopt() function need
2283 not be reentrant", so this isn't guaranteed to work. The Mac
2284 OS X 10.4[.x] getopt() man page says
2286 In order to use getopt() to evaluate multiple sets of arguments, or to
2287 evaluate a single set of arguments multiple times, the variable optreset
2288 must be set to 1 before the second and each additional set of calls to
2289 getopt(), and the variable optind must be reinitialized.
2293 The optreset variable was added to make it possible to call the getopt()
2294 function multiple times. This is an extension to the IEEE Std 1003.2
2295 (``POSIX.2'') specification.
2297 which I think comes from one of the other BSDs.
2299 XXX - if we want to control all the command-line option errors, so
2300 that we can display them where we choose (e.g., in a window), we'd
2301 want to leave opterr as 0, and produce our own messages using optopt.
2302 We'd have to check the value of optopt to see if it's a valid option
2303 letter, in which case *presumably* the error is "this option requires
2304 an argument but none was specified", or not a valid option letter,
2305 in which case *presumably* the error is "this option isn't valid".
2306 Some versions of getopt() let you supply a option string beginning
2307 with ':', which means that getopt() will return ':' rather than '?'
2308 for "this option requires an argument but none was specified", but
2310 optind = optind_initial;
2314 g_thread_init(NULL);
2317 /* Set the current locale according to the program environment.
2318 * We haven't localized anything, but some GTK widgets are localized
2319 * (the file selection dialogue, for example).
2320 * This also sets the C-language locale to the native environment. */
2321 setlocale (LC_ALL, "");
2323 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2324 gtk_init (&argc, &argv);
2326 cf_callback_add(main_cf_callback, NULL);
2328 capture_callback_add(main_capture_callback, NULL);
2330 cf_callback_add(statusbar_cf_callback, NULL);
2332 capture_callback_add(statusbar_capture_callback, NULL);
2335 /* Arrange that if we have no console window, and a GLib message logging
2336 routine is called to log a message, we pop up a console window.
2338 We do that by inserting our own handler for all messages logged
2339 to the default domain; that handler pops up a console if necessary,
2340 and then calls the default handler. */
2342 /* We might want to have component specific log levels later ... */
2346 G_LOG_LEVEL_CRITICAL|
2347 G_LOG_LEVEL_WARNING|
2348 G_LOG_LEVEL_MESSAGE|
2351 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2353 g_log_set_handler(NULL,
2355 console_log_handler, NULL /* user_data */);
2356 g_log_set_handler(LOG_DOMAIN_MAIN,
2358 console_log_handler, NULL /* user_data */);
2361 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2363 console_log_handler, NULL /* user_data */);
2364 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2366 console_log_handler, NULL /* user_data */);
2368 /* Set the initial values in the capture options. This might be overwritten
2369 by preference settings and then again by the command line parameters. */
2370 capture_opts_init(&global_capture_opts, &cfile);
2373 /* Initialize whatever we need to allocate colors for GTK+ */
2376 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2377 filter = get_conn_cfilter();
2378 if ( *filter != '\0' ) {
2379 info_update_freq = 1000; /* Milliseconds */
2382 /* We won't come till here, if we had a "console only" command line parameter. */
2383 splash_win = splash_new("Loading Wireshark ...");
2384 if (init_progfile_dir_error != NULL) {
2385 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2386 "Can't get pathname of Wireshark: %s.\n"
2387 "It won't be possible to capture traffic.\n"
2388 "Report this to the Wireshark developers.",
2389 init_progfile_dir_error);
2390 g_free(init_progfile_dir_error);
2393 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2395 /* Register all dissectors; we must do this before checking for the
2396 "-G" flag, as the "-G" flag dumps information registered by the
2397 dissectors, and we must do it before we read the preferences, in
2398 case any dissectors register preferences. */
2399 epan_init(register_all_protocols,register_all_protocol_handoffs,
2400 splash_update, (gpointer) splash_win,
2401 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2402 write_failure_alert_box);
2404 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2406 /* Register all tap listeners; we do this before we parse the arguments,
2407 as the "-z" argument can specify a registered tap. */
2409 /* we register the plugin taps before the other taps because
2410 stats_tree taps plugins will be registered as tap listeners
2411 by stats_tree_stat.c and need to registered before that */
2414 register_all_plugin_tap_listeners();
2417 register_all_tap_listeners();
2419 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2421 /* Now register the preferences for any non-dissector modules.
2422 We must do that before we read the preferences as well. */
2423 prefs_register_modules();
2425 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2426 /* Removed thread code:
2427 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2430 /* this is to keep tap extensions updating once every 3 seconds */
2431 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2433 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2435 cap_file_init(&cfile);
2437 /* Fill in capture options with values from the preferences */
2438 prefs_to_capture_opts();
2440 /* Now get our args */
2441 while ((opt = getopt(argc, argv, optstring)) != -1) {
2443 /*** capture option specific ***/
2444 case 'a': /* autostop criteria */
2445 case 'b': /* Ringbuffer option */
2446 case 'c': /* Capture xxx packets */
2447 case 'f': /* capture filter */
2448 case 'k': /* Start capture immediately */
2449 case 'H': /* Hide capture info dialog box */
2450 case 'i': /* Use interface xxx */
2451 case 'p': /* Don't capture in promiscuous mode */
2452 #ifdef HAVE_PCAP_CREATE
2453 case 'I': /* Capture in monitor mode, if available */
2455 case 'Q': /* Quit after capture (just capture to file) */
2456 case 's': /* Set the snapshot (capture) length */
2457 case 'S': /* "Sync" mode: used for following file ala tail -f */
2458 case 'w': /* Write to capture file xxx */
2459 case 'y': /* Set the pcap data link type */
2460 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2461 case 'B': /* Buffer size */
2462 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2464 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2470 capture_option_specified = TRUE;
2475 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2476 case 'K': /* Kerberos keytab file */
2477 read_keytab_file(optarg);
2481 /*** all non capture option specific ***/
2483 /* Configuration profile settings were already processed just ignore them this time*/
2485 case 'j': /* Search backwards for a matching packet from filter in option J */
2486 jump_backwards = TRUE;
2488 case 'g': /* Go to packet with the given packet number */
2489 go_to_packet = get_positive_int(optarg, "go to packet");
2491 case 'J': /* Jump to the first packet which matches the filter criteria */
2494 case 'l': /* Automatic scrolling in live capture mode */
2496 auto_scroll_live = TRUE;
2498 capture_option_specified = TRUE;
2502 case 'L': /* Print list of link-layer types and exit */
2504 list_link_layer_types = TRUE;
2506 capture_option_specified = TRUE;
2510 case 'm': /* Fixed-width font for the display */
2511 g_free(prefs_p->gui_font_name);
2512 prefs_p->gui_font_name = g_strdup(optarg);
2514 case 'n': /* No name resolution */
2515 gbl_resolv_flags = RESOLV_NONE;
2517 case 'N': /* Select what types of addresses/port #s to resolve */
2518 if (gbl_resolv_flags == RESOLV_ALL)
2519 gbl_resolv_flags = RESOLV_NONE;
2520 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2521 if (badopt != '\0') {
2522 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2527 case 'o': /* Override preference from command line */
2528 switch (prefs_set_pref(optarg)) {
2531 case PREFS_SET_SYNTAX_ERR:
2532 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2535 case PREFS_SET_NO_SUCH_PREF:
2536 /* not a preference, might be a recent setting */
2537 switch (recent_set_arg(optarg)) {
2540 case PREFS_SET_SYNTAX_ERR:
2541 /* shouldn't happen, checked already above */
2542 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2545 case PREFS_SET_NO_SUCH_PREF:
2546 case PREFS_SET_OBSOLETE:
2547 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2552 g_assert_not_reached();
2555 case PREFS_SET_OBSOLETE:
2556 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2561 g_assert_not_reached();
2565 /* Path settings were already processed just ignore them this time*/
2567 case 'r': /* Read capture file xxx */
2568 /* We may set "last_open_dir" to "cf_name", and if we change
2569 "last_open_dir" later, we free the old value, so we have to
2570 set "cf_name" to something that's been allocated. */
2571 cf_name = g_strdup(optarg);
2573 case 'R': /* Read file filter */
2576 case 't': /* Time stamp type */
2577 if (strcmp(optarg, "r") == 0)
2578 timestamp_set_type(TS_RELATIVE);
2579 else if (strcmp(optarg, "a") == 0)
2580 timestamp_set_type(TS_ABSOLUTE);
2581 else if (strcmp(optarg, "ad") == 0)
2582 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2583 else if (strcmp(optarg, "d") == 0)
2584 timestamp_set_type(TS_DELTA);
2585 else if (strcmp(optarg, "dd") == 0)
2586 timestamp_set_type(TS_DELTA_DIS);
2587 else if (strcmp(optarg, "e") == 0)
2588 timestamp_set_type(TS_EPOCH);
2589 else if (strcmp(optarg, "u") == 0)
2590 timestamp_set_type(TS_UTC);
2591 else if (strcmp(optarg, "ud") == 0)
2592 timestamp_set_type(TS_UTC_WITH_DATE);
2594 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2595 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2596 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2600 case 'u': /* Seconds type */
2601 if (strcmp(optarg, "s") == 0)
2602 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2603 else if (strcmp(optarg, "hms") == 0)
2604 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2606 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2607 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2612 /* ext ops were already processed just ignore them this time*/
2615 /* We won't call the init function for the stat this soon
2616 as it would disallow MATE's fields (which are registered
2617 by the preferences set callback) from being used as
2618 part of a tap filter. Instead, we just add the argument
2619 to a list of stat arguments. */
2620 if (!process_stat_cmd_arg(optarg)) {
2621 cmdarg_err("Invalid -z argument.");
2622 cmdarg_err_cont(" -z argument must be one of :");
2623 list_stat_cmd_args();
2628 case '?': /* Bad flag - print usage message */
2637 if (cf_name != NULL) {
2639 * Input file name specified with "-r" *and* specified as a regular
2640 * command-line argument.
2642 cmdarg_err("File name specified both with -r and regular argument");
2646 * Input file name not specified with "-r", and a command-line argument
2647 * was specified; treat it as the input file name.
2649 * Yes, this is different from tshark, where non-flag command-line
2650 * arguments are a filter, but this works better on GUI desktops
2651 * where a command can be specified to be run to open a particular
2652 * file - yes, you could have "-r" as the last part of the command,
2653 * but that's a bit ugly.
2655 cf_name = g_strdup(argv[0]);
2663 * Extra command line arguments were specified; complain.
2665 cmdarg_err("Invalid argument: %s", argv[0]);
2670 #ifndef HAVE_LIBPCAP
2671 if (capture_option_specified) {
2672 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2680 if (start_capture && list_link_layer_types) {
2681 /* Specifying *both* is bogus. */
2682 cmdarg_err("You can't specify both -L and a live capture.");
2686 if (list_link_layer_types) {
2687 /* We're supposed to list the link-layer types for an interface;
2688 did the user also specify a capture file to be read? */
2690 /* Yes - that's bogus. */
2691 cmdarg_err("You can't specify -L and a capture file to be read.");
2694 /* No - did they specify a ring buffer option? */
2695 if (global_capture_opts.multi_files_on) {
2696 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2700 /* We're supposed to do a live capture; did the user also specify
2701 a capture file to be read? */
2702 if (start_capture && cf_name) {
2703 /* Yes - that's bogus. */
2704 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2708 /* No - was the ring buffer option specified and, if so, does it make
2710 if (global_capture_opts.multi_files_on) {
2711 /* Ring buffer works only under certain conditions:
2712 a) ring buffer does not work with temporary files;
2713 b) real_time_mode and multi_files_on are mutually exclusive -
2714 real_time_mode takes precedence;
2715 c) it makes no sense to enable the ring buffer if the maximum
2716 file size is set to "infinite". */
2717 if (global_capture_opts.save_file == NULL) {
2718 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2719 global_capture_opts.multi_files_on = FALSE;
2721 /* if (global_capture_opts.real_time_mode) {
2722 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2723 global_capture_opts.multi_files_on = FALSE;
2725 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2726 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2727 /* XXX - this must be redesigned as the conditions changed */
2728 /* global_capture_opts.multi_files_on = FALSE;*/
2733 if (start_capture || list_link_layer_types) {
2734 /* Did the user specify an interface to use? */
2735 if (!capture_opts_trim_iface(&global_capture_opts,
2736 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2741 if (list_link_layer_types) {
2742 /* Get the list of link-layer types for the capture devices. */
2743 if_capabilities_t *caps;
2745 interface_options interface_opts;
2747 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2749 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
2750 caps = capture_get_if_capabilities(interface_opts.name, interface_opts.monitor_mode, &err_str);
2752 cmdarg_err("%s", err_str);
2756 if (caps->data_link_types == NULL) {
2757 cmdarg_err("The capture device \"%s\" has no data link types.", interface_opts.name);
2760 capture_opts_print_if_capabilities(caps, interface_opts.name, interface_opts.monitor_mode);
2761 free_if_capabilities(caps);
2766 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2767 capture_opts_trim_ring_num_files(&global_capture_opts);
2768 #endif /* HAVE_LIBPCAP */
2770 /* Notify all registered modules that have had any of their preferences
2771 changed either from one of the preferences file or from the command
2772 line that their preferences have changed. */
2777 if ((global_capture_opts.ifaces->len > 1) && start_capture) {
2778 cmdarg_err("You specified multiple interfaces for capturing which this version of Wireshark doesn't support.");
2782 if ((global_capture_opts.ifaces->len == 0) &&
2783 (prefs.capture_device != NULL)) {
2784 GList *curr, *combo_list;
2785 gboolean found = FALSE;
2787 if_list = capture_interface_list(&err, NULL);
2788 if (g_list_length(if_list) > 0) {
2789 combo_list = build_capture_combo_list(if_list, FALSE);
2790 free_interface_list(if_list);
2791 for (curr = combo_list; curr; curr = g_list_next(curr)) {
2792 if (strcmp(curr->data, prefs.capture_device) == 0) {
2799 interface_options interface_opts;
2801 interface_opts.name = g_strdup(get_if_name(prefs.capture_device));
2802 interface_opts.descr = get_interface_descriptive_name(interface_opts.name);
2803 interface_opts.monitor_mode = prefs_capture_device_monitor_mode(interface_opts.name);
2804 interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name);
2805 interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
2806 interface_opts.snaplen = global_capture_opts.default_options.snaplen;
2807 interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen;
2808 interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode;
2809 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2810 interface_opts.buffer_size = global_capture_opts.default_options.buffer_size;
2812 #ifdef HAVE_PCAP_REMOTE
2813 interface_opts.src_type = global_capture_opts.default_options.src_type;
2814 interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
2815 interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
2816 interface_opts.auth_type = global_capture_opts.default_options.auth_type;
2817 interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
2818 interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
2819 interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
2820 interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
2821 interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
2823 #ifdef HAVE_PCAP_SETSAMPLING
2824 interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
2825 interface_opts.sampling_param = global_capture_opts.default_options.sampling_param;
2827 g_array_insert_val(global_capture_opts.ifaces, 0, interface_opts);
2832 /* disabled protocols as per configuration file */
2833 if (gdp_path == NULL && dp_path == NULL) {
2834 set_disabled_protos_list();
2837 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2839 /* read in rc file from global and personal configuration paths. */
2840 rc_file = get_datafile_path(RC_FILE);
2841 #if GTK_CHECK_VERSION(3,0,0)
2842 /* XXX resolve later */
2844 gtk_rc_parse(rc_file);
2846 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2847 gtk_rc_parse(rc_file);
2857 /* close the splash screen, as we are going to open the main window now */
2858 splash_destroy(splash_win);
2860 /************************************************************************/
2861 /* Everything is prepared now, preferences and command line was read in */
2863 /* Pop up the main window. */
2864 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2866 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2867 recent_read_dynamic(&rf_path, &rf_open_errno);
2868 if (rf_path != NULL && rf_open_errno != 0) {
2869 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2870 "Could not open recent file\n\"%s\": %s.",
2871 rf_path, g_strerror(rf_open_errno));
2874 color_filters_enable(recent.packet_list_colorize);
2876 /* rearrange all the widgets as we now have all recent settings ready for this */
2877 main_widgets_rearrange();
2879 /* Fill in column titles. This must be done after the top level window
2882 XXX - is that still true, with fixed-width columns? */
2884 menu_recent_read_finished();
2886 menu_auto_scroll_live_changed(auto_scroll_live);
2889 switch (user_font_apply()) {
2892 case FA_FONT_NOT_RESIZEABLE:
2893 /* "user_font_apply()" popped up an alert box. */
2894 /* turn off zooming - font can't be resized */
2895 case FA_FONT_NOT_AVAILABLE:
2896 /* XXX - did we successfully load the un-zoomed version earlier?
2897 If so, this *probably* means the font is available, but not at
2898 this particular zoom level, but perhaps some other failure
2899 occurred; I'm not sure you can determine which is the case,
2901 /* turn off zooming - zoom level is unavailable */
2903 /* in any other case than FA_SUCCESS, turn off zooming */
2904 recent.gui_zoom_level = 0;
2905 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2908 dnd_init(top_level);
2910 color_filters_init();
2913 /* the window can be sized only, if it's not already shown, so do it now! */
2914 main_load_window_geometry(top_level);
2916 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2919 /* If we were given the name of a capture file, read it in now;
2920 we defer it until now, so that, if we can't open it, and pop
2921 up an alert box, the alert box is more likely to come up on
2922 top of the main window - but before the preference-file-error
2923 alert box, so, if we get one of those, it's more likely to come
2926 show_main_window(TRUE);
2927 check_and_warn_user_startup(cf_name);
2928 if (rfilter != NULL) {
2929 if (!dfilter_compile(rfilter, &rfcode)) {
2930 bad_dfilter_alert_box(rfilter);
2931 rfilter_parse_failed = TRUE;
2934 if (!rfilter_parse_failed) {
2935 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2936 /* "cf_open()" succeeded, so it closed the previous
2937 capture file, and thus destroyed any previous read filter
2938 attached to "cf". */
2940 cfile.rfcode = rfcode;
2941 /* Open stat windows; we do so after creating the main window,
2942 to avoid GTK warnings, and after successfully opening the
2943 capture file, so we know we have something to compute stats
2944 on, and after registering all dissectors, so that MATE will
2945 have registered its field array and we can have a tap filter
2946 with one of MATE's late-registered fields as part of the
2948 start_requested_stats();
2950 /* Read the capture file. */
2951 switch (cf_read(&cfile, FALSE)) {
2955 /* Just because we got an error, that doesn't mean we were unable
2956 to read any of the file; we handle what we could get from the
2958 /* if the user told us to jump to a specific packet, do it now */
2959 if(go_to_packet != 0) {
2960 /* Jump to the specified frame number, kept for backward
2962 cf_goto_frame(&cfile, go_to_packet);
2963 } else if (jfilter != NULL) {
2964 /* try to compile given filter */
2965 if (!dfilter_compile(jfilter, &jump_to_filter)) {
2966 bad_dfilter_alert_box(jfilter);
2968 /* Filter ok, jump to the first packet matching the filter
2969 conditions. Default search direction is forward, but if
2970 option d was given, search backwards */
2971 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
2976 case CF_READ_ABORTED:
2982 /* If the filename is not the absolute path, prepend the current dir. This happens
2983 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
2984 if (!g_path_is_absolute(cf_name)) {
2985 char *old_cf_name = cf_name;
2986 char *pwd = g_get_current_dir();
2987 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
2988 g_free(old_cf_name);
2992 /* Save the name of the containing directory specified in the
2993 path name, if any; we can write over cf_name, which is a
2994 good thing, given that "get_dirname()" does write over its
2996 s = get_dirname(cf_name);
2997 set_last_open_dir(s);
3002 dfilter_free(rfcode);
3003 cfile.rfcode = NULL;
3004 show_main_window(FALSE);
3005 /* Don't call check_and_warn_user_startup(): we did it above */
3006 set_menus_for_capture_in_progress(FALSE);
3007 set_capture_if_dialog_for_capture_in_progress(FALSE);
3012 if (start_capture) {
3013 if (global_capture_opts.save_file != NULL) {
3014 /* Save the directory name for future file dialogs. */
3015 /* (get_dirname overwrites filename) */
3016 s = get_dirname(g_strdup(global_capture_opts.save_file));
3017 set_last_open_dir(s);
3020 /* "-k" was specified; start a capture. */
3021 show_main_window(TRUE);
3022 check_and_warn_user_startup(cf_name);
3023 if (capture_start(&global_capture_opts)) {
3024 /* The capture started. Open stat windows; we do so after creating
3025 the main window, to avoid GTK warnings, and after successfully
3026 opening the capture file, so we know we have something to compute
3027 stats on, and after registering all dissectors, so that MATE will
3028 have registered its field array and we can have a tap filter with
3029 one of MATE's late-registered fields as part of the filter. */
3030 start_requested_stats();
3033 show_main_window(FALSE);
3034 check_and_warn_user_startup(cf_name);
3035 set_menus_for_capture_in_progress(FALSE);
3036 set_capture_if_dialog_for_capture_in_progress(FALSE);
3039 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3040 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3041 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3043 #else /* HAVE_LIBPCAP */
3044 show_main_window(FALSE);
3045 check_and_warn_user_startup(cf_name);
3046 set_menus_for_capture_in_progress(FALSE);
3047 set_capture_if_dialog_for_capture_in_progress(FALSE);
3048 #endif /* HAVE_LIBPCAP */
3051 /* register our pid if we are being run from a U3 device */
3054 profile_store_persconffiles (FALSE);
3056 #ifdef HAVE_GTKOSXAPPLICATION
3057 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3058 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3059 gtk_osxapplication_ready(theApp);
3062 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3064 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3066 /* ... back from GTK, we're going down now! */
3068 /* deregister our pid */
3069 u3_deregister_pid();
3073 AirPDcapDestroyContext(&airpdcap_ctx);
3076 /* hide the (unresponsive) main window, while asking the user to close the console window */
3077 gtk_widget_hide(top_level);
3079 #ifdef HAVE_GTKOSXAPPLICATION
3080 g_object_unref(theApp);
3083 /* Shutdown windows sockets */
3086 /* For some unknown reason, the "atexit()" call in "create_console()"
3087 doesn't arrange that "destroy_console()" be called when we exit,
3088 so we call it here if a console was created. */
3097 /* We build this as a GUI subsystem application on Win32, so
3098 "WinMain()", not "main()", gets called.
3100 Hack shamelessly stolen from the Win32 port of the GIMP. */
3102 #define _stdcall __attribute__((stdcall))
3106 WinMain (struct HINSTANCE__ *hInstance,
3107 struct HINSTANCE__ *hPrevInstance,
3111 INITCOMMONCONTROLSEX comm_ctrl;
3114 * Initialize our DLL search path. MUST be called before LoadLibrary
3117 ws_init_dll_search_path();
3119 /* Initialize our controls. Required for native Windows file dialogs. */
3120 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3121 comm_ctrl.dwSize = sizeof(comm_ctrl);
3122 /* Includes the animate, header, hot key, list view, progress bar,
3123 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3126 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3127 InitCommonControlsEx(&comm_ctrl);
3129 /* RichEd20.DLL is needed for filter entries. */
3130 ws_load_library("riched20.dll");
3132 has_console = FALSE;
3133 console_wait = FALSE;
3134 return main (__argc, __argv);
3137 /* The code to create and desstroy console windows should not be necessary,
3138 at least as I read the GLib source code, as it looks as if GLib is, on
3139 Win32, *supposed* to create a console window into which to display its
3142 That doesn't happen, however. I suspect there's something completely
3143 broken about that code in GLib-for-Win32, and that it may be related
3144 to the breakage that forces us to just call "printf()" on the message
3145 rather than passing the message on to "g_log_default_handler()"
3146 (which is the routine that does the aforementioned non-functional
3147 console window creation). */
3150 * If this application has no console window to which its standard output
3151 * would go, create one.
3154 create_console(void)
3156 if (stdin_capture) {
3157 /* We've been handed "-i -". Don't mess with stdio. */
3162 /* We have no console to which to print the version string, so
3163 create one and make it the standard input, output, and error. */
3166 * See if we have an existing console (i.e. we were run from a
3169 if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3170 if (AllocConsole()) {
3171 console_wait = TRUE;
3172 SetConsoleTitle(_T("Wireshark Debug Console"));
3174 return; /* couldn't create console */
3178 ws_freopen("CONIN$", "r", stdin);
3179 ws_freopen("CONOUT$", "w", stdout);
3180 ws_freopen("CONOUT$", "w", stderr);
3181 fprintf(stdout, "\n");
3182 fprintf(stderr, "\n");
3184 /* Now register "destroy_console()" as a routine to be called just
3185 before the application exits, so that we can destroy the console
3186 after the user has typed a key (so that the console doesn't just
3187 disappear out from under them, giving the user no chance to see
3188 the message(s) we put in there). */
3189 atexit(destroy_console);
3191 /* Well, we have a console now. */
3197 destroy_console(void)
3200 printf("\n\nPress any key to exit\n");
3209 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3210 const char *message, gpointer user_data _U_)
3217 /* ignore log message, if log_level isn't interesting based
3218 upon the console log preferences.
3219 If the preferences haven't been loaded loaded yet, display the
3222 The default console_log_level preference value is such that only
3223 ERROR, CRITICAL and WARNING level messages are processed;
3224 MESSAGE, INFO and DEBUG level messages are ignored. */
3225 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3226 prefs.console_log_level != 0) {
3231 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3232 /* the user wants a console or the application will terminate immediately */
3236 /* For some unknown reason, the above doesn't appear to actually cause
3237 anything to be sent to the standard output, so we'll just splat the
3238 message out directly, just to make sure it gets out. */
3240 switch(log_level & G_LOG_LEVEL_MASK) {
3241 case G_LOG_LEVEL_ERROR:
3244 case G_LOG_LEVEL_CRITICAL:
3247 case G_LOG_LEVEL_WARNING:
3250 case G_LOG_LEVEL_MESSAGE:
3253 case G_LOG_LEVEL_INFO:
3256 case G_LOG_LEVEL_DEBUG:
3260 fprintf(stderr, "unknown log_level %u\n", log_level);
3262 g_assert_not_reached();
3265 /* create a "timestamp" */
3267 today = localtime(&curr);
3269 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3270 today->tm_hour, today->tm_min, today->tm_sec,
3271 log_domain != NULL ? log_domain : "",
3274 if(log_level & G_LOG_LEVEL_ERROR) {
3275 /* wait for a key press before the following error handler will terminate the program
3276 this way the user at least can read the error message */
3277 printf("\n\nPress any key to exit\n");
3281 /* XXX - on UN*X, should we just use g_log_default_handler()?
3282 We want the error messages to go to the standard output;
3283 on Mac OS X, that will cause them to show up in various
3284 per-user logs accessible through Console (details depend
3285 on whether you're running 10.0 through 10.4 or running
3286 10.5 and later), and, on other UN*X desktop environments,
3287 if they don't show up in some form of console log, that's
3288 a deficiency in that desktop environment. (Too bad
3289 Windows doesn't set the standard output and error for
3290 GUI apps to something that shows up in such a log.) */
3291 g_log_default_handler(log_domain, log_level, message, user_data);
3298 * Helper for main_widgets_rearrange()
3300 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3301 gtk_container_remove(GTK_CONTAINER(data), widget);
3304 static GtkWidget *main_widget_layout(gint layout_content)
3306 switch(layout_content) {
3307 case(layout_pane_content_none):
3309 case(layout_pane_content_plist):
3311 case(layout_pane_content_pdetails):
3313 case(layout_pane_content_pbytes):
3314 return byte_nb_ptr_gbl;
3316 g_assert_not_reached();
3323 * Rearrange the main window widgets
3325 void main_widgets_rearrange(void) {
3326 GtkWidget *first_pane_widget1, *first_pane_widget2;
3327 GtkWidget *second_pane_widget1, *second_pane_widget2;
3328 gboolean split_top_left;
3330 /* be a bit faster */
3331 gtk_widget_hide(main_vbox);
3333 /* be sure we don't lose a widget while rearranging */
3334 g_object_ref(G_OBJECT(menubar));
3335 g_object_ref(G_OBJECT(main_tb));
3336 g_object_ref(G_OBJECT(filter_tb));
3338 g_object_ref(G_OBJECT(airpcap_tb));
3340 g_object_ref(G_OBJECT(pkt_scrollw));
3341 g_object_ref(G_OBJECT(tv_scrollw));
3342 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3343 g_object_ref(G_OBJECT(statusbar));
3344 g_object_ref(G_OBJECT(main_pane_v1));
3345 g_object_ref(G_OBJECT(main_pane_v2));
3346 g_object_ref(G_OBJECT(main_pane_h1));
3347 g_object_ref(G_OBJECT(main_pane_h2));
3348 g_object_ref(G_OBJECT(welcome_pane));
3350 /* empty all containers participating */
3351 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3352 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3353 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3354 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3355 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3357 statusbar_widgets_emptying(statusbar);
3359 /* add the menubar always at the top */
3360 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3363 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3365 /* filter toolbar in toolbar area */
3366 if (!prefs.filter_toolbar_show_in_statusbar) {
3367 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3371 /* airpcap toolbar */
3372 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3375 /* fill the main layout panes */
3376 switch(prefs.gui_layout_type) {
3377 case(layout_type_5):
3378 main_first_pane = main_pane_v1;
3379 main_second_pane = main_pane_v2;
3380 split_top_left = FALSE;
3382 case(layout_type_2):
3383 main_first_pane = main_pane_v1;
3384 main_second_pane = main_pane_h1;
3385 split_top_left = FALSE;
3387 case(layout_type_1):
3388 main_first_pane = main_pane_v1;
3389 main_second_pane = main_pane_h1;
3390 split_top_left = TRUE;
3392 case(layout_type_4):
3393 main_first_pane = main_pane_h1;
3394 main_second_pane = main_pane_v1;
3395 split_top_left = FALSE;
3397 case(layout_type_3):
3398 main_first_pane = main_pane_h1;
3399 main_second_pane = main_pane_v1;
3400 split_top_left = TRUE;
3402 case(layout_type_6):
3403 main_first_pane = main_pane_h1;
3404 main_second_pane = main_pane_h2;
3405 split_top_left = FALSE;
3408 main_first_pane = NULL;
3409 main_second_pane = NULL;
3410 split_top_left = FALSE;
3411 g_assert_not_reached();
3413 if (split_top_left) {
3414 first_pane_widget1 = main_second_pane;
3415 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3416 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3417 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3419 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3420 first_pane_widget2 = main_second_pane;
3421 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3422 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3424 if (first_pane_widget1 != NULL)
3425 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3426 if (first_pane_widget2 != NULL)
3427 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3428 if (second_pane_widget1 != NULL)
3429 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3430 if (second_pane_widget2 != NULL)
3431 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3433 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3436 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3439 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3441 /* filter toolbar in statusbar hbox */
3442 if (prefs.filter_toolbar_show_in_statusbar) {
3443 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3446 /* statusbar widgets */
3447 statusbar_widgets_pack(statusbar);
3449 /* hide widgets on users recent settings */
3450 main_widgets_show_or_hide();
3452 gtk_widget_show(main_vbox);
3456 is_widget_visible(GtkWidget *widget, gpointer data)
3458 gboolean *is_visible = data;
3461 if (gtk_widget_get_visible(widget))
3468 main_widgets_show_or_hide(void)
3470 gboolean main_second_pane_show;
3472 if (recent.main_toolbar_show) {
3473 gtk_widget_show(main_tb);
3475 gtk_widget_hide(main_tb);
3478 statusbar_widgets_show_or_hide(statusbar);
3480 if (recent.filter_toolbar_show) {
3481 gtk_widget_show(filter_tb);
3483 gtk_widget_hide(filter_tb);
3487 if (recent.airpcap_toolbar_show) {
3488 gtk_widget_show(airpcap_tb);
3490 gtk_widget_hide(airpcap_tb);
3494 if (recent.packet_list_show && have_capture_file) {
3495 gtk_widget_show(pkt_scrollw);
3497 gtk_widget_hide(pkt_scrollw);
3500 if (recent.tree_view_show && have_capture_file) {
3501 gtk_widget_show(tv_scrollw);
3503 gtk_widget_hide(tv_scrollw);
3506 if (recent.byte_view_show && have_capture_file) {
3507 gtk_widget_show(byte_nb_ptr_gbl);
3509 gtk_widget_hide(byte_nb_ptr_gbl);
3512 if (have_capture_file) {
3513 gtk_widget_show(main_first_pane);
3515 gtk_widget_hide(main_first_pane);
3519 * Is anything in "main_second_pane" visible?
3520 * If so, show it, otherwise hide it.
3522 main_second_pane_show = FALSE;
3523 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3524 &main_second_pane_show);
3525 if (main_second_pane_show) {
3526 gtk_widget_show(main_second_pane);
3528 gtk_widget_hide(main_second_pane);
3531 if (!have_capture_file) {
3533 gtk_widget_show(welcome_pane);
3537 gtk_widget_hide(welcome_pane);
3542 /* called, when the window state changes (minimized, maximized, ...) */
3544 window_state_event_cb (GtkWidget *widget _U_,
3548 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3550 if( (event->type) == (GDK_WINDOW_STATE)) {
3551 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3552 /* we might have dialogs popped up while we where iconified,
3554 display_queued_messages();
3562 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3564 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3566 if (event->keyval == GDK_F8) {
3567 new_packet_list_next();
3569 } else if (event->keyval == GDK_F7) {
3570 new_packet_list_prev();
3572 } else if (event->state & NO_SHIFT_MOD_MASK) {
3573 return FALSE; /* Skip control, alt, and other modifiers */
3575 * A comment in gdkkeysyms.h says that it's autogenerated from
3576 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3577 * don't explicitly say so, isprint() should work as expected
3580 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3581 /* Forward the keypress on to the display filter entry */
3582 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3583 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3584 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3592 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3594 GtkAccelGroup *accel;
3597 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3598 set_main_window_name("The Wireshark Network Analyzer");
3600 gtk_widget_set_name(top_level, "main window");
3601 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3603 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3604 G_CALLBACK(window_state_event_cb), NULL);
3605 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3606 G_CALLBACK(top_level_key_pressed_cb), NULL );
3608 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3609 main_vbox = gtk_vbox_new(FALSE, 1);
3610 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3611 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3612 gtk_widget_show(main_vbox);
3615 menubar = main_menu_new(&accel);
3617 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3618 /* Mac OS X native menus are created and displayed by main_menu_new() */
3619 if(!prefs_p->gui_macosx_style) {
3621 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3622 gtk_widget_show(menubar);
3623 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3628 main_tb = toolbar_new();
3629 gtk_widget_show (main_tb);
3631 /* Filter toolbar */
3632 filter_tb = filter_toolbar_new();
3635 pkt_scrollw = new_packet_list_create();
3636 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3637 gtk_widget_show_all(pkt_scrollw);
3640 tv_scrollw = main_tree_view_new(prefs_p, &tree_view_gbl);
3641 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3642 gtk_widget_show(tv_scrollw);
3644 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3645 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3646 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3647 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3648 gtk_widget_show(tree_view_gbl);
3651 byte_nb_ptr_gbl = byte_view_new();
3652 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3653 gtk_widget_show(byte_nb_ptr_gbl);
3655 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3656 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3658 /* Panes for the packet list, tree, and byte view */
3659 main_pane_v1 = gtk_vpaned_new();
3660 gtk_widget_show(main_pane_v1);
3661 main_pane_v2 = gtk_vpaned_new();
3662 gtk_widget_show(main_pane_v2);
3663 main_pane_h1 = gtk_hpaned_new();
3664 gtk_widget_show(main_pane_h1);
3665 main_pane_h2 = gtk_hpaned_new();
3666 gtk_widget_show(main_pane_h2);
3668 airpcap_tb = airpcap_toolbar_new();
3669 gtk_widget_show(airpcap_tb);
3672 statusbar = statusbar_new();
3673 gtk_widget_show(statusbar);
3675 /* Pane for the welcome screen */
3676 welcome_pane = welcome_new();
3677 gtk_widget_show(welcome_pane);
3681 show_main_window(gboolean doing_work)
3683 main_set_for_capture_file(doing_work);
3685 /*** we have finished all init things, show the main window ***/
3686 gtk_widget_show(top_level);
3688 /* the window can be maximized only, if it's visible, so do it after show! */
3689 main_load_window_geometry(top_level);
3691 /* process all pending GUI events before continue */
3692 while (gtk_events_pending()) gtk_main_iteration();
3694 /* Pop up any queued-up alert boxes. */
3695 display_queued_messages();
3697 /* Move the main window to the front, in case it isn't already there */
3698 gdk_window_raise(gtk_widget_get_window(top_level));
3701 airpcap_toolbar_show(airpcap_tb);
3702 #endif /* HAVE_AIRPCAP */
3705 /* Fill in capture options with values from the preferences */
3707 prefs_to_capture_opts(void)
3710 /* Set promiscuous mode from the preferences setting. */
3711 /* the same applies to other preferences settings as well. */
3712 global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
3713 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3714 global_capture_opts.show_info = prefs.capture_show_info;
3715 global_capture_opts.real_time_mode = prefs.capture_real_time;
3716 auto_scroll_live = prefs.capture_auto_scroll;
3717 #endif /* HAVE_LIBPCAP */
3719 /* Set the name resolution code's flags from the preferences. */
3720 gbl_resolv_flags = prefs.name_resolve;
3723 static void copy_global_profile (const gchar *profile_name)
3725 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3727 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3728 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3729 "Can't create directory\n\"%s\":\n%s.",
3730 pf_dir_path, g_strerror(errno));
3732 g_free(pf_dir_path);
3735 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3736 &pf_dir_path, &pf_dir_path2) == -1) {
3737 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3738 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3739 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3741 g_free(pf_filename);
3742 g_free(pf_dir_path);
3743 g_free(pf_dir_path2);
3747 /* Change configuration profile */
3748 void change_configuration_profile (const gchar *profile_name)
3750 char *gdp_path, *dp_path;
3754 /* First check if profile exists */
3755 if (!profile_exists(profile_name, FALSE)) {
3756 if (profile_exists(profile_name, TRUE)) {
3757 /* Copy from global profile */
3758 copy_global_profile (profile_name);
3760 /* No personal and no global profile exists */
3765 /* Then check if changing to another profile */
3766 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3770 /* Get the current geometry, before writing it to disk */
3771 main_save_window_geometry(top_level);
3773 if (profile_exists(get_profile_name(), FALSE)) {
3774 /* Write recent file for profile we are leaving, if it still exists */
3775 write_profile_recent();
3778 /* Set profile name and update the status bar */
3779 set_profile_name (profile_name);
3780 profile_bar_update ();
3782 /* Reset current preferences and apply the new */
3786 (void) read_configuration_files (&gdp_path, &dp_path);
3788 recent_read_profile_static(&rf_path, &rf_open_errno);
3789 if (rf_path != NULL && rf_open_errno != 0) {
3790 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3791 "Could not open common recent file\n\"%s\": %s.",
3792 rf_path, g_strerror(rf_open_errno));
3794 if (recent.gui_fileopen_remembered_dir &&
3795 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3796 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3798 timestamp_set_type (recent.gui_time_format);
3799 timestamp_set_seconds_type (recent.gui_seconds_format);
3800 color_filters_enable(recent.packet_list_colorize);
3802 prefs_to_capture_opts();
3804 macros_post_update();
3806 /* Update window view and redraw the toolbar */
3807 update_main_window_title();
3808 toolbar_redraw_all();
3810 /* Enable all protocols and disable from the disabled list */
3812 if (gdp_path == NULL && dp_path == NULL) {
3813 set_disabled_protos_list();
3816 /* Reload color filters */
3817 color_filters_reload();
3819 /* Reload list of interfaces on welcome page */
3820 welcome_if_panel_reload();
3822 /* Recreate the packet list according to new preferences */
3823 new_packet_list_recreate ();
3824 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3827 /* Update menus with new recent values */
3828 menu_recent_read_finished();
3830 /* Reload pane geometry, must be done after recreating the list */
3831 main_pane_load_window_geometry();
3834 /** redissect packets and update UI */
3835 void redissect_packets(void)
3837 cf_redissect_packets(&cfile);
3838 status_expert_update();