5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10 * needed by dissect routines
11 * Jeff Foster, 2001/03/12, added support tabbed hex display windowss
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <gdk/gdkkeysyms.h>
43 #ifdef NEED_STRERROR_H
51 #ifdef _WIN32 /* Needed for console I/O */
56 #ifdef HAVE_LIBPORTAUDIO
57 #include <portaudio.h>
58 #endif /* HAVE_LIBPORTAUDIO */
60 #include <epan/epan.h>
61 #include <epan/filesystem.h>
62 #include <epan/privileges.h>
63 #include <epan/epan_dissect.h>
64 #include <epan/timestamp.h>
65 #include <epan/packet.h>
66 #include <epan/plugins.h>
67 #include <epan/dfilter/dfilter.h>
68 #include <epan/strutil.h>
69 #include <epan/addr_resolv.h>
70 #include <epan/emem.h>
71 #include <epan/ex-opt.h>
72 #include <epan/funnel.h>
73 #include <epan/expert.h>
74 #include <epan/frequency-utils.h>
76 /* general (not GTK specific) */
80 #include "disabled_protos.h"
81 #include <epan/prefs.h>
82 #include "filter_dlg.h"
83 #include "layout_prefs.h"
85 #include "color_filters.h"
87 #include "simple_dialog.h"
89 #include <epan/prefs-int.h>
90 #include "ringbuffer.h"
91 #include "../ui_util.h"
93 #include <epan/stat_cmd_args.h>
95 #include "clopts_common.h"
96 #include "cmdarg_err.h"
97 #include "version_info.h"
101 #include "epan/uat.h"
105 #include "capture-pcap-util.h"
107 #include "capture_sync.h"
111 #include "capture-wpcap.h"
112 #include "capture_wpcap_packet.h"
113 #include <tchar.h> /* Needed for Unicode */
114 #include <commctrl.h>
118 #include "alert_box.h"
120 #include "dlg_utils.h"
122 #include "file_dlg.h"
123 #include "gtkglobals.h"
125 #include "gui_utils.h"
126 #include "color_dlg.h"
129 #include "main_menu.h"
130 #include "main_packet_list.h"
131 #include "main_statusbar.h"
132 #include "main_toolbar.h"
133 #include "main_welcome.h"
134 #include "../main_window.h"
135 #include "drag_and_drop.h"
136 #include "capture_file_dlg.h"
137 #include <epan/column.h>
138 #include "proto_draw.h"
140 #include "packet_win.h"
141 #include "stock_icons.h"
142 #include "find_dlg.h"
144 #include "follow_tcp.h"
145 #include "font_utils.h"
146 #include "about_dlg.h"
147 #include "help_dlg.h"
148 #include "decode_as_dlg.h"
149 #include "webbrowser.h"
150 #include "capture_dlg.h"
151 #include "capture_ui_utils.h"
153 #include "../epan/emem.h"
154 #include "file_util.h"
156 #include "../image/wsicon16.xpm"
157 #include "../image/wsicon32.xpm"
158 #include "../image/wsicon48.xpm"
159 #include "../image/wsicon64.xpm"
160 #include "../image/wsiconcap16.xpm"
161 #include "../image/wsiconcap32.xpm"
162 #include "../image/wsiconcap48.xpm"
167 #include "airpcap_loader.h"
168 #include "airpcap_dlg.h"
169 #include "airpcap_gui_utils.h"
171 #include "./image/toolbar/wep_closed_24.xpm"
175 /* Davide Schiera (2006-11-22): including AirPDcap project */
176 #include <epan/crypt/airpdcap_ws.h>
177 /* Davide Schiera (2006-11-22) ---------------------------------------------- */
181 * Files under personal and global preferences directories in which
182 * GTK settings for Wireshark are stored.
184 #define RC_FILE "gtkrc"
187 GtkWidget *main_display_filter_widget=NULL;
188 GtkWidget *top_level = NULL, *tree_view, *byte_nb_ptr, *tv_scrollw;
189 GtkWidget *pkt_scrollw;
190 static GtkWidget *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
191 static GtkWidget *main_first_pane, *main_second_pane;
192 GtkWidget *statusbar;
193 static GtkWidget *menubar, *main_vbox, *main_tb, *filter_tb;
194 static GtkWidget *priv_warning_dialog;
197 GtkWidget *airpcap_tb;
198 static GtkWidget *driver_warning_dialog;
199 static int airpcap_dll_ret_val = -1;
202 static GtkWidget *welcome_pane;
204 GString *comp_info_str, *runtime_info_str;
205 gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
208 static gboolean has_console; /* TRUE if app has console */
209 static void destroy_console(void);
211 static void console_log_handler(const char *log_domain,
212 GLogLevelFlags log_level, const char *message, gpointer user_data);
215 static gboolean list_link_layer_types;
216 capture_options global_capture_opts;
217 capture_options *capture_opts = &global_capture_opts;
220 gboolean block_toolbar_signals = FALSE;
222 static void create_main_window(gint, gint, gint, e_prefs*);
223 static void show_main_window(gboolean);
224 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
225 static void main_save_window_geometry(GtkWidget *widget);
227 #define E_DFILTER_CM_KEY "display_filter_combo"
228 #define E_DFILTER_FL_KEY "display_filter_list"
230 /* Match selected byte pattern */
232 match_selected_cb_do(gpointer data, int action, gchar *text)
234 GtkWidget *filter_te;
235 char *cur_filter, *new_filter;
237 if ((!text) || (0 == strlen(text))) {
238 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
243 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
246 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
248 switch (action&MATCH_SELECTED_MASK) {
250 case MATCH_SELECTED_REPLACE:
251 new_filter = g_strdup(text);
254 case MATCH_SELECTED_AND:
255 if ((!cur_filter) || (0 == strlen(cur_filter)))
256 new_filter = g_strdup(text);
258 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
261 case MATCH_SELECTED_OR:
262 if ((!cur_filter) || (0 == strlen(cur_filter)))
263 new_filter = g_strdup(text);
265 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
268 case MATCH_SELECTED_NOT:
269 new_filter = g_strconcat("!(", text, ")", NULL);
272 case MATCH_SELECTED_AND_NOT:
273 if ((!cur_filter) || (0 == strlen(cur_filter)))
274 new_filter = g_strconcat("!(", text, ")", NULL);
276 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
279 case MATCH_SELECTED_OR_NOT:
280 if ((!cur_filter) || (0 == strlen(cur_filter)))
281 new_filter = g_strconcat("!(", text, ")", NULL);
283 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
287 g_assert_not_reached();
292 /* Free up the copy we got of the old filter text. */
295 /* Don't change the current display filter if we only want to copy the filter */
296 if (action&MATCH_SELECTED_COPY_ONLY) {
297 GString *gtk_text_str = g_string_new("");
298 g_string_sprintfa(gtk_text_str, "%s", new_filter);
299 copy_to_clipboard(gtk_text_str);
300 g_string_free(gtk_text_str, TRUE);
302 /* create a new one and set the display filter entry accordingly */
303 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
305 /* Run the display filter so it goes in effect. */
306 if (action&MATCH_SELECTED_APPLY_NOW)
307 main_filter_packets(&cfile, new_filter, FALSE);
310 /* Free up the new filter text. */
315 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
319 if (cfile.finfo_selected) {
320 filter = proto_construct_match_selected_string(cfile.finfo_selected,
322 match_selected_cb_do((data ? data : w), action, filter);
327 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
331 if (cfile.finfo_selected) {
332 filter = proto_construct_match_selected_string(cfile.finfo_selected,
334 if ((!filter) || (0 == strlen(filter))) {
335 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
336 "Could not acquire information to build a filter!\n"
337 "Try expanding or choosing another item.");
342 color_display_with_filter(filter);
345 color_filters_reset_tmp();
347 color_filters_set_tmp(filt_nr,filter, FALSE);
349 cf_colorize_packets(&cfile);
355 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
357 gchar *selected_proto_url;
358 gchar *proto_abbrev = data;
363 if (cfile.finfo_selected) {
364 /* open wiki page using the protocol abbreviation */
365 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
366 browser_open_url(selected_proto_url);
367 g_free(selected_proto_url);
370 case(ESD_BTN_CANCEL):
373 g_assert_not_reached();
379 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
382 const gchar *proto_abbrev;
386 if (cfile.finfo_selected) {
387 /* convert selected field to protocol abbreviation */
388 /* XXX - could this conversion be simplified? */
389 field_id = cfile.finfo_selected->hfinfo->id;
390 /* if the selected field isn't a protocol, get it's parent */
391 if(!proto_registrar_is_protocol(field_id)) {
392 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
395 proto_abbrev = proto_registrar_get_abbrev(field_id);
397 /* ask the user if the wiki page really should be opened */
398 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
399 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
401 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
403 "The Wireshark Wiki is a collaborative approach to provide information\n"
404 "about Wireshark in several ways (not limited to protocol specifics).\n"
406 "This Wiki is new, so the page of the selected protocol\n"
407 "may not exist and/or may not contain valuable information.\n"
409 "As everyone can edit the Wiki and add new content (or extend existing),\n"
410 "you are encouraged to add information if you can.\n"
412 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
414 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate,\n"
415 "which will save you a lot of editing and will give a consistent look over the pages.",
416 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
417 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer) proto_abbrev);
423 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
426 const gchar *proto_abbrev;
427 gchar *selected_proto_url;
430 if (cfile.finfo_selected) {
431 /* convert selected field to protocol abbreviation */
432 /* XXX - could this conversion be simplified? */
433 field_id = cfile.finfo_selected->hfinfo->id;
434 /* if the selected field isn't a protocol, get it's parent */
435 if(!proto_registrar_is_protocol(field_id)) {
436 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
439 proto_abbrev = proto_registrar_get_abbrev(field_id);
441 /* open reference page using the protocol abbreviation */
442 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s.html", proto_abbrev[0], proto_abbrev);
443 browser_open_url(selected_proto_url);
444 g_free(selected_proto_url);
449 get_text_from_packet_list(gpointer data)
451 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
452 gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
453 frame_data *fdata = (frame_data *)packet_list_get_row_data(row);
455 if(strlen(fdata->col_expr.col_expr[column]) != 0 &&
456 strlen(fdata->col_expr.col_expr_val[column]) != 0)
457 return ep_strdup_printf("%s == %s",
458 fdata->col_expr.col_expr[column],
459 fdata->col_expr.col_expr_val[column]);
465 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
467 match_selected_cb_do(data,
469 get_text_from_packet_list(data));
472 /* This function allows users to right click in the details window and copy the text
473 * information to the operating systems clipboard.
475 * We first check to see if a string representation is setup in the tree and then
476 * read the string. If not available then we try to grab the value. If all else
477 * fails we display a message to the user to indicate the copy could not be completed.
480 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_)
482 GString *gtk_text_str = g_string_new("");
483 char labelstring[256];
484 char *stringpointer = labelstring;
486 if (cfile.finfo_selected->rep->representation != 0) {
487 g_string_sprintfa(gtk_text_str, "%s", cfile.finfo_selected->rep->representation); /* Get the represented data */
489 if (gtk_text_str->len == 0) { /* If no representation then... */
490 proto_item_fill_label(cfile.finfo_selected, stringpointer); /* Try to read the value */
491 g_string_sprintfa(gtk_text_str, "%s", stringpointer);
493 if (gtk_text_str->len == 0) { /* Could not get item so display error msg */
494 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
498 copy_to_clipboard(gtk_text_str); /* Copy string to clipboard */
500 g_string_free(gtk_text_str, TRUE); /* Free the memory */
504 /* XXX: use a preference for this setting! */
505 static guint dfilter_combo_max_recent = 10;
507 /* add a display filter to the combo box */
508 /* Note: a new filter string will replace an old identical one */
510 dfilter_combo_add(GtkWidget *filter_cm, char *s) {
512 GList *dfilter_list = g_object_get_data(G_OBJECT(filter_cm), E_DFILTER_FL_KEY);
515 /* GtkCombos don't let us get at their list contents easily, so we maintain
516 our own filter list, and feed it to gtk_combo_set_popdown_strings when
517 a new filter is added. */
518 li = g_list_first(dfilter_list);
520 /* If the filter is already in the list, remove the old one and
521 * append the new one at the latest position (at g_list_append() below) */
522 if (li->data && strcmp(s, li->data) == 0) {
523 dfilter_list = g_list_remove(dfilter_list, li->data);
529 dfilter_list = g_list_append(dfilter_list, s);
530 g_object_set_data(G_OBJECT(filter_cm), E_DFILTER_FL_KEY, dfilter_list);
531 gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), dfilter_list);
532 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), g_list_last(dfilter_list)->data);
538 /* write all non empty display filters (until maximum count)
539 * of the combo box GList to the user's recent file */
541 dfilter_recent_combo_write_all(FILE *rf) {
542 GtkWidget *filter_cm = g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY);
543 GList *dfilter_list = g_object_get_data(G_OBJECT(filter_cm), E_DFILTER_FL_KEY);
548 /* write all non empty display filter strings to the recent file (until max count) */
549 li = g_list_first(dfilter_list);
550 while ( li && (max_count++ <= dfilter_combo_max_recent) ) {
551 if (strlen(li->data)) {
552 fprintf (rf, RECENT_KEY_DISPLAY_FILTER ": %s\n", (char *)li->data);
558 /* empty the combobox entry field */
560 dfilter_combo_add_empty(void) {
561 GtkWidget *filter_cm = g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY);
563 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), "");
567 /* add a display filter coming from the user's recent file to the dfilter combo box */
569 dfilter_combo_add_recent(gchar *s) {
570 GtkWidget *filter_cm = g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY);
574 if (!dfilter_combo_add(filter_cm, dup)) {
583 /* call cf_filter_packets() and add this filter string to the recent filter list */
585 main_filter_packets(capture_file *cf, const gchar *dftext, gboolean force)
587 GtkCombo *filter_cm = g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY);
588 GList *dfilter_list = g_object_get_data(G_OBJECT(filter_cm), E_DFILTER_FL_KEY);
590 gboolean add_filter = TRUE;
591 gboolean free_filter = TRUE;
593 cf_status_t cf_status;
595 s = g_strdup(dftext);
597 cf_status = cf_filter_packets(cf, s, force);
599 return (cf_status == CF_OK);
601 /* GtkCombos don't let us get at their list contents easily, so we maintain
602 our own filter list, and feed it to gtk_combo_set_popdown_strings when
603 a new filter is added. */
604 if (cf_status == CF_OK) {
605 li = g_list_first(dfilter_list);
607 if (li->data && strcmp(s, li->data) == 0)
613 /* trim list size first */
614 while (g_list_length(dfilter_list) >= dfilter_combo_max_recent) {
615 dfilter_list = g_list_remove(dfilter_list, g_list_first(dfilter_list)->data);
619 dfilter_list = g_list_append(dfilter_list, s);
620 g_object_set_data(G_OBJECT(filter_cm), E_DFILTER_FL_KEY, dfilter_list);
621 gtk_combo_set_popdown_strings(filter_cm, dfilter_list);
622 gtk_entry_set_text(GTK_ENTRY(filter_cm->entry), g_list_last(dfilter_list)->data);
628 return (cf_status == CF_OK);
632 /* Run the current display filter on the current packet set, and
635 filter_activate_cb(GtkWidget *w _U_, gpointer data)
639 s = gtk_entry_get_text(GTK_ENTRY(data));
641 main_filter_packets(&cfile, s, FALSE);
644 /* redisplay with no display filter */
646 filter_reset_cb(GtkWidget *w, gpointer data _U_)
648 GtkWidget *filter_te = NULL;
650 if ((filter_te = g_object_get_data(G_OBJECT(w), E_DFILTER_TE_KEY))) {
651 gtk_entry_set_text(GTK_ENTRY(filter_te), "");
653 main_filter_packets(&cfile, NULL, FALSE);
656 /* mark as reference time frame */
658 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
662 frame->flags.ref_time=1;
664 frame->flags.ref_time=0;
666 cf_reftime_packets(&cfile);
670 GtkWidget *reftime_dialog = NULL;
672 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
676 timestamp_set_type(TS_RELATIVE);
677 recent.gui_time_format = TS_RELATIVE;
678 cf_change_time_formats(&cfile);
683 g_assert_not_reached();
686 if (cfile.current_frame) {
687 /* XXX hum, should better have a "cfile->current_row" here ... */
688 set_frame_reftime(!cfile.current_frame->flags.ref_time,
690 packet_list_find_row_from_data(cfile.current_frame));
696 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
701 if (cfile.current_frame) {
702 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
703 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
704 "%sSwitch to the appropriate Time Display Format?%s\n\n"
705 "Time References don't work well with the currently selected Time Display Format.\n\n"
706 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
707 simple_dialog_primary_start(), simple_dialog_primary_end());
708 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
710 /* XXX hum, should better have a "cfile->current_row" here ... */
711 set_frame_reftime(!cfile.current_frame->flags.ref_time,
713 packet_list_find_row_from_data(cfile.current_frame));
717 case REFTIME_FIND_NEXT:
718 find_previous_next_frame_with_filter("frame.ref_time", FALSE);
720 case REFTIME_FIND_PREV:
721 find_previous_next_frame_with_filter("frame.ref_time", TRUE);
727 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
729 find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
733 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
735 find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
739 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
742 gchar *help_str = NULL;
743 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
745 gboolean has_blurb = FALSE;
746 guint length = 0, byte_len;
747 GtkWidget *byte_view;
748 const guint8 *byte_data;
753 /* if nothing is selected */
754 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
757 * Which byte view is displaying the current protocol tree
760 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
761 if (byte_view == NULL)
764 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
765 if (byte_data == NULL)
768 cf_unselect_field(&cfile);
769 packet_hex_print(byte_view, byte_data,
770 cfile.current_frame, NULL, byte_len);
773 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
776 set_notebook_page(byte_nb_ptr, finfo->ds_tvb);
778 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
779 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
780 g_assert(byte_data != NULL);
782 cfile.finfo_selected = finfo;
783 set_menus_for_selected_tree_row(&cfile);
786 if (finfo->hfinfo->blurb != NULL &&
787 finfo->hfinfo->blurb[0] != '\0') {
789 length = strlen(finfo->hfinfo->blurb);
791 length = strlen(finfo->hfinfo->name);
793 finfo_length = finfo->length + finfo->appendix_length;
795 if (finfo_length == 0) {
797 } else if (finfo_length == 1) {
798 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
800 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
802 statusbar_pop_field_msg(); /* get rid of current help msg */
804 help_str = g_strdup_printf(" %s (%s)%s",
805 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
806 finfo->hfinfo->abbrev, len_str);
807 statusbar_push_field_msg(help_str);
811 * Don't show anything if the field name is zero-length;
812 * the pseudo-field for "proto_tree_add_text()" is such
813 * a field, and we don't want "Text (text)" showing up
814 * on the status line if you've selected such a field.
816 * XXX - there are zero-length fields for which we *do*
817 * want to show the field name.
819 * XXX - perhaps the name and abbrev field should be null
820 * pointers rather than null strings for that pseudo-field,
821 * but we'd have to add checks for null pointers in some
822 * places if we did that.
824 * Or perhaps protocol tree items added with
825 * "proto_tree_add_text()" should have -1 as the field index,
826 * with no pseudo-field being used, but that might also
827 * require special checks for -1 to be added.
829 statusbar_push_field_msg("");
832 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
836 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
838 collapse_all_tree(cfile.edt->tree, tree_view);
841 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
843 expand_all_tree(cfile.edt->tree, tree_view);
846 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
849 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view), cfile.finfo_selected);
851 /* the mouse position is at an entry, expand that one */
852 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view), path, TRUE);
853 gtk_tree_path_free(path);
857 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
858 if (cfile.edt->tree) {
859 guint32 tmp = g_resolv_flags;
860 g_resolv_flags = RESOLV_ALL;
861 proto_tree_draw(cfile.edt->tree, tree_view);
862 g_resolv_flags = tmp;
867 main_set_for_capture_file(gboolean have_capture_file_in)
869 have_capture_file = have_capture_file_in;
871 main_widgets_show_or_hide();
877 /* get the current geometry, before writing it to disk */
878 main_save_window_geometry(top_level);
880 /* write user's recent file to disk
881 * It is no problem to write this file, even if we do not quit */
884 /* XXX - should we check whether the capture file is an
885 unsaved temporary file for a live capture and, if so,
886 pop up a "do you want to exit without saving the capture
887 file?" dialog, and then just return, leaving said dialog
888 box to forcibly quit if the user clicks "OK"?
890 If so, note that this should be done in a subroutine that
891 returns TRUE if we do so, and FALSE otherwise, and if it
892 returns TRUE we should return TRUE without nuking anything.
894 Note that, if we do that, we might also want to check if
895 an "Update list of packets in real time" capture is in
896 progress and, if so, ask whether they want to terminate
897 the capture and discard it, and return TRUE, before nuking
898 any child capture, if they say they don't want to do so. */
901 /* Nuke any child capture in progress. */
902 capture_kill_child(capture_opts);
905 /* Are we in the middle of reading a capture? */
906 if (cfile.state == FILE_READ_IN_PROGRESS) {
907 /* Yes, so we can't just close the file and quit, as
908 that may yank the rug out from under the read in
909 progress; instead, just set the state to
910 "FILE_READ_ABORTED" and return - the code doing the read
911 will check for that and, if it sees that, will clean
913 cfile.state = FILE_READ_ABORTED;
915 /* Say that the window should *not* be deleted;
916 that'll be done by the code that cleans up. */
919 /* Close any capture file we have open; on some OSes, you
920 can't unlink a temporary capture file if you have it
922 "cf_close()" will unlink it after closing it if
923 it's a temporary file.
925 We do this here, rather than after the main loop returns,
926 as, after the main loop returns, the main window may have
927 been destroyed (if this is called due to a "destroy"
928 even on the main window rather than due to the user
929 selecting a menu item), and there may be a crash
930 or other problem when "cf_close()" tries to
931 clean up stuff in the main window.
933 XXX - is there a better place to put this?
934 Or should we have a routine that *just* closes the
935 capture file, and doesn't do anything with the UI,
936 which we'd call here, and another routine that
937 calls that routine and also cleans up the UI, which
938 we'd call elsewhere? */
941 /* Exit by leaving the main loop, so that any quit functions
942 we registered get called. */
945 /* Say that the window should be deleted. */
951 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
955 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
956 gtk_window_present(GTK_WINDOW(top_level));
957 /* user didn't saved his current file, ask him */
958 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
959 "%sSave capture file before program quit?%s\n\n"
960 "If you quit the program without saving, your capture data will be discarded.",
961 simple_dialog_primary_start(), simple_dialog_primary_end());
962 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
965 /* unchanged file, just exit */
966 /* "main_do_quit()" indicates whether the main window should be deleted. */
967 return main_do_quit();
974 main_load_window_geometry(GtkWidget *widget)
976 window_geometry_t geom;
978 geom.set_pos = prefs.gui_geometry_save_position;
979 geom.x = recent.gui_geometry_main_x;
980 geom.y = recent.gui_geometry_main_y;
981 geom.set_size = prefs.gui_geometry_save_size;
982 if (recent.gui_geometry_main_width > 0 &&
983 recent.gui_geometry_main_height > 0) {
984 geom.width = recent.gui_geometry_main_width;
985 geom.height = recent.gui_geometry_main_height;
986 geom.set_maximized = prefs.gui_geometry_save_maximized;
988 /* We assume this means the width and height weren't set in
989 the "recent" file (or that there is no "recent" file),
990 and weren't set to a default value, so we don't set the
991 size. (The "recent" file code rejects non-positive width
992 and height values.) */
993 geom.set_size = FALSE;
995 geom.maximized = recent.gui_geometry_main_maximized;
997 window_set_geometry(widget, &geom);
999 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1000 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1001 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
1002 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1003 statusbar_load_window_geometry();
1008 main_save_window_geometry(GtkWidget *widget)
1010 window_geometry_t geom;
1012 window_get_geometry(widget, &geom);
1014 if (prefs.gui_geometry_save_position) {
1015 recent.gui_geometry_main_x = geom.x;
1016 recent.gui_geometry_main_y = geom.y;
1019 if (prefs.gui_geometry_save_size) {
1020 recent.gui_geometry_main_width = geom.width;
1021 recent.gui_geometry_main_height = geom.height;
1024 if(prefs.gui_geometry_save_maximized) {
1025 recent.gui_geometry_main_maximized = geom.maximized;
1028 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1029 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1030 statusbar_save_window_geometry();
1033 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1037 /* save file first */
1038 file_save_as_cmd(after_save_exit, NULL);
1040 case(ESD_BTN_DONT_SAVE):
1043 case(ESD_BTN_CANCEL):
1046 g_assert_not_reached();
1051 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1055 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1056 /* user didn't saved his current file, ask him */
1057 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1058 "%sSave capture file before program quit?%s\n\n"
1059 "If you quit the program without saving, your capture data will be discarded.",
1060 simple_dialog_primary_start(), simple_dialog_primary_end());
1061 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1063 /* unchanged file, just exit */
1069 print_usage(gboolean print_ver) {
1079 fprintf(output, "Wireshark " VERSION "%s\n"
1080 "Interactively dump and analyze network traffic.\n"
1081 "See http://www.wireshark.org for more information.\n"
1084 wireshark_svnversion, get_copyright_info());
1088 fprintf(output, "\n");
1089 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1090 fprintf(output, "\n");
1093 fprintf(output, "Capture interface:\n");
1094 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1095 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1096 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1097 fprintf(output, " -p don't capture in promiscuous mode\n");
1098 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1099 fprintf(output, " -Q quit Wireshark after capturing\n");
1100 fprintf(output, " -S update packet display when new packets are captured\n");
1101 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1103 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1105 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1106 fprintf(output, " -D print list of interfaces and exit\n");
1107 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1108 fprintf(output, "\n");
1109 fprintf(output, "Capture stop conditions:\n");
1110 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1111 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1112 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1113 fprintf(output, " files:NUM - stop after NUM files\n");
1114 /*fprintf(output, "\n");*/
1115 fprintf(output, "Capture output:\n");
1116 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1117 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1118 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1119 #endif /* HAVE_LIBPCAP */
1121 /*fprintf(output, "\n");*/
1122 fprintf(output, "Input file:\n");
1123 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1125 fprintf(output, "\n");
1126 fprintf(output, "Processing:\n");
1127 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1128 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1129 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1131 fprintf(output, "\n");
1132 fprintf(output, "User interface:\n");
1133 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1134 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1135 fprintf(output, " -m <font> set the font name used for most text\n");
1136 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1137 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1138 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1140 fprintf(output, "\n");
1141 fprintf(output, "Output:\n");
1142 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1144 fprintf(output, "\n");
1145 fprintf(output, "Miscellaneous:\n");
1146 fprintf(output, " -h display this help and exit\n");
1147 fprintf(output, " -v display version info and exit\n");
1148 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1149 fprintf(output, " persdata:path - personal data files\n");
1150 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1152 fprintf(output, " --display=DISPLAY X display to use\n");
1167 printf(PACKAGE " " VERSION "%s\n"
1174 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1175 runtime_info_str->str);
1183 * Report an error in command-line arguments.
1184 * Creates a console on Windows.
1185 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1186 * terminal isn't the standard error?
1189 cmdarg_err(const char *fmt, ...)
1197 fprintf(stderr, "wireshark: ");
1198 vfprintf(stderr, fmt, ap);
1199 fprintf(stderr, "\n");
1204 * Report additional information for an error in command-line arguments.
1205 * Creates a console on Windows.
1206 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1207 * terminal isn't the standard error?
1210 cmdarg_err_cont(const char *fmt, ...)
1218 vfprintf(stderr, fmt, ap);
1219 fprintf(stderr, "\n");
1223 #if defined(_WIN32) || ! defined USE_THREADS
1225 Once every 3 seconds we get a callback here which we use to update
1226 the tap extensions. Since Gtk1 is single threaded we dont have to
1227 worry about any locking or critical regions.
1230 update_cb(gpointer data _U_)
1232 draw_tap_listeners(FALSE);
1237 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1238 use threads all update_thread_mutex can be dropped and protect/unprotect
1239 would just be empty functions.
1241 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1242 gtk1-wireshark and it will just work.
1244 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1246 update_thread(gpointer data _U_)
1250 g_get_current_time(&tv1);
1251 g_static_mutex_lock(&update_thread_mutex);
1252 gdk_threads_enter();
1253 draw_tap_listeners(FALSE);
1254 gdk_threads_leave();
1255 g_static_mutex_unlock(&update_thread_mutex);
1257 g_get_current_time(&tv2);
1258 if( ((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) >
1259 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1260 g_usleep(((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) -
1261 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1268 protect_thread_critical_region(void)
1270 #if !defined(_WIN32) && defined USE_THREADS
1271 g_static_mutex_lock(&update_thread_mutex);
1275 unprotect_thread_critical_region(void)
1277 #if !defined(_WIN32) && defined USE_THREADS
1278 g_static_mutex_unlock(&update_thread_mutex);
1282 /* Set the file name in the name for the main window and in the name for the main window's icon. */
1284 set_display_filename(capture_file *cf)
1286 const gchar *name_ptr;
1289 name_ptr = cf_get_display_name(cf);
1291 if (!cf->is_tempfile && cf->filename) {
1292 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1293 add_menu_recent_capture_file(cf->filename);
1297 win_name = g_strdup_printf("%s - Wireshark", name_ptr);
1298 set_main_window_name(win_name);
1302 GtkWidget *close_dlg = NULL;
1305 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1307 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1312 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1314 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1319 main_cf_cb_file_closing(capture_file *cf)
1322 /* if we have more than 10000 packets, show a splash screen while closing */
1323 /* XXX - don't know a better way to decide wether to show or not,
1324 * as most of the time is spend in a single eth_clist_clear function,
1325 * so we can't use a progress bar here! */
1326 if(cf->count > 10000) {
1327 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1328 "%sClosing file!%s\n\nPlease wait ...",
1329 simple_dialog_primary_start(),
1330 simple_dialog_primary_end());
1331 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1334 /* Destroy all windows, which refer to the
1335 capture file we're closing. */
1336 destroy_packet_wins();
1337 file_save_as_destroy();
1339 /* Restore the standard title bar message. */
1340 set_main_window_name("The Wireshark Network Analyzer");
1342 /* Disable all menu items that make sense only if you have a capture. */
1343 set_menus_for_capture_file(NULL);
1344 set_menus_for_captured_packets(FALSE);
1345 set_menus_for_selected_packet(cf);
1346 set_menus_for_capture_in_progress(FALSE);
1347 set_capture_if_dialog_for_capture_in_progress(FALSE);
1348 set_menus_for_selected_tree_row(cf);
1350 /* Set up main window for no capture file. */
1351 main_set_for_capture_file(FALSE);
1353 main_window_update();
1357 main_cf_cb_file_closed(capture_file *cf _U_)
1359 if(close_dlg != NULL) {
1360 splash_destroy(close_dlg);
1367 main_cf_cb_file_read_start(capture_file *cf _U_)
1369 /* Set up main window for a capture file. */
1370 main_set_for_capture_file(TRUE);
1374 main_cf_cb_file_read_finished(capture_file *cf)
1376 set_display_filename(cf);
1378 /* Enable menu items that make sense if you have a capture file you've
1379 finished reading. */
1380 set_menus_for_capture_file(cf);
1382 /* Enable menu items that make sense if you have some captured packets. */
1383 set_menus_for_captured_packets(TRUE);
1386 GList *icon_list_create(
1387 const char **icon16_xpm,
1388 const char **icon32_xpm,
1389 const char **icon48_xpm,
1390 const char **icon64_xpm)
1392 GList *icon_list = NULL;
1393 GdkPixbuf * pixbuf16;
1394 GdkPixbuf * pixbuf32;
1395 GdkPixbuf * pixbuf48;
1396 GdkPixbuf * pixbuf64;
1399 if(icon16_xpm != NULL) {
1400 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1402 icon_list = g_list_append(icon_list, pixbuf16);
1405 if(icon32_xpm != NULL) {
1406 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1408 icon_list = g_list_append(icon_list, pixbuf32);
1411 if(icon48_xpm != NULL) {
1412 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1414 icon_list = g_list_append(icon_list, pixbuf48);
1417 if(icon64_xpm != NULL) {
1418 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1420 icon_list = g_list_append(icon_list, pixbuf64);
1428 main_cf_cb_live_capture_prepared(capture_options *capture_opts)
1431 static GList *icon_list = NULL;
1434 if(capture_opts->iface) {
1435 title = g_strdup_printf("%s: Capturing - Wireshark",
1436 get_iface_description(capture_opts));
1438 title = g_strdup_printf("Capturing - Wireshark");
1440 set_main_window_name(title);
1443 if(icon_list == NULL) {
1444 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1446 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1448 /* Disable menu items that make no sense if you're currently running
1450 set_menus_for_capture_in_progress(TRUE);
1451 set_capture_if_dialog_for_capture_in_progress(TRUE);
1453 /* Don't set up main window for a capture file. */
1454 main_set_for_capture_file(FALSE);
1458 main_cf_cb_live_capture_update_started(capture_options *capture_opts)
1462 /* We've done this in "prepared" above, but it will be cleared while
1463 switching to the next multiple file. */
1464 if(capture_opts->iface) {
1465 title = g_strdup_printf("%s: Capturing - Wireshark",
1466 get_iface_description(capture_opts));
1468 title = g_strdup_printf("Capturing - Wireshark");
1470 set_main_window_name(title);
1473 set_menus_for_capture_in_progress(TRUE);
1474 set_capture_if_dialog_for_capture_in_progress(TRUE);
1476 /* Enable menu items that make sense if you have some captured
1477 packets (yes, I know, we don't have any *yet*). */
1478 set_menus_for_captured_packets(TRUE);
1480 /* Set up main window for a capture file. */
1481 main_set_for_capture_file(TRUE);
1485 main_cf_cb_live_capture_update_finished(capture_file *cf)
1487 static GList *icon_list = NULL;
1489 set_display_filename(cf);
1491 /* Enable menu items that make sense if you're not currently running
1493 set_menus_for_capture_in_progress(FALSE);
1494 set_capture_if_dialog_for_capture_in_progress(FALSE);
1496 /* Enable menu items that make sense if you have a capture file
1497 you've finished reading. */
1498 set_menus_for_capture_file(cf);
1500 /* Set up main window for a capture file. */
1501 main_set_for_capture_file(TRUE);
1503 if(icon_list == NULL) {
1504 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1506 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1508 if(capture_opts->quit_after_cap) {
1509 /* command line asked us to quit after the capture */
1510 /* don't pop up a dialog to ask for unsaved files etc. */
1516 main_cf_cb_live_capture_fixed_started(capture_options *capture_opts _U_)
1518 /* Don't set up main window for a capture file. */
1519 main_set_for_capture_file(FALSE);
1523 main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_)
1525 static GList *icon_list = NULL;
1527 /*set_display_filename(cf);*/
1529 /* Enable menu items that make sense if you're not currently running
1531 set_menus_for_capture_in_progress(FALSE);
1532 set_capture_if_dialog_for_capture_in_progress(FALSE);
1534 /* Restore the standard title bar message */
1535 /* (just in case we have trouble opening the capture file). */
1536 set_main_window_name("The Wireshark Network Analyzer");
1538 if(icon_list == NULL) {
1539 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1541 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1543 /* We don't have loaded the capture file, this will be done later.
1544 * For now we still have simply a blank screen. */
1546 if(capture_opts->quit_after_cap) {
1547 /* command line asked us to quit after the capture */
1548 /* don't pop up a dialog to ask for unsaved files etc. */
1556 main_cf_cb_packet_selected(gpointer data)
1558 capture_file *cf = data;
1560 /* Display the GUI protocol tree and hex dump.
1561 XXX - why do we dump core if we call "proto_tree_draw()"
1562 before calling "add_byte_views()"? */
1563 add_main_byte_views(cf->edt);
1564 main_proto_tree_draw(cf->edt->tree);
1566 /* The user is searching for a string in the data or a hex value,
1567 * highlight the field that is found in the tree and hex displays. */
1568 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1569 highlight_field(cf->edt->tvb, cfile.search_pos,
1570 (GtkTreeView *)tree_view, cf->edt->tree);
1571 cfile.search_pos = 0; /* Reset the position */
1574 /* A packet is selected. */
1575 set_menus_for_selected_packet(cf);
1579 main_cf_cb_packet_unselected(capture_file *cf)
1581 /* Clear out the display of that packet. */
1582 clear_tree_and_hex_views();
1584 /* No packet is selected. */
1585 set_menus_for_selected_packet(cf);
1589 main_cf_cb_field_unselected(capture_file *cf)
1591 set_menus_for_selected_tree_row(cf);
1595 main_cf_cb_file_safe_reload_finished(gpointer data _U_)
1597 set_menus_for_capture_file(&cfile);
1600 static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1603 case(cf_cb_file_closing):
1604 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1605 main_cf_cb_file_closing(data);
1607 case(cf_cb_file_closed):
1608 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1609 main_cf_cb_file_closed(data);
1611 case(cf_cb_file_read_start):
1612 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read start");
1613 main_cf_cb_file_read_start(data);
1615 case(cf_cb_file_read_finished):
1616 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1617 main_cf_cb_file_read_finished(data);
1620 case(cf_cb_live_capture_prepared):
1621 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1622 main_cf_cb_live_capture_prepared(data);
1624 case(cf_cb_live_capture_update_started):
1625 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1626 main_cf_cb_live_capture_update_started(data);
1628 case(cf_cb_live_capture_update_continue):
1629 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1631 case(cf_cb_live_capture_update_finished):
1632 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1633 main_cf_cb_live_capture_update_finished(data);
1635 case(cf_cb_live_capture_fixed_started):
1636 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1637 main_cf_cb_live_capture_fixed_started(data);
1639 case(cf_cb_live_capture_fixed_continue):
1640 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1642 case(cf_cb_live_capture_fixed_finished):
1643 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1644 main_cf_cb_live_capture_fixed_finished(data);
1646 case(cf_cb_live_capture_stopping):
1647 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1648 /* Beware: this state won't be called, if the capture child
1649 * closes the capturing on it's own! */
1652 case(cf_cb_packet_selected):
1653 main_cf_cb_packet_selected(data);
1655 case(cf_cb_packet_unselected):
1656 main_cf_cb_packet_unselected(data);
1658 case(cf_cb_field_unselected):
1659 main_cf_cb_field_unselected(data);
1661 case(cf_cb_file_safe_started):
1662 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe started");
1664 case(cf_cb_file_safe_finished):
1665 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe finished");
1667 case(cf_cb_file_safe_reload_finished):
1668 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: reload finished");
1669 main_cf_cb_file_safe_reload_finished(data);
1671 case(cf_cb_file_safe_failed):
1672 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe failed");
1675 g_warning("main_cf_callback: event %u unknown", event);
1676 g_assert_not_reached();
1681 get_gui_compiled_info(GString *str)
1683 get_epan_compiled_version_info(str);
1685 g_string_append(str, ", ");
1686 #ifdef HAVE_LIBPORTAUDIO
1687 #ifdef PORTAUDIO_API_1
1688 g_string_append(str, "with PortAudio <= V18");
1689 #else /* PORTAUDIO_API_1 */
1690 g_string_append(str, "with ");
1691 g_string_append(str, Pa_GetVersionText());
1692 #endif /* PORTAUDIO_API_1 */
1693 #else /* HAVE_LIBPORTAUDIO */
1694 g_string_append(str, "without PortAudio");
1695 #endif /* HAVE_LIBPORTAUDIO */
1697 g_string_append(str, ", ");
1699 get_compiled_airpcap_version(str);
1701 g_string_append(str, "without AirPcap");
1706 get_gui_runtime_info(GString *str
1707 #ifndef HAVE_AIRPCAP
1713 g_string_append(str, ", ");
1714 get_runtime_airpcap_version(str);
1718 g_string_append(str, ", ");
1719 u3_runtime_info(str);
1725 read_configuration_files(char **gdp_path, char **dp_path)
1727 int gpf_open_errno, gpf_read_errno;
1728 int cf_open_errno, df_open_errno;
1729 int gdp_open_errno, gdp_read_errno;
1730 int dp_open_errno, dp_read_errno;
1731 char *gpf_path, *pf_path;
1732 char *cf_path, *df_path;
1733 int pf_open_errno, pf_read_errno;
1736 /* Read the preference files. */
1737 prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1738 &pf_open_errno, &pf_read_errno, &pf_path);
1740 if (gpf_path != NULL) {
1741 if (gpf_open_errno != 0) {
1742 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1743 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1744 strerror(gpf_open_errno));
1746 if (gpf_read_errno != 0) {
1747 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1748 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1749 strerror(gpf_read_errno));
1752 if (pf_path != NULL) {
1753 if (pf_open_errno != 0) {
1754 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1755 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1756 strerror(pf_open_errno));
1758 if (pf_read_errno != 0) {
1759 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1760 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1761 strerror(pf_read_errno));
1768 /* if the user wants a console to be always there, well, we should open one for him */
1769 if (prefs->gui_console_open == console_open_always) {
1774 /* Read the capture filter file. */
1775 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1776 if (cf_path != NULL) {
1777 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1778 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1779 strerror(cf_open_errno));
1783 /* Read the display filter file. */
1784 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1785 if (df_path != NULL) {
1786 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1787 "Could not open your display filter file\n\"%s\": %s.", df_path,
1788 strerror(df_open_errno));
1792 /* Read the disabled protocols file. */
1793 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1794 dp_path, &dp_open_errno, &dp_read_errno);
1795 if (*gdp_path != NULL) {
1796 if (gdp_open_errno != 0) {
1797 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1798 "Could not open global disabled protocols file\n\"%s\": %s.",
1799 *gdp_path, strerror(gdp_open_errno));
1801 if (gdp_read_errno != 0) {
1802 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1803 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1804 *gdp_path, strerror(gdp_read_errno));
1809 if (*dp_path != NULL) {
1810 if (dp_open_errno != 0) {
1811 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1812 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1813 strerror(dp_open_errno));
1815 if (dp_read_errno != 0) {
1816 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1817 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1818 strerror(dp_read_errno));
1827 /* And now our feature presentation... [ fade to music ] */
1829 main(int argc, char *argv[])
1831 char *init_progfile_dir_error;
1834 extern char *optarg;
1835 gboolean arg_error = FALSE;
1843 char *gdp_path, *dp_path;
1846 gboolean start_capture = FALSE;
1848 gboolean capture_option_specified = FALSE;
1850 gint pl_size = 280, tv_size = 95, bv_size = 75;
1851 gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
1852 dfilter_t *rfcode = NULL;
1853 gboolean rfilter_parse_failed = FALSE;
1856 GtkWidget *splash_win = NULL;
1857 GLogLevelFlags log_flags;
1858 guint go_to_packet = 0;
1861 gchar *cur_user, *cur_group;
1865 /*gchar *cant_get_if_list_errstr;*/
1868 #define OPTSTRING_INIT "a:b:c:C:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
1870 #if defined HAVE_LIBPCAP && defined _WIN32
1871 #define OPTSTRING_WIN32 "B:"
1873 #define OPTSTRING_WIN32 ""
1876 char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
1877 OPTSTRING_INIT OPTSTRING_WIN32;
1880 * Get credential information for later use, and drop privileges
1881 * before doing anything else.
1882 * Let the user know if anything happened.
1884 get_credential_info();
1885 relinquish_special_privs_perm();
1888 * Attempt to get the pathname of the executable file.
1890 init_progfile_dir_error = init_progfile_dir(argv[0]);
1892 /* initialize the funnel mini-api */
1893 initialize_funnel_ops();
1895 #ifdef HAVE_AIRPDCAP
1896 /* Davide Schiera (2006-11-18): init AirPDcap context */
1897 AirPDcapInitContext(&airpdcap_ctx);
1898 /* Davide Schiera (2006-11-18) ------------------------------------------- */
1902 /* Load wpcap if possible. Do this before collecting the run-time version information */
1905 /* ... and also load the packet.dll from wpcap */
1906 wpcap_packet_load();
1909 /* Load the airpcap.dll. This must also be done before collecting
1910 * run-time version information. */
1911 airpcap_dll_ret_val = load_airpcap();
1913 switch (airpcap_dll_ret_val) {
1914 case AIRPCAP_DLL_OK:
1915 /* load the airpcap interfaces */
1916 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
1918 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
1919 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
1920 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
1923 airpcap_if_active = NULL;
1927 /* select the first ad default (THIS SHOULD BE CHANGED) */
1928 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
1933 * XXX - Maybe we need to warn the user if one of the following happens???
1935 case AIRPCAP_DLL_OLD:
1936 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
1939 case AIRPCAP_DLL_ERROR:
1940 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
1943 case AIRPCAP_DLL_NOT_FOUND:
1944 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
1948 #endif /* HAVE_AIRPCAP */
1950 /* Start windows sockets */
1951 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
1954 /* Assemble the compile-time version information string */
1955 comp_info_str = g_string_new("Compiled ");
1957 g_string_append(comp_info_str, "with ");
1958 g_string_sprintfa(comp_info_str,
1959 #ifdef GTK_MAJOR_VERSION
1960 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1963 "GTK+ (version unknown)");
1965 g_string_append(comp_info_str, ", ");
1967 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
1969 /* Assemble the run-time version information string */
1970 runtime_info_str = g_string_new("Running ");
1971 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
1974 /* "pre-scan" the command line parameters, if we have "console only"
1975 parameters. We do this so we don't start GTK+ if we're only showing
1976 command-line help or version information.
1978 XXX - this pre-scan is done before we start GTK+, so we haven't
1979 run gtk_init() on the arguments. That means that GTK+ arguments
1980 have not been removed from the argument list; those arguments
1981 begin with "--", and will be treated as an error by getopt().
1983 We thus ignore errors - *and* set "opterr" to 0 to suppress the
1986 optind_initial = optind;
1987 while ((opt = getopt(argc, argv, optstring)) != -1) {
1989 case 'C': /* Configuration Profile */
1990 if (profile_exists (optarg)) {
1991 set_profile_name (optarg);
1993 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
1997 case 'h': /* Print help and exit */
2001 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2002 status = filesystem_opt(opt, optarg);
2004 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2008 case 'v': /* Show version and exit */
2014 * Extension command line options have to be processed before
2015 * we call epan_init() as they are supposed to be used by dissectors
2016 * or taps very early in the registration process.
2020 case '?': /* Ignore errors - the "real" scan will catch them. */
2025 /* Init the "Open file" dialog directory */
2026 /* (do this after the path settings are processed) */
2027 set_last_open_dir(get_persdatafile_dir());
2029 /* Set getopt index back to initial value, so it will start with the
2030 first command line parameter again. Also reset opterr to 1, so that
2031 error messages are printed by getopt().
2033 XXX - this seems to work on most platforms, but time will tell.
2034 The Single UNIX Specification says "The getopt() function need
2035 not be reentrant", so this isn't guaranteed to work. The Mac
2036 OS X 10.4[.x] getopt() man page says
2038 In order to use getopt() to evaluate multiple sets of arguments, or to
2039 evaluate a single set of arguments multiple times, the variable optreset
2040 must be set to 1 before the second and each additional set of calls to
2041 getopt(), and the variable optind must be reinitialized.
2045 The optreset variable was added to make it possible to call the getopt()
2046 function multiple times. This is an extension to the IEEE Std 1003.2
2047 (``POSIX.2'') specification.
2049 which I think comes from one of the other BSDs.
2051 XXX - if we want to control all the command-line option errors, so
2052 that we can display them where we choose (e.g., in a window), we'd
2053 want to leave opterr as 0, and produce our own messages using optopt.
2054 We'd have to check the value of optopt to see if it's a valid option
2055 letter, in which case *presumably* the error is "this option requires
2056 an argument but none was specified", or not a valid option letter,
2057 in which case *presumably* the error is "this option isn't valid".
2058 Some versions of getopt() let you supply a option string beginning
2059 with ':', which means that getopt() will return ':' rather than '?'
2060 for "this option requires an argument but none was specified", but
2062 optind = optind_initial;
2065 /* Set the current locale according to the program environment.
2066 * We haven't localized anything, but some GTK widgets are localized
2067 * (the file selection dialogue, for example).
2068 * This also sets the C-language locale to the native environment. */
2071 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2072 gtk_init (&argc, &argv);
2074 cf_callback_add(main_cf_callback, NULL);
2075 cf_callback_add(statusbar_cf_callback, NULL);
2077 /* Arrange that if we have no console window, and a GLib message logging
2078 routine is called to log a message, we pop up a console window.
2080 We do that by inserting our own handler for all messages logged
2081 to the default domain; that handler pops up a console if necessary,
2082 and then calls the default handler. */
2084 /* We might want to have component specific log levels later ... */
2088 G_LOG_LEVEL_CRITICAL|
2089 G_LOG_LEVEL_WARNING|
2090 G_LOG_LEVEL_MESSAGE|
2093 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2095 g_log_set_handler(NULL,
2097 console_log_handler, NULL /* user_data */);
2098 g_log_set_handler(LOG_DOMAIN_MAIN,
2100 console_log_handler, NULL /* user_data */);
2103 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2105 console_log_handler, NULL /* user_data */);
2106 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2108 console_log_handler, NULL /* user_data */);
2110 /* Set the initial values in the capture_opts. This might be overwritten
2111 by preference settings and then again by the command line parameters. */
2112 capture_opts_init(capture_opts, &cfile);
2114 capture_opts->snaplen = MIN_PACKET_SIZE;
2115 capture_opts->has_ring_num_files = TRUE;
2118 /* We won't come till here, if we had a "console only" command line parameter. */
2119 splash_win = splash_new("Loading Wireshark ...");
2120 if (init_progfile_dir_error != NULL) {
2121 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2122 "Can't get pathname of Wireshark: %s.\n"
2123 "It won't be possible to capture traffic.\n"
2124 "Report this to the Wireshark developers.",
2125 init_progfile_dir_error);
2126 g_free(init_progfile_dir_error);
2129 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2131 /* Register all dissectors; we must do this before checking for the
2132 "-G" flag, as the "-G" flag dumps information registered by the
2133 dissectors, and we must do it before we read the preferences, in
2134 case any dissectors register preferences. */
2135 epan_init(register_all_protocols,register_all_protocol_handoffs,
2136 splash_update, (gpointer) splash_win,
2137 failure_alert_box,open_failure_alert_box,read_failure_alert_box);
2139 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2141 /* Register all tap listeners; we do this before we parse the arguments,
2142 as the "-z" argument can specify a registered tap. */
2144 /* we register the plugin taps before the other taps because
2145 stats_tree taps plugins will be registered as tap listeners
2146 by stats_tree_stat.c and need to registered before that */
2149 register_all_plugin_tap_listeners();
2152 register_all_tap_listeners();
2154 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2156 /* Now register the preferences for any non-dissector modules.
2157 We must do that before we read the preferences as well. */
2158 prefs_register_modules();
2160 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2161 #if !defined(_WIN32) && defined(G_THREADS_ENABLED) && defined USE_THREADS
2164 g_thread_init(NULL);
2166 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2167 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2169 #else /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2170 /* this is to keep tap extensions updating once every 3 seconds */
2171 gtk_timeout_add(3000, (GtkFunction)update_cb,(gpointer)NULL);
2172 #endif /* !_WIN32 && G_THREADS_ENABLED && USE_THREADS */
2175 gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
2178 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2180 prefs = read_configuration_files (&gdp_path, &dp_path);
2182 /* Read the (static part) of the recent file. Only the static part of it will be read, */
2183 /* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
2184 /* We have to do this already here, so command line parameters can overwrite these values. */
2185 recent_read_static(&rf_path, &rf_open_errno);
2187 init_cap_file(&cfile);
2189 /* Now get our args */
2190 while ((opt = getopt(argc, argv, optstring)) != -1) {
2192 /*** capture option specific ***/
2193 case 'a': /* autostop criteria */
2194 case 'b': /* Ringbuffer option */
2195 case 'c': /* Capture xxx packets */
2196 case 'f': /* capture filter */
2197 case 'k': /* Start capture immediately */
2198 case 'H': /* Hide capture info dialog box */
2199 case 'i': /* Use interface xxx */
2200 case 'p': /* Don't capture in promiscuous mode */
2201 case 'Q': /* Quit after capture (just capture to file) */
2202 case 's': /* Set the snapshot (capture) length */
2203 case 'S': /* "Sync" mode: used for following file ala tail -f */
2204 case 'w': /* Write to capture file xxx */
2205 case 'y': /* Set the pcap data link type */
2207 case 'B': /* Buffer size */
2210 status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
2215 capture_option_specified = TRUE;
2220 /*** all non capture option specific ***/
2222 /* Configuration profile settings were already processed just ignore them this time*/
2224 case 'D': /* Print a list of capture devices and exit */
2226 capture_opts_list_interfaces(FALSE);
2229 capture_option_specified = TRUE;
2233 case 'g': /* Go to packet */
2234 go_to_packet = get_positive_int(optarg, "go to packet");
2236 case 'l': /* Automatic scrolling in live capture mode */
2238 auto_scroll_live = TRUE;
2240 capture_option_specified = TRUE;
2244 case 'L': /* Print list of link-layer types and exit */
2246 list_link_layer_types = TRUE;
2248 capture_option_specified = TRUE;
2252 case 'm': /* Fixed-width font for the display */
2253 if (prefs->gui_font_name != NULL)
2254 g_free(prefs->gui_font_name);
2255 prefs->gui_font_name = g_strdup(optarg);
2257 case 'n': /* No name resolution */
2258 g_resolv_flags = RESOLV_NONE;
2260 case 'N': /* Select what types of addresses/port #s to resolve */
2261 if (g_resolv_flags == RESOLV_ALL)
2262 g_resolv_flags = RESOLV_NONE;
2263 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2264 if (badopt != '\0') {
2265 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2270 case 'o': /* Override preference from command line */
2271 switch (prefs_set_pref(optarg)) {
2274 case PREFS_SET_SYNTAX_ERR:
2275 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2278 case PREFS_SET_NO_SUCH_PREF:
2279 /* not a preference, might be a recent setting */
2280 switch (recent_set_arg(optarg)) {
2283 case PREFS_SET_SYNTAX_ERR:
2284 /* shouldn't happen, checked already above */
2285 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2288 case PREFS_SET_NO_SUCH_PREF:
2289 case PREFS_SET_OBSOLETE:
2290 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2295 g_assert_not_reached();
2298 case PREFS_SET_OBSOLETE:
2299 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2304 g_assert_not_reached();
2308 /* Path settings were already processed just ignore them this time*/
2310 case 'r': /* Read capture file xxx */
2311 /* We may set "last_open_dir" to "cf_name", and if we change
2312 "last_open_dir" later, we free the old value, so we have to
2313 set "cf_name" to something that's been allocated. */
2314 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2315 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2316 cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2318 cf_name = g_strdup(optarg);
2321 case 'R': /* Read file filter */
2324 case 't': /* Time stamp type */
2325 if (strcmp(optarg, "r") == 0)
2326 timestamp_set_type(TS_RELATIVE);
2327 else if (strcmp(optarg, "a") == 0)
2328 timestamp_set_type(TS_ABSOLUTE);
2329 else if (strcmp(optarg, "ad") == 0)
2330 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2331 else if (strcmp(optarg, "d") == 0)
2332 timestamp_set_type(TS_DELTA);
2333 else if (strcmp(optarg, "dd") == 0)
2334 timestamp_set_type(TS_DELTA_DIS);
2335 else if (strcmp(optarg, "e") == 0)
2336 timestamp_set_type(TS_EPOCH);
2338 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2339 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2340 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2345 /* ext ops were already processed just ignore them this time*/
2348 /* We won't call the init function for the stat this soon
2349 as it would disallow MATE's fields (which are registered
2350 by the preferences set callback) from being used as
2351 part of a tap filter. Instead, we just add the argument
2352 to a list of stat arguments. */
2353 if (!process_stat_cmd_arg(optarg)) {
2354 cmdarg_err("Invalid -z argument.");
2355 cmdarg_err_cont(" -z argument must be one of :");
2356 list_stat_cmd_args();
2361 case '?': /* Bad flag - print usage message */
2369 if (cf_name != NULL) {
2371 * Input file name specified with "-r" *and* specified as a regular
2372 * command-line argument.
2374 cmdarg_err("File name specified both with -r and regular argument");
2378 * Input file name not specified with "-r", and a command-line argument
2379 * was specified; treat it as the input file name.
2381 * Yes, this is different from tshark, where non-flag command-line
2382 * arguments are a filter, but this works better on GUI desktops
2383 * where a command can be specified to be run to open a particular
2384 * file - yes, you could have "-r" as the last part of the command,
2385 * but that's a bit ugly.
2387 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
2388 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2389 cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2391 cf_name = g_strdup(argv[0]);
2402 * Extra command line arguments were specified; complain.
2404 cmdarg_err("Invalid argument: %s", argv[0]);
2409 #ifndef HAVE_LIBPCAP
2410 if (capture_option_specified) {
2411 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2419 if (start_capture && list_link_layer_types) {
2420 /* Specifying *both* is bogus. */
2421 cmdarg_err("You can't specify both -L and a live capture.");
2425 if (list_link_layer_types) {
2426 /* We're supposed to list the link-layer types for an interface;
2427 did the user also specify a capture file to be read? */
2429 /* Yes - that's bogus. */
2430 cmdarg_err("You can't specify -L and a capture file to be read.");
2433 /* No - did they specify a ring buffer option? */
2434 if (capture_opts->multi_files_on) {
2435 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2439 /* We're supposed to do a live capture; did the user also specify
2440 a capture file to be read? */
2441 if (start_capture && cf_name) {
2442 /* Yes - that's bogus. */
2443 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2447 /* No - was the ring buffer option specified and, if so, does it make
2449 if (capture_opts->multi_files_on) {
2450 /* Ring buffer works only under certain conditions:
2451 a) ring buffer does not work with temporary files;
2452 b) real_time_mode and multi_files_on are mutually exclusive -
2453 real_time_mode takes precedence;
2454 c) it makes no sense to enable the ring buffer if the maximum
2455 file size is set to "infinite". */
2456 if (capture_opts->save_file == NULL) {
2457 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2458 capture_opts->multi_files_on = FALSE;
2460 /* if (capture_opts->real_time_mode) {
2461 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2462 capture_opts->multi_files_on = FALSE;
2464 if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
2465 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2466 /* XXX - this must be redesigned as the conditions changed */
2467 /* capture_opts->multi_files_on = FALSE;*/
2472 if (start_capture || list_link_layer_types) {
2473 /* Did the user specify an interface to use? */
2474 if (!capture_opts_trim_iface(capture_opts,
2475 (prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
2480 if (list_link_layer_types) {
2481 status = capture_opts_list_link_layer_types(capture_opts, FALSE);
2485 /* Fill in capture options with values from the preferences */
2486 prefs_to_capture_opts();
2488 capture_opts_trim_snaplen(capture_opts, MIN_PACKET_SIZE);
2489 capture_opts_trim_ring_num_files(capture_opts);
2490 #endif /* HAVE_LIBPCAP */
2492 /* Notify all registered modules that have had any of their preferences
2493 changed either from one of the preferences file or from the command
2494 line that their preferences have changed. */
2497 /* disabled protocols as per configuration file */
2498 if (gdp_path == NULL && dp_path == NULL) {
2499 set_disabled_protos_list();
2502 build_column_format_array(&cfile, TRUE);
2504 /* read in rc file from global and personal configuration paths. */
2505 rc_file = get_datafile_path(RC_FILE);
2506 gtk_rc_parse(rc_file);
2508 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2509 gtk_rc_parse(rc_file);
2516 /* close the splash screen, as we are going to open the main window now */
2517 splash_destroy(splash_win);
2519 /************************************************************************/
2520 /* Everything is prepared now, preferences and command line was read in */
2522 /* Pop up the main window. */
2523 create_main_window(pl_size, tv_size, bv_size, prefs);
2525 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2526 recent_read_dynamic(&rf_path, &rf_open_errno);
2527 color_filters_enable(recent.packet_list_colorize);
2529 /* rearrange all the widgets as we now have all recent settings ready for this */
2530 main_widgets_rearrange();
2532 /* Fill in column titles. This must be done after the top level window
2535 XXX - is that still true, with fixed-width columns? */
2536 packet_list_set_column_titles();
2538 menu_recent_read_finished();
2540 menu_auto_scroll_live_changed(auto_scroll_live);
2543 switch (user_font_apply(prefs->gui_geometry_save_column_width)) {
2546 case FA_FONT_NOT_RESIZEABLE:
2547 /* "user_font_apply()" popped up an alert box. */
2548 /* turn off zooming - font can't be resized */
2549 case FA_FONT_NOT_AVAILABLE:
2550 /* XXX - did we successfully load the un-zoomed version earlier?
2551 If so, this *probably* means the font is available, but not at
2552 this particular zoom level, but perhaps some other failure
2553 occurred; I'm not sure you can determine which is the case,
2555 /* turn off zooming - zoom level is unavailable */
2557 /* in any other case than FA_SUCCESS, turn off zooming */
2558 recent.gui_zoom_level = 0;
2559 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2562 dnd_init(top_level);
2565 color_filters_init();
2568 /* the window can be sized only, if it's not already shown, so do it now! */
2569 main_load_window_geometry(top_level);
2571 /* Tell the user not to run as root. */
2572 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2573 cur_user = get_cur_username();
2574 cur_group = get_cur_groupname();
2575 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2576 "Running as user \"%s\" and group \"%s\".\n"
2577 "This could be dangerous.", cur_user, cur_group);
2580 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2581 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2585 /* Warn the user if npf.sys isn't loaded. */
2586 if (!npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2587 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2588 "The NPF driver isn't running. You may have trouble\n"
2589 "capturing or listing interfaces.");
2590 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2591 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2595 /* If we were given the name of a capture file, read it in now;
2596 we defer it until now, so that, if we can't open it, and pop
2597 up an alert box, the alert box is more likely to come up on
2598 top of the main window - but before the preference-file-error
2599 alert box, so, if we get one of those, it's more likely to come
2602 show_main_window(TRUE);
2603 if (rfilter != NULL) {
2604 if (!dfilter_compile(rfilter, &rfcode)) {
2605 bad_dfilter_alert_box(rfilter);
2606 rfilter_parse_failed = TRUE;
2609 if (!rfilter_parse_failed) {
2610 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2611 /* "cf_open()" succeeded, so it closed the previous
2612 capture file, and thus destroyed any previous read filter
2613 attached to "cf". */
2615 cfile.rfcode = rfcode;
2616 /* Open stat windows; we do so after creating the main window,
2617 to avoid GTK warnings, and after successfully opening the
2618 capture file, so we know we have something to compute stats
2619 on, and after registering all dissectors, so that MATE will
2620 have registered its field array and we can have a tap filter
2621 with one of MATE's late-registered fields as part of the
2623 start_requested_stats();
2625 /* Read the capture file. */
2626 switch (cf_read(&cfile)) {
2630 /* Just because we got an error, that doesn't mean we were unable
2631 to read any of the file; we handle what we could get from the
2633 /* if the user told us to jump to a specific packet, do it now */
2634 if(go_to_packet != 0) {
2635 cf_goto_frame(&cfile, go_to_packet);
2639 case CF_READ_ABORTED:
2644 /* Save the name of the containing directory specified in the
2645 path name, if any; we can write over cf_name, which is a
2646 good thing, given that "get_dirname()" does write over its
2648 s = get_dirname(cf_name);
2649 set_last_open_dir(s);
2654 dfilter_free(rfcode);
2655 cfile.rfcode = NULL;
2656 show_main_window(FALSE);
2657 set_menus_for_capture_in_progress(FALSE);
2658 set_capture_if_dialog_for_capture_in_progress(FALSE);
2663 if (start_capture) {
2664 if (capture_opts->save_file != NULL) {
2665 /* Save the directory name for future file dialogs. */
2666 /* (get_dirname overwrites filename) */
2667 s = get_dirname(g_strdup(capture_opts->save_file));
2668 set_last_open_dir(s);
2671 /* "-k" was specified; start a capture. */
2672 show_main_window(TRUE);
2673 if (capture_start(capture_opts)) {
2674 /* The capture started. Open stat windows; we do so after creating
2675 the main window, to avoid GTK warnings, and after successfully
2676 opening the capture file, so we know we have something to compute
2677 stats on, and after registering all dissectors, so that MATE will
2678 have registered its field array and we can have a tap filter with
2679 one of MATE's late-registered fields as part of the filter. */
2680 start_requested_stats();
2684 show_main_window(FALSE);
2685 set_menus_for_capture_in_progress(FALSE);
2686 set_capture_if_dialog_for_capture_in_progress(FALSE);
2689 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
2690 if (!start_capture && strlen(capture_opts->cfilter) == 0) {
2691 g_free(capture_opts->cfilter);
2692 capture_opts->cfilter = g_strdup(get_conn_cfilter());
2694 #else /* HAVE_LIBPCAP */
2695 show_main_window(FALSE);
2696 set_menus_for_capture_in_progress(FALSE);
2697 set_capture_if_dialog_for_capture_in_progress(FALSE);
2698 #endif /* HAVE_LIBPCAP */
2701 /* register our pid if we are being run from a U3 device */
2704 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
2706 /* we'll enter the GTK loop now and hand the control over to GTK ... */
2708 /* ... back from GTK, we're going down now! */
2710 /* deregister our pid */
2711 u3_deregister_pid();
2715 #ifdef HAVE_AIRPDCAP
2716 /* Davide Schiera (2006-11-18): destroy AirPDcap context */
2717 AirPDcapDestroyContext(&airpdcap_ctx);
2718 /* Davide Schiera (2006-11-18) ------------------------------------------- */
2722 /* hide the (unresponsive) main window, while asking the user to close the console window */
2723 gtk_widget_hide(top_level);
2725 /* Shutdown windows sockets */
2728 /* For some unknown reason, the "atexit()" call in "create_console()"
2729 doesn't arrange that "destroy_console()" be called when we exit,
2730 so we call it here if a console was created. */
2736 /* This isn't reached, but we need it to keep GCC from complaining
2737 that "main()" returns without returning a value - it knows that
2738 "exit()" never returns, but it doesn't know that "gtk_exit()"
2739 doesn't, as GTK+ doesn't declare it with the attribute
2741 return 0; /* not reached */
2746 /* We build this as a GUI subsystem application on Win32, so
2747 "WinMain()", not "main()", gets called.
2749 Hack shamelessly stolen from the Win32 port of the GIMP. */
2751 #define _stdcall __attribute__((stdcall))
2755 WinMain (struct HINSTANCE__ *hInstance,
2756 struct HINSTANCE__ *hPrevInstance,
2760 INITCOMMONCONTROLSEX comm_ctrl;
2762 /* Initialize our controls. Required for native Windows file dialogs. */
2763 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
2764 comm_ctrl.dwSize = sizeof(comm_ctrl);
2765 /* Includes the animate, header, hot key, list view, progress bar,
2766 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
2769 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
2770 InitCommonControlsEx(&comm_ctrl);
2772 /* RichEd20.DLL is needed for filter entries. */
2773 LoadLibrary(_T("riched20.dll"));
2775 has_console = FALSE;
2776 return main (__argc, __argv);
2780 * If this application has no console window to which its standard output
2781 * would go, create one.
2784 create_console(void)
2787 /* We have no console to which to print the version string, so
2788 create one and make it the standard input, output, and error. */
2789 if (!AllocConsole())
2790 return; /* couldn't create console */
2791 eth_freopen("CONIN$", "r", stdin);
2792 eth_freopen("CONOUT$", "w", stdout);
2793 eth_freopen("CONOUT$", "w", stderr);
2795 /* Well, we have a console now. */
2798 /* Now register "destroy_console()" as a routine to be called just
2799 before the application exits, so that we can destroy the console
2800 after the user has typed a key (so that the console doesn't just
2801 disappear out from under them, giving the user no chance to see
2802 the message(s) we put in there). */
2803 atexit(destroy_console);
2805 SetConsoleTitle(_T("Wireshark Debug Console"));
2810 destroy_console(void)
2813 printf("\n\nPress any key to exit\n");
2821 /* This routine should not be necessary, at least as I read the GLib
2822 source code, as it looks as if GLib is, on Win32, *supposed* to
2823 create a console window into which to display its output.
2825 That doesn't happen, however. I suspect there's something completely
2826 broken about that code in GLib-for-Win32, and that it may be related
2827 to the breakage that forces us to just call "printf()" on the message
2828 rather than passing the message on to "g_log_default_handler()"
2829 (which is the routine that does the aforementioned non-functional
2830 console window creation). */
2832 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
2833 const char *message, gpointer user_data _U_)
2840 /* ignore log message, if log_level isn't interesting.
2841 If preferences aren't loaded yet, display message anyway */
2842 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
2843 prefs.console_log_level != 0) {
2847 /* create a "timestamp" */
2849 today = localtime(&curr);
2852 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
2853 /* the user wants a console or the application will terminate immediately */
2857 /* For some unknown reason, the above doesn't appear to actually cause
2858 anything to be sent to the standard output, so we'll just splat the
2859 message out directly, just to make sure it gets out. */
2861 switch(log_level & G_LOG_LEVEL_MASK) {
2862 case G_LOG_LEVEL_ERROR:
2865 case G_LOG_LEVEL_CRITICAL:
2868 case G_LOG_LEVEL_WARNING:
2871 case G_LOG_LEVEL_MESSAGE:
2874 case G_LOG_LEVEL_INFO:
2877 case G_LOG_LEVEL_DEBUG:
2881 fprintf(stderr, "unknown log_level %u\n", log_level);
2883 g_assert_not_reached();
2886 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
2887 today->tm_hour, today->tm_min, today->tm_sec,
2888 log_domain != NULL ? log_domain : "",
2891 if(log_level & G_LOG_LEVEL_ERROR) {
2892 /* wait for a key press before the following error handler will terminate the program
2893 this way the user at least can read the error message */
2894 printf("\n\nPress any key to exit\n");
2898 g_log_default_handler(log_domain, log_level, message, user_data);
2905 * Helper for main_widgets_rearrange()
2907 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
2908 gtk_container_remove(GTK_CONTAINER(data), widget);
2911 static GtkWidget *main_widget_layout(gint layout_content)
2913 switch(layout_content) {
2914 case(layout_pane_content_none):
2916 case(layout_pane_content_plist):
2918 case(layout_pane_content_pdetails):
2920 case(layout_pane_content_pbytes):
2923 g_assert_not_reached();
2930 * Rearrange the main window widgets
2932 void main_widgets_rearrange(void) {
2933 GtkWidget *first_pane_widget1, *first_pane_widget2;
2934 GtkWidget *second_pane_widget1, *second_pane_widget2;
2935 gboolean split_top_left;
2937 /* be a bit faster */
2938 gtk_widget_hide(main_vbox);
2940 /* be sure, we don't loose a widget while rearranging */
2941 gtk_widget_ref(menubar);
2942 gtk_widget_ref(main_tb);
2943 gtk_widget_ref(filter_tb);
2946 gtk_widget_ref(airpcap_tb);
2949 gtk_widget_ref(pkt_scrollw);
2950 gtk_widget_ref(tv_scrollw);
2951 gtk_widget_ref(byte_nb_ptr);
2952 gtk_widget_ref(statusbar);
2953 gtk_widget_ref(main_pane_v1);
2954 gtk_widget_ref(main_pane_v2);
2955 gtk_widget_ref(main_pane_h1);
2956 gtk_widget_ref(main_pane_h2);
2957 gtk_widget_ref(welcome_pane);
2959 /* empty all containers participating */
2960 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
2961 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
2962 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
2963 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
2964 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
2966 statusbar_widgets_emptying(statusbar);
2968 /* add the menubar always at the top */
2969 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2972 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
2974 /* filter toolbar in toolbar area */
2975 if (!prefs.filter_toolbar_show_in_statusbar) {
2976 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
2980 /* airpcap toolbar */
2981 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
2984 /* fill the main layout panes */
2985 switch(prefs.gui_layout_type) {
2986 case(layout_type_5):
2987 main_first_pane = main_pane_v1;
2988 main_second_pane = main_pane_v2;
2989 split_top_left = FALSE;
2991 case(layout_type_2):
2992 main_first_pane = main_pane_v1;
2993 main_second_pane = main_pane_h1;
2994 split_top_left = FALSE;
2996 case(layout_type_1):
2997 main_first_pane = main_pane_v1;
2998 main_second_pane = main_pane_h1;
2999 split_top_left = TRUE;
3001 case(layout_type_4):
3002 main_first_pane = main_pane_h1;
3003 main_second_pane = main_pane_v1;
3004 split_top_left = FALSE;
3006 case(layout_type_3):
3007 main_first_pane = main_pane_h1;
3008 main_second_pane = main_pane_v1;
3009 split_top_left = TRUE;
3011 case(layout_type_6):
3012 main_first_pane = main_pane_h1;
3013 main_second_pane = main_pane_h2;
3014 split_top_left = FALSE;
3017 main_first_pane = NULL;
3018 main_second_pane = NULL;
3019 split_top_left = FALSE;
3020 g_assert_not_reached();
3022 if (split_top_left) {
3023 first_pane_widget1 = main_second_pane;
3024 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3025 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3026 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3028 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3029 first_pane_widget2 = main_second_pane;
3030 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3031 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3033 if (first_pane_widget1 != NULL)
3034 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3035 if (first_pane_widget2 != NULL)
3036 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3037 if (second_pane_widget1 != NULL)
3038 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3039 if (second_pane_widget2 != NULL)
3040 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3042 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3045 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3048 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3050 /* filter toolbar in statusbar hbox */
3051 if (prefs.filter_toolbar_show_in_statusbar) {
3052 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3056 /* airpcap toolbar */
3057 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3060 /* statusbar widgets */
3061 statusbar_widgets_pack(statusbar);
3063 /* hide widgets on users recent settings */
3064 main_widgets_show_or_hide();
3066 gtk_widget_show(main_vbox);
3070 is_widget_visible(GtkWidget *widget, gpointer data)
3072 gboolean *is_visible = data;
3075 if (GTK_WIDGET_VISIBLE(widget))
3083 * XXX - this doesn't appear to work with the paned widgets in
3084 * GTK+ 1.2[.x]; if you hide one of the panes, the splitter remains
3085 * and the other pane doesn't grow to take up the rest of the pane.
3086 * It does appear to work with GTK+ 2.x.
3089 main_widgets_show_or_hide(void)
3091 gboolean main_second_pane_show;
3093 if (recent.main_toolbar_show) {
3094 gtk_widget_show(main_tb);
3096 gtk_widget_hide(main_tb);
3099 statusbar_widgets_show_or_hide(statusbar);
3101 if (recent.filter_toolbar_show) {
3102 gtk_widget_show(filter_tb);
3104 gtk_widget_hide(filter_tb);
3108 if (recent.airpcap_toolbar_show) {
3109 gtk_widget_show(airpcap_tb);
3111 gtk_widget_hide(airpcap_tb);
3115 if (recent.packet_list_show && have_capture_file) {
3116 gtk_widget_show(pkt_scrollw);
3118 gtk_widget_hide(pkt_scrollw);
3121 if (recent.tree_view_show && have_capture_file) {
3122 gtk_widget_show(tv_scrollw);
3124 gtk_widget_hide(tv_scrollw);
3127 if (recent.byte_view_show && have_capture_file) {
3128 gtk_widget_show(byte_nb_ptr);
3130 gtk_widget_hide(byte_nb_ptr);
3133 if (have_capture_file) {
3134 gtk_widget_show(main_first_pane);
3136 gtk_widget_hide(main_first_pane);
3140 * Is anything in "main_second_pane" visible?
3141 * If so, show it, otherwise hide it.
3143 main_second_pane_show = FALSE;
3144 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3145 &main_second_pane_show);
3146 if (main_second_pane_show) {
3147 gtk_widget_show(main_second_pane);
3149 gtk_widget_hide(main_second_pane);
3152 if (!have_capture_file) {
3154 gtk_widget_show(welcome_pane);
3157 gtk_widget_hide(welcome_pane);
3160 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
3161 packet_list_freeze ();
3162 packet_list_thaw ();
3166 /* called, when the window state changes (minimized, maximized, ...) */
3168 window_state_event_cb (GtkWidget *widget _U_,
3172 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3174 if( (event->type) == (GDK_WINDOW_STATE)) {
3175 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3176 /* we might have dialogs popped up while we where iconified,
3178 display_queued_messages();
3187 * Changed callback for the channel combobox
3190 airpcap_toolbar_channel_changed_cb(GtkWidget *w _U_, gpointer data)
3195 if ((data != NULL) && (w != NULL) && change_airpcap_settings) {
3196 s = gtk_entry_get_text(GTK_ENTRY(w));
3197 if ((g_ascii_strcasecmp("",s))) {
3198 ch_freq = airpcap_get_frequency_from_str(s);
3199 if (airpcap_if_active != NULL) {
3200 airpcap_if_active->channelInfo.Frequency = ch_freq;
3201 airpcap_update_channel_offset_cb(airpcap_if_active, ch_freq, GTK_WIDGET(data));
3208 * Changed callback for the channel offset combobox
3211 on_channel_offset_cb_changed(GtkWidget *w _U_, gpointer data)
3216 if ((data != NULL) && (w != NULL) && change_airpcap_settings)
3218 s = gtk_entry_get_text(GTK_ENTRY(w));
3219 if ((g_ascii_strcasecmp("",s)))
3221 if (airpcap_if_active != NULL)
3223 sscanf(s,"%d",&offset);
3224 airpcap_if_active->channelInfo.ExtChannel = offset;
3225 if (change_airpcap_settings != NULL)
3227 airpcap_update_frequency_and_offset(airpcap_if_active);
3235 * Callback for the wrong crc combo
3238 airpcap_toolbar_wrong_crc_combo_cb(GtkWidget *entry, gpointer user_data)
3240 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
3243 if( !block_toolbar_signals && (airpcap_if_active != NULL)) {
3244 ad = airpcap_if_open(airpcap_if_active->name, ebuf);
3247 airpcap_if_active->CrcValidationOn = airpcap_get_validation_type(gtk_entry_get_text(GTK_ENTRY(entry)));
3248 airpcap_if_set_fcs_validation(ad,airpcap_if_active->CrcValidationOn);
3249 /* Save configuration */
3250 airpcap_if_store_cur_config_as_adapter_default(ad);
3251 airpcap_if_close(ad);
3257 airpcap_toolbar_encryption_cb(GtkWidget *entry, gpointer user_data)
3259 /* We need to directly access the .ddl functions here... */
3260 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
3265 airpcap_if_info_t* curr_if = NULL;
3267 /* Apply changes to the current adapter */
3268 if( (airpcap_if_active != NULL)) {
3269 ad = airpcap_if_open(airpcap_if_active->name, ebuf);
3272 if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON) {
3273 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_OFF;
3274 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
3275 /* Save configuration */
3276 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
3277 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
3279 airpcap_if_close(ad);
3281 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_ON;
3282 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
3283 /* Save configuration */
3284 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
3285 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
3287 airpcap_if_close(ad);
3291 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No active AirPcap Adapter selected!");
3295 if (!(airpcap_if_list == NULL)){
3296 n = g_list_length(airpcap_if_list);
3298 /* The same kind of settings should be propagated to all the adapters */
3299 /* Apply this change to all the adapters !!! */
3300 for(i = 0; i < n; i++) {
3301 curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
3303 if( (curr_if != NULL) && (curr_if != airpcap_if_selected) ) {
3304 ad = airpcap_if_open(curr_if->name, ebuf);
3306 curr_if->DecryptionOn = airpcap_if_selected->DecryptionOn;
3307 airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
3308 /* Save configuration for the curr_if */
3309 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
3310 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
3312 airpcap_if_close(ad);
3317 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "AirPcap Adapter Error!");
3323 * Callback for the Advanced Wireless Settings button
3326 toolbar_display_airpcap_advanced_cb(GtkWidget *w, gpointer data)
3330 from_widget = (gint*)g_malloc(sizeof(gint));
3331 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
3332 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_ADVANCED_FROM_KEY,from_widget);
3334 display_airpcap_advanced_cb(w,data);
3338 * Callback for the Decryption Key Management button
3341 toolbar_display_airpcap_key_management_cb(GtkWidget *w, gpointer data)
3345 from_widget = (gint*)g_malloc(sizeof(gint));
3346 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
3347 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_ADVANCED_FROM_KEY,from_widget);
3349 display_airpcap_key_management_cb(w,data);
3351 #endif /* HAVE_AIRPCAP */
3353 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_LOCK_MASK))
3355 top_level_key_pressed_cb(GtkCTree *ctree _U_, GdkEventKey *event, gpointer user_data _U_)
3357 if (event->keyval == GDK_F8) {
3360 } else if (event->keyval == GDK_F7) {
3363 } else if (event->state & NO_SHIFT_MOD_MASK) {
3364 return FALSE; /* Skip control, alt, and other modifiers */
3366 * A comment in gdkkeysyms.h says that it's autogenerated from
3367 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3368 * don't explicitly say so, isprint() should work as expected
3371 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3372 /* Forward the keypress on to the display filter entry */
3373 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3374 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3375 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3383 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
3386 *filter_bt, *filter_cm, *filter_te,
3387 *filter_add_expr_bt,
3390 GList *dfilter_list = NULL;
3391 GtkTooltips *tooltips;
3393 GtkAccelGroup *accel;
3397 GtkWidget *key_management_bt = NULL,
3398 *advanced_bt = NULL,
3401 *channel_offset_lb = NULL,
3402 *channel_offset_cb = NULL,
3403 *wrong_crc_lb = NULL,
3404 *wrong_crc_cm = NULL;
3406 GtkWidget *enable_decryption_lb;
3407 GtkWidget *enable_decryption_cb;
3408 GList *enable_decryption_cb_items = NULL;
3409 GtkWidget *enable_decryption_en;
3411 GList *channel_list = NULL;
3412 GList *linktype_list = NULL;
3413 GList *link_list = NULL;
3414 GtkTooltips *airpcap_tooltips;
3415 /* gchar *if_label_text; */
3416 gint *from_widget = NULL;
3420 /* Display filter construct dialog has an Apply button, and "OK" not
3421 only sets our text widget, it activates it (i.e., it causes us to
3422 filter the capture). */
3423 static construct_args_t args = {
3424 "Wireshark: Display Filter",
3430 /* use user-defined title if preference is set */
3431 title = create_user_window_title("The Wireshark Network Analyzer");
3434 top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
3437 tooltips = gtk_tooltips_new();
3440 airpcap_tooltips = gtk_tooltips_new();
3443 gtk_widget_set_name(top_level, "main window");
3444 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3446 g_signal_connect(GTK_OBJECT(top_level), "window_state_event",
3447 G_CALLBACK(window_state_event_cb), NULL);
3448 g_signal_connect(GTK_OBJECT(top_level), "key-press-event",
3449 G_CALLBACK(top_level_key_pressed_cb), NULL );
3451 gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
3453 /* Container for menu bar, toolbar(s), paned windows and progress/info box */
3454 main_vbox = gtk_vbox_new(FALSE, 1);
3455 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
3456 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3457 gtk_widget_show(main_vbox);
3460 menubar = main_menu_new(&accel);
3461 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3462 gtk_widget_show(menubar);
3465 main_tb = toolbar_new();
3466 gtk_widget_show (main_tb);
3469 pkt_scrollw = packet_list_new(prefs);
3470 gtk_widget_set_size_request(packet_list, -1, pl_size);
3471 gtk_widget_show(pkt_scrollw);
3474 tv_scrollw = main_tree_view_new(prefs, &tree_view);
3475 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3476 gtk_widget_show(tv_scrollw);
3478 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
3479 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3480 g_signal_connect(tree_view, "button_press_event", G_CALLBACK(popup_menu_handler),
3481 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3482 gtk_widget_show(tree_view);
3485 byte_nb_ptr = byte_view_new();
3486 gtk_widget_set_size_request(byte_nb_ptr, -1, bv_size);
3487 gtk_widget_show(byte_nb_ptr);
3489 g_signal_connect(byte_nb_ptr, "button_press_event", G_CALLBACK(popup_menu_handler),
3490 g_object_get_data(G_OBJECT(popup_menu_object), PM_HEXDUMP_KEY));
3493 /* Panes for the packet list, tree, and byte view */
3494 main_pane_v1 = gtk_vpaned_new();
3495 gtk_widget_show(main_pane_v1);
3496 main_pane_v2 = gtk_vpaned_new();
3497 gtk_widget_show(main_pane_v2);
3498 main_pane_h1 = gtk_hpaned_new();
3499 gtk_widget_show(main_pane_h1);
3500 main_pane_h2 = gtk_hpaned_new();
3501 gtk_widget_show(main_pane_h2);
3504 /* airpcap toolbar */
3505 airpcap_tb = gtk_toolbar_new();
3506 gtk_toolbar_set_orientation(GTK_TOOLBAR(airpcap_tb),
3507 GTK_ORIENTATION_HORIZONTAL);
3508 gtk_widget_show(airpcap_tb);
3510 /* Interface Label */
3511 /*if(airpcap_if_active != NULL) {
3512 if_label_text = g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_active));
3513 interface_lb = gtk_label_new(if_label_text);
3514 g_free(if_label_text);
3516 interface_lb = gtk_label_new("No Wireless Interface Found ");
3519 /* Add the label to the toolbar */
3520 /*gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), interface_lb,
3521 "Current Wireless Interface", "Private");
3522 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_INTERFACE_KEY,interface_lb);
3523 gtk_widget_show(interface_lb);
3524 gtk_toolbar_insert_space(GTK_TOOLBAR(airpcap_tb),1);*/
3527 /* Create the "802.11 Channel:" label */
3528 channel_lb = gtk_label_new("802.11 Channel: ");
3529 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_CHANNEL_LABEL_KEY,channel_lb);
3530 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_lb,
3531 "Current 802.11 Channel", "Private");
3532 gtk_widget_show(channel_lb);
3534 gtk_widget_set_size_request(channel_lb, 85, 28);
3536 /* Create the channel combo box */
3537 channel_cm = gtk_combo_new();
3538 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(channel_cm)->entry),FALSE);
3539 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_CHANNEL_KEY,channel_cm);
3541 if (airpcap_if_active != NULL && airpcap_if_active->pSupportedChannels != NULL && airpcap_if_active->numSupportedChannels > 0){
3543 for (; i<airpcap_if_active->numSupportedChannels; i++){
3544 channel_list = g_list_append(channel_list, ieee80211_mhz_to_str(airpcap_if_active->pSupportedChannels[i].Frequency));
3546 gtk_combo_set_popdown_strings( GTK_COMBO(channel_cm), channel_list);
3547 airpcap_free_channel_combo_list(channel_list);
3550 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(channel_cm)->entry),
3551 "Change the 802.11 RF channel", NULL);
3553 gtk_widget_set_size_request(channel_cm, 120, 28);
3555 if(airpcap_if_active != NULL) {
3556 chan_str = ieee80211_mhz_to_str(airpcap_if_active->channelInfo.Frequency);
3557 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry), chan_str);
3561 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry),"");
3563 gtk_widget_show(channel_cm);
3565 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_cm,
3566 "802.11 Channel", "Private");
3568 /* gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb)); */
3570 /* Create the "Channel Offset:" label */
3571 channel_offset_lb = gtk_label_new("Channel Offset: ");
3572 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_CHANNEL_OFFSET_LABEL_KEY,channel_offset_lb);
3573 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_offset_lb,
3574 "Current 802.11 Channel Offset", "Private");
3575 gtk_widget_show(channel_offset_lb);
3577 gtk_widget_set_size_request(channel_offset_lb, 80, 28);
3579 /* Start: Channel offset combo box */
3580 channel_offset_cb = gtk_combo_new();
3581 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(channel_offset_cb)->entry),FALSE);
3582 g_object_set_data(G_OBJECT(airpcap_tb), AIRPCAP_TOOLBAR_CHANNEL_OFFSET_KEY, channel_offset_cb);
3584 if(airpcap_if_active != NULL){
3585 airpcap_update_channel_offset_cb(airpcap_if_active, airpcap_if_active->channelInfo.Frequency, channel_offset_cb);
3586 airpcap_update_channel_offset_combo_entry(channel_offset_cb, airpcap_if_active->channelInfo.ExtChannel);
3588 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_offset_cb)->entry),"");
3591 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(channel_offset_cb)->entry),
3592 "Change channel offset", NULL);
3594 gtk_widget_set_size_request(channel_offset_cb, 50, 28);
3596 gtk_widget_show(channel_offset_cb);
3598 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_offset_cb,
3599 "802.11 Channel Offset", "Private");
3601 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
3603 /* callback for channel combo box */
3604 g_signal_connect(GTK_COMBO(channel_cm)->entry,"changed", G_CALLBACK(airpcap_toolbar_channel_changed_cb), channel_offset_cb);
3605 /* callback for channel offset combo box */
3606 g_signal_connect(GTK_COMBO(channel_offset_cb)->entry,"changed", G_CALLBACK(on_channel_offset_cb_changed), channel_offset_cb);
3607 /* End: Channel offset combo box */
3609 /* Wrong CRC Label */
3610 wrong_crc_lb = gtk_label_new(" FCS Filter: ");
3611 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_FCS_FILTER_LABEL_KEY,wrong_crc_lb);
3612 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_lb,
3614 gtk_widget_show(wrong_crc_lb);
3616 /* Wrong CRC combo */
3617 wrong_crc_cm = gtk_combo_new();
3618 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(wrong_crc_cm)->entry),FALSE);
3619 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_FCS_FILTER_KEY,wrong_crc_cm);
3620 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_cm,
3623 gtk_widget_set_size_request(wrong_crc_cm, 100, -1);
3625 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_ALL);
3626 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRECT);
3627 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRUPT);
3629 gtk_combo_set_popdown_strings( GTK_COMBO(wrong_crc_cm), linktype_list) ;
3630 g_list_free(linktype_list);
3631 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(wrong_crc_cm)->entry),
3632 "Select the 802.11 FCS filter that the wireless adapter will apply.",
3635 if(airpcap_if_active != NULL)
3636 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry), airpcap_get_validation_name(airpcap_if_active->CrcValidationOn));
3638 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry),"");
3640 g_signal_connect(GTK_COMBO(wrong_crc_cm)->entry,"changed",G_CALLBACK(airpcap_toolbar_wrong_crc_combo_cb),airpcap_tb);
3641 gtk_widget_show(wrong_crc_cm);
3643 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
3645 /* Decryption mode combo box */
3646 enable_decryption_lb = gtk_label_new ("Decryption Mode: ");
3647 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_DECRYPTION_LABEL_KEY,enable_decryption_lb);
3648 gtk_widget_set_name (enable_decryption_lb, "enable_decryption_lb");
3649 gtk_widget_show (enable_decryption_lb);
3650 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_lb,
3653 enable_decryption_cb = gtk_combo_new ();
3654 gtk_widget_set_name (enable_decryption_cb, "enable_decryption_cb");
3655 gtk_widget_show (enable_decryption_cb);
3656 gtk_widget_set_size_request(enable_decryption_cb, 83, -1);
3657 update_decryption_mode_list(enable_decryption_cb);
3659 enable_decryption_en = GTK_COMBO (enable_decryption_cb)->entry;
3660 gtk_widget_set_name (enable_decryption_en, "enable_decryption_en");
3661 gtk_widget_show (enable_decryption_en);
3662 gtk_editable_set_editable (GTK_EDITABLE (enable_decryption_en), FALSE);
3663 GTK_WIDGET_UNSET_FLAGS (enable_decryption_en, GTK_CAN_FOCUS);
3665 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_cb,
3666 "Choose a Decryption Mode", "Private");
3668 /* Set current decryption mode!!!! */
3669 update_decryption_mode_cm(enable_decryption_cb);
3670 g_signal_connect(enable_decryption_en, "changed", G_CALLBACK(on_enable_decryption_en_changed), airpcap_tb);
3671 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_DECRYPTION_KEY,enable_decryption_cb);
3673 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
3675 /* Advanced button */
3676 advanced_bt = gtk_button_new_with_label("Wireless Settings...");
3677 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_ADVANCED_KEY,advanced_bt);
3679 g_signal_connect(advanced_bt, "clicked", G_CALLBACK(toolbar_display_airpcap_advanced_cb), airpcap_tb);
3680 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), advanced_bt,
3681 "Set Advanced Wireless Settings", "Private");
3684 gtk_widget_show(advanced_bt);
3686 /* Key Management button */
3687 key_management_bt = gtk_button_new_with_label("Decryption Keys...");
3688 g_object_set_data(G_OBJECT(airpcap_tb),AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY,key_management_bt);
3690 g_signal_connect(key_management_bt, "clicked", G_CALLBACK(toolbar_display_airpcap_key_management_cb), airpcap_tb);
3691 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), key_management_bt,
3692 "Manage Decryption Keys", "Private");
3693 gtk_widget_show(key_management_bt);
3695 /* If no airpcap interface is present, gray everything */
3696 if(airpcap_if_active == NULL) {
3697 if(airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0) {
3698 /*No airpcap device found */
3699 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
3700 /* recent.airpcap_toolbar_show = TRUE; */
3702 /* default adapter is not airpcap... or is airpcap but is not found*/
3703 airpcap_set_toolbar_stop_capture(airpcap_if_active);
3704 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
3705 /* recent.airpcap_toolbar_show = TRUE; */
3708 airpcap_set_toolbar_stop_capture(airpcap_if_active);
3709 /* recent.airpcap_toolbar_show = TRUE; */
3713 /* filter toolbar */
3714 filter_tb = gtk_toolbar_new();
3715 gtk_toolbar_set_orientation(GTK_TOOLBAR(filter_tb),
3716 GTK_ORIENTATION_HORIZONTAL);
3717 gtk_widget_show(filter_tb);
3719 /* Create the "Filter:" button */
3720 filter_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
3721 g_signal_connect(filter_bt, "clicked", G_CALLBACK(display_filter_construct_cb), &args);
3722 gtk_widget_show(filter_bt);
3723 g_object_set_data(G_OBJECT(top_level), E_FILT_BT_PTR_KEY, filter_bt);
3725 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_bt,
3726 "Open the \"Display Filter\" dialog, to edit/apply filters", "Private");
3728 /* Create the filter combobox */
3729 filter_cm = gtk_combo_new();
3730 dfilter_list = NULL;
3731 gtk_combo_disable_activate(GTK_COMBO(filter_cm));
3732 gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
3733 g_object_set_data(G_OBJECT(filter_cm), E_DFILTER_FL_KEY, dfilter_list);
3734 filter_te = GTK_COMBO(filter_cm)->entry;
3735 main_display_filter_widget=filter_te;
3736 g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
3737 g_object_set_data(G_OBJECT(filter_te), E_DFILTER_CM_KEY, filter_cm);
3738 g_object_set_data(G_OBJECT(top_level), E_DFILTER_CM_KEY, filter_cm);
3739 g_signal_connect(filter_te, "activate", G_CALLBACK(filter_activate_cb), filter_te);
3740 g_signal_connect(filter_te, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
3741 gtk_widget_set_size_request(filter_cm, 400, -1);
3742 gtk_widget_show(filter_cm);
3743 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_cm,
3745 /* setting a tooltip for a combobox will do nothing, so add it to the corresponding text entry */
3746 gtk_tooltips_set_tip(tooltips, filter_te,
3747 "Enter a display filter, or choose one of your recently used filters. "
3748 "The background color of this field is changed by a continuous syntax check (green is valid, red is invalid, yellow may have unexpected results).",
3751 /* Create the "Add Expression..." button, to pop up a dialog
3752 for constructing filter comparison expressions. */
3753 filter_add_expr_bt = gtk_button_new_from_stock(WIRESHARK_STOCK_ADD_EXPRESSION);
3754 g_object_set_data(G_OBJECT(filter_tb), E_FILT_FILTER_TE_KEY, filter_te);
3755 g_signal_connect(filter_add_expr_bt, "clicked", G_CALLBACK(filter_add_expr_bt_cb), filter_tb);
3756 gtk_widget_show(filter_add_expr_bt);
3757 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_add_expr_bt,
3758 "Add an expression to this filter string", "Private");
3760 /* Create the "Clear" button */
3761 filter_reset = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
3762 g_object_set_data(G_OBJECT(filter_reset), E_DFILTER_TE_KEY, filter_te);
3763 g_signal_connect(filter_reset, "clicked", G_CALLBACK(filter_reset_cb), NULL);
3764 gtk_widget_show(filter_reset);
3765 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_reset,
3766 "Clear this filter string and update the display", "Private");
3768 /* Create the "Apply" button */
3769 filter_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY);
3770 g_object_set_data(G_OBJECT(filter_apply), E_DFILTER_CM_KEY, filter_cm);
3771 g_signal_connect(filter_apply, "clicked", G_CALLBACK(filter_activate_cb), filter_te);
3772 gtk_widget_show(filter_apply);
3773 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_apply,
3774 "Apply this filter string to the display", "Private");
3776 /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data
3777 * of any widget that ends up calling a callback which needs
3778 * that text entry pointer */
3779 set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te);
3780 set_menu_object_data("/Edit/Copy/As Filter", E_DFILTER_TE_KEY,
3782 set_menu_object_data("/Analyze/Display Filters...", E_FILT_TE_PTR_KEY,
3784 set_menu_object_data("/Analyze/Follow TCP Stream", E_DFILTER_TE_KEY,
3786 set_menu_object_data("/Analyze/Follow UDP Stream", E_DFILTER_TE_KEY,
3788 set_menu_object_data("/Analyze/Follow SSL Stream", E_DFILTER_TE_KEY,
3790 set_menu_object_data("/Analyze/Apply as Filter/Selected", E_DFILTER_TE_KEY,
3792 set_menu_object_data("/Analyze/Apply as Filter/Not Selected", E_DFILTER_TE_KEY,
3794 set_menu_object_data("/Analyze/Apply as Filter/... and Selected", E_DFILTER_TE_KEY,
3796 set_menu_object_data("/Analyze/Apply as Filter/... or Selected", E_DFILTER_TE_KEY,
3798 set_menu_object_data("/Analyze/Apply as Filter/... and not Selected", E_DFILTER_TE_KEY,
3800 set_menu_object_data("/Analyze/Apply as Filter/... or not Selected", E_DFILTER_TE_KEY,
3802 set_menu_object_data("/Analyze/Prepare a Filter/Selected", E_DFILTER_TE_KEY,
3804 set_menu_object_data("/Analyze/Prepare a Filter/Not Selected", E_DFILTER_TE_KEY,
3806 set_menu_object_data("/Analyze/Prepare a Filter/... and Selected", E_DFILTER_TE_KEY,
3808 set_menu_object_data("/Analyze/Prepare a Filter/... or Selected", E_DFILTER_TE_KEY,
3810 set_menu_object_data("/Analyze/Prepare a Filter/... and not Selected", E_DFILTER_TE_KEY,
3812 set_menu_object_data("/Analyze/Prepare a Filter/... or not Selected", E_DFILTER_TE_KEY,
3814 set_menu_object_data("/Conversation Filter/Ethernet", E_DFILTER_TE_KEY,
3816 set_menu_object_data("/Conversation Filter/IP", E_DFILTER_TE_KEY,
3818 set_menu_object_data("/Conversation Filter/TCP", E_DFILTER_TE_KEY,
3820 set_menu_object_data("/Conversation Filter/UDP", E_DFILTER_TE_KEY,
3822 set_menu_object_data("/Conversation Filter/PN-CBA Server", E_DFILTER_TE_KEY,
3824 set_toolbar_object_data(E_DFILTER_TE_KEY, filter_te);
3825 g_object_set_data(G_OBJECT(popup_menu_object), E_DFILTER_TE_KEY, filter_te);
3826 g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY, packet_list);
3829 statusbar = statusbar_new();
3831 /* Pane for the welcome screen */
3832 welcome_pane = welcome_new();
3833 gtk_widget_show(welcome_pane);
3838 driver_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
3842 r = simple_dialog_check_get(dialog);
3843 recent.airpcap_driver_check_show = !r;
3848 show_main_window(gboolean doing_work)
3850 main_set_for_capture_file(doing_work);
3852 /*** we have finished all init things, show the main window ***/
3853 gtk_widget_show(top_level);
3855 /* the window can be maximized only, if it's visible, so do it after show! */
3856 main_load_window_geometry(top_level);
3858 /* process all pending GUI events before continue */
3859 while (gtk_events_pending()) gtk_main_iteration();
3861 /* Pop up any queued-up alert boxes. */
3862 display_queued_messages();
3864 /* Move the main window to the front, in case it isn't already there */
3865 gdk_window_raise(top_level->window);
3869 * This will read the decryption keys from the preferences file, and will
3870 * store them into the registry...
3872 if(airpcap_if_list != NULL && g_list_length(airpcap_if_list) > 0){
3873 if (!airpcap_check_decryption_keys(airpcap_if_list)) {
3874 /* Ask the user what to do ...*/
3875 airpcap_keys_check_w(NULL,NULL);
3877 /* Keys from lists are equals, or wireshark has got no keys */
3878 airpcap_load_decryption_keys(airpcap_if_list);
3882 switch (airpcap_dll_ret_val) {
3884 case AIRPCAP_DLL_OK:
3887 case AIRPCAP_DLL_OLD:
3888 if(recent.airpcap_driver_check_show) {
3889 driver_warning_dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
3890 "WARNING: The version of AirPcap on this system\n"
3891 "does not support driver-level decryption. Please\n"
3892 "download a more recent version from\n" "http://www.cacetech.com/support/downloads.htm \n");
3893 simple_dialog_check_set(driver_warning_dialog,"Don't show this message again.");
3894 simple_dialog_set_cb(driver_warning_dialog, driver_warning_dialog_cb, NULL);
3900 * XXX - Maybe we need to warn the user if one of the following happens???
3902 case AIRPCAP_DLL_ERROR:
3903 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
3906 case AIRPCAP_DLL_NOT_FOUND:
3907 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
3911 #endif /* HAVE_AIRPCAP */
3914 /* Fill in capture options with values from the preferences */
3916 prefs_to_capture_opts(void)
3919 /* Set promiscuous mode from the preferences setting. */
3920 /* the same applies to other preferences settings as well. */
3921 capture_opts->promisc_mode = prefs.capture_prom_mode;
3922 capture_opts->show_info = prefs.capture_show_info;
3923 capture_opts->real_time_mode = prefs.capture_real_time;
3924 auto_scroll_live = prefs.capture_auto_scroll;
3925 #endif /* HAVE_LIBPCAP */
3927 /* Set the name resolution code's flags from the preferences. */
3928 g_resolv_flags = prefs.name_resolve;
3932 /* Change configuration profile */
3933 void change_configuration_profile (const gchar *profile_name)
3935 char *gdp_path, *dp_path;
3937 /* First check if profile exists */
3938 if (!profile_exists(profile_name)) {
3942 /* Set profile name and update the status bar */
3943 set_profile_name (profile_name);
3944 profile_bar_update ();
3946 /* Reset current preferences and apply the new */
3948 (void) read_configuration_files (&gdp_path, &dp_path);
3951 /* Update window view and redraw the toolbar */
3952 update_main_window_name();
3953 toolbar_redraw_all();
3955 /* Enable all protocols and disable from the disabled list */
3957 if (gdp_path == NULL && dp_path == NULL) {
3958 set_disabled_protos_list();
3961 /* Reload color filters */
3962 color_filters_reload();
3964 /* Recreate the packet list according to new preferences */
3965 packet_list_recreate ();
3966 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3967 user_font_apply(prefs.gui_geometry_save_column_width);