3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * Richard Sharpe, 13-Feb-1999, added support for initializing structures
8 * needed by dissect routines
9 * Jeff Foster, 2001/03/12, added support tabbed hex display windowss
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <gdk/gdkkeysyms.h>
31 #if GTK_CHECK_VERSION(3,0,0)
32 # include <gdk/gdkkeysyms-compat.h>
44 #include "wsutil/wsgetopt.h"
48 #include <zlib.h> /* to get the libz version number */
51 #ifdef HAVE_LIBPORTAUDIO
52 #include <portaudio.h>
53 #endif /* HAVE_LIBPORTAUDIO */
55 #include <wsutil/clopts_common.h>
56 #include <wsutil/crash_info.h>
57 #include <wsutil/filesystem.h>
58 #include <wsutil/file_util.h>
59 #include <wsutil/privileges.h>
60 #include <wsutil/report_err.h>
61 #include <wsutil/u3.h>
62 #include <wsutil/copyright_info.h>
63 #include <wsutil/os_version_info.h>
64 #include <wsutil/ws_version_info.h>
66 #include <wiretap/merge.h>
68 #include <epan/addr_resolv.h>
69 #include <epan/column.h>
70 #include <epan/disabled_protos.h>
71 #include <epan/epan.h>
72 #include <epan/proto.h>
73 #include <epan/epan_dissect.h>
74 #include <epan/dfilter/dfilter.h>
75 #include <epan/strutil.h>
76 #include <epan/emem.h>
77 #include <epan/ex-opt.h>
78 #include <epan/funnel.h>
79 #include <epan/expert.h>
80 #include <epan/frequency-utils.h>
81 #include <epan/prefs.h>
82 #include <epan/prefs-int.h>
84 #include <epan/stat_tap_ui.h>
86 #include <epan/print.h>
87 #include <epan/timestamp.h>
88 #include <epan/conversation_table.h>
90 #include <wsutil/cmdarg_err.h>
91 #include <wsutil/plugins.h>
93 /* general (not GTK specific) */
95 #include "../frame_tvbuff.h"
96 #include "../summary.h"
98 #include "../color_filters.h"
99 #include "../register.h"
100 #include "../ringbuffer.h"
101 #include "../version_info.h"
104 #include "gtk_iface_monitor.h"
106 #include "ui/alert_box.h"
107 #include "ui/console.h"
108 #include "ui/decode_as_utils.h"
109 #include "ui/filters.h"
110 #include "ui/main_statusbar.h"
111 #include "ui/persfilepath_opt.h"
112 #include "ui/preference_utils.h"
113 #include "ui/recent.h"
114 #include "ui/recent_utils.h"
115 #include "ui/software_update.h"
116 #include "ui/ui_util.h"
120 #include "ui/capture_ui_utils.h"
121 #include "ui/capture_globals.h"
122 #include "ui/iface_lists.h"
125 #include "codecs/codecs.h"
127 #include "caputils/capture-pcap-util.h"
130 #include "caputils/capture_ifinfo.h"
131 #include "ui/capture.h"
132 #include <capchild/capture_sync.h>
136 #include "caputils/capture-wpcap.h"
137 #include "caputils/capture_wpcap_packet.h"
138 #include <tchar.h> /* Needed for Unicode */
139 #include <wsutil/unicode-utils.h>
140 #include <commctrl.h>
141 #include <shellapi.h>
145 #include "ui/gtk/file_dlg.h"
146 #include "ui/gtk/gtkglobals.h"
147 #include "ui/gtk/color_utils.h"
148 #include "ui/gtk/gui_utils.h"
149 #include "ui/gtk/color_dlg.h"
150 #include "ui/gtk/filter_dlg.h"
151 #include "ui/gtk/fileset_dlg.h"
152 #include "ui/gtk/uat_gui.h"
153 #include "ui/gtk/main.h"
154 #include "ui/gtk/main_80211_toolbar.h"
155 #include "ui/gtk/main_airpcap_toolbar.h"
156 #include "ui/gtk/main_filter_toolbar.h"
157 #include "ui/gtk/main_titlebar.h"
158 #include "ui/gtk/menus.h"
159 #include "ui/gtk/main_menubar_private.h"
160 #include "ui/gtk/macros_dlg.h"
161 #include "ui/gtk/main_statusbar_private.h"
162 #include "ui/gtk/main_toolbar.h"
163 #include "ui/gtk/main_toolbar_private.h"
164 #include "ui/gtk/main_welcome.h"
165 #include "ui/gtk/drag_and_drop.h"
166 #include "ui/gtk/capture_file_dlg.h"
167 #include "ui/gtk/packet_panes.h"
168 #include "ui/gtk/keys.h"
169 #include "ui/gtk/packet_win.h"
170 #include "ui/gtk/stock_icons.h"
171 #include "ui/gtk/find_dlg.h"
172 #include "ui/gtk/follow_tcp.h"
173 #include "ui/gtk/font_utils.h"
174 #include "ui/gtk/about_dlg.h"
175 #include "ui/gtk/help_dlg.h"
176 #include "ui/gtk/decode_as_dlg.h"
177 #include "ui/gtk/webbrowser.h"
178 #include "ui/gtk/capture_dlg.h"
179 #include "ui/gtk/capture_if_dlg.h"
180 #include "ui/gtk/tap_param_dlg.h"
181 #include "ui/gtk/prefs_column.h"
182 #include "ui/gtk/prefs_dlg.h"
183 #include "ui/gtk/proto_help.h"
184 #include "ui/gtk/packet_list.h"
185 #include "ui/gtk/filter_expression_save_dlg.h"
186 #include "ui/gtk/conversations_table.h"
187 #include "ui/gtk/hostlist_table.h"
188 #include "simple_dialog.h"
190 #include "ui/gtk/old-gtk-compat.h"
194 #include "wsiconcap.h"
198 #include <caputils/airpcap.h>
199 #include <caputils/airpcap_loader.h>
200 #include "airpcap_dlg.h"
201 #include "airpcap_gui_utils.h"
204 #include <epan/crypt/airpdcap_ws.h>
207 #ifdef HAVE_GTKOSXAPPLICATION
208 #include <gtkmacintegration/gtkosxapplication.h>
212 * Files under personal and global preferences directories in which
213 * GTK settings for Wireshark are stored.
215 #define RC_FILE "gtkrc"
218 capture_options global_capture_opts;
219 capture_session global_capture_session;
224 static gboolean capture_stopping;
226 /* "exported" main widgets */
227 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
229 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
230 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
231 static GtkWidget *main_first_pane, *main_second_pane;
233 /* internally used widgets */
234 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
236 GtkWidget *wireless_tb;
238 int airpcap_dll_ret_val = -1;
241 GString *comp_info_str, *runtime_info_str;
243 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
245 static guint tap_update_timer_id;
247 static void create_main_window(gint, gint, gint, e_prefs*);
248 static void show_main_window(gboolean);
249 static void main_save_window_geometry(GtkWidget *widget);
252 /* Match selected byte pattern */
254 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
256 char *cur_filter, *new_filter;
258 if ((!text) || (0 == strlen(text))) {
259 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
265 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
267 switch (action&MATCH_SELECTED_MASK) {
269 case MATCH_SELECTED_REPLACE:
270 new_filter = g_strdup(text);
273 case MATCH_SELECTED_AND:
274 if ((!cur_filter) || (0 == strlen(cur_filter)))
275 new_filter = g_strdup(text);
277 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
280 case MATCH_SELECTED_OR:
281 if ((!cur_filter) || (0 == strlen(cur_filter)))
282 new_filter = g_strdup(text);
284 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
287 case MATCH_SELECTED_NOT:
288 new_filter = g_strconcat("!(", text, ")", NULL);
291 case MATCH_SELECTED_AND_NOT:
292 if ((!cur_filter) || (0 == strlen(cur_filter)))
293 new_filter = g_strconcat("!(", text, ")", NULL);
295 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
298 case MATCH_SELECTED_OR_NOT:
299 if ((!cur_filter) || (0 == strlen(cur_filter)))
300 new_filter = g_strconcat("!(", text, ")", NULL);
302 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
306 g_assert_not_reached();
311 /* Free up the copy we got of the old filter text. */
314 /* Don't change the current display filter if we only want to copy the filter */
315 if (action&MATCH_SELECTED_COPY_ONLY) {
316 GString *gtk_text_str = g_string_new("");
317 g_string_append(gtk_text_str, new_filter);
318 copy_to_clipboard(gtk_text_str);
319 g_string_free(gtk_text_str, TRUE);
321 /* create a new one and set the display filter entry accordingly */
322 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
324 /* Run the display filter so it goes in effect. */
325 if (action&MATCH_SELECTED_APPLY_NOW)
326 main_filter_packets(&cfile, new_filter, FALSE);
329 /* Free up the new filter text. */
334 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
338 if (cfile.finfo_selected) {
339 filter = proto_construct_match_selected_string(cfile.finfo_selected,
341 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
346 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
350 if (cfile.finfo_selected) {
351 filter = proto_construct_match_selected_string(cfile.finfo_selected,
353 if ((!filter) || (0 == strlen(filter))) {
354 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
355 "Could not acquire information to build a filter!\n"
356 "Try expanding or choosing another item.");
361 color_display_with_filter(filter);
364 color_filters_reset_tmp();
366 color_filters_set_tmp(filt_nr,filter, FALSE);
368 packet_list_colorize_packets();
374 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
376 gchar *selected_proto_url;
377 gchar *proto_abbrev = (gchar *)data;
382 if (cfile.finfo_selected) {
383 /* open wiki page using the protocol abbreviation */
384 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
385 browser_open_url(selected_proto_url);
386 g_free(selected_proto_url);
389 case(ESD_BTN_CANCEL):
392 g_assert_not_reached();
398 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
401 const gchar *proto_abbrev;
405 if (cfile.finfo_selected) {
406 /* convert selected field to protocol abbreviation */
407 /* XXX - could this conversion be simplified? */
408 field_id = cfile.finfo_selected->hfinfo->id;
409 /* if the selected field isn't a protocol, get its parent */
410 if(!proto_registrar_is_protocol(field_id)) {
411 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
414 proto_abbrev = proto_registrar_get_abbrev(field_id);
416 if (!proto_is_private(field_id)) {
417 /* ask the user if the wiki page really should be opened */
418 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
419 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
421 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
423 "The Wireshark Wiki is a collaborative approach to provide information "
424 "about Wireshark in several ways (not limited to protocol specifics).\n"
426 "This Wiki is new, so the page of the selected protocol "
427 "may not exist and/or may not contain valuable information.\n"
429 "As everyone can edit the Wiki and add new content (or extend existing), "
430 "you are encouraged to add information if you can.\n"
432 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
434 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
435 "which will save you a lot of editing and will give a consistent look over the pages.",
436 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
437 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
439 /* appologize to the user that the wiki page cannot be opened */
440 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
441 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
443 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
445 "Since this is a private protocol, such information is not available in "
446 "a public wiki. Therefore this wiki entry is blocked.\n"
448 "Sorry for the inconvenience.\n",
449 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
454 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
456 gchar *selected_proto_url;
457 gchar *proto_abbrev = (gchar *)data;
461 if (cfile.finfo_selected) {
462 /* open reference page using the protocol abbreviation */
463 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
464 browser_open_url(selected_proto_url);
465 g_free(selected_proto_url);
468 case(ESD_BTN_CANCEL):
471 g_assert_not_reached();
476 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
479 const gchar *proto_abbrev;
483 if (cfile.finfo_selected) {
484 /* convert selected field to protocol abbreviation */
485 /* XXX - could this conversion be simplified? */
486 field_id = cfile.finfo_selected->hfinfo->id;
487 /* if the selected field isn't a protocol, get its parent */
488 if(!proto_registrar_is_protocol(field_id)) {
489 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
492 proto_abbrev = proto_registrar_get_abbrev(field_id);
494 if (!proto_is_private(field_id)) {
495 /* ask the user if the wiki page really should be opened */
496 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
497 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
499 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
501 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
502 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
504 /* appologize to the user that the wiki page cannot be opened */
505 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
506 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
508 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
510 "Since this is a private protocol, such information is not available on "
511 "a public website. Therefore this filter entry is blocked.\n"
513 "Sorry for the inconvenience.\n",
514 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
520 is_address_column (gint column)
522 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
523 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
524 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
525 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
526 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
535 get_ip_address_list_from_packet_list_row(gpointer data)
537 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
538 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
541 GList *addr_list = NULL;
543 fdata = (frame_data *) packet_list_get_row_data(row);
548 if (!cf_read_record(&cfile, fdata))
549 return NULL; /* error reading the frame */
551 epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
552 col_custom_prime_edt(&edt, &cfile.cinfo);
554 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
555 frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
556 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
558 /* First check selected column */
559 if (is_address_column (column)) {
560 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
563 for (col = 0; col < cfile.cinfo.num_cols; col++) {
564 /* Then check all columns except the selected */
565 if ((col != column) && (is_address_column (col))) {
566 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
570 epan_dissect_cleanup(&edt);
577 get_filter_from_packet_list_row_and_column(gpointer data)
579 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
580 gint column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
584 fdata = (frame_data *) packet_list_get_row_data(row);
589 if (!cf_read_record(&cfile, fdata))
590 return NULL; /* error reading the record */
591 /* proto tree, visible. We need a proto tree if there's custom columns */
592 epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
593 col_custom_prime_edt(&edt, &cfile.cinfo);
595 epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
596 frame_tvbuff_new_buffer(fdata, &cfile.buf),
597 fdata, &cfile.cinfo);
598 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
600 if ((cfile.cinfo.col_custom_occurrence[column]) ||
601 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
603 /* Only construct the filter when a single occurrence is displayed
604 * otherwise we might end up with a filter like "ip.proto==1,6".
606 * Or do we want to be able to filter on multiple occurrences so that
607 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
610 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
611 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
612 /* leak a little but safer than ep_ here */
613 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
614 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
615 if (hfi && hfi->parent == -1) {
617 buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
618 } else if (hfi && IS_FT_STRING(hfi->type)) {
619 /* Custom string, add quotes */
620 buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
621 cfile.cinfo.col_expr.col_expr_val[column]);
625 buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
626 cfile.cinfo.col_expr.col_expr_val[column]);
631 epan_dissect_cleanup(&edt);
638 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
642 filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
644 match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
650 /* This function allows users to right click in the details window and copy the text
651 * information to the operating systems clipboard.
653 * We first check to see if a string representation is setup in the tree and then
654 * read the string. If not available then we try to grab the value. If all else
655 * fails we display a message to the user to indicate the copy could not be completed.
658 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
660 GString *gtk_text_str = g_string_new("");
661 char labelstring[ITEM_LABEL_LENGTH];
662 char *stringpointer = labelstring;
666 case COPY_SELECTED_DESCRIPTION:
667 if (cfile.finfo_selected->rep &&
668 strlen (cfile.finfo_selected->rep->representation) > 0) {
669 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
672 case COPY_SELECTED_FIELDNAME:
673 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
674 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
677 case COPY_SELECTED_VALUE:
678 if (cfile.edt !=0 ) {
679 gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
680 g_string_append(gtk_text_str, field_str);
688 if (gtk_text_str->len == 0) {
689 /* If no representation then... Try to read the value */
690 proto_item_fill_label(cfile.finfo_selected, stringpointer);
691 g_string_append(gtk_text_str, stringpointer);
694 if (gtk_text_str->len == 0) {
695 /* Could not get item so display error msg */
696 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
698 /* Copy string to clipboard */
699 copy_to_clipboard(gtk_text_str);
701 g_string_free(gtk_text_str, TRUE); /* Free the memory */
705 /* mark as reference time frame */
707 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
711 frame->flags.ref_time=1;
712 cfile.ref_time_count++;
714 frame->flags.ref_time=0;
715 cfile.ref_time_count--;
717 cf_reftime_packets(&cfile);
718 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
719 packet_list_freeze();
720 cfile.displayed_count--;
721 packet_list_recreate_visible_rows();
724 packet_list_queue_draw();
728 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
732 timestamp_set_type(TS_RELATIVE);
733 recent.gui_time_format = TS_RELATIVE;
734 cf_timestamp_auto_precision(&cfile);
735 packet_list_queue_draw();
740 g_assert_not_reached();
743 if (cfile.current_frame) {
744 set_frame_reftime(!cfile.current_frame->flags.ref_time,
745 cfile.current_frame, cfile.current_row);
751 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
753 static GtkWidget *reftime_dialog = NULL;
757 if (cfile.current_frame) {
758 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
759 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
760 "%sSwitch to the appropriate Time Display Format?%s\n\n"
761 "Time References don't work well with the currently selected Time Display Format.\n\n"
762 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
763 simple_dialog_primary_start(), simple_dialog_primary_end());
764 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
766 set_frame_reftime(!cfile.current_frame->flags.ref_time,
767 cfile.current_frame, cfile.current_row);
771 case REFTIME_FIND_NEXT:
772 cf_find_packet_time_reference(&cfile, SD_FORWARD);
774 case REFTIME_FIND_PREV:
775 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
781 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
783 cf_find_packet_marked(&cfile, SD_FORWARD);
787 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
789 cf_find_packet_marked(&cfile, SD_BACKWARD);
793 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
796 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
798 gboolean has_blurb = FALSE;
799 guint length = 0, byte_len;
800 GtkWidget *byte_view;
801 const guint8 *byte_data;
806 /* if nothing is selected */
807 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
810 * Which byte view is displaying the current protocol tree
813 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
814 if (byte_view == NULL)
817 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
818 if (byte_data == NULL)
821 cf_unselect_field(&cfile);
822 packet_hex_print(byte_view, byte_data,
823 cfile.current_frame, NULL, byte_len);
824 proto_help_menu_modify(sel, &cfile);
827 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
830 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
832 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
833 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
834 g_assert(byte_data != NULL);
836 cfile.finfo_selected = finfo;
837 set_menus_for_selected_tree_row(&cfile);
840 if (finfo->hfinfo->blurb != NULL &&
841 finfo->hfinfo->blurb[0] != '\0') {
843 length = (guint) strlen(finfo->hfinfo->blurb);
845 length = (guint) strlen(finfo->hfinfo->name);
847 finfo_length = finfo->length + finfo->appendix_length;
849 if (finfo_length == 0) {
851 } else if (finfo_length == 1) {
852 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
854 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
856 statusbar_pop_field_msg(); /* get rid of current help msg */
858 statusbar_push_field_msg(" %s (%s)%s",
859 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
860 finfo->hfinfo->abbrev, len_str);
863 * Don't show anything if the field name is zero-length;
864 * the pseudo-field for "proto_tree_add_text()" is such
865 * a field, and we don't want "Text (text)" showing up
866 * on the status line if you've selected such a field.
868 * XXX - there are zero-length fields for which we *do*
869 * want to show the field name.
871 * XXX - perhaps the name and abbrev field should be null
872 * pointers rather than null strings for that pseudo-field,
873 * but we'd have to add checks for null pointers in some
874 * places if we did that.
876 * Or perhaps protocol tree items added with
877 * "proto_tree_add_text()" should have -1 as the field index,
878 * with no pseudo-field being used, but that might also
879 * require special checks for -1 to be added.
881 statusbar_push_field_msg("%s", "");
884 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
886 proto_help_menu_modify(sel, &cfile);
889 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
892 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
895 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
898 expand_all_tree(cfile.edt->tree, tree_view_gbl);
901 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
903 if (cfile.finfo_selected) {
904 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
905 cfile.finfo_selected->hfinfo->abbrev,0);
906 /* Recreate the packet list according to new preferences */
907 packet_list_recreate ();
908 if (!prefs.gui_use_pref_save) {
911 cfile.columns_changed = FALSE; /* Reset value */
915 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
919 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
921 /* the mouse position is at an entry, expand that one */
922 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
923 gtk_tree_path_free(path);
927 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
931 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
933 /* the mouse position is at an entry, expand that one */
935 tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
936 gtk_tree_path_free(path);
940 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
942 static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
944 if (cfile.edt->tree) {
945 proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
949 /* Update main window items based on whether there's a capture in progress. */
951 main_set_for_capture_in_progress(gboolean capture_in_progress)
953 set_menus_for_capture_in_progress(capture_in_progress);
956 set_toolbar_for_capture_in_progress(capture_in_progress);
958 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
962 /* Update main window items based on whether we have a capture file. */
964 main_set_for_capture_file(gboolean have_capture_file_in)
966 have_capture_file = have_capture_file_in;
968 main_widgets_show_or_hide();
971 /* Update main window items based on whether we have captured packets. */
973 main_set_for_captured_packets(gboolean have_captured_packets)
975 set_menus_for_captured_packets(have_captured_packets);
976 set_toolbar_for_captured_packets(have_captured_packets);
979 /* Update main window items based on whether we have a packet history. */
981 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
983 set_menus_for_packet_history(back_history, forward_history);
984 set_toolbar_for_packet_history(back_history, forward_history);
990 /* get the current geometry, before writing it to disk */
991 main_save_window_geometry(top_level);
993 /* write user's recent file to disk
994 * It is no problem to write this file, even if we do not quit */
995 write_profile_recent();
998 /* XXX - should we check whether the capture file is an
999 unsaved temporary file for a live capture and, if so,
1000 pop up a "do you want to exit without saving the capture
1001 file?" dialog, and then just return, leaving said dialog
1002 box to forcibly quit if the user clicks "OK"?
1004 If so, note that this should be done in a subroutine that
1005 returns TRUE if we do so, and FALSE otherwise, and if it
1006 returns TRUE we should return TRUE without nuking anything.
1008 Note that, if we do that, we might also want to check if
1009 an "Update list of packets in real time" capture is in
1010 progress and, if so, ask whether they want to terminate
1011 the capture and discard it, and return TRUE, before nuking
1012 any child capture, if they say they don't want to do so. */
1015 /* Nuke any child capture in progress. */
1016 capture_kill_child(&global_capture_session);
1019 /* Are we in the middle of reading a capture? */
1020 if (cfile.state == FILE_READ_IN_PROGRESS) {
1021 /* Yes, so we can't just close the file and quit, as
1022 that may yank the rug out from under the read in
1023 progress; instead, just set the state to
1024 "FILE_READ_ABORTED" and return - the code doing the read
1025 will check for that and, if it sees that, will clean
1027 cfile.state = FILE_READ_ABORTED;
1029 /* Say that the window should *not* be deleted;
1030 that'll be done by the code that cleans up. */
1033 /* Close any capture file we have open; on some OSes, you
1034 can't unlink a temporary capture file if you have it
1036 "cf_close()" will unlink it after closing it if
1037 it's a temporary file.
1039 We do this here, rather than after the main loop returns,
1040 as, after the main loop returns, the main window may have
1041 been destroyed (if this is called due to a "destroy"
1042 even on the main window rather than due to the user
1043 selecting a menu item), and there may be a crash
1044 or other problem when "cf_close()" tries to
1045 clean up stuff in the main window.
1047 XXX - is there a better place to put this?
1048 Or should we have a routine that *just* closes the
1049 capture file, and doesn't do anything with the UI,
1050 which we'd call here, and another routine that
1051 calls that routine and also cleans up the UI, which
1052 we'd call elsewhere? */
1055 /* Exit by leaving the main loop, so that any quit functions
1056 we registered get called. */
1059 /* Say that the window should be deleted. */
1065 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1067 /* If we're in the middle of stopping a capture, don't do anything;
1068 the user can try deleting the window after the capture stops. */
1069 if (capture_stopping)
1072 /* If there's unsaved data, let the user save it first.
1073 If they cancel out of it, don't quit. */
1074 if (do_file_close(&cfile, TRUE, " before quitting"))
1075 return main_do_quit();
1077 return TRUE; /* will this keep the window from being deleted? */
1082 main_pane_load_window_geometry(void)
1084 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1085 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1086 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1087 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1093 main_load_window_geometry(GtkWidget *widget)
1095 window_geometry_t geom;
1097 geom.set_pos = prefs.gui_geometry_save_position;
1098 geom.x = recent.gui_geometry_main_x;
1099 geom.y = recent.gui_geometry_main_y;
1100 geom.set_size = prefs.gui_geometry_save_size;
1101 if (recent.gui_geometry_main_width > 0 &&
1102 recent.gui_geometry_main_height > 0) {
1103 geom.width = recent.gui_geometry_main_width;
1104 geom.height = recent.gui_geometry_main_height;
1105 geom.set_maximized = prefs.gui_geometry_save_maximized;
1107 /* We assume this means the width and height weren't set in
1108 the "recent" file (or that there is no "recent" file),
1109 and weren't set to a default value, so we don't set the
1110 size. (The "recent" file code rejects non-positive width
1111 and height values.) */
1112 geom.set_size = FALSE;
1114 geom.maximized = recent.gui_geometry_main_maximized;
1116 window_set_geometry(widget, &geom);
1118 main_pane_load_window_geometry();
1119 statusbar_load_window_geometry();
1124 main_save_window_geometry(GtkWidget *widget)
1126 window_geometry_t geom;
1128 window_get_geometry(widget, &geom);
1130 if (prefs.gui_geometry_save_position) {
1131 recent.gui_geometry_main_x = geom.x;
1132 recent.gui_geometry_main_y = geom.y;
1135 if (prefs.gui_geometry_save_size) {
1136 recent.gui_geometry_main_width = geom.width;
1137 recent.gui_geometry_main_height = geom.height;
1140 if(prefs.gui_geometry_save_maximized) {
1141 recent.gui_geometry_main_maximized = geom.maximized;
1144 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1145 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1146 statusbar_save_window_geometry();
1150 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1152 /* If there's unsaved data, let the user save it first. */
1153 if (do_file_close(&cfile, TRUE, " before quitting"))
1158 print_usage(gboolean for_help_option) {
1166 if (for_help_option) {
1168 fprintf(output, "Wireshark %s\n"
1169 "Interactively dump and analyze network traffic.\n"
1170 "See http://www.wireshark.org for more information.\n",
1171 get_ws_vcs_version_info());
1175 fprintf(output, "\n");
1176 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1177 fprintf(output, "\n");
1180 fprintf(output, "Capture interface:\n");
1181 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1182 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1183 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1184 fprintf(output, " -p don't capture in promiscuous mode\n");
1185 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1186 fprintf(output, " -S update packet display when new packets are captured\n");
1187 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1188 #ifdef HAVE_PCAP_CREATE
1189 fprintf(output, " -I capture in monitor mode, if available\n");
1191 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1192 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1194 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1195 fprintf(output, " -D print list of interfaces and exit\n");
1196 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1197 fprintf(output, "\n");
1198 fprintf(output, "Capture stop conditions:\n");
1199 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1200 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1201 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1202 fprintf(output, " files:NUM - stop after NUM files\n");
1203 /*fprintf(output, "\n");*/
1204 fprintf(output, "Capture output:\n");
1205 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1206 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1207 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1208 #endif /* HAVE_LIBPCAP */
1209 #ifdef HAVE_PCAP_REMOTE
1210 fprintf(output, "RPCAP options:\n");
1211 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
1213 /*fprintf(output, "\n");*/
1214 fprintf(output, "Input file:\n");
1215 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1217 fprintf(output, "\n");
1218 fprintf(output, "Processing:\n");
1219 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1220 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1221 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1223 fprintf(output, "\n");
1224 fprintf(output, "User interface:\n");
1225 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1226 fprintf(output, " -Y <display filter> start with the given display filter\n");
1227 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1228 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1229 fprintf(output, " filter\n");
1230 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1231 fprintf(output, " -m <font> set the font name used for most text\n");
1232 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
1233 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1234 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1235 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1237 fprintf(output, "\n");
1238 fprintf(output, "Output:\n");
1239 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1241 fprintf(output, "\n");
1242 fprintf(output, "Miscellaneous:\n");
1243 fprintf(output, " -h display this help and exit\n");
1244 fprintf(output, " -v display version info and exit\n");
1245 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1246 fprintf(output, " persdata:path - personal data files\n");
1247 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1248 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1250 fprintf(output, " --display=DISPLAY X display to use\n");
1261 printf("Wireshark %s\n"
1268 get_ws_vcs_version_info(), get_copyright_info(), comp_info_str->str,
1269 runtime_info_str->str);
1273 * Report an error in command-line arguments.
1274 * Creates a console on Windows.
1275 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1276 * terminal isn't the standard error?
1279 wireshark_cmdarg_err(const char *fmt, va_list ap)
1284 fprintf(stderr, "wireshark: ");
1285 vfprintf(stderr, fmt, ap);
1286 fprintf(stderr, "\n");
1290 * Report additional information for an error in command-line arguments.
1291 * Creates a console on Windows.
1292 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1293 * terminal isn't the standard error?
1296 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1301 vfprintf(stderr, fmt, ap);
1302 fprintf(stderr, "\n");
1306 Once every 3 seconds we get a callback here which we use to update
1310 tap_update_cb(gpointer data _U_)
1312 draw_tap_listeners(FALSE);
1317 * Periodically process outstanding hostname lookups. If we have new items,
1318 * redraw the packet list and tree view.
1322 resolv_update_cb(gpointer data _U_)
1324 /* Anything new show up? */
1325 if (host_name_lookup_process()) {
1326 if (gtk_widget_get_window(pkt_scrollw))
1327 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1328 if (gtk_widget_get_window(tv_scrollw))
1329 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1332 /* Always check. Even if we don't do async lookups we could still get
1333 passive updates, e.g. from DNS packets. */
1338 /* Update various parts of the main window for a capture file "unsaved
1339 changes" change - update the title to reflect whether there are
1340 unsaved changes or not, and update the menus and toolbar to
1341 enable or disable the "Save" operation. */
1343 main_update_for_unsaved_changes(capture_file *cf)
1345 set_titlebar_for_capture_file(cf);
1346 set_menus_for_capture_file(cf);
1347 set_toolbar_for_capture_file(cf);
1352 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1354 /* Update menubar and toolbar */
1355 menu_auto_scroll_live_changed(auto_scroll_live_in);
1356 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1358 /* change auto scroll state */
1359 auto_scroll_live = auto_scroll_live_in;
1364 main_colorize_changed(gboolean packet_list_colorize)
1366 /* Update menubar and toolbar */
1367 menu_colorize_changed(packet_list_colorize);
1368 toolbar_colorize_changed(packet_list_colorize);
1370 /* change colorization */
1371 if(packet_list_colorize != recent.packet_list_colorize) {
1372 recent.packet_list_colorize = packet_list_colorize;
1373 color_filters_enable(packet_list_colorize);
1374 packet_list_colorize_packets();
1378 static GtkWidget *close_dlg = NULL;
1381 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1383 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1388 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1390 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1395 main_cf_cb_file_closing(capture_file *cf)
1397 /* if we have more than 10000 packets, show a splash screen while closing */
1398 /* XXX - don't know a better way to decide whether to show or not,
1399 * as most of the time is spend in various calls that destroy various
1400 * data structures, so it wouldn't be easy to use a progress bar,
1401 * rather than, say, a progress spinner, here! */
1402 if(cf->count > 10000) {
1403 close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1404 "%sClosing file!%s\n\nPlease wait ...",
1405 simple_dialog_primary_start(),
1406 simple_dialog_primary_end());
1407 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1409 /* Clear maunally resolved addresses */
1410 manually_resolve_cleanup();
1411 /* Destroy all windows that refer to the
1412 capture file we're closing. */
1413 destroy_packet_wins();
1415 /* Update the titlebar to reflect the lack of a capture file. */
1416 set_titlebar_for_capture_file(NULL);
1418 /* Disable all menu and toolbar items that make sense only if
1419 you have a capture. */
1420 set_menus_for_capture_file(NULL);
1421 set_toolbar_for_capture_file(NULL);
1422 main_set_for_captured_packets(FALSE);
1423 set_menus_for_selected_packet(cf);
1424 main_set_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();
1436 main_cf_cb_file_closed(capture_file *cf _U_)
1438 if(close_dlg != NULL) {
1439 splash_destroy(close_dlg);
1446 main_cf_cb_file_read_started(capture_file *cf _U_)
1448 tap_param_dlg_update();
1450 /* Set up main window for a capture file. */
1451 main_set_for_capture_file(TRUE);
1455 main_cf_cb_file_read_finished(capture_file *cf)
1459 if (!cf->is_tempfile && cf->filename) {
1460 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1461 add_menu_recent_capture_file(cf->filename);
1463 /* Remember folder for next Open dialog and save it in recent */
1464 dir_path = get_dirname(g_strdup(cf->filename));
1465 set_last_open_dir(dir_path);
1469 /* Update the appropriate parts of the main window. */
1470 main_update_for_unsaved_changes(cf);
1472 /* Enable menu items that make sense if you have some captured packets. */
1473 main_set_for_captured_packets(TRUE);
1477 main_cf_cb_file_rescan_finished(capture_file *cf)
1481 if (!cf->is_tempfile && cf->filename) {
1482 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1483 add_menu_recent_capture_file(cf->filename);
1485 /* Remember folder for next Open dialog and save it in recent */
1486 dir_path = get_dirname(g_strdup(cf->filename));
1487 set_last_open_dir(dir_path);
1491 /* Update the appropriate parts of the main window. */
1492 main_update_for_unsaved_changes(cf);
1496 static GList *icon_list_create(
1497 const guint8 *icon16_pb,
1498 const guint8 *icon32_pb,
1499 const guint8 *icon48_pb,
1500 const guint8 *icon64_pb)
1502 GList *icon_list = NULL;
1503 GdkPixbuf * pixbuf16;
1504 GdkPixbuf * pixbuf32;
1505 GdkPixbuf * pixbuf48;
1506 GdkPixbuf * pixbuf64;
1509 if(icon16_pb != NULL) {
1510 pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1512 icon_list = g_list_append(icon_list, pixbuf16);
1515 if(icon32_pb != NULL) {
1516 pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1518 icon_list = g_list_append(icon_list, pixbuf32);
1521 if(icon48_pb != NULL) {
1522 pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1524 icon_list = g_list_append(icon_list, pixbuf48);
1527 if(icon64_pb != NULL) {
1528 pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1530 icon_list = g_list_append(icon_list, pixbuf64);
1537 main_capture_cb_capture_prepared(capture_session *cap_session)
1539 static GList *icon_list = NULL;
1541 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1543 if(icon_list == NULL) {
1544 icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1546 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1548 /* Disable menu items that make no sense if you're currently running
1550 main_set_for_capture_in_progress(TRUE);
1551 set_capture_if_dialog_for_capture_in_progress(TRUE);
1553 /* Don't set up main window for a capture file. */
1554 main_set_for_capture_file(FALSE);
1558 main_capture_cb_capture_update_started(capture_session *cap_session)
1560 /* We've done this in "prepared" above, but it will be cleared while
1561 switching to the next multiple file. */
1562 set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1564 main_set_for_capture_in_progress(TRUE);
1565 set_capture_if_dialog_for_capture_in_progress(TRUE);
1567 /* Enable menu items that make sense if you have some captured
1568 packets (yes, I know, we don't have any *yet*). */
1569 main_set_for_captured_packets(TRUE);
1571 /* Set up main window for a capture file. */
1572 main_set_for_capture_file(TRUE);
1576 main_capture_cb_capture_update_finished(capture_session *cap_session)
1578 capture_file *cf = (capture_file *)cap_session->cf;
1579 static GList *icon_list = NULL;
1581 /* The capture isn't stopping any more - it's stopped. */
1582 capture_stopping = FALSE;
1584 if (!cf->is_tempfile && cf->filename) {
1585 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1586 add_menu_recent_capture_file(cf->filename);
1589 /* Enable menu items that make sense if you're not currently running
1591 main_set_for_capture_in_progress(FALSE);
1592 set_capture_if_dialog_for_capture_in_progress(FALSE);
1594 /* Update the main window as appropriate. This has to occur AFTER
1595 * main_set_for_capture_in_progress() or else some of the menus are
1596 * incorrectly disabled (see bug
1597 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1598 main_update_for_unsaved_changes(cf);
1600 /* Set up main window for a capture file. */
1601 main_set_for_capture_file(TRUE);
1603 if(icon_list == NULL) {
1604 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1606 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1608 if(global_capture_opts.quit_after_cap) {
1609 /* command line asked us to quit after the capture */
1610 /* don't pop up a dialog to ask for unsaved files etc. */
1616 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1618 /* Don't set up main window for a capture file. */
1619 main_set_for_capture_file(FALSE);
1623 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1626 capture_file *cf = (capture_file *)cap_session->cf;
1628 static GList *icon_list = NULL;
1630 /* The capture isn't stopping any more - it's stopped. */
1631 capture_stopping = FALSE;
1633 /*set_titlebar_for_capture_file(cf);*/
1635 /* Enable menu items that make sense if you're not currently running
1637 main_set_for_capture_in_progress(FALSE);
1638 set_capture_if_dialog_for_capture_in_progress(FALSE);
1640 /* Restore the standard title bar message */
1641 /* (just in case we have trouble opening the capture file). */
1642 set_titlebar_for_capture_file(NULL);
1644 if(icon_list == NULL) {
1645 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1647 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1649 /* We don't have loaded the capture file, this will be done later.
1650 * For now we still have simply a blank screen. */
1652 if(global_capture_opts.quit_after_cap) {
1653 /* command line asked us to quit after the capture */
1654 /* don't pop up a dialog to ask for unsaved files etc. */
1660 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1662 capture_stopping = TRUE;
1663 set_menus_for_capture_stopping();
1665 set_toolbar_for_capture_stopping();
1667 set_capture_if_dialog_for_capture_stopping();
1672 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1674 static GList *icon_list = NULL;
1676 /* Capture isn't stopping any more. */
1677 capture_stopping = FALSE;
1679 /* the capture failed before the first packet was captured
1680 reset title, menus and icon */
1681 set_titlebar_for_capture_file(NULL);
1683 main_set_for_capture_in_progress(FALSE);
1684 set_capture_if_dialog_for_capture_in_progress(FALSE);
1686 main_set_for_capture_file(FALSE);
1688 if(icon_list == NULL) {
1689 icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1691 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1694 if(global_capture_opts.quit_after_cap) {
1695 /* command line asked us to quit after the capture */
1696 /* don't pop up a dialog to ask for unsaved files etc. */
1700 #endif /* HAVE_LIBPCAP */
1703 main_cf_cb_packet_selected(gpointer data)
1705 capture_file *cf = (capture_file *)data;
1707 /* Display the GUI protocol tree and packet bytes.
1708 XXX - why do we dump core if we call "proto_tree_draw()"
1709 before calling "add_byte_views()"? */
1710 add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1711 proto_tree_draw(cf->edt->tree, tree_view_gbl);
1713 /* Note: Both string and hex value searches in the packet data produce a non-zero
1714 search_pos if successful */
1715 if(cf->search_in_progress &&
1716 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1717 highlight_field(cf->edt->tvb, cf->search_pos,
1718 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1721 /* A packet is selected. */
1722 set_menus_for_selected_packet(cf);
1726 main_cf_cb_packet_unselected(capture_file *cf)
1728 /* No packet is being displayed; clear the hex dump pane by getting
1729 rid of all the byte views. */
1730 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1731 gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1733 /* Add a placeholder byte view so that there's at least something
1734 displayed in the byte view notebook. */
1735 add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1737 /* And clear the protocol tree display as well. */
1738 proto_tree_draw(NULL, tree_view_gbl);
1740 /* No packet is selected. */
1741 set_menus_for_selected_packet(cf);
1745 main_cf_cb_field_unselected(capture_file *cf)
1747 set_menus_for_selected_tree_row(cf);
1751 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1753 capture_file *cf = (capture_file *)data;
1755 case(cf_cb_file_opened):
1756 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1757 fileset_file_opened(cf);
1759 case(cf_cb_file_closing):
1760 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1761 main_cf_cb_file_closing(cf);
1763 case(cf_cb_file_closed):
1764 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1765 main_cf_cb_file_closed(cf);
1766 fileset_file_closed();
1768 case(cf_cb_file_read_started):
1769 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1770 main_cf_cb_file_read_started(cf);
1772 case(cf_cb_file_read_finished):
1773 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1774 main_cf_cb_file_read_finished(cf);
1776 case(cf_cb_file_reload_started):
1777 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1778 main_cf_cb_file_read_started(cf);
1780 case(cf_cb_file_reload_finished):
1781 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1782 main_cf_cb_file_read_finished(cf);
1784 case(cf_cb_file_rescan_started):
1785 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1787 case(cf_cb_file_rescan_finished):
1788 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1789 main_cf_cb_file_rescan_finished(cf);
1791 case(cf_cb_file_fast_save_finished):
1792 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1793 main_cf_cb_file_rescan_finished(cf);
1795 case(cf_cb_packet_selected):
1796 main_cf_cb_packet_selected(cf);
1798 case(cf_cb_packet_unselected):
1799 main_cf_cb_packet_unselected(cf);
1801 case(cf_cb_field_unselected):
1802 main_cf_cb_field_unselected(cf);
1804 case(cf_cb_file_save_started):
1805 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1807 case(cf_cb_file_save_finished):
1808 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1810 case(cf_cb_file_save_failed):
1811 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1813 case(cf_cb_file_save_stopped):
1814 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1816 case(cf_cb_file_export_specified_packets_started):
1817 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1819 case(cf_cb_file_export_specified_packets_finished):
1820 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1822 case(cf_cb_file_export_specified_packets_failed):
1823 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1825 case(cf_cb_file_export_specified_packets_stopped):
1826 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1829 g_warning("main_cf_callback: event %u unknown", event);
1830 g_assert_not_reached();
1836 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1838 #ifdef HAVE_GTKOSXAPPLICATION
1839 GtkosxApplication *theApp;
1842 case(capture_cb_capture_prepared):
1843 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1844 main_capture_cb_capture_prepared(cap_session);
1846 case(capture_cb_capture_update_started):
1847 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1848 main_capture_cb_capture_update_started(cap_session);
1849 #ifdef HAVE_GTKOSXAPPLICATION
1850 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1851 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1854 case(capture_cb_capture_update_continue):
1855 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1857 case(capture_cb_capture_update_finished):
1858 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1859 main_capture_cb_capture_update_finished(cap_session);
1861 case(capture_cb_capture_fixed_started):
1862 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1863 main_capture_cb_capture_fixed_started(cap_session);
1865 case(capture_cb_capture_fixed_continue):
1866 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1868 case(capture_cb_capture_fixed_finished):
1869 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1870 main_capture_cb_capture_fixed_finished(cap_session);
1872 case(capture_cb_capture_stopping):
1873 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1874 /* Beware: this state won't be called, if the capture child
1875 * closes the capturing on its own! */
1876 #ifdef HAVE_GTKOSXAPPLICATION
1877 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1878 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1880 main_capture_cb_capture_stopping(cap_session);
1882 case(capture_cb_capture_failed):
1883 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1884 main_capture_cb_capture_failed(cap_session);
1887 g_warning("main_capture_callback: event %u unknown", event);
1888 g_assert_not_reached();
1894 get_wireshark_gtk_compiled_info(GString *str)
1896 g_string_append(str, "with ");
1897 g_string_append_printf(str,
1898 #ifdef GTK_MAJOR_VERSION
1899 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1902 "GTK+ (version unknown)");
1906 g_string_append(str, ", with Cairo ");
1907 g_string_append(str, CAIRO_VERSION_STRING);
1910 g_string_append(str, ", with Pango ");
1911 g_string_append(str, PANGO_VERSION_STRING);
1913 /* Capture libraries */
1914 g_string_append(str, ", ");
1915 get_compiled_caplibs_version(str);
1918 g_string_append(str, ", ");
1920 g_string_append(str, "with libz ");
1922 g_string_append(str, ZLIB_VERSION);
1923 #else /* ZLIB_VERSION */
1924 g_string_append(str, "(version unknown)");
1925 #endif /* ZLIB_VERSION */
1926 #else /* HAVE_LIBZ */
1927 g_string_append(str, "without libz");
1928 #endif /* HAVE_LIBZ */
1932 get_gui_compiled_info(GString *str)
1934 epan_get_compiled_version_info(str);
1936 g_string_append(str, ", ");
1937 #ifdef HAVE_LIBPORTAUDIO
1938 #ifdef PORTAUDIO_API_1
1939 g_string_append(str, "with PortAudio <= V18");
1940 #else /* PORTAUDIO_API_1 */
1941 g_string_append(str, "with ");
1942 g_string_append(str, Pa_GetVersionText());
1943 #endif /* PORTAUDIO_API_1 */
1944 #else /* HAVE_LIBPORTAUDIO */
1945 g_string_append(str, "without PortAudio");
1946 #endif /* HAVE_LIBPORTAUDIO */
1948 g_string_append(str, ", ");
1950 get_compiled_airpcap_version(str);
1952 g_string_append(str, "without AirPcap");
1957 get_wireshark_runtime_info(GString *str)
1960 /* Capture libraries */
1961 g_string_append(str, ", ");
1962 get_runtime_caplibs_version(str);
1966 #if defined(HAVE_LIBZ) && !defined(_WIN32)
1967 g_string_append_printf(str, ", with libz %s", zlibVersion());
1970 /* stuff used by libwireshark */
1971 epan_get_runtime_version_info(str);
1974 g_string_append(str, ", ");
1975 get_runtime_airpcap_version(str);
1979 g_string_append(str, ", ");
1980 u3_runtime_info(str);
1985 read_configuration_files(char **gdp_path, char **dp_path)
1987 int gpf_open_errno, gpf_read_errno;
1988 int cf_open_errno, df_open_errno;
1989 int gdp_open_errno, gdp_read_errno;
1990 int dp_open_errno, dp_read_errno;
1991 char *gpf_path, *pf_path;
1992 char *cf_path, *df_path;
1993 int pf_open_errno, pf_read_errno;
1996 /* load the decode as entries of this profile */
1997 load_decode_as_entries();
1999 /* Read the preference files. */
2000 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2001 &pf_open_errno, &pf_read_errno, &pf_path);
2003 if (gpf_path != NULL) {
2004 if (gpf_open_errno != 0) {
2005 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2006 "Could not open global preferences file\n\"%s\": %s.",
2007 gpf_path, g_strerror(gpf_open_errno));
2009 if (gpf_read_errno != 0) {
2010 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2011 "I/O error reading global preferences file\n\"%s\": %s.",
2012 gpf_path, g_strerror(gpf_read_errno));
2015 if (pf_path != NULL) {
2016 if (pf_open_errno != 0) {
2017 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2018 "Could not open your preferences file\n\"%s\": %s.",
2019 pf_path, g_strerror(pf_open_errno));
2021 if (pf_read_errno != 0) {
2022 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2023 "I/O error reading your preferences file\n\"%s\": %s.",
2024 pf_path, g_strerror(pf_read_errno));
2031 /* if the user wants a console to be always there, well, we should open one for him */
2032 if (prefs_p->gui_console_open == console_open_always) {
2037 /* Read the capture filter file. */
2038 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2039 if (cf_path != NULL) {
2040 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2041 "Could not open your capture filter file\n\"%s\": %s.",
2042 cf_path, g_strerror(cf_open_errno));
2046 /* Read the display filter file. */
2047 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2048 if (df_path != NULL) {
2049 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2050 "Could not open your display filter file\n\"%s\": %s.",
2051 df_path, g_strerror(df_open_errno));
2055 /* Read the disabled protocols file. */
2056 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2057 dp_path, &dp_open_errno, &dp_read_errno);
2058 if (*gdp_path != NULL) {
2059 if (gdp_open_errno != 0) {
2060 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2061 "Could not open global disabled protocols file\n\"%s\": %s.",
2062 *gdp_path, g_strerror(gdp_open_errno));
2064 if (gdp_read_errno != 0) {
2065 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2066 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2067 *gdp_path, g_strerror(gdp_read_errno));
2072 if (*dp_path != NULL) {
2073 if (dp_open_errno != 0) {
2074 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2075 "Could not open your disabled protocols file\n\"%s\": %s.",
2076 *dp_path, g_strerror(dp_open_errno));
2078 if (dp_read_errno != 0) {
2079 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2080 "I/O error reading your disabled protocols file\n\"%s\": %s.",
2081 *dp_path, g_strerror(dp_read_errno));
2090 /* Check if there's something important to tell the user during startup.
2091 * We want to do this *after* showing the main window so that any windows
2092 * we pop up will be above the main window.
2096 check_and_warn_user_startup(gchar *cf_name)
2098 check_and_warn_user_startup(gchar *cf_name _U_)
2101 gchar *cur_user, *cur_group;
2102 gpointer priv_warning_dialog;
2104 /* Tell the user not to run as root. */
2105 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2106 cur_user = get_cur_username();
2107 cur_group = get_cur_groupname();
2108 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2109 "Running as user \"%s\" and group \"%s\".\n"
2110 "This could be dangerous.\n\n"
2111 "If you're running Wireshark this way in order to perform live capture, "
2112 "you may want to be aware that there is a better way documented at\n"
2113 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2116 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2117 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2121 /* Warn the user if npf.sys isn't loaded. */
2122 if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2123 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2124 "The NPF driver isn't running. You may have trouble\n"
2125 "capturing or listing interfaces.");
2126 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2127 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2133 /* And now our feature presentation... [ fade to music ] */
2135 main(int argc, char *argv[])
2137 char *init_progfile_dir_error;
2140 gboolean arg_error = FALSE;
2142 extern int info_update_freq; /* Found in about_dlg.c. */
2143 const gchar *filter;
2151 char *gdp_path, *dp_path;
2154 gboolean start_capture = FALSE;
2155 gboolean list_link_layer_types = FALSE;
2160 gboolean capture_option_specified = FALSE;
2167 gint pl_size = 280, tv_size = 95, bv_size = 75;
2168 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2169 dfilter_t *rfcode = NULL;
2170 gboolean rfilter_parse_failed = FALSE;
2173 GtkWidget *splash_win = NULL;
2174 guint go_to_packet = 0;
2175 search_direction jump_backwards = SD_FORWARD;
2176 dfilter_t *jump_to_filter = NULL;
2178 unsigned int in_file_type = WTAP_TYPE_AUTO;
2179 #ifdef HAVE_GTKOSXAPPLICATION
2180 GtkosxApplication *theApp;
2183 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
2185 static const char optstring[] = OPTSTRING;
2187 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2189 /* Set the C-language locale to the native environment. */
2190 setlocale(LC_ALL, "");
2192 arg_list_utf_16to8(argc, argv);
2193 create_app_running_mutex();
2197 * Get credential information for later use, and drop privileges
2198 * before doing anything else.
2199 * Let the user know if anything happened.
2201 init_process_policies();
2202 relinquish_special_privs_perm();
2205 * Attempt to get the pathname of the executable file.
2207 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2209 /* initialize the funnel mini-api */
2210 initialize_funnel_ops();
2212 AirPDcapInitContext(&airpdcap_ctx);
2215 /* Load wpcap if possible. Do this before collecting the run-time version information */
2218 /* ... and also load the packet.dll from wpcap */
2219 wpcap_packet_load();
2222 /* Load the airpcap.dll. This must also be done before collecting
2223 * run-time version information. */
2224 airpcap_dll_ret_val = load_airpcap();
2226 switch (airpcap_dll_ret_val) {
2227 case AIRPCAP_DLL_OK:
2228 /* load the airpcap interfaces */
2229 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2231 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2232 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2233 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2236 airpcap_if_active = NULL;
2240 /* select the first ad default (THIS SHOULD BE CHANGED) */
2241 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2246 * XXX - Maybe we need to warn the user if one of the following happens???
2248 case AIRPCAP_DLL_OLD:
2249 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2252 case AIRPCAP_DLL_ERROR:
2253 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2256 case AIRPCAP_DLL_NOT_FOUND:
2257 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2261 #endif /* HAVE_AIRPCAP */
2264 /* Assemble the compile-time version information string */
2265 comp_info_str = g_string_new("Compiled ");
2267 get_compiled_version_info(comp_info_str, get_wireshark_gtk_compiled_info,
2268 get_gui_compiled_info);
2270 /* Assemble the run-time version information string */
2271 runtime_info_str = g_string_new("Running ");
2272 get_runtime_version_info(runtime_info_str, get_wireshark_runtime_info);
2274 /* Add it to the information to be reported on a crash. */
2275 ws_add_crash_info("Wireshark %s\n"
2280 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2283 /* Start windows sockets */
2284 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2287 profile_store_persconffiles (TRUE);
2289 /* Read the profile independent recent file. We have to do this here so we can */
2290 /* set the profile before it can be set from the command line parameter */
2291 recent_read_static(&rf_path, &rf_open_errno);
2292 if (rf_path != NULL && rf_open_errno != 0) {
2293 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2294 "Could not open common recent file\n\"%s\": %s.",
2295 rf_path, g_strerror(rf_open_errno));
2298 /* "pre-scan" the command line parameters, if we have "console only"
2299 parameters. We do this so we don't start GTK+ if we're only showing
2300 command-line help or version information.
2302 XXX - this pre-scan is done before we start GTK+, so we haven't
2303 run gtk_init() on the arguments. That means that GTK+ arguments
2304 have not been removed from the argument list; those arguments
2305 begin with "--", and will be treated as an error by getopt().
2307 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2310 optind_initial = optind;
2311 while ((opt = getopt(argc, argv, optstring)) != -1) {
2313 case 'C': /* Configuration Profile */
2314 if (profile_exists (optarg, FALSE)) {
2315 set_profile_name (optarg);
2317 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2321 case 'D': /* Print a list of capture devices and exit */
2323 if_list = capture_interface_list(&err, &err_str,main_window_update);
2324 if (if_list == NULL) {
2326 cmdarg_err("There are no interfaces on which a capture can be done");
2328 cmdarg_err("%s", err_str);
2336 capture_opts_print_interfaces(if_list);
2337 free_interface_list(if_list);
2342 #else /* HAVE_LIBPCAP */
2343 capture_option_specified = TRUE;
2345 #endif /* HAVE_LIBPCAP */
2347 case 'h': /* Print help and exit */
2353 if (strcmp(optarg, "-") == 0)
2354 set_stdin_capture(TRUE);
2357 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
2358 if (!persfilepath_opt(opt, optarg)) {
2359 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2363 case 'v': /* Show version and exit */
2375 * Extension command line options have to be processed before
2376 * we call epan_init() as they are supposed to be used by dissectors
2377 * or taps very early in the registration process.
2381 case '?': /* Ignore errors - the "real" scan will catch them. */
2386 /* Init the "Open file" dialog directory */
2387 /* (do this after the path settings are processed) */
2389 /* Read the profile dependent (static part) of the recent file. */
2390 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2391 /* recent lists which is done in the dynamic part. */
2392 /* We have to do this already here, so command line parameters can overwrite these values. */
2393 recent_read_profile_static(&rf_path, &rf_open_errno);
2394 if (rf_path != NULL && rf_open_errno != 0) {
2395 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2396 "Could not open recent file\n\"%s\": %s.",
2397 rf_path, g_strerror(rf_open_errno));
2400 if (recent.gui_fileopen_remembered_dir &&
2401 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2402 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2404 set_last_open_dir(get_persdatafile_dir());
2407 /* Set getopt index back to initial value, so it will start with the
2408 first command line parameter again. Also reset opterr to 1, so that
2409 error messages are printed by getopt().
2411 XXX - this seems to work on most platforms, but time will tell.
2412 The Single UNIX Specification says "The getopt() function need
2413 not be reentrant", so this isn't guaranteed to work. The Mac
2414 OS X 10.4[.x] getopt() man page says
2416 In order to use getopt() to evaluate multiple sets of arguments, or to
2417 evaluate a single set of arguments multiple times, the variable optreset
2418 must be set to 1 before the second and each additional set of calls to
2419 getopt(), and the variable optind must be reinitialized.
2423 The optreset variable was added to make it possible to call the getopt()
2424 function multiple times. This is an extension to the IEEE Std 1003.2
2425 (``POSIX.2'') specification.
2427 which I think comes from one of the other BSDs.
2429 XXX - if we want to control all the command-line option errors, so
2430 that we can display them where we choose (e.g., in a window), we'd
2431 want to leave opterr as 0, and produce our own messages using optopt.
2432 We'd have to check the value of optopt to see if it's a valid option
2433 letter, in which case *presumably* the error is "this option requires
2434 an argument but none was specified", or not a valid option letter,
2435 in which case *presumably* the error is "this option isn't valid".
2436 Some versions of getopt() let you supply a option string beginning
2437 with ':', which means that getopt() will return ':' rather than '?'
2438 for "this option requires an argument but none was specified", but
2440 optind = optind_initial;
2443 #if !GLIB_CHECK_VERSION(2,31,0)
2444 g_thread_init(NULL);
2447 /* Set the current locale according to the program environment.
2448 * We haven't localized anything, but some GTK widgets are localized
2449 * (the file selection dialogue, for example).
2450 * This also sets the C-language locale to the native environment. */
2451 setlocale (LC_ALL, "");
2453 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2454 gtk_init (&argc, &argv);
2456 cf_callback_add(main_cf_callback, NULL);
2458 capture_callback_add(main_capture_callback, NULL);
2460 cf_callback_add(statusbar_cf_callback, NULL);
2462 capture_callback_add(statusbar_capture_callback, NULL);
2465 set_console_log_handler();
2468 /* Set the initial values in the capture options. This might be overwritten
2469 by preference settings and then again by the command line parameters. */
2470 capture_opts_init(&global_capture_opts);
2472 capture_session_init(&global_capture_session, (void *)&cfile);
2475 init_report_err(failure_alert_box, open_failure_alert_box,
2476 read_failure_alert_box, write_failure_alert_box);
2478 /* Initialize whatever we need to allocate colors for GTK+ */
2481 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2482 filter = get_conn_cfilter();
2483 if ( *filter != '\0' ) {
2484 info_update_freq = 1000; /* Milliseconds */
2487 /* We won't come till here, if we had a "console only" command line parameter. */
2488 splash_win = splash_new("Loading Wireshark ...");
2489 if (init_progfile_dir_error != NULL) {
2490 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2491 "Can't get pathname of Wireshark: %s.\n"
2492 "It won't be possible to capture traffic.\n"
2493 "Report this to the Wireshark developers.",
2494 init_progfile_dir_error);
2495 g_free(init_progfile_dir_error);
2498 init_open_routines();
2501 /* Register all the plugin types we have. */
2502 epan_register_plugin_types(); /* Types known to libwireshark */
2503 wtap_register_plugin_types(); /* Types known to libwiretap */
2504 codec_register_plugin_types(); /* Types known to libcodec */
2506 /* Scan for plugins. This does *not* call their registration routines;
2507 that's done later. */
2510 /* Register all libwiretap plugin modules. */
2511 register_all_wiretap_modules();
2513 /* Register all audio codec plugins. */
2514 register_all_codecs();
2517 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2519 /* Register all dissectors; we must do this before checking for the
2520 "-G" flag, as the "-G" flag dumps information registered by the
2521 dissectors, and we must do it before we read the preferences, in
2522 case any dissectors register preferences. */
2523 epan_init(register_all_protocols,register_all_protocol_handoffs,
2524 splash_update, (gpointer) splash_win);
2526 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2528 /* Register all tap listeners; we do this before we parse the arguments,
2529 as the "-z" argument can specify a registered tap. */
2531 /* we register the plugin taps before the other taps because
2532 stats_tree taps plugins will be registered as tap listeners
2533 by stats_tree_stat.c and need to registered before that */
2536 register_all_plugin_tap_listeners();
2539 register_all_tap_listeners();
2540 conversation_table_set_gui_info(init_conversation_table);
2541 hostlist_table_set_gui_info(init_hostlist_table);
2543 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2545 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2546 /* Removed thread code:
2547 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2550 /* this is to keep tap extensions updating once every 3 seconds */
2551 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2553 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2555 cap_file_init(&cfile);
2557 /* Fill in capture options with values from the preferences */
2558 prefs_to_capture_opts();
2560 /*#ifdef HAVE_LIBPCAP
2561 fill_in_local_interfaces();
2563 /* Now get our args */
2564 while ((opt = getopt(argc, argv, optstring)) != -1) {
2566 /*** capture option specific ***/
2567 case 'a': /* autostop criteria */
2568 case 'b': /* Ringbuffer option */
2569 case 'c': /* Capture xxx packets */
2570 case 'f': /* capture filter */
2571 case 'k': /* Start capture immediately */
2572 case 'H': /* Hide capture info dialog box */
2573 case 'p': /* Don't capture in promiscuous mode */
2574 case 'i': /* Use interface x */
2575 #ifdef HAVE_PCAP_CREATE
2576 case 'I': /* Capture in monitor mode, if available */
2578 #ifdef HAVE_PCAP_REMOTE
2579 case 'A': /* Authentication */
2581 case 's': /* Set the snapshot (capture) length */
2582 case 'S': /* "Sync" mode: used for following file ala tail -f */
2583 case 'w': /* Write to capture file xxx */
2584 case 'y': /* Set the pcap data link type */
2585 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2586 case 'B': /* Buffer size */
2587 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2589 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2595 capture_option_specified = TRUE;
2600 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2601 case 'K': /* Kerberos keytab file */
2602 read_keytab_file(optarg);
2606 /*** all non capture option specific ***/
2608 /* Configuration profile settings were already processed just ignore them this time*/
2610 case 'j': /* Search backwards for a matching packet from filter in option J */
2611 jump_backwards = SD_BACKWARD;
2613 case 'g': /* Go to packet with the given packet number */
2614 go_to_packet = get_positive_int(optarg, "go to packet");
2616 case 'J': /* Jump to the first packet which matches the filter criteria */
2619 case 'l': /* Automatic scrolling in live capture mode */
2621 auto_scroll_live = TRUE;
2623 capture_option_specified = TRUE;
2627 case 'L': /* Print list of link-layer types and exit */
2629 list_link_layer_types = TRUE;
2631 capture_option_specified = TRUE;
2635 case 'm': /* Fixed-width font for the display */
2636 g_free(prefs_p->gui_gtk2_font_name);
2637 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2639 case 'n': /* No name resolution */
2640 gbl_resolv_flags.mac_name = FALSE;
2641 gbl_resolv_flags.network_name = FALSE;
2642 gbl_resolv_flags.transport_name = FALSE;
2643 gbl_resolv_flags.concurrent_dns = FALSE;
2645 case 'N': /* Select what types of addresses/port #s to resolve */
2646 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2647 if (badopt != '\0') {
2648 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2653 case 'o': /* Override preference from command line */
2654 switch (prefs_set_pref(optarg)) {
2657 case PREFS_SET_SYNTAX_ERR:
2658 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2661 case PREFS_SET_NO_SUCH_PREF:
2662 /* not a preference, might be a recent setting */
2663 switch (recent_set_arg(optarg)) {
2666 case PREFS_SET_SYNTAX_ERR:
2667 /* shouldn't happen, checked already above */
2668 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2671 case PREFS_SET_NO_SUCH_PREF:
2672 case PREFS_SET_OBSOLETE:
2673 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2678 g_assert_not_reached();
2681 case PREFS_SET_OBSOLETE:
2682 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2687 g_assert_not_reached();
2691 /* Path settings were already processed just ignore them this time*/
2693 case 'r': /* Read capture file xxx */
2694 /* We may set "last_open_dir" to "cf_name", and if we change
2695 "last_open_dir" later, we free the old value, so we have to
2696 set "cf_name" to something that's been allocated. */
2697 cf_name = g_strdup(optarg);
2699 case 'R': /* Read file filter */
2702 case 't': /* Time stamp type */
2703 if (strcmp(optarg, "r") == 0)
2704 timestamp_set_type(TS_RELATIVE);
2705 else if (strcmp(optarg, "a") == 0)
2706 timestamp_set_type(TS_ABSOLUTE);
2707 else if (strcmp(optarg, "ad") == 0)
2708 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2709 else if (strcmp(optarg, "adoy") == 0)
2710 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
2711 else if (strcmp(optarg, "d") == 0)
2712 timestamp_set_type(TS_DELTA);
2713 else if (strcmp(optarg, "dd") == 0)
2714 timestamp_set_type(TS_DELTA_DIS);
2715 else if (strcmp(optarg, "e") == 0)
2716 timestamp_set_type(TS_EPOCH);
2717 else if (strcmp(optarg, "u") == 0)
2718 timestamp_set_type(TS_UTC);
2719 else if (strcmp(optarg, "ud") == 0)
2720 timestamp_set_type(TS_UTC_WITH_YMD);
2721 else if (strcmp(optarg, "udoy") == 0)
2722 timestamp_set_type(TS_UTC_WITH_YDOY);
2724 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2726 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2728 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2730 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2732 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2734 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2738 case 'u': /* Seconds type */
2739 if (strcmp(optarg, "s") == 0)
2740 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2741 else if (strcmp(optarg, "hms") == 0)
2742 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2744 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2746 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2751 /* ext ops were already processed just ignore them this time*/
2757 /* We won't call the init function for the stat this soon
2758 as it would disallow MATE's fields (which are registered
2759 by the preferences set callback) from being used as
2760 part of a tap filter. Instead, we just add the argument
2761 to a list of stat arguments. */
2762 if (strcmp("help", optarg) == 0) {
2763 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
2764 list_stat_cmd_args();
2767 if (!process_stat_cmd_arg(optarg)) {
2768 cmdarg_err("Invalid -z argument.");
2769 cmdarg_err_cont(" -z argument must be one of :");
2770 list_stat_cmd_args();
2775 case '?': /* Bad flag - print usage message */
2784 if (cf_name != NULL) {
2786 * Input file name specified with "-r" *and* specified as a regular
2787 * command-line argument.
2789 cmdarg_err("File name specified both with -r and regular argument");
2793 * Input file name not specified with "-r", and a command-line argument
2794 * was specified; treat it as the input file name.
2796 * Yes, this is different from tshark, where non-flag command-line
2797 * arguments are a filter, but this works better on GUI desktops
2798 * where a command can be specified to be run to open a particular
2799 * file - yes, you could have "-r" as the last part of the command,
2800 * but that's a bit ugly.
2802 #ifndef HAVE_GTKOSXAPPLICATION
2804 * For GTK+ Mac Integration, file name passed as free argument passed
2805 * through grag-and-drop and opened twice sometimes causing crashes.
2806 * Subject to report to GTK+ MAC.
2808 cf_name = g_strdup(argv[0]);
2817 * Extra command line arguments were specified; complain.
2819 cmdarg_err("Invalid argument: %s", argv[0]);
2825 #ifndef HAVE_LIBPCAP
2826 if (capture_option_specified) {
2827 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2835 fill_in_local_interfaces(main_window_update);
2836 if (start_capture && list_link_layer_types) {
2837 /* Specifying *both* is bogus. */
2838 cmdarg_err("You can't specify both -L and a live capture.");
2842 if (list_link_layer_types) {
2843 /* We're supposed to list the link-layer types for an interface;
2844 did the user also specify a capture file to be read? */
2846 /* Yes - that's bogus. */
2847 cmdarg_err("You can't specify -L and a capture file to be read.");
2850 /* No - did they specify a ring buffer option? */
2851 if (global_capture_opts.multi_files_on) {
2852 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2856 /* We're supposed to do a live capture; did the user also specify
2857 a capture file to be read? */
2858 if (start_capture && cf_name) {
2859 /* Yes - that's bogus. */
2860 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2864 /* No - was the ring buffer option specified and, if so, does it make
2866 if (global_capture_opts.multi_files_on) {
2867 /* Ring buffer works only under certain conditions:
2868 a) ring buffer does not work with temporary files;
2869 b) real_time_mode and multi_files_on are mutually exclusive -
2870 real_time_mode takes precedence;
2871 c) it makes no sense to enable the ring buffer if the maximum
2872 file size is set to "infinite". */
2873 if (global_capture_opts.save_file == NULL) {
2874 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2875 global_capture_opts.multi_files_on = FALSE;
2877 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2878 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2879 /* XXX - this must be redesigned as the conditions changed */
2884 if (start_capture || list_link_layer_types) {
2885 /* We're supposed to do a live capture or get a list of link-layer
2886 types for a live capture device; if the user didn't specify an
2887 interface to use, pick a default. */
2888 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2889 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2895 if (list_link_layer_types) {
2896 /* Get the list of link-layer types for the capture devices. */
2897 if_capabilities_t *caps;
2900 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2902 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2903 if (device.selected) {
2904 #if defined(HAVE_PCAP_CREATE)
2905 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str, main_window_update);
2907 caps = capture_get_if_capabilities(device.name, FALSE, &err_str,main_window_update);
2910 cmdarg_err("%s", err_str);
2914 if (caps->data_link_types == NULL) {
2915 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2921 #if defined(HAVE_PCAP_CREATE)
2922 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2924 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2929 free_if_capabilities(caps);
2934 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2935 capture_opts_trim_ring_num_files(&global_capture_opts);
2936 #endif /* HAVE_LIBPCAP */
2938 /* Notify all registered modules that have had any of their preferences
2939 changed either from one of the preferences file or from the command
2940 line that their preferences have changed. */
2944 if ((global_capture_opts.num_selected == 0) &&
2945 ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2948 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2949 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2950 if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2951 device.selected = TRUE;
2952 global_capture_opts.num_selected++;
2953 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2954 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2959 if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2960 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2961 device.selected = TRUE;
2962 global_capture_opts.num_selected++;
2963 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2964 g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2968 /* disabled protocols as per configuration file */
2969 if (gdp_path == NULL && dp_path == NULL) {
2970 set_disabled_protos_list();
2973 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2975 /* read in rc file from global and personal configuration paths. */
2976 rc_file = get_datafile_path(RC_FILE);
2977 #if GTK_CHECK_VERSION(3,0,0)
2978 /* XXX resolve later */
2980 gtk_rc_parse(rc_file);
2982 rc_file = get_persconffile_path(RC_FILE, FALSE);
2983 gtk_rc_parse(rc_file);
2993 /* close the splash screen, as we are going to open the main window now */
2994 splash_destroy(splash_win);
2996 /************************************************************************/
2997 /* Everything is prepared now, preferences and command line was read in */
2999 /* Pop up the main window. */
3000 create_main_window(pl_size, tv_size, bv_size, prefs_p);
3002 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3003 recent_read_dynamic(&rf_path, &rf_open_errno);
3004 if (rf_path != NULL && rf_open_errno != 0) {
3005 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3006 "Could not open recent file\n\"%s\": %s.",
3007 rf_path, g_strerror(rf_open_errno));
3010 color_filters_enable(recent.packet_list_colorize);
3012 /* rearrange all the widgets as we now have all recent settings ready for this */
3013 main_widgets_rearrange();
3015 /* Fill in column titles. This must be done after the top level window
3018 XXX - is that still true, with fixed-width columns? */
3020 menu_recent_read_finished();
3022 main_auto_scroll_live_changed(auto_scroll_live);
3025 switch (user_font_apply()) {
3028 case FA_FONT_NOT_RESIZEABLE:
3029 /* "user_font_apply()" popped up an alert box. */
3030 /* turn off zooming - font can't be resized */
3031 case FA_FONT_NOT_AVAILABLE:
3032 /* XXX - did we successfully load the un-zoomed version earlier?
3033 If so, this *probably* means the font is available, but not at
3034 this particular zoom level, but perhaps some other failure
3035 occurred; I'm not sure you can determine which is the case,
3037 /* turn off zooming - zoom level is unavailable */
3039 /* in any other case than FA_SUCCESS, turn off zooming */
3040 recent.gui_zoom_level = 0;
3041 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3044 dnd_init(top_level);
3046 color_filters_init();
3048 capture_filter_init();
3051 /* the window can be sized only, if it's not already shown, so do it now! */
3052 main_load_window_geometry(top_level);
3054 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3056 /* If we were given the name of a capture file, read it in now;
3057 we defer it until now, so that, if we can't open it, and pop
3058 up an alert box, the alert box is more likely to come up on
3059 top of the main window - but before the preference-file-error
3060 alert box, so, if we get one of those, it's more likely to come
3063 show_main_window(TRUE);
3064 check_and_warn_user_startup(cf_name);
3065 if (rfilter != NULL) {
3066 if (!dfilter_compile(rfilter, &rfcode)) {
3067 bad_dfilter_alert_box(top_level, rfilter);
3068 rfilter_parse_failed = TRUE;
3071 if (ex_opt_count("read_format") > 0) {
3072 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
3074 if (!rfilter_parse_failed) {
3075 if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
3076 /* "cf_open()" succeeded, so it closed the previous
3077 capture file, and thus destroyed any previous read filter
3078 attached to "cf". */
3080 cfile.rfcode = rfcode;
3081 /* Open stat windows; we do so after creating the main window,
3082 to avoid GTK warnings, and after successfully opening the
3083 capture file, so we know we have something to compute stats
3084 on, and after registering all dissectors, so that MATE will
3085 have registered its field array and we can have a tap filter
3086 with one of MATE's late-registered fields as part of the
3088 start_requested_stats();
3090 /* Read the capture file. */
3091 switch (cf_read(&cfile, FALSE)) {
3095 /* Just because we got an error, that doesn't mean we were unable
3096 to read any of the file; we handle what we could get from the
3098 /* if the user told us to jump to a specific packet, do it now */
3099 if(go_to_packet != 0) {
3100 /* Jump to the specified frame number, kept for backward
3102 cf_goto_frame(&cfile, go_to_packet);
3103 } else if (jfilter != NULL) {
3104 /* try to compile given filter */
3105 if (!dfilter_compile(jfilter, &jump_to_filter)) {
3106 bad_dfilter_alert_box(top_level, jfilter);
3108 /* Filter ok, jump to the first packet matching the filter
3109 conditions. Default search direction is forward, but if
3110 option d was given, search backwards */
3111 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3116 case CF_READ_ABORTED:
3122 /* If the filename is not the absolute path, prepend the current dir. This happens
3123 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3124 if (!g_path_is_absolute(cf_name)) {
3125 char *old_cf_name = cf_name;
3126 char *pwd = g_get_current_dir();
3127 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3128 g_free(old_cf_name);
3132 /* Save the name of the containing directory specified in the
3133 path name, if any; we can write over cf_name, which is a
3134 good thing, given that "get_dirname()" does write over its
3136 s = get_dirname(cf_name);
3137 set_last_open_dir(s);
3142 dfilter_free(rfcode);
3143 cfile.rfcode = NULL;
3144 show_main_window(FALSE);
3145 /* Don't call check_and_warn_user_startup(): we did it above */
3146 main_set_for_capture_in_progress(FALSE);
3147 set_capture_if_dialog_for_capture_in_progress(FALSE);
3152 if (start_capture) {
3153 if (global_capture_opts.save_file != NULL) {
3154 /* Save the directory name for future file dialogs. */
3155 /* (get_dirname overwrites filename) */
3156 s = get_dirname(g_strdup(global_capture_opts.save_file));
3157 set_last_open_dir(s);
3160 /* "-k" was specified; start a capture. */
3161 show_main_window(FALSE);
3162 check_and_warn_user_startup(cf_name);
3164 /* If no user interfaces were specified on the command line,
3165 copy the list of selected interfaces to the set of interfaces
3166 to use for this capture. */
3167 if (global_capture_opts.ifaces->len == 0)
3168 collect_ifaces(&global_capture_opts);
3169 if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3170 /* The capture started. Open stat windows; we do so after creating
3171 the main window, to avoid GTK warnings, and after successfully
3172 opening the capture file, so we know we have something to compute
3173 stats on, and after registering all dissectors, so that MATE will
3174 have registered its field array and we can have a tap filter with
3175 one of MATE's late-registered fields as part of the filter. */
3176 start_requested_stats();
3179 show_main_window(FALSE);
3180 check_and_warn_user_startup(cf_name);
3181 main_set_for_capture_in_progress(FALSE);
3182 set_capture_if_dialog_for_capture_in_progress(FALSE);
3184 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3185 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3186 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3188 #else /* HAVE_LIBPCAP */
3189 show_main_window(FALSE);
3190 check_and_warn_user_startup(cf_name);
3191 main_set_for_capture_in_progress(FALSE);
3192 set_capture_if_dialog_for_capture_in_progress(FALSE);
3193 #endif /* HAVE_LIBPCAP */
3197 GtkWidget *filter_te;
3198 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3199 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3201 /* Run the display filter so it goes in effect. */
3202 main_filter_packets(&cfile, dfilter, FALSE);
3206 /* register our pid if we are being run from a U3 device */
3209 profile_store_persconffiles (FALSE);
3211 #ifdef HAVE_GTKOSXAPPLICATION
3212 theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3213 gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3214 gtkosx_application_ready(theApp);
3217 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3220 gtk_iface_mon_start();
3223 software_update_init();
3225 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3227 /* ... back from GTK, we're going down now! */
3230 gtk_iface_mon_stop();
3233 /* deregister our pid */
3234 u3_deregister_pid();
3238 AirPDcapDestroyContext(&airpdcap_ctx);
3240 #ifdef HAVE_GTKOSXAPPLICATION
3241 g_object_unref(theApp);
3245 /* hide the (unresponsive) main window, while asking the user to close the console window */
3246 if (G_IS_OBJECT(top_level))
3247 gtk_widget_hide(top_level);
3249 software_update_cleanup();
3251 /* Shutdown windows sockets */
3254 /* For some unknown reason, the "atexit()" call in "create_console()"
3255 doesn't arrange that "destroy_console()" be called when we exit,
3256 so we call it here if a console was created. */
3265 /* We build this as a GUI subsystem application on Win32, so
3266 "WinMain()", not "main()", gets called.
3268 Hack shamelessly stolen from the Win32 port of the GIMP. */
3270 #define _stdcall __attribute__((stdcall))
3274 WinMain (struct HINSTANCE__ *hInstance,
3275 struct HINSTANCE__ *hPrevInstance,
3279 INITCOMMONCONTROLSEX comm_ctrl;
3282 * Initialize our DLL search path. MUST be called before LoadLibrary
3285 ws_init_dll_search_path();
3287 /* Initialize our controls. Required for native Windows file dialogs. */
3288 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3289 comm_ctrl.dwSize = sizeof(comm_ctrl);
3290 /* Includes the animate, header, hot key, list view, progress bar,
3291 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3294 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3295 InitCommonControlsEx(&comm_ctrl);
3297 /* RichEd20.DLL is needed for filter entries. */
3298 ws_load_library("riched20.dll");
3300 set_has_console(FALSE);
3301 set_console_wait(FALSE);
3302 return main (__argc, __argv);
3311 * Helper for main_widgets_rearrange()
3313 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3314 gtk_container_remove(GTK_CONTAINER(data), widget);
3317 static GtkWidget *main_widget_layout(gint layout_content)
3319 switch(layout_content) {
3320 case(layout_pane_content_none):
3322 case(layout_pane_content_plist):
3324 case(layout_pane_content_pdetails):
3326 case(layout_pane_content_pbytes):
3327 return byte_nb_ptr_gbl;
3329 g_assert_not_reached();
3335 * Rearrange the main window widgets
3337 void main_widgets_rearrange(void) {
3338 GtkWidget *first_pane_widget1, *first_pane_widget2;
3339 GtkWidget *second_pane_widget1, *second_pane_widget2;
3340 gboolean split_top_left = FALSE;
3342 /* be a bit faster */
3343 gtk_widget_hide(main_vbox);
3345 /* be sure we don't lose a widget while rearranging */
3346 g_object_ref(G_OBJECT(menubar));
3347 g_object_ref(G_OBJECT(main_tb));
3348 g_object_ref(G_OBJECT(filter_tb));
3349 g_object_ref(G_OBJECT(wireless_tb));
3350 g_object_ref(G_OBJECT(pkt_scrollw));
3351 g_object_ref(G_OBJECT(tv_scrollw));
3352 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3353 g_object_ref(G_OBJECT(statusbar));
3354 g_object_ref(G_OBJECT(main_pane_v1));
3355 g_object_ref(G_OBJECT(main_pane_v2));
3356 g_object_ref(G_OBJECT(main_pane_h1));
3357 g_object_ref(G_OBJECT(main_pane_h2));
3358 g_object_ref(G_OBJECT(welcome_pane));
3360 /* empty all containers participating */
3361 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3362 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3363 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3364 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3365 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3367 statusbar_widgets_emptying(statusbar);
3369 /* add the menubar always at the top */
3370 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3373 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3375 /* filter toolbar in toolbar area */
3376 if (!prefs.filter_toolbar_show_in_statusbar) {
3377 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3380 /* airpcap toolbar */
3381 gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3383 /* fill the main layout panes */
3384 switch(prefs.gui_layout_type) {
3385 case(layout_type_5):
3386 main_first_pane = main_pane_v1;
3387 main_second_pane = main_pane_v2;
3388 split_top_left = FALSE;
3390 case(layout_type_2):
3391 main_first_pane = main_pane_v1;
3392 main_second_pane = main_pane_h1;
3393 split_top_left = FALSE;
3395 case(layout_type_1):
3396 main_first_pane = main_pane_v1;
3397 main_second_pane = main_pane_h1;
3398 split_top_left = TRUE;
3400 case(layout_type_4):
3401 main_first_pane = main_pane_h1;
3402 main_second_pane = main_pane_v1;
3403 split_top_left = FALSE;
3405 case(layout_type_3):
3406 main_first_pane = main_pane_h1;
3407 main_second_pane = main_pane_v1;
3408 split_top_left = TRUE;
3410 case(layout_type_6):
3411 main_first_pane = main_pane_h1;
3412 main_second_pane = main_pane_h2;
3413 split_top_left = FALSE;
3416 main_first_pane = NULL;
3417 main_second_pane = NULL;
3418 g_assert_not_reached();
3420 if (split_top_left) {
3421 first_pane_widget1 = main_second_pane;
3422 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3423 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3424 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3426 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3427 first_pane_widget2 = main_second_pane;
3428 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3429 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3431 if (first_pane_widget1 != NULL)
3432 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3433 if (first_pane_widget2 != NULL)
3434 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3435 if (second_pane_widget1 != NULL)
3436 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3437 if (second_pane_widget2 != NULL)
3438 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3440 gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3443 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3446 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3448 /* filter toolbar in statusbar hbox */
3449 if (prefs.filter_toolbar_show_in_statusbar) {
3450 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3453 /* statusbar widgets */
3454 statusbar_widgets_pack(statusbar);
3456 /* hide widgets on users recent settings */
3457 main_widgets_show_or_hide();
3459 gtk_widget_show(main_vbox);
3463 is_widget_visible(GtkWidget *widget, gpointer data)
3465 gboolean *is_visible = ( gboolean *)data;
3468 if (gtk_widget_get_visible(widget))
3475 main_widgets_show_or_hide(void)
3477 gboolean main_second_pane_show;
3479 if (recent.main_toolbar_show) {
3480 gtk_widget_show(main_tb);
3482 gtk_widget_hide(main_tb);
3485 statusbar_widgets_show_or_hide(statusbar);
3487 if (recent.filter_toolbar_show) {
3488 gtk_widget_show(filter_tb);
3490 gtk_widget_hide(filter_tb);
3493 if (recent.wireless_toolbar_show) {
3494 gtk_widget_show(wireless_tb);
3496 gtk_widget_hide(wireless_tb);
3499 if (recent.packet_list_show && have_capture_file) {
3500 gtk_widget_show(pkt_scrollw);
3502 gtk_widget_hide(pkt_scrollw);
3505 if (recent.tree_view_show && have_capture_file) {
3506 gtk_widget_show(tv_scrollw);
3508 gtk_widget_hide(tv_scrollw);
3511 if (recent.byte_view_show && have_capture_file) {
3512 gtk_widget_show(byte_nb_ptr_gbl);
3514 gtk_widget_hide(byte_nb_ptr_gbl);
3517 if (have_capture_file) {
3518 gtk_widget_show(main_first_pane);
3520 gtk_widget_hide(main_first_pane);
3524 * Is anything in "main_second_pane" visible?
3525 * If so, show it, otherwise hide it.
3527 main_second_pane_show = FALSE;
3528 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3529 &main_second_pane_show);
3530 if (main_second_pane_show) {
3531 gtk_widget_show(main_second_pane);
3533 gtk_widget_hide(main_second_pane);
3536 if (!have_capture_file) {
3538 gtk_widget_show(welcome_pane);
3541 gtk_widget_hide(welcome_pane);
3546 /* called, when the window state changes (minimized, maximized, ...) */
3548 window_state_event_cb (GtkWidget *widget _U_,
3552 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3554 if( (event->type) == (GDK_WINDOW_STATE)) {
3555 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3556 /* we might have dialogs popped up while we where iconified,
3558 display_queued_messages();
3566 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3568 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3570 if (event->keyval == GDK_F8) {
3573 } else if (event->keyval == GDK_F7) {
3576 } else if (event->state & NO_SHIFT_MOD_MASK) {
3577 return FALSE; /* Skip control, alt, and other modifiers */
3579 * A comment in gdkkeysyms.h says that it's autogenerated from
3580 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3581 * don't explicitly say so, g_ascii_isprint() should work as expected
3584 } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3585 /* Forward the keypress on to the display filter entry */
3586 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3587 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3588 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3596 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3597 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3602 GtkAccelGroup *accel;
3605 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3606 set_titlebar_for_capture_file(NULL);
3608 gtk_widget_set_name(top_level, "main window");
3609 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3611 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3612 G_CALLBACK(window_state_event_cb), NULL);
3613 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3614 G_CALLBACK(top_level_key_pressed_cb), NULL );
3616 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3617 main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3619 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3620 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3621 gtk_widget_show(main_vbox);
3624 menubar = main_menu_new(&accel);
3626 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3627 /* Mac OS X native menus are created and displayed by main_menu_new() */
3628 if(!prefs_p->gui_macosx_style) {
3630 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3631 gtk_widget_show(menubar);
3632 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3634 gtk_widget_hide(menubar);
3639 main_tb = toolbar_new();
3640 gtk_widget_show (main_tb);
3642 /* Filter toolbar */
3643 filter_tb = filter_toolbar_new();
3646 pkt_scrollw = packet_list_create();
3647 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3648 gtk_widget_show_all(pkt_scrollw);
3651 tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3652 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3653 gtk_widget_show(tv_scrollw);
3655 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3656 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3657 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3658 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3659 gtk_widget_show(tree_view_gbl);
3662 byte_nb_ptr_gbl = byte_view_new();
3663 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3664 gtk_widget_show(byte_nb_ptr_gbl);
3666 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3667 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3669 /* Panes for the packet list, tree, and byte view */
3670 main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3671 gtk_widget_show(main_pane_v1);
3672 main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3673 gtk_widget_show(main_pane_v2);
3674 main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3675 gtk_widget_show(main_pane_h1);
3676 main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3677 gtk_widget_show(main_pane_h2);
3679 wireless_tb = airpcap_toolbar_new();
3681 wireless_tb = ws80211_toolbar_new();
3683 gtk_widget_show(wireless_tb);
3686 statusbar = statusbar_new();
3687 gtk_widget_show(statusbar);
3689 /* Pane for the welcome screen */
3690 welcome_pane = welcome_new();
3691 gtk_widget_show(welcome_pane);
3695 show_main_window(gboolean doing_work)
3697 main_set_for_capture_file(doing_work);
3699 /*** we have finished all init things, show the main window ***/
3700 gtk_widget_show(top_level);
3702 /* the window can be maximized only, if it's visible, so do it after show! */
3703 main_load_window_geometry(top_level);
3705 /* process all pending GUI events before continue */
3706 while (gtk_events_pending()) gtk_main_iteration();
3708 /* Pop up any queued-up alert boxes. */
3709 display_queued_messages();
3711 /* Move the main window to the front, in case it isn't already there */
3712 gdk_window_raise(gtk_widget_get_window(top_level));
3715 airpcap_toolbar_show(wireless_tb);
3716 #endif /* HAVE_AIRPCAP */
3719 static void copy_global_profile (const gchar *profile_name)
3721 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3723 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3724 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3725 "Can't create directory\n\"%s\":\n%s.",
3726 pf_dir_path, g_strerror(errno));
3728 g_free(pf_dir_path);
3731 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3732 &pf_dir_path, &pf_dir_path2) == -1) {
3733 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3734 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3735 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3737 g_free(pf_filename);
3738 g_free(pf_dir_path);
3739 g_free(pf_dir_path2);
3743 /* Change configuration profile */
3744 void change_configuration_profile (const gchar *profile_name)
3746 char *gdp_path, *dp_path;
3750 /* First check if profile exists */
3751 if (!profile_exists(profile_name, FALSE)) {
3752 if (profile_exists(profile_name, TRUE)) {
3753 /* Copy from global profile */
3754 copy_global_profile (profile_name);
3756 /* No personal and no global profile exists */
3761 /* Then check if changing to another profile */
3762 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3766 /* Get the current geometry, before writing it to disk */
3767 main_save_window_geometry(top_level);
3769 if (profile_exists(get_profile_name(), FALSE)) {
3770 /* Write recent file for profile we are leaving, if it still exists */
3771 write_profile_recent();
3774 /* Set profile name and update the status bar */
3775 set_profile_name (profile_name);
3776 profile_bar_update ();
3777 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3779 /* Reset current preferences and apply the new */
3783 (void) read_configuration_files (&gdp_path, &dp_path);
3785 recent_read_profile_static(&rf_path, &rf_open_errno);
3786 if (rf_path != NULL && rf_open_errno != 0) {
3787 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3788 "Could not open common recent file\n\"%s\": %s.",
3789 rf_path, g_strerror(rf_open_errno));
3791 if (recent.gui_fileopen_remembered_dir &&
3792 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3793 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3795 timestamp_set_type (recent.gui_time_format);
3796 timestamp_set_seconds_type (recent.gui_seconds_format);
3797 color_filters_enable(recent.packet_list_colorize);
3799 prefs_to_capture_opts();
3801 macros_post_update();
3803 /* Update window view and redraw the toolbar */
3804 main_titlebar_update();
3805 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3806 toolbar_redraw_all();
3808 /* Enable all protocols and disable from the disabled list */
3810 if (gdp_path == NULL && dp_path == NULL) {
3811 set_disabled_protos_list();
3814 /* Reload color filters */
3815 color_filters_reload();
3817 /* Reload list of interfaces on welcome page */
3818 welcome_if_panel_reload();
3820 /* Recreate the packet list according to new preferences */
3821 packet_list_recreate ();
3822 cfile.columns_changed = FALSE; /* Reset value */
3825 /* Update menus with new recent values */
3826 menu_recent_read_finished();
3828 /* Reload pane geometry, must be done after recreating the list */
3829 main_pane_load_window_geometry();
3833 main_fields_changed (void)
3835 /* Reload color filters */
3836 color_filters_reload();
3838 /* Syntax check filter */
3839 filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3840 if (cfile.dfilter) {
3841 /* Check if filter is still valid */
3842 dfilter_t *dfp = NULL;
3843 if (!dfilter_compile(cfile.dfilter, &dfp)) {
3844 /* Not valid. Enable 'Apply' button and remove dfilter. */
3845 g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3846 g_free(cfile.dfilter);
3847 cfile.dfilter = NULL;
3852 if (have_custom_cols(&cfile.cinfo)) {
3853 /* Recreate packet list according to new/changed/deleted fields */
3854 packet_list_recreate();
3855 } else if (cfile.state != FILE_CLOSED) {
3856 /* Redissect packets if we have any */
3857 redissect_packets();
3859 destroy_packet_wins(); /* TODO: close windows until we can recreate */
3861 proto_free_deregistered_fields();
3864 /** redissect packets and update UI */
3865 void redissect_packets(void)
3867 cf_redissect_packets(&cfile);
3868 status_expert_update();
3877 * indent-tabs-mode: nil
3880 * ex: set shiftwidth=4 tabstop=8 expandtab:
3881 * :indentSize=4:tabSize=8:noTabs=true: