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>
75 /* general (not GTK specific) */
79 #include "disabled_protos.h"
80 #include <epan/prefs.h>
81 #include "filter_dlg.h"
82 #include "layout_prefs.h"
84 #include "color_filters.h"
86 #include "simple_dialog.h"
88 #include <epan/prefs-int.h>
89 #include "ringbuffer.h"
90 #include "../ui_util.h"
92 #include <epan/stat_cmd_args.h>
94 #include "clopts_common.h"
95 #include "cmdarg_err.h"
96 #include "version_info.h"
102 #include "capture-pcap-util.h"
104 #include "capture_sync.h"
108 #include "capture-wpcap.h"
109 #include "capture_wpcap_packet.h"
110 #include <tchar.h> /* Needed for Unicode */
111 #if GTK_MAJOR_VERSION >= 2
112 #include <commctrl.h>
113 #endif /* GTK_MAJOR_VERSION >= 2 */
116 #if GTK_MAJOR_VERSION < 2 && GTK_MINOR_VERSION < 3
117 #include "ethclist.h"
121 #include "statusbar.h"
122 #include "alert_box.h"
124 #include "dlg_utils.h"
126 #include "file_dlg.h"
127 #include "gtkglobals.h"
129 #include "gui_utils.h"
130 #include "compat_macros.h"
134 #include "../main_window.h"
136 #include "capture_file_dlg.h"
137 #include <epan/column.h>
138 #include "proto_draw.h"
140 #include "packet_win.h"
142 #include "find_dlg.h"
143 #include "packet_list.h"
145 #include "follow_dlg.h"
146 #include "font_utils.h"
147 #include "about_dlg.h"
148 #include "help_dlg.h"
149 #include "decode_as_dlg.h"
150 #include "webbrowser.h"
151 #include "capture_dlg.h"
152 #include "capture_ui_utils.h"
154 #include "../epan/emem.h"
155 #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"
166 #include "airpcap_loader.h"
167 #include "airpcap_dlg.h"
168 #include "airpcap_gui_utils.h"
170 #include "./gtk/toolbar.h"
172 #include "./image/toolbar/wep_closed_24.xpm"
176 /* Davide Schiera (2006-11-22): including AirPDcap project */
177 #include "..\airpdcap\airpdcap_ws.h"
178 /* Davide Schiera (2006-11-22) ---------------------------------------------- */
182 * Files under personal and global preferences directories in which
183 * GTK settings for Wireshark are stored.
185 #define RC_FILE "gtkrc"
188 #define DEF_READY_MESSAGE " Ready to load or capture"
190 #define DEF_READY_MESSAGE " Ready to load file"
194 GtkWidget *main_display_filter_widget=NULL;
195 GtkWidget *top_level = NULL, *tree_view, *byte_nb_ptr, *tv_scrollw;
196 static GtkWidget *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
197 static GtkWidget *main_first_pane, *main_second_pane;
198 static GtkWidget *status_pane;
199 static GtkWidget *menubar, *main_vbox, *main_tb, *pkt_scrollw, *stat_hbox, *filter_tb;
202 GtkWidget *airpcap_tb;
203 static GtkWidget *driver_warning_dialog;
204 static int airpcap_dll_ret_val = -1;
207 static GtkWidget *info_bar;
208 static GtkWidget *packets_bar = NULL;
209 static GtkWidget *welcome_pane;
210 static guint main_ctx, file_ctx, help_ctx;
211 static guint packets_ctx;
212 static gchar *packets_str = NULL;
213 GString *comp_info_str, *runtime_info_str;
214 gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
217 static gboolean has_console; /* TRUE if app has console */
218 static void destroy_console(void);
220 static void console_log_handler(const char *log_domain,
221 GLogLevelFlags log_level, const char *message, gpointer user_data);
224 static gboolean list_link_layer_types;
225 capture_options global_capture_opts;
226 capture_options *capture_opts = &global_capture_opts;
229 gboolean block_toolbar_signals = FALSE;
231 static void create_main_window(gint, gint, gint, e_prefs*);
232 static void show_main_window(gboolean);
233 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
234 static void main_save_window_geometry(GtkWidget *widget);
236 #define E_DFILTER_CM_KEY "display_filter_combo"
237 #define E_DFILTER_FL_KEY "display_filter_list"
239 /* Match selected byte pattern */
241 match_selected_cb_do(gpointer data, int action, gchar *text)
243 GtkWidget *filter_te;
244 char *cur_filter, *new_filter;
249 filter_te = OBJECT_GET_DATA(data, E_DFILTER_TE_KEY);
252 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
254 switch (action&MATCH_SELECTED_MASK) {
256 case MATCH_SELECTED_REPLACE:
257 new_filter = g_strdup(text);
260 case MATCH_SELECTED_AND:
261 if ((!cur_filter) || (0 == strlen(cur_filter)))
262 new_filter = g_strdup(text);
264 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
267 case MATCH_SELECTED_OR:
268 if ((!cur_filter) || (0 == strlen(cur_filter)))
269 new_filter = g_strdup(text);
271 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
274 case MATCH_SELECTED_NOT:
275 new_filter = g_strconcat("!(", text, ")", NULL);
278 case MATCH_SELECTED_AND_NOT:
279 if ((!cur_filter) || (0 == strlen(cur_filter)))
280 new_filter = g_strconcat("!(", text, ")", NULL);
282 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
285 case MATCH_SELECTED_OR_NOT:
286 if ((!cur_filter) || (0 == strlen(cur_filter)))
287 new_filter = g_strconcat("!(", text, ")", NULL);
289 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
293 g_assert_not_reached();
298 /* Free up the copy we got of the old filter text. */
301 /* create a new one and set the display filter entry accordingly */
302 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
304 /* Run the display filter so it goes in effect. */
305 if (action&MATCH_SELECTED_APPLY_NOW)
306 main_filter_packets(&cfile, new_filter, FALSE);
308 /* Free up the new filter text. */
313 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
317 if (cfile.finfo_selected) {
318 filter = proto_construct_match_selected_string(cfile.finfo_selected,
321 match_selected_cb_do((data ? data : w), action, filter);
326 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
328 gchar *selected_proto_url;
329 gchar *proto_abbrev = data;
334 if (cfile.finfo_selected) {
335 /* open wiki page using the protocol abbreviation */
336 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
337 browser_open_url(selected_proto_url);
338 g_free(selected_proto_url);
341 case(ESD_BTN_CANCEL):
344 g_assert_not_reached();
350 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
353 const gchar *proto_abbrev;
357 if (cfile.finfo_selected) {
358 /* convert selected field to protocol abbreviation */
359 /* XXX - could this conversion be simplified? */
360 field_id = cfile.finfo_selected->hfinfo->id;
361 /* if the selected field isn't a protocol, get it's parent */
362 if(!proto_registrar_is_protocol(field_id)) {
363 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
366 proto_abbrev = proto_registrar_get_abbrev(field_id);
368 /* ask the user if the wiki page really should be opened */
369 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
370 PRIMARY_TEXT_START "Open Wireshark Wiki page of protocol \"%s\"?" PRIMARY_TEXT_END "\n"
372 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
374 "The Wireshark Wiki is a collaborative approach to provide information\n"
375 "about Wireshark in several ways (not limited to protocol specifics).\n"
377 "This Wiki is new, so the page of the selected protocol\n"
378 "may not exist and/or may not contain valuable information.\n"
380 "As everyone can edit the Wiki and add new content (or extend existing),\n"
381 "you are encouraged to add information if you can.\n"
383 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
385 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate,\n"
386 "which will save you a lot of editing and will give a consistent look over the pages.",
387 proto_abbrev, proto_abbrev);
388 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer) proto_abbrev);
394 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
397 const gchar *proto_abbrev;
398 gchar *selected_proto_url;
401 if (cfile.finfo_selected) {
402 /* convert selected field to protocol abbreviation */
403 /* XXX - could this conversion be simplified? */
404 field_id = cfile.finfo_selected->hfinfo->id;
405 /* if the selected field isn't a protocol, get it's parent */
406 if(!proto_registrar_is_protocol(field_id)) {
407 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
410 proto_abbrev = proto_registrar_get_abbrev(field_id);
412 /* open reference page using the protocol abbreviation */
413 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s.html", proto_abbrev[0], proto_abbrev);
414 browser_open_url(selected_proto_url);
415 g_free(selected_proto_url);
420 get_text_from_packet_list(gpointer data)
422 gint row = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_ROW_KEY));
423 gint column = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_COL_KEY));
424 frame_data *fdata = (frame_data *)packet_list_get_row_data(row);
432 if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
433 cfile.pd, fdata->cap_len, &err, &err_info)) {
434 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
435 cf_read_error_message(err, err_info), cfile.filename);
439 edt = epan_dissect_new(FALSE, FALSE);
440 epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata,
442 epan_dissect_fill_in_columns(edt);
444 if (strlen(cfile.cinfo.col_expr[column]) != 0 &&
445 strlen(cfile.cinfo.col_expr_val[column]) != 0) {
446 len = strlen(cfile.cinfo.col_expr[column]) +
447 strlen(cfile.cinfo.col_expr_val[column]) + 5;
448 buf = ep_alloc0(len);
449 g_snprintf(buf, len, "%s == %s", cfile.cinfo.col_expr[column],
450 cfile.cinfo.col_expr_val[column]);
453 epan_dissect_free(edt);
460 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
462 match_selected_cb_do(data,
464 get_text_from_packet_list(data));
467 /* This function allows users to right click in the details window and copy the text
468 * information to the operating systems clipboard.
470 * We first check to see if a string representation is setup in the tree and then
471 * read the string. If not available then we try to grab the value. If all else
472 * fails we display a message to the user to indicate the copy could not be completed.
475 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_)
477 GString *gtk_text_str = g_string_new("");
478 char labelstring[256];
479 char *stringpointer = labelstring;
481 if (cfile.finfo_selected->rep->representation != 0) {
482 g_string_sprintfa(gtk_text_str, "%s", cfile.finfo_selected->rep->representation); /* Get the represented data */
484 if (gtk_text_str->len == 0) { /* If no representation then... */
485 proto_item_fill_label(cfile.finfo_selected, stringpointer); /* Try to read the value */
486 g_string_sprintfa(gtk_text_str, "%s", stringpointer);
488 if (gtk_text_str->len == 0) { /* Could not get item so display error msg */
489 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
493 copy_to_clipboard(gtk_text_str); /* Copy string to clipboard */
495 g_string_free(gtk_text_str, TRUE); /* Free the memory */
499 /* XXX: use a preference for this setting! */
500 static guint dfilter_combo_max_recent = 10;
502 /* add a display filter to the combo box */
503 /* Note: a new filter string will replace an old identical one */
505 dfilter_combo_add(GtkWidget *filter_cm, char *s) {
507 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
510 /* GtkCombos don't let us get at their list contents easily, so we maintain
511 our own filter list, and feed it to gtk_combo_set_popdown_strings when
512 a new filter is added. */
513 li = g_list_first(dfilter_list);
515 /* If the filter is already in the list, remove the old one and
516 * append the new one at the latest position (at g_list_append() below) */
517 if (li->data && strcmp(s, li->data) == 0) {
518 dfilter_list = g_list_remove(dfilter_list, li->data);
524 dfilter_list = g_list_append(dfilter_list, s);
525 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
526 gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), dfilter_list);
527 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), g_list_last(dfilter_list)->data);
533 /* write all non empty display filters (until maximum count)
534 * of the combo box GList to the user's recent file */
536 dfilter_recent_combo_write_all(FILE *rf) {
537 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
538 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
543 /* write all non empty display filter strings to the recent file (until max count) */
544 li = g_list_first(dfilter_list);
545 while ( li && (max_count++ <= dfilter_combo_max_recent) ) {
546 if (strlen(li->data)) {
547 fprintf (rf, RECENT_KEY_DISPLAY_FILTER ": %s\n", (char *)li->data);
553 /* empty the combobox entry field */
555 dfilter_combo_add_empty(void) {
556 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
558 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), "");
562 /* add a display filter coming from the user's recent file to the dfilter combo box */
564 dfilter_combo_add_recent(gchar *s) {
565 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
569 if (!dfilter_combo_add(filter_cm, dup)) {
578 /* call cf_filter_packets() and add this filter string to the recent filter list */
580 main_filter_packets(capture_file *cf, const gchar *dftext, gboolean force)
582 GtkCombo *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
583 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
585 gboolean add_filter = TRUE;
586 gboolean free_filter = TRUE;
588 cf_status_t cf_status;
590 /* we'll crash later on if dftext is NULL */
591 g_assert(dftext != NULL);
593 s = g_strdup(dftext);
595 /* GtkCombos don't let us get at their list contents easily, so we maintain
596 our own filter list, and feed it to gtk_combo_set_popdown_strings when
597 a new filter is added. */
598 cf_status = cf_filter_packets(cf, s, force);
599 if (cf_status == CF_OK) {
600 li = g_list_first(dfilter_list);
602 if (li->data && strcmp(s, li->data) == 0)
608 /* trim list size first */
609 while (g_list_length(dfilter_list) >= dfilter_combo_max_recent) {
610 dfilter_list = g_list_remove(dfilter_list, g_list_first(dfilter_list)->data);
614 dfilter_list = g_list_append(dfilter_list, s);
615 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
616 gtk_combo_set_popdown_strings(filter_cm, dfilter_list);
617 gtk_entry_set_text(GTK_ENTRY(filter_cm->entry), g_list_last(dfilter_list)->data);
623 return (cf_status == CF_OK);
627 /* Run the current display filter on the current packet set, and
630 filter_activate_cb(GtkWidget *w _U_, gpointer data)
634 s = gtk_entry_get_text(GTK_ENTRY(data));
636 main_filter_packets(&cfile, s, FALSE);
639 /* redisplay with no display filter */
641 filter_reset_cb(GtkWidget *w, gpointer data _U_)
643 GtkWidget *filter_te = NULL;
645 if ((filter_te = OBJECT_GET_DATA(w, E_DFILTER_TE_KEY))) {
646 gtk_entry_set_text(GTK_ENTRY(filter_te), "");
648 main_filter_packets(&cfile, "", FALSE);
651 /* mark as reference time frame */
653 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
657 frame->flags.ref_time=1;
659 frame->flags.ref_time=0;
661 cf_reftime_packets(&cfile);
665 GtkWidget *reftime_dialog = NULL;
667 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
671 timestamp_set_type(TS_RELATIVE);
672 recent.gui_time_format = TS_RELATIVE;
673 cf_change_time_formats(&cfile);
678 g_assert_not_reached();
681 if (cfile.current_frame) {
682 /* XXX hum, should better have a "cfile->current_row" here ... */
683 set_frame_reftime(!cfile.current_frame->flags.ref_time,
685 packet_list_find_row_from_data(cfile.current_frame));
691 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
696 if (cfile.current_frame) {
697 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
698 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
699 PRIMARY_TEXT_START "Switch to the appropriate Time Display Format?" PRIMARY_TEXT_END "\n\n"
700 "Time References don't work well with the currently selected Time Display Format.\n\n"
701 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?");
702 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
704 /* XXX hum, should better have a "cfile->current_row" here ... */
705 set_frame_reftime(!cfile.current_frame->flags.ref_time,
707 packet_list_find_row_from_data(cfile.current_frame));
711 case REFTIME_FIND_NEXT:
712 find_previous_next_frame_with_filter("frame.ref_time", FALSE);
714 case REFTIME_FIND_PREV:
715 find_previous_next_frame_with_filter("frame.ref_time", TRUE);
721 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
723 find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
727 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
729 find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
732 #if GTK_MAJOR_VERSION < 2
734 tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_,
735 gpointer user_data _U_)
738 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;
749 #if GTK_MAJOR_VERSION >= 2
754 #if GTK_MAJOR_VERSION >= 2
755 /* if nothing is selected */
756 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
759 * Which byte view is displaying the current protocol tree
762 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
763 if (byte_view == NULL)
766 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
767 if (byte_data == NULL)
770 cf_unselect_field(&cfile);
771 packet_hex_print(byte_view, byte_data,
772 cfile.current_frame, NULL, byte_len);
775 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
778 finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
782 set_notebook_page(byte_nb_ptr, finfo->ds_tvb);
784 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
785 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
786 g_assert(byte_data != NULL);
788 cfile.finfo_selected = finfo;
789 set_menus_for_selected_tree_row(&cfile);
792 if (finfo->hfinfo->blurb != NULL &&
793 finfo->hfinfo->blurb[0] != '\0') {
795 length = strlen(finfo->hfinfo->blurb);
797 length = strlen(finfo->hfinfo->name);
799 if (finfo->length == 0) {
801 } else if (finfo->length == 1) {
802 strcpy (len_str, ", 1 byte");
804 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo->length);
806 statusbar_pop_field_msg(); /* get rid of current help msg */
808 help_str = g_strdup_printf("%s (%s)%s",
809 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
810 finfo->hfinfo->abbrev, len_str);
811 statusbar_push_field_msg(help_str);
815 * Don't show anything if the field name is zero-length;
816 * the pseudo-field for "proto_tree_add_text()" is such
817 * a field, and we don't want "Text (text)" showing up
818 * on the status line if you've selected such a field.
820 * XXX - there are zero-length fields for which we *do*
821 * want to show the field name.
823 * XXX - perhaps the name and abbrev field should be null
824 * pointers rather than null strings for that pseudo-field,
825 * but we'd have to add checks for null pointers in some
826 * places if we did that.
828 * Or perhaps protocol tree items added with
829 * "proto_tree_add_text()" should have -1 as the field index,
830 * with no pseudo-field being used, but that might also
831 * require special checks for -1 to be added.
833 statusbar_push_field_msg("");
837 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
841 #if GTK_MAJOR_VERSION < 2
843 tree_view_unselect_row_cb(GtkCTree *ctree _U_, GList *node _U_, gint column _U_,
844 gpointer user_data _U_)
846 GtkWidget *byte_view;
851 * Which byte view is displaying the current protocol tree
854 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
855 if (byte_view == NULL)
858 data = get_byte_view_data_and_length(byte_view, &len);
862 cf_unselect_field(&cfile);
863 packet_hex_print(byte_view, data, cfile.current_frame, NULL, len);
867 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
869 collapse_all_tree(cfile.edt->tree, tree_view);
872 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
874 expand_all_tree(cfile.edt->tree, tree_view);
877 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
878 #if GTK_MAJOR_VERSION < 2
884 #if GTK_MAJOR_VERSION < 2
885 node = gtk_ctree_find_by_row_data(GTK_CTREE(tree_view), NULL, cfile.finfo_selected);
887 /* the mouse position is at an entry, expand that one */
888 gtk_ctree_expand_recursive(GTK_CTREE(tree_view), node);
891 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view), cfile.finfo_selected);
893 /* the mouse position is at an entry, expand that one */
894 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view), path, TRUE);
895 gtk_tree_path_free(path);
900 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
901 if (cfile.edt->tree) {
902 guint32 tmp = g_resolv_flags;
903 g_resolv_flags = RESOLV_ALL;
904 proto_tree_draw(cfile.edt->tree, tree_view);
905 g_resolv_flags = tmp;
910 * Push a message referring to file access onto the statusbar.
913 statusbar_push_file_msg(gchar *msg)
915 /*g_warning("statusbar_push: %s", msg);*/
916 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
920 * Pop a message referring to file access off the statusbar.
923 statusbar_pop_file_msg(void)
925 /*g_warning("statusbar_pop");*/
926 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
930 * XXX - do we need multiple statusbar contexts?
934 * Push a message referring to the currently-selected field onto the statusbar.
937 statusbar_push_field_msg(gchar *msg)
939 gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
943 * Pop a message referring to the currently-selected field off the statusbar.
946 statusbar_pop_field_msg(void)
948 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
952 * update the packets statusbar to the current values
954 void packets_bar_update(void)
958 /* remove old status */
961 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
964 /* do we have any packets? */
966 if(cfile.drops_known) {
967 packets_str = g_strdup_printf(" P: %u D: %u M: %u Drops: %u",
968 cfile.count, cfile.displayed_count, cfile.marked_count, cfile.drops);
970 packets_str = g_strdup_printf(" P: %u D: %u M: %u",
971 cfile.count, cfile.displayed_count, cfile.marked_count);
974 packets_str = g_strdup(" No Packets");
976 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str);
981 main_set_for_capture_file(gboolean have_capture_file_in)
983 have_capture_file = have_capture_file_in;
985 main_widgets_show_or_hide();
991 /* get the current geometry, before writing it to disk */
992 main_save_window_geometry(top_level);
994 /* write user's recent file to disk
995 * It is no problem to write this file, even if we do not quit */
998 /* XXX - should we check whether the capture file is an
999 unsaved temporary file for a live capture and, if so,
1000 pop up a "do you want to exit without saving the capture
1001 file?" dialog, and then just return, leaving said dialog
1002 box to forcibly quit if the user clicks "OK"?
1004 If so, note that this should be done in a subroutine that
1005 returns TRUE if we do so, and FALSE otherwise, and if it
1006 returns TRUE we should return TRUE without nuking anything.
1008 Note that, if we do that, we might also want to check if
1009 an "Update list of packets in real time" capture is in
1010 progress and, if so, ask whether they want to terminate
1011 the capture and discard it, and return TRUE, before nuking
1012 any child capture, if they say they don't want to do so. */
1015 /* Nuke any child capture in progress. */
1016 capture_kill_child(capture_opts);
1019 /* Are we in the middle of reading a capture? */
1020 if (cfile.state == FILE_READ_IN_PROGRESS) {
1021 /* Yes, so we can't just close the file and quit, as
1022 that may yank the rug out from under the read in
1023 progress; instead, just set the state to
1024 "FILE_READ_ABORTED" and return - the code doing the read
1025 will check for that and, if it sees that, will clean
1027 cfile.state = FILE_READ_ABORTED;
1029 /* Say that the window should *not* be deleted;
1030 that'll be done by the code that cleans up. */
1033 /* Close any capture file we have open; on some OSes, you
1034 can't unlink a temporary capture file if you have it
1036 "cf_close()" will unlink it after closing it if
1037 it's a temporary file.
1039 We do this here, rather than after the main loop returns,
1040 as, after the main loop returns, the main window may have
1041 been destroyed (if this is called due to a "destroy"
1042 even on the main window rather than due to the user
1043 selecting a menu item), and there may be a crash
1044 or other problem when "cf_close()" tries to
1045 clean up stuff in the main window.
1047 XXX - is there a better place to put this?
1048 Or should we have a routine that *just* closes the
1049 capture file, and doesn't do anything with the UI,
1050 which we'd call here, and another routine that
1051 calls that routine and also cleans up the UI, which
1052 we'd call elsewhere? */
1055 /* Exit by leaving the main loop, so that any quit functions
1056 we registered get called. */
1059 /* Say that the window should be deleted. */
1065 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1069 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1070 #if GTK_MAJOR_VERSION >= 2
1071 gtk_window_present(GTK_WINDOW(top_level));
1073 /* user didn't saved his current file, ask him */
1074 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1075 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1076 "If you quit the program without saving, your capture data will be discarded.");
1077 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1080 /* unchanged file, just exit */
1081 /* "main_do_quit()" indicates whether the main window should be deleted. */
1082 return main_do_quit();
1089 main_load_window_geometry(GtkWidget *widget)
1091 window_geometry_t geom;
1093 geom.set_pos = prefs.gui_geometry_save_position;
1094 geom.x = recent.gui_geometry_main_x;
1095 geom.y = recent.gui_geometry_main_y;
1096 geom.set_size = prefs.gui_geometry_save_size;
1097 if (recent.gui_geometry_main_width > 0 &&
1098 recent.gui_geometry_main_height > 0) {
1099 geom.width = recent.gui_geometry_main_width;
1100 geom.height = recent.gui_geometry_main_height;
1101 geom.set_maximized = prefs.gui_geometry_save_maximized;
1103 /* We assume this means the width and height weren't set in
1104 the "recent" file (or that there is no "recent" file),
1105 and weren't set to a default value, so we don't set the
1106 size. (The "recent" file code rejects non-positive width
1107 and height values.) */
1108 geom.set_size = FALSE;
1110 geom.maximized = recent.gui_geometry_main_maximized;
1112 window_set_geometry(widget, &geom);
1114 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1115 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1116 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
1117 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1118 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_status_pane)
1119 gtk_paned_set_position(GTK_PANED(status_pane), recent.gui_geometry_status_pane);
1124 main_save_window_geometry(GtkWidget *widget)
1126 window_geometry_t geom;
1128 window_get_geometry(widget, &geom);
1130 if (prefs.gui_geometry_save_position) {
1131 recent.gui_geometry_main_x = geom.x;
1132 recent.gui_geometry_main_y = geom.y;
1135 if (prefs.gui_geometry_save_size) {
1136 recent.gui_geometry_main_width = geom.width,
1137 recent.gui_geometry_main_height = geom.height;
1140 #if GTK_MAJOR_VERSION >= 2
1141 if(prefs.gui_geometry_save_maximized) {
1142 recent.gui_geometry_main_maximized = geom.maximized;
1145 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1146 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1147 recent.gui_geometry_status_pane = gtk_paned_get_position(GTK_PANED(status_pane));
1151 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1155 /* save file first */
1156 file_save_as_cmd(after_save_exit, NULL);
1158 case(ESD_BTN_DONT_SAVE):
1161 case(ESD_BTN_CANCEL):
1164 g_assert_not_reached();
1169 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1173 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1174 /* user didn't saved his current file, ask him */
1175 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1176 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1177 "If you quit the program without saving, your capture data will be discarded.");
1178 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1180 /* unchanged file, just exit */
1186 print_usage(gboolean print_ver) {
1196 fprintf(output, "Wireshark " VERSION "%s\n"
1197 "Interactively dump and analyze network traffic.\n"
1198 "See http://www.wireshark.org for more information.\n"
1201 svnversion, get_copyright_info());
1205 fprintf(output, "\n");
1206 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1207 fprintf(output, "\n");
1210 fprintf(output, "Capture interface:\n");
1211 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1212 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1213 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1214 fprintf(output, " -p don't capture in promiscuous mode\n");
1215 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1216 fprintf(output, " -Q quit Wireshark after capturing\n");
1217 fprintf(output, " -S update packet display when new packets are captured\n");
1218 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1220 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1222 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1223 fprintf(output, " -D print list of interfaces and exit\n");
1224 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1225 fprintf(output, "\n");
1226 fprintf(output, "Capture stop conditions:\n");
1227 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1228 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1229 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1230 fprintf(output, " files:NUM - stop after NUM files\n");
1231 /*fprintf(output, "\n");*/
1232 fprintf(output, "Capture output:\n");
1233 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1234 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1235 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1236 #endif /* HAVE_LIBPCAP */
1238 /*fprintf(output, "\n");*/
1239 fprintf(output, "Input file:\n");
1240 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1242 fprintf(output, "\n");
1243 fprintf(output, "Processing:\n");
1244 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1245 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1246 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1248 fprintf(output, "\n");
1249 fprintf(output, "User interface:\n");
1250 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1251 fprintf(output, " -m <font> set the font name used for most text\n");
1252 fprintf(output, " -t ad|a|r|d|e output format of time stamps (def: r: rel. to first)\n");
1253 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1254 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1256 fprintf(output, "\n");
1257 fprintf(output, "Output:\n");
1258 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1260 fprintf(output, "\n");
1261 fprintf(output, "Miscellaneous:\n");
1262 fprintf(output, " -h display this help and exit\n");
1263 fprintf(output, " -v display version info and exit\n");
1264 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1266 fprintf(output, " --display=DISPLAY X display to use\n");
1281 printf(PACKAGE " " VERSION "%s\n"
1288 svnversion, get_copyright_info(), comp_info_str->str,
1289 runtime_info_str->str);
1297 * Report an error in command-line arguments.
1298 * Creates a console on Windows.
1299 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1300 * terminal isn't the standard error?
1303 cmdarg_err(const char *fmt, ...)
1311 fprintf(stderr, "wireshark: ");
1312 vfprintf(stderr, fmt, ap);
1313 fprintf(stderr, "\n");
1318 * Report additional information for an error in command-line arguments.
1319 * Creates a console on Windows.
1320 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1321 * terminal isn't the standard error?
1324 cmdarg_err_cont(const char *fmt, ...)
1332 vfprintf(stderr, fmt, ap);
1333 fprintf(stderr, "\n");
1337 #if defined(_WIN32) || GTK_MAJOR_VERSION < 2 || ! defined USE_THREADS
1339 Once every 3 seconds we get a callback here which we use to update
1340 the tap extensions. Since Gtk1 is single threaded we dont have to
1341 worry about any locking or critical regions.
1344 update_cb(gpointer data _U_)
1346 draw_tap_listeners(FALSE);
1351 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1352 use threads all updte_thread_mutex can be dropped and protect/unprotect
1353 would just be empty functions.
1355 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1356 gtk1-wireshark and it will just work.
1358 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1360 update_thread(gpointer data _U_)
1364 g_get_current_time(&tv1);
1365 g_static_mutex_lock(&update_thread_mutex);
1366 gdk_threads_enter();
1367 draw_tap_listeners(FALSE);
1368 gdk_threads_leave();
1369 g_static_mutex_unlock(&update_thread_mutex);
1371 g_get_current_time(&tv2);
1372 if( ((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) >
1373 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1374 g_usleep(((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) -
1375 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1382 protect_thread_critical_region(void)
1384 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1385 g_static_mutex_lock(&update_thread_mutex);
1389 unprotect_thread_critical_region(void)
1391 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1392 g_static_mutex_unlock(&update_thread_mutex);
1396 /* Set the file name in the status line, in the name for the main window,
1397 and in the name for the main window's icon. */
1399 set_display_filename(capture_file *cf)
1401 const gchar *name_ptr;
1406 name_ptr = cf_get_display_name(cf);
1408 if (!cf->is_tempfile && cf->filename) {
1409 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1410 add_menu_recent_capture_file(cf->filename);
1413 /* convert file size */
1414 if (cf->f_datalen/1024/1024 > 10) {
1415 size_str = g_strdup_printf("%lld MB", cf->f_datalen/1024/1024);
1416 } else if (cf->f_datalen/1024 > 10) {
1417 size_str = g_strdup_printf("%lld KB", cf->f_datalen/1024);
1419 size_str = g_strdup_printf("%lld Bytes", cf->f_datalen);
1424 /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1425 status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu [Expert: %s]",
1426 (cf->filename) ? cf->filename : "", size_str,
1427 (long)cf->elapsed_time.secs/3600,
1428 (long)cf->elapsed_time.secs%3600/60,
1429 (long)cf->elapsed_time.secs%60,
1430 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1432 status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu",
1433 (cf->filename) ? cf->filename : "", size_str,
1434 (long)cf->elapsed_time.secs/3600,
1435 (long)cf->elapsed_time.secs%3600/60,
1436 (long)cf->elapsed_time.secs%60);
1438 statusbar_push_file_msg(status_msg);
1442 win_name = g_strdup_printf("%s - Wireshark", name_ptr);
1443 set_main_window_name(win_name);
1447 GtkWidget *close_dlg = NULL;
1450 main_cf_cb_file_closing(capture_file *cf)
1453 /* if we have more than 10000 packets, show a splash screen while closing */
1454 /* XXX - don't know a better way to decide wether to show or not,
1455 * as most of the time is spend in a single eth_clist_clear function,
1456 * so we can't use a progress bar here! */
1457 if(cf->count > 10000) {
1458 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1459 "%sClosing file!%s\n\nPlease wait ...",
1460 simple_dialog_primary_start(),
1461 simple_dialog_primary_end());
1462 #if GTK_MAJOR_VERSION >= 2
1463 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1465 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER);
1469 /* Destroy all windows, which refer to the
1470 capture file we're closing. */
1471 destroy_packet_wins();
1472 file_save_as_destroy();
1474 /* Clear any file-related status bar messages.
1475 XXX - should be "clear *ALL* file-related status bar messages;
1476 will there ever be more than one on the stack? */
1477 statusbar_pop_file_msg();
1479 /* Restore the standard title bar message. */
1480 set_main_window_name("The Wireshark Network Analyzer");
1482 /* Disable all menu items that make sense only if you have a capture. */
1483 set_menus_for_capture_file(FALSE);
1484 set_menus_for_unsaved_capture_file(FALSE);
1485 set_menus_for_captured_packets(FALSE);
1486 set_menus_for_selected_packet(cf);
1487 set_menus_for_capture_in_progress(FALSE);
1488 set_menus_for_selected_tree_row(cf);
1490 /* Set up main window for no capture file. */
1491 main_set_for_capture_file(FALSE);
1493 main_window_update();
1497 main_cf_cb_file_closed(capture_file *cf _U_)
1499 if(close_dlg != NULL) {
1500 splash_destroy(close_dlg);
1504 /* go back to "No packets" */
1505 packets_bar_update();
1509 main_cf_cb_file_read_start(capture_file *cf)
1511 const gchar *name_ptr;
1514 name_ptr = get_basename(cf->filename);
1516 load_msg = g_strdup_printf(" Loading: %s", name_ptr);
1517 statusbar_push_file_msg(load_msg);
1520 /* Set up main window for a capture file. */
1521 main_set_for_capture_file(TRUE);
1525 main_cf_cb_file_read_finished(capture_file *cf)
1527 statusbar_pop_file_msg();
1528 set_display_filename(cf);
1530 /* Enable menu items that make sense if you have a capture file you've
1531 finished reading. */
1532 set_menus_for_capture_file(TRUE);
1533 set_menus_for_unsaved_capture_file(!cf->user_saved);
1535 /* Enable menu items that make sense if you have some captured packets. */
1536 set_menus_for_captured_packets(TRUE);
1539 #if GTK_MAJOR_VERSION >= 2
1540 GList *icon_list_create(
1541 const char **icon16_xpm,
1542 const char **icon32_xpm,
1543 const char **icon48_xpm,
1544 const char **icon64_xpm)
1546 GList *icon_list = NULL;
1547 GdkPixbuf * pixbuf16;
1548 GdkPixbuf * pixbuf32;
1549 GdkPixbuf * pixbuf48;
1550 GdkPixbuf * pixbuf64;
1553 if(icon16_xpm != NULL) {
1554 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1556 icon_list = g_list_append(icon_list, pixbuf16);
1559 if(icon32_xpm != NULL) {
1560 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1562 icon_list = g_list_append(icon_list, pixbuf32);
1565 if(icon48_xpm != NULL) {
1566 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1568 icon_list = g_list_append(icon_list, pixbuf48);
1571 if(icon64_xpm != NULL) {
1572 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1574 icon_list = g_list_append(icon_list, pixbuf64);
1583 main_cf_cb_live_capture_prepared(capture_options *capture_opts)
1586 #if GTK_MAJOR_VERSION >= 2
1587 static GList *icon_list = NULL;
1591 if(capture_opts->iface) {
1592 title = g_strdup_printf("%s: Capturing - Wireshark",
1593 get_interface_descriptive_name(capture_opts->iface));
1595 title = g_strdup_printf("Capturing - Wireshark");
1597 set_main_window_name(title);
1600 #if GTK_MAJOR_VERSION >= 2
1601 if(icon_list == NULL) {
1602 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1604 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1607 /* Disable menu items that make no sense if you're currently running
1609 set_menus_for_capture_in_progress(TRUE);
1611 /* update statusbar */
1612 statusbar_push_file_msg("Waiting for capture input data ...");
1614 /* Don't set up main window for a capture file. */
1615 main_set_for_capture_file(FALSE);
1619 main_cf_cb_live_capture_update_started(capture_options *capture_opts)
1624 /* We've done this in "prepared" above, but it will be cleared while
1625 switching to the next multiple file. */
1626 if(capture_opts->iface) {
1627 title = g_strdup_printf("%s: Capturing - Wireshark",
1628 get_interface_descriptive_name(capture_opts->iface));
1630 title = g_strdup_printf("Capturing - Wireshark");
1632 set_main_window_name(title);
1635 set_menus_for_capture_in_progress(TRUE);
1637 /* Enable menu items that make sense if you have some captured
1638 packets (yes, I know, we don't have any *yet*). */
1639 set_menus_for_captured_packets(TRUE);
1641 statusbar_pop_file_msg();
1643 if(capture_opts->iface) {
1644 capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1645 get_interface_descriptive_name(capture_opts->iface),
1646 (capture_opts->save_file) ? capture_opts->save_file : "");
1648 capture_msg = g_strdup_printf(" <live capture in progress> to file: %s",
1649 (capture_opts->save_file) ? capture_opts->save_file : "");
1652 statusbar_push_file_msg(capture_msg);
1654 g_free(capture_msg);
1656 /* Set up main window for a capture file. */
1657 main_set_for_capture_file(TRUE);
1661 main_cf_cb_live_capture_update_continue(capture_file *cf)
1666 statusbar_pop_file_msg();
1669 /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1670 if (cf->f_datalen/1024/1024 > 10) {
1671 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB [Expert: %s]",
1672 get_interface_descriptive_name(capture_opts->iface),
1673 capture_opts->save_file,
1674 cf->f_datalen/1024/1024,
1675 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1676 } else if (cf->f_datalen/1024 > 10) {
1677 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB [Expert: %s]",
1678 get_interface_descriptive_name(capture_opts->iface),
1679 capture_opts->save_file,
1681 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1683 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes [Expert: %s]",
1684 get_interface_descriptive_name(capture_opts->iface),
1685 capture_opts->save_file,
1687 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1690 if (cf->f_datalen/1024/1024 > 10) {
1691 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB",
1692 get_interface_descriptive_name(capture_opts->iface),
1693 capture_opts->save_file,
1694 cf->f_datalen/1024/1024);
1695 } else if (cf->f_datalen/1024 > 10) {
1696 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB",
1697 get_interface_descriptive_name(capture_opts->iface),
1698 capture_opts->save_file,
1699 cf->f_datalen/1024);
1701 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes",
1702 get_interface_descriptive_name(capture_opts->iface),
1703 capture_opts->save_file,
1707 statusbar_push_file_msg(capture_msg);
1710 GtkWidget * stop_dlg = NULL;
1713 main_cf_cb_live_capture_update_finished(capture_file *cf)
1715 #if GTK_MAJOR_VERSION >= 2
1716 static GList *icon_list = NULL;
1719 if(stop_dlg != NULL) {
1720 simple_dialog_close(stop_dlg);
1724 /* Pop the "<live capture in progress>" message off the status bar. */
1725 statusbar_pop_file_msg();
1727 set_display_filename(cf);
1729 /* Enable menu items that make sense if you're not currently running
1731 set_menus_for_capture_in_progress(FALSE);
1733 /* Enable menu items that make sense if you have a capture file
1734 you've finished reading. */
1735 set_menus_for_capture_file(TRUE);
1736 set_menus_for_unsaved_capture_file(!cf->user_saved);
1738 /* Set up main window for a capture file. */
1739 main_set_for_capture_file(TRUE);
1741 #if GTK_MAJOR_VERSION >= 2
1742 if(icon_list == NULL) {
1743 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1745 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1748 if(capture_opts->quit_after_cap) {
1749 /* command line asked us to quit after the capture */
1750 /* don't pop up a dialog to ask for unsaved files etc. */
1756 main_cf_cb_live_capture_fixed_started(capture_options *capture_opts)
1761 /* Enable menu items that make sense if you have some captured
1762 packets (yes, I know, we don't have any *yet*). */
1763 /*set_menus_for_captured_packets(TRUE);*/
1765 statusbar_pop_file_msg();
1767 capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1768 get_interface_descriptive_name(capture_opts->iface),
1769 (capture_opts->save_file) ? capture_opts->save_file : "");
1771 statusbar_push_file_msg(capture_msg);
1772 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " P: 0");
1774 g_free(capture_msg);
1776 /* Don't set up main window for a capture file. */
1777 main_set_for_capture_file(FALSE);
1781 main_cf_cb_live_capture_fixed_continue(capture_file *cf)
1786 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1788 capture_msg = g_strdup_printf(" P: %u",
1789 cf_get_packet_count(cf));
1791 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, capture_msg);
1793 g_free(capture_msg);
1797 main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_)
1799 #if GTK_MAJOR_VERSION >= 2
1800 static GList *icon_list = NULL;
1803 if(stop_dlg != NULL) {
1804 simple_dialog_close(stop_dlg);
1808 /* Pop the "<live capture in progress>" message off the status bar. */
1809 statusbar_pop_file_msg();
1811 /* Pop the "<capturing>" message off the status bar */
1812 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1814 /*set_display_filename(cf);*/
1816 /* Enable menu items that make sense if you're not currently running
1818 set_menus_for_capture_in_progress(FALSE);
1820 /* Restore the standard title bar message */
1821 /* (just in case we have trouble opening the capture file). */
1822 set_main_window_name("The Wireshark Network Analyzer");
1824 #if GTK_MAJOR_VERSION >= 2
1825 if(icon_list == NULL) {
1826 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1828 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1831 /* We don't have loaded the capture file, this will be done later.
1832 * For now we still have simply a blank screen. */
1834 if(capture_opts->quit_after_cap) {
1835 /* command line asked us to quit after the capture */
1836 /* don't pop up a dialog to ask for unsaved files etc. */
1842 main_cf_cb_live_capture_stopping(capture_file *cf _U_)
1844 /* Beware: this state won't be called, if the capture child
1845 * closes the capturing on it's own! */
1847 /* XXX - the time to stop the capture has been reduced (this was only a
1848 * problem on Win32 because of the capture piping), so showing a splash
1849 * isn't really necessary any longer. Unfortunately, the GTKClist packet
1850 * list seems to have problems updating after the dialog is closed, so
1851 * this was disabled here. */
1852 stop_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE, "%sCapture stop!%s\n\nPlease wait ...",
1853 simple_dialog_primary_start(), simple_dialog_primary_end());
1854 #if GTK_MAJOR_VERSION >= 2
1855 gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1857 gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER);
1865 main_cf_cb_packet_selected(gpointer data)
1867 capture_file *cf = data;
1869 /* Display the GUI protocol tree and hex dump.
1870 XXX - why do we dump core if we call "proto_tree_draw()"
1871 before calling "add_byte_views()"? */
1872 add_main_byte_views(cf->edt);
1873 main_proto_tree_draw(cf->edt->tree);
1875 /* The user is searching for a string in the data or a hex value,
1876 * highlight the field that is found in the tree and hex displays. */
1877 #if GTK_MAJOR_VERSION < 2
1878 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1879 highlight_field(cf->edt->tvb, cfile.search_pos,
1880 (GtkCTree *)tree_view, cf->edt->tree);
1882 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1883 highlight_field(cf->edt->tvb, cfile.search_pos,
1884 (GtkTreeView *)tree_view, cf->edt->tree);
1886 cfile.search_pos = 0; /* Reset the position */
1889 /* A packet is selected. */
1890 set_menus_for_selected_packet(cf);
1894 main_cf_cb_packet_unselected(capture_file *cf)
1896 /* Clear out the display of that packet. */
1897 clear_tree_and_hex_views();
1899 /* No packet is selected. */
1900 set_menus_for_selected_packet(cf);
1904 main_cf_cb_field_unselected(capture_file *cf)
1906 statusbar_pop_field_msg();
1907 set_menus_for_selected_tree_row(cf);
1911 main_cf_cb_file_safe_started(gchar * filename)
1913 const gchar *name_ptr;
1916 name_ptr = get_basename(filename);
1918 save_msg = g_strdup_printf(" Saving: %s...", name_ptr);
1920 statusbar_push_file_msg(save_msg);
1925 main_cf_cb_file_safe_finished(gpointer data _U_)
1927 /* Pop the "Saving:" message off the status bar. */
1928 statusbar_pop_file_msg();
1932 main_cf_cb_file_safe_failed(gpointer data _U_)
1934 /* Pop the "Saving:" message off the status bar. */
1935 statusbar_pop_file_msg();
1939 main_cf_cb_file_safe_reload_finished(gpointer data _U_)
1941 set_menus_for_unsaved_capture_file(FALSE);
1944 static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1947 case(cf_cb_file_closing):
1948 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1949 main_cf_cb_file_closing(data);
1951 case(cf_cb_file_closed):
1952 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1953 main_cf_cb_file_closed(data);
1955 case(cf_cb_file_read_start):
1956 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read start");
1957 main_cf_cb_file_read_start(data);
1959 case(cf_cb_file_read_finished):
1960 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1961 main_cf_cb_file_read_finished(data);
1964 case(cf_cb_live_capture_prepared):
1965 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1966 main_cf_cb_live_capture_prepared(data);
1968 case(cf_cb_live_capture_update_started):
1969 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1970 main_cf_cb_live_capture_update_started(data);
1972 case(cf_cb_live_capture_update_continue):
1973 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1974 main_cf_cb_live_capture_update_continue(data);
1976 case(cf_cb_live_capture_update_finished):
1977 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1978 main_cf_cb_live_capture_update_finished(data);
1980 case(cf_cb_live_capture_fixed_started):
1981 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1982 main_cf_cb_live_capture_fixed_started(data);
1984 case(cf_cb_live_capture_fixed_continue):
1985 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");
1986 main_cf_cb_live_capture_fixed_continue(data);
1988 case(cf_cb_live_capture_fixed_finished):
1989 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1990 main_cf_cb_live_capture_fixed_finished(data);
1992 case(cf_cb_live_capture_stopping):
1993 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1994 main_cf_cb_live_capture_stopping(data);
1997 case(cf_cb_packet_selected):
1998 main_cf_cb_packet_selected(data);
2000 case(cf_cb_packet_unselected):
2001 main_cf_cb_packet_unselected(data);
2003 case(cf_cb_field_unselected):
2004 main_cf_cb_field_unselected(data);
2006 case(cf_cb_file_safe_started):
2007 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe started");
2008 main_cf_cb_file_safe_started(data);
2010 case(cf_cb_file_safe_finished):
2011 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe finished");
2012 main_cf_cb_file_safe_finished(data);
2014 case(cf_cb_file_safe_reload_finished):
2015 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: reload finished");
2016 main_cf_cb_file_safe_reload_finished(data);
2018 case(cf_cb_file_safe_failed):
2019 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe failed");
2020 main_cf_cb_file_safe_failed(data);
2023 g_warning("main_cf_callback: event %u unknown", event);
2024 g_assert_not_reached();
2029 get_gui_compiled_info(GString *str)
2031 get_epan_compiled_version_info(str);
2033 g_string_append(str, ", ");
2034 #ifdef HAVE_LIBPORTAUDIO
2035 #ifdef PORTAUDIO_API_1
2036 g_string_append(str, "with PortAudio <= V18");
2037 #else /* PORTAUDIO_API_1 */
2038 g_string_append(str, "with PortAudio ");
2039 g_string_append(str, Pa_GetVersionText());
2040 #endif /* PORTAUDIO_API_1 */
2041 #else /* HAVE_LIBPORTAUDIO */
2042 g_string_append(str, "without PortAudio");
2043 #endif /* HAVE_LIBPORTAUDIO */
2045 g_string_append(str, ", ");
2047 get_compiled_airpcap_version(str);
2049 g_string_append(str, "without AirPcap");
2054 get_gui_runtime_info(GString *str
2055 #ifndef HAVE_AIRPCAP
2061 g_string_append(str, ", ");
2062 get_runtime_airpcap_version(str);
2066 /* And now our feature presentation... [ fade to music ] */
2068 main(int argc, char *argv[])
2070 char *init_progfile_dir_error;
2074 extern char *optarg;
2075 gboolean arg_error = FALSE;
2083 char *gpf_path, *pf_path;
2084 char *cf_path, *df_path;
2085 char *gdp_path, *dp_path;
2086 int gpf_open_errno, gpf_read_errno;
2087 int pf_open_errno, pf_read_errno;
2088 int cf_open_errno, df_open_errno;
2089 int gdp_open_errno, gdp_read_errno;
2090 int dp_open_errno, dp_read_errno;
2093 gboolean start_capture = FALSE;
2095 gboolean capture_option_specified = FALSE;
2097 gint pl_size = 280, tv_size = 95, bv_size = 75;
2098 gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
2099 dfilter_t *rfcode = NULL;
2100 gboolean rfilter_parse_failed = FALSE;
2103 GtkWidget *splash_win = NULL;
2104 GLogLevelFlags log_flags;
2105 guint go_to_packet = 0;
2110 char err_str[AIRPCAP_ERRBUF_SIZE];
2111 gchar *cant_get_if_list_errstr;
2114 #define OPTSTRING_INIT "a:b:c:Df:g:Hhi:klLm:nN:o:pQr:R:Ss:t:vw:X:y:z:"
2116 #if defined HAVE_LIBPCAP && defined _WIN32
2117 #define OPTSTRING_WIN32 "B:"
2119 #define OPTSTRING_WIN32 ""
2122 char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
2123 OPTSTRING_INIT OPTSTRING_WIN32;
2125 #ifdef HAVE_AIRPDCAP
2126 /* Davide Schiera (2006-11-18): init AirPDcap context */
2127 AirPDcapInitContext(&airpdcap_ctx);
2128 /* Davide Schiera (2006-11-18) ------------------------------------------- */
2132 * Attempt to get the pathname of the executable file.
2134 init_progfile_dir_error = init_progfile_dir(argv[0]);
2137 * Get credential information for later use.
2139 get_credential_info();
2141 /* initialize the funnel mini-api */
2142 initialize_funnel_ops();
2145 /* Load wpcap if possible. Do this before collecting the run-time version information */
2148 /* ... and also load the packet.dll from wpcap */
2149 wpcap_packet_load();
2152 /* Load the airpcap.dll. This must also be done before collecting
2153 * run-time version information. */
2154 airpcap_dll_ret_val = load_airpcap();
2156 switch (airpcap_dll_ret_val) {
2157 case AIRPCAP_DLL_OK:
2158 /* load the airpcap interfaces */
2159 airpcap_if_list = get_airpcap_interface_list(&err, err_str);
2161 if (airpcap_if_list == NULL && err == CANT_GET_AIRPCAP_INTERFACE_LIST) {
2162 cant_get_if_list_errstr = cant_get_airpcap_if_list_error_message(err_str);
2163 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", cant_get_if_list_errstr);
2164 g_free(cant_get_if_list_errstr);
2166 /* select the first ad default (THIS SHOULD BE CHANGED) */
2167 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2172 * XXX - Maybe we need to warn the user if one of the following happens???
2174 case AIRPCAP_DLL_OLD:
2175 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2178 case AIRPCAP_DLL_ERROR:
2179 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2182 case AIRPCAP_DLL_NOT_FOUND:
2183 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2187 #endif /* HAVE_AIRPCAP */
2189 /* Start windows sockets */
2190 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2193 /* Assemble the compile-time version information string */
2194 comp_info_str = g_string_new("Compiled ");
2196 g_string_append(comp_info_str, "with ");
2197 g_string_sprintfa(comp_info_str,
2198 #ifdef GTK_MAJOR_VERSION
2199 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
2202 "GTK+ (version unknown)");
2204 g_string_append(comp_info_str, ", ");
2206 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
2208 /* Assemble the run-time version information string */
2209 runtime_info_str = g_string_new("Running ");
2210 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2213 /* "pre-scan" the command line parameters, if we have "console only"
2214 parameters. We do this so we don't start GTK+ if we're only showing
2215 command-line help or version information.
2217 XXX - this pre-scan is doen before we start GTK+, so we haven't
2218 run gtk_init() on the arguments. That means that GTK+ arguments
2219 have not been removed from the argument list; those arguments
2220 begin with "--", and will be treated as an error by getopt().
2222 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2225 optind_initial = optind;
2226 while ((opt = getopt(argc, argv, optstring)) != -1) {
2228 case 'h': /* Print help and exit */
2232 case 'v': /* Show version and exit */
2238 * Extension command line options have to be processed before
2239 * we call epan_init() as they are supposed to be used by dissectors
2240 * or taps very early in the registration process.
2244 case '?': /* Ignore errors - the "real" scan will catch them. */
2249 /* Set getopt index back to initial value, so it will start with the
2250 first command line parameter again. Also reset opterr to 1, so that
2251 error messages are printed by getopt().
2253 XXX - this seems to work on most platforms, but time will tell.
2254 The Single UNIX Specification says "The getopt() function need
2255 not be reentrant", so this isn't guaranteed to work. The Mac
2256 OS X 10.4[.x] getopt() man page says
2258 In order to use getopt() to evaluate multiple sets of arguments, or to
2259 evaluate a single set of arguments multiple times, the variable optreset
2260 must be set to 1 before the second and each additional set of calls to
2261 getopt(), and the variable optind must be reinitialized.
2265 The optreset variable was added to make it possible to call the getopt()
2266 function multiple times. This is an extension to the IEEE Std 1003.2
2267 (``POSIX.2'') specification.
2269 which I think comes from one of the other BSDs.
2271 XXX - if we want to control all the command-line option errors, so
2272 that we can display them where we choose (e.g., in a window), we'd
2273 want to leave opterr as 0, and produce our own messages using optopt.
2274 We'd have to check the value of optopt to see if it's a valid option
2275 letter, in which case *presumably* the error is "this option requires
2276 an argument but none was specified", or not a valid option letter,
2277 in which case *presumably* the error is "this option isn't valid".
2278 Some versions of getopt() let you supply a option string beginning
2279 with ':', which means that getopt() will return ':' rather than '?'
2280 for "this option requires an argument but none was specified", but
2282 optind = optind_initial;
2285 /* Set the current locale according to the program environment.
2286 * We haven't localized anything, but some GTK widgets are localized
2287 * (the file selection dialogue, for example).
2288 * This also sets the C-language locale to the native environment. */
2291 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2292 gtk_init (&argc, &argv);
2294 cf_callback_add(main_cf_callback, NULL);
2296 #if GTK_MAJOR_VERSION < 2 && GTK_MINOR_VERSION < 3
2297 /* initialize our GTK eth_clist_type */
2298 init_eth_clist_type();
2301 /* Arrange that if we have no console window, and a GLib message logging
2302 routine is called to log a message, we pop up a console window.
2304 We do that by inserting our own handler for all messages logged
2305 to the default domain; that handler pops up a console if necessary,
2306 and then calls the default handler. */
2308 /* We might want to have component specific log levels later ... */
2312 G_LOG_LEVEL_CRITICAL|
2313 G_LOG_LEVEL_WARNING|
2314 G_LOG_LEVEL_MESSAGE|
2317 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2319 g_log_set_handler(NULL,
2321 console_log_handler, NULL /* user_data */);
2322 g_log_set_handler(LOG_DOMAIN_MAIN,
2324 console_log_handler, NULL /* user_data */);
2327 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2329 console_log_handler, NULL /* user_data */);
2330 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2332 console_log_handler, NULL /* user_data */);
2334 /* Set the initial values in the capture_opts. This might be overwritten
2335 by preference settings and then again by the command line parameters. */
2336 capture_opts_init(capture_opts, &cfile);
2338 capture_opts->snaplen = MIN_PACKET_SIZE;
2339 capture_opts->has_ring_num_files = TRUE;
2342 /* We won't come till here, if we had a "console only" command line parameter. */
2343 splash_win = splash_new("Loading Wireshark ...");
2344 if (init_progfile_dir_error != NULL) {
2345 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2346 "Can't get pathname of Wireshark: %s.\n"
2347 "It won't be possible to capture traffic.\n"
2348 "Report this to the Wireshark developers.",
2349 init_progfile_dir_error);
2350 g_free(init_progfile_dir_error);
2353 splash_update(splash_win, "Init dissectors ...");
2355 /* Register all dissectors; we must do this before checking for the
2356 "-G" flag, as the "-G" flag dumps information registered by the
2357 dissectors, and we must do it before we read the preferences, in
2358 case any dissectors register preferences. */
2359 epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs,
2360 failure_alert_box,open_failure_alert_box,read_failure_alert_box);
2362 splash_update(splash_win, "Init tap listeners ...");
2364 /* Register all tap listeners; we do this before we parse the arguments,
2365 as the "-z" argument can specify a registered tap. */
2367 /* we register the plugin taps before the other taps because
2368 stats_tree taps plugins will be registered as tap listeners
2369 by stats_tree_stat.c and need to registered before that */
2372 register_all_plugin_tap_listeners();
2375 register_all_tap_listeners();
2377 splash_update(splash_win, "Loading module preferences ...");
2379 /* Now register the preferences for any non-dissector modules.
2380 We must do that before we read the preferences as well. */
2381 prefs_register_modules();
2383 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2384 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined(G_THREADS_ENABLED) && defined USE_THREADS
2387 g_thread_init(NULL);
2389 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2390 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2392 #else /* _WIN32 || GTK1.2 || !G_THREADS_ENABLED || !USE_THREADS */
2393 /* this is to keep tap extensions updating once every 3 seconds */
2394 gtk_timeout_add(3000, (GtkFunction)update_cb,(gpointer)NULL);
2395 #endif /* !_WIN32 && GTK2 && G_THREADS_ENABLED */
2398 gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
2401 splash_update(splash_win, "Loading configuration files ...");
2403 /* Read the preference files. */
2404 prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2405 &pf_open_errno, &pf_read_errno, &pf_path);
2407 if (gpf_path != NULL) {
2408 if (gpf_open_errno != 0) {
2409 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2410 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2411 strerror(gpf_open_errno));
2413 if (gpf_read_errno != 0) {
2414 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2415 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2416 strerror(gpf_read_errno));
2419 if (pf_path != NULL) {
2420 if (pf_open_errno != 0) {
2421 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2422 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2423 strerror(pf_open_errno));
2425 if (pf_read_errno != 0) {
2426 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2427 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2428 strerror(pf_read_errno));
2435 /* if the user wants a console to be always there, well, we should open one for him */
2436 if (prefs->gui_console_open == console_open_always) {
2441 /* Fill in capture options with values from the preferences */
2442 prefs_to_capture_opts();
2444 /* Read the capture filter file. */
2445 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2446 if (cf_path != NULL) {
2447 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2448 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2449 strerror(cf_open_errno));
2453 /* Read the display filter file. */
2454 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2455 if (df_path != NULL) {
2456 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2457 "Could not open your display filter file\n\"%s\": %s.", df_path,
2458 strerror(df_open_errno));
2462 /* Read the disabled protocols file. */
2463 read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
2464 &dp_path, &dp_open_errno, &dp_read_errno);
2465 if (gdp_path != NULL) {
2466 if (gdp_open_errno != 0) {
2467 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2468 "Could not open global disabled protocols file\n\"%s\": %s.",
2469 gdp_path, strerror(gdp_open_errno));
2471 if (gdp_read_errno != 0) {
2472 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2473 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2474 gdp_path, strerror(gdp_read_errno));
2478 if (dp_path != NULL) {
2479 if (dp_open_errno != 0) {
2480 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2481 "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
2482 strerror(dp_open_errno));
2484 if (dp_read_errno != 0) {
2485 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2486 "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
2487 strerror(dp_read_errno));
2492 /* Read the (static part) of the recent file. Only the static part of it will be read, */
2493 /* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
2494 /* We have to do this already here, so command line parameters can overwrite these values. */
2495 recent_read_static(&rf_path, &rf_open_errno);
2497 init_cap_file(&cfile);
2499 /* Now get our args */
2500 while ((opt = getopt(argc, argv, optstring)) != -1) {
2502 /*** capture option specific ***/
2503 case 'a': /* autostop criteria */
2504 case 'b': /* Ringbuffer option */
2505 case 'c': /* Capture xxx packets */
2506 case 'f': /* capture filter */
2507 case 'k': /* Start capture immediately */
2508 case 'H': /* Hide capture info dialog box */
2509 case 'i': /* Use interface xxx */
2510 case 'p': /* Don't capture in promiscuous mode */
2511 case 'Q': /* Quit after capture (just capture to file) */
2512 case 's': /* Set the snapshot (capture) length */
2513 case 'S': /* "Sync" mode: used for following file ala tail -f */
2514 case 'w': /* Write to capture file xxx */
2515 case 'y': /* Set the pcap data link type */
2517 case 'B': /* Buffer size */
2520 status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
2525 capture_option_specified = TRUE;
2530 /*** all non capture option specific ***/
2531 case 'D': /* Print a list of capture devices and exit */
2533 capture_opts_list_interfaces();
2536 capture_option_specified = TRUE;
2540 case 'g': /* Go to packet */
2541 go_to_packet = get_positive_int(optarg, "go to packet");
2543 case 'l': /* Automatic scrolling in live capture mode */
2545 auto_scroll_live = TRUE;
2547 capture_option_specified = TRUE;
2551 case 'L': /* Print list of link-layer types and exit */
2553 list_link_layer_types = TRUE;
2555 capture_option_specified = TRUE;
2559 case 'm': /* Fixed-width font for the display */
2560 if (prefs->PREFS_GUI_FONT_NAME != NULL)
2561 g_free(prefs->PREFS_GUI_FONT_NAME);
2562 prefs->PREFS_GUI_FONT_NAME = g_strdup(optarg);
2564 case 'n': /* No name resolution */
2565 g_resolv_flags = RESOLV_NONE;
2567 case 'N': /* Select what types of addresses/port #s to resolve */
2568 if (g_resolv_flags == RESOLV_ALL)
2569 g_resolv_flags = RESOLV_NONE;
2570 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2571 if (badopt != '\0') {
2572 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2577 case 'o': /* Override preference from command line */
2578 switch (prefs_set_pref(optarg)) {
2581 case PREFS_SET_SYNTAX_ERR:
2582 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2585 case PREFS_SET_NO_SUCH_PREF:
2586 /* not a preference, might be a recent setting */
2587 switch (recent_set_arg(optarg)) {
2590 case PREFS_SET_SYNTAX_ERR:
2591 /* shouldn't happen, checked already above */
2592 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2595 case PREFS_SET_NO_SUCH_PREF:
2596 case PREFS_SET_OBSOLETE:
2597 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2602 g_assert_not_reached();
2605 case PREFS_SET_OBSOLETE:
2606 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2611 g_assert_not_reached();
2614 case 'r': /* Read capture file xxx */
2615 /* We may set "last_open_dir" to "cf_name", and if we change
2616 "last_open_dir" later, we free the old value, so we have to
2617 set "cf_name" to something that's been allocated. */
2618 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2619 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2620 cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2622 cf_name = g_strdup(optarg);
2625 case 'R': /* Read file filter */
2628 case 't': /* Time stamp type */
2629 if (strcmp(optarg, "r") == 0)
2630 timestamp_set_type(TS_RELATIVE);
2631 else if (strcmp(optarg, "a") == 0)
2632 timestamp_set_type(TS_ABSOLUTE);
2633 else if (strcmp(optarg, "ad") == 0)
2634 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2635 else if (strcmp(optarg, "d") == 0)
2636 timestamp_set_type(TS_DELTA);
2637 else if (strcmp(optarg, "e") == 0)
2638 timestamp_set_type(TS_EPOCH);
2640 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2641 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2642 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2647 /* ext ops were already processed just ignore them this time*/
2650 /* We won't call the init function for the stat this soon
2651 as it would disallow MATE's fields (which are registered
2652 by the preferences set callback) from being used as
2653 part of a tap filter. Instead, we just add the argument
2654 to a list of stat arguments. */
2655 if (!process_stat_cmd_arg(optarg)) {
2656 cmdarg_err("Invalid -z argument.");
2657 cmdarg_err_cont(" -z argument must be one of :");
2658 list_stat_cmd_args();
2663 case '?': /* Bad flag - print usage message */
2671 if (cf_name != NULL) {
2673 * Input file name specified with "-r" *and* specified as a regular
2674 * command-line argument.
2676 cmdarg_err("File name specified both with -r and regular argument");
2680 * Input file name not specified with "-r", and a command-line argument
2681 * was specified; treat it as the input file name.
2683 * Yes, this is different from tshark, where non-flag command-line
2684 * arguments are a filter, but this works better on GUI desktops
2685 * where a command can be specified to be run to open a particular
2686 * file - yes, you could have "-r" as the last part of the command,
2687 * but that's a bit ugly.
2689 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2690 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2691 cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2693 cf_name = g_strdup(argv[0]);
2704 * Extra command line arguments were specified; complain.
2706 cmdarg_err("Invalid argument: %s", argv[0]);
2711 #ifndef HAVE_LIBPCAP
2712 if (capture_option_specified) {
2713 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2721 if (start_capture && list_link_layer_types) {
2722 /* Specifying *both* is bogus. */
2723 cmdarg_err("You can't specify both -L and a live capture.");
2727 if (list_link_layer_types) {
2728 /* We're supposed to list the link-layer types for an interface;
2729 did the user also specify a capture file to be read? */
2731 /* Yes - that's bogus. */
2732 cmdarg_err("You can't specify -L and a capture file to be read.");
2735 /* No - did they specify a ring buffer option? */
2736 if (capture_opts->multi_files_on) {
2737 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2741 /* We're supposed to do a live capture; did the user also specify
2742 a capture file to be read? */
2743 if (start_capture && cf_name) {
2744 /* Yes - that's bogus. */
2745 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2749 /* No - was the ring buffer option specified and, if so, does it make
2751 if (capture_opts->multi_files_on) {
2752 /* Ring buffer works only under certain conditions:
2753 a) ring buffer does not work with temporary files;
2754 b) real_time_mode and multi_files_on are mutually exclusive -
2755 real_time_mode takes precedence;
2756 c) it makes no sense to enable the ring buffer if the maximum
2757 file size is set to "infinite". */
2758 if (capture_opts->save_file == NULL) {
2759 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2760 capture_opts->multi_files_on = FALSE;
2762 /* if (capture_opts->real_time_mode) {
2763 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2764 capture_opts->multi_files_on = FALSE;
2766 if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
2767 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2768 /* XXX - this must be redesigned as the conditions changed */
2769 /* capture_opts->multi_files_on = FALSE;*/
2774 if (start_capture || list_link_layer_types) {
2775 /* Did the user specify an interface to use? */
2776 if (!capture_opts_trim_iface(capture_opts,
2777 (prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
2782 if (list_link_layer_types) {
2783 status = capture_opts_list_link_layer_types(capture_opts);
2787 capture_opts_trim_snaplen(capture_opts, MIN_PACKET_SIZE);
2788 capture_opts_trim_ring_num_files(capture_opts);
2789 #endif /* HAVE_LIBPCAP */
2791 /* Notify all registered modules that have had any of their preferences
2792 changed either from one of the preferences file or from the command
2793 line that their preferences have changed. */
2796 /* disabled protocols as per configuration file */
2797 if (gdp_path == NULL && dp_path == NULL) {
2798 set_disabled_protos_list();
2801 /* Build the column format array */
2802 col_setup(&cfile.cinfo, prefs->num_cols);
2803 for (i = 0; i < cfile.cinfo.num_cols; i++) {
2804 cfile.cinfo.col_fmt[i] = get_column_format(i);
2805 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
2806 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
2808 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
2809 cfile.cinfo.col_data[i] = NULL;
2810 if (cfile.cinfo.col_fmt[i] == COL_INFO)
2811 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
2813 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2814 cfile.cinfo.col_fence[i] = 0;
2815 cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2816 cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2819 for (i = 0; i < cfile.cinfo.num_cols; i++) {
2822 for (j = 0; j < NUM_COL_FMTS; j++) {
2823 if (!cfile.cinfo.fmt_matx[i][j])
2826 if (cfile.cinfo.col_first[j] == -1)
2827 cfile.cinfo.col_first[j] = i;
2828 cfile.cinfo.col_last[j] = i;
2832 /* read in rc file from global and personal configuration paths. */
2833 rc_file = get_datafile_path(RC_FILE);
2834 gtk_rc_parse(rc_file);
2835 rc_file = get_persconffile_path(RC_FILE, FALSE);
2836 gtk_rc_parse(rc_file);
2840 /* close the splash screen, as we are going to open the main window now */
2841 splash_destroy(splash_win);
2843 /************************************************************************/
2844 /* Everything is prepared now, preferences and command line was read in */
2846 /* Pop up the main window. */
2847 create_main_window(pl_size, tv_size, bv_size, prefs);
2849 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2850 recent_read_dynamic(&rf_path, &rf_open_errno);
2851 color_filters_enable(recent.packet_list_colorize);
2853 /* rearrange all the widgets as we now have all recent settings ready for this */
2854 main_widgets_rearrange();
2856 /* Fill in column titles. This must be done after the top level window
2859 XXX - is that still true, with fixed-width columns? */
2860 packet_list_set_column_titles();
2862 menu_recent_read_finished();
2864 switch (user_font_apply()) {
2867 case FA_FONT_NOT_RESIZEABLE:
2868 /* "user_font_apply()" popped up an alert box. */
2869 /* turn off zooming - font can't be resized */
2870 case FA_FONT_NOT_AVAILABLE:
2871 /* XXX - did we successfully load the un-zoomed version earlier?
2872 If so, this *probably* means the font is available, but not at
2873 this particular zoom level, but perhaps some other failure
2874 occurred; I'm not sure you can determine which is the case,
2876 /* turn off zooming - zoom level is unavailable */
2878 /* in any other case than FA_SUCCESS, turn off zooming */
2879 recent.gui_zoom_level = 0;
2880 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2883 dnd_init(top_level);
2886 color_filters_init();
2889 /* the window can be sized only, if it's not already shown, so do it now! */
2890 main_load_window_geometry(top_level);
2892 /* If we were given the name of a capture file, read it in now;
2893 we defer it until now, so that, if we can't open it, and pop
2894 up an alert box, the alert box is more likely to come up on
2895 top of the main window - but before the preference-file-error
2896 alert box, so, if we get one of those, it's more likely to come
2899 show_main_window(TRUE);
2900 if (rfilter != NULL) {
2901 if (!dfilter_compile(rfilter, &rfcode)) {
2902 bad_dfilter_alert_box(rfilter);
2903 rfilter_parse_failed = TRUE;
2906 if (!rfilter_parse_failed) {
2907 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2908 /* "cf_open()" succeeded, so it closed the previous
2909 capture file, and thus destroyed any previous read filter
2910 attached to "cf". */
2912 cfile.rfcode = rfcode;
2913 /* Open stat windows; we do so after creating the main window,
2914 to avoid GTK warnings, and after successfully opening the
2915 capture file, so we know we have something to compute stats
2916 on, and after registering all dissectors, so that MATE will
2917 have registered its field array and we can have a tap filter
2918 with one of MATE's late-registered fields as part of the
2920 start_requested_stats();
2922 /* Read the capture file. */
2923 switch (cf_read(&cfile)) {
2927 /* Just because we got an error, that doesn't mean we were unable
2928 to read any of the file; we handle what we could get from the
2930 /* if the user told us to jump to a specific packet, do it now */
2931 if(go_to_packet != 0) {
2932 cf_goto_frame(&cfile, go_to_packet);
2936 case CF_READ_ABORTED:
2941 /* Save the name of the containing directory specified in the
2942 path name, if any; we can write over cf_name, which is a
2943 good thing, given that "get_dirname()" does write over its
2945 s = get_dirname(cf_name);
2946 /* we might already set this from the recent file, don't overwrite this */
2947 if(get_last_open_dir() == NULL)
2948 set_last_open_dir(s);
2953 dfilter_free(rfcode);
2954 cfile.rfcode = NULL;
2955 show_main_window(FALSE);
2956 set_menus_for_capture_in_progress(FALSE);
2961 if (start_capture) {
2962 if (capture_opts->save_file != NULL) {
2963 /* Save the directory name for future file dialogs. */
2964 /* (get_dirname overwrites filename) */
2965 s = get_dirname(g_strdup(capture_opts->save_file));
2966 set_last_open_dir(s);
2969 /* "-k" was specified; start a capture. */
2970 show_main_window(TRUE);
2971 if (capture_start(capture_opts)) {
2972 /* The capture started. Open stat windows; we do so after creating
2973 the main window, to avoid GTK warnings, and after successfully
2974 opening the capture file, so we know we have something to compute
2975 stats on, and after registering all dissectors, so that MATE will
2976 have registered its field array and we can have a tap filter with
2977 one of MATE's late-registered fields as part of the filter. */
2978 start_requested_stats();
2982 show_main_window(FALSE);
2983 set_menus_for_capture_in_progress(FALSE);
2986 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
2987 if (!start_capture && strlen(capture_opts->cfilter) == 0) {
2988 g_free(capture_opts->cfilter);
2989 capture_opts->cfilter = g_strdup(get_conn_cfilter());
2991 #else /* HAVE_LIBPCAP */
2992 show_main_window(FALSE);
2993 set_menus_for_capture_in_progress(FALSE);
2994 #endif /* HAVE_LIBPCAP */
2997 /* register our pid if we are being run from a U3 device */
3000 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3002 /* ... back from GTK, we're going down now! */
3004 /* deregister our pid */
3005 u3_deregister_pid();
3010 #ifdef HAVE_AIRPDCAP
3011 /* Davide Schiera (2006-11-18): destroy AirPDcap context */
3012 AirPDcapDestroyContext(&airpdcap_ctx);
3013 /* Davide Schiera (2006-11-18) ------------------------------------------- */
3017 /* hide the (unresponsive) main window, while asking the user to close the console window */
3018 gtk_widget_hide(top_level);
3020 /* Shutdown windows sockets */
3023 /* For some unknown reason, the "atexit()" call in "create_console()"
3024 doesn't arrange that "destroy_console()" be called when we exit,
3025 so we call it here if a console was created. */
3031 /* This isn't reached, but we need it to keep GCC from complaining
3032 that "main()" returns without returning a value - it knows that
3033 "exit()" never returns, but it doesn't know that "gtk_exit()"
3034 doesn't, as GTK+ doesn't declare it with the attribute
3036 return 0; /* not reached */
3041 /* We build this as a GUI subsystem application on Win32, so
3042 "WinMain()", not "main()", gets called.
3044 Hack shamelessly stolen from the Win32 port of the GIMP. */
3046 #define _stdcall __attribute__((stdcall))
3050 WinMain (struct HINSTANCE__ *hInstance,
3051 struct HINSTANCE__ *hPrevInstance,
3055 #if GTK_MAJOR_VERSION >= 2
3056 INITCOMMONCONTROLSEX comm_ctrl;
3058 /* Initialize our controls. Required for native Windows file dialogs. */
3059 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3060 comm_ctrl.dwSize = sizeof(comm_ctrl);
3061 /* Includes the animate, header, hot key, list view, progress bar,
3062 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3065 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3066 InitCommonControlsEx(&comm_ctrl);
3068 /* RichEd20.DLL is needed for filter entries. */
3069 LoadLibrary(_T("riched20.dll"));
3070 #endif /* GTK_MAJOR_VERSION >= 2 */
3072 has_console = FALSE;
3073 return main (__argc, __argv);
3077 * If this application has no console window to which its standard output
3078 * would go, create one.
3081 create_console(void)
3084 /* We have no console to which to print the version string, so
3085 create one and make it the standard input, output, and error. */
3086 if (!AllocConsole())
3087 return; /* couldn't create console */
3088 eth_freopen("CONIN$", "r", stdin);
3089 eth_freopen("CONOUT$", "w", stdout);
3090 eth_freopen("CONOUT$", "w", stderr);
3092 /* Well, we have a console now. */
3095 /* Now register "destroy_console()" as a routine to be called just
3096 before the application exits, so that we can destroy the console
3097 after the user has typed a key (so that the console doesn't just
3098 disappear out from under them, giving the user no chance to see
3099 the message(s) we put in there). */
3100 atexit(destroy_console);
3102 SetConsoleTitle(_T("Wireshark Debug Console"));
3107 destroy_console(void)
3110 printf("\n\nPress any key to exit\n");
3118 /* This routine should not be necessary, at least as I read the GLib
3119 source code, as it looks as if GLib is, on Win32, *supposed* to
3120 create a console window into which to display its output.
3122 That doesn't happen, however. I suspect there's something completely
3123 broken about that code in GLib-for-Win32, and that it may be related
3124 to the breakage that forces us to just call "printf()" on the message
3125 rather than passing the message on to "g_log_default_handler()"
3126 (which is the routine that does the aforementioned non-functional
3127 console window creation). */
3129 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3130 const char *message, gpointer user_data _U_)
3137 /* ignore log message, if log_level isn't interesting.
3138 If preferences aren't loaded yet, display message anyway */
3139 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3140 prefs.console_log_level != 0) {
3144 /* create a "timestamp" */
3146 today = localtime(&curr);
3149 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3150 /* the user wants a console or the application will terminate immediately */
3154 /* For some unknown reason, the above doesn't appear to actually cause
3155 anything to be sent to the standard output, so we'll just splat the
3156 message out directly, just to make sure it gets out. */
3158 switch(log_level & G_LOG_LEVEL_MASK) {
3159 case G_LOG_LEVEL_ERROR:
3162 case G_LOG_LEVEL_CRITICAL:
3165 case G_LOG_LEVEL_WARNING:
3168 case G_LOG_LEVEL_MESSAGE:
3171 case G_LOG_LEVEL_INFO:
3174 case G_LOG_LEVEL_DEBUG:
3178 fprintf(stderr, "unknown log_level %u\n", log_level);
3180 g_assert_not_reached();
3183 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3184 today->tm_hour, today->tm_min, today->tm_sec,
3185 log_domain != NULL ? log_domain : "",
3188 if(log_level & G_LOG_LEVEL_ERROR) {
3189 /* wait for a key press before the following error handler will terminate the program
3190 this way the user at least can read the error message */
3191 printf("\n\nPress any key to exit\n");
3195 g_log_default_handler(log_domain, log_level, message, user_data);
3201 static GtkWidget *info_bar_new(void)
3203 /* tip: tooltips don't work on statusbars! */
3204 info_bar = gtk_statusbar_new();
3205 main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
3206 file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
3207 help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
3208 #if GTK_MAJOR_VERSION >= 2
3209 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(info_bar), FALSE);
3211 gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
3216 static GtkWidget *packets_bar_new(void)
3218 /* tip: tooltips don't work on statusbars! */
3219 packets_bar = gtk_statusbar_new();
3220 packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
3221 packets_bar_update();
3228 * Helper for main_widgets_rearrange()
3230 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3231 gtk_container_remove(GTK_CONTAINER(data), widget);
3234 static GtkWidget *main_widget_layout(gint layout_content)
3236 switch(layout_content) {
3237 case(layout_pane_content_none):
3240 case(layout_pane_content_plist):
3243 case(layout_pane_content_pdetails):
3246 case(layout_pane_content_pbytes):
3250 g_assert_not_reached();
3257 * Rearrange the main window widgets
3259 void main_widgets_rearrange(void) {
3260 GtkWidget *first_pane_widget1, *first_pane_widget2;
3261 GtkWidget *second_pane_widget1, *second_pane_widget2;
3262 gboolean split_top_left;
3264 /* be a bit faster */
3265 gtk_widget_hide(main_vbox);
3267 /* be sure, we don't loose a widget while rearranging */
3268 gtk_widget_ref(menubar);
3269 gtk_widget_ref(main_tb);
3270 gtk_widget_ref(filter_tb);
3273 gtk_widget_ref(airpcap_tb);
3276 gtk_widget_ref(pkt_scrollw);
3277 gtk_widget_ref(tv_scrollw);
3278 gtk_widget_ref(byte_nb_ptr);
3279 gtk_widget_ref(stat_hbox);
3280 gtk_widget_ref(info_bar);
3281 gtk_widget_ref(packets_bar);
3282 gtk_widget_ref(status_pane);
3283 gtk_widget_ref(main_pane_v1);
3284 gtk_widget_ref(main_pane_v2);
3285 gtk_widget_ref(main_pane_h1);
3286 gtk_widget_ref(main_pane_h2);
3287 gtk_widget_ref(welcome_pane);
3289 /* empty all containers participating */
3290 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3291 gtk_container_foreach(GTK_CONTAINER(stat_hbox), foreach_remove_a_child, stat_hbox);
3292 gtk_container_foreach(GTK_CONTAINER(status_pane), foreach_remove_a_child, status_pane);
3293 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3294 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3295 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3296 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3298 /* add the menubar always at the top */
3299 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3302 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3304 /* filter toolbar in toolbar area */
3305 if (!prefs.filter_toolbar_show_in_statusbar) {
3306 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3310 /* airpcap toolbar */
3311 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3314 /* fill the main layout panes */
3315 switch(prefs.gui_layout_type) {
3316 case(layout_type_5):
3317 main_first_pane = main_pane_v1;
3318 main_second_pane = main_pane_v2;
3319 split_top_left = FALSE;
3321 case(layout_type_2):
3322 main_first_pane = main_pane_v1;
3323 main_second_pane = main_pane_h1;
3324 split_top_left = FALSE;
3326 case(layout_type_1):
3327 main_first_pane = main_pane_v1;
3328 main_second_pane = main_pane_h1;
3329 split_top_left = TRUE;
3331 case(layout_type_4):
3332 main_first_pane = main_pane_h1;
3333 main_second_pane = main_pane_v1;
3334 split_top_left = FALSE;
3336 case(layout_type_3):
3337 main_first_pane = main_pane_h1;
3338 main_second_pane = main_pane_v1;
3339 split_top_left = TRUE;
3341 case(layout_type_6):
3342 main_first_pane = main_pane_h1;
3343 main_second_pane = main_pane_h2;
3344 split_top_left = FALSE;
3347 main_first_pane = NULL;
3348 main_second_pane = NULL;
3349 split_top_left = FALSE;
3350 g_assert_not_reached();
3352 if (split_top_left) {
3353 first_pane_widget1 = main_second_pane;
3354 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3355 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3356 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3358 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3359 first_pane_widget2 = main_second_pane;
3360 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3361 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3363 if (first_pane_widget1 != NULL)
3364 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3365 if (first_pane_widget2 != NULL)
3366 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3367 if (second_pane_widget1 != NULL)
3368 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3369 if (second_pane_widget2 != NULL)
3370 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3372 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3375 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3377 /* statusbar hbox */
3378 gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0);
3380 /* filter toolbar in statusbar hbox */
3381 if (prefs.filter_toolbar_show_in_statusbar) {
3382 gtk_box_pack_start(GTK_BOX(stat_hbox), filter_tb, FALSE, TRUE, 1);
3386 /* airpcap toolbar */
3387 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3391 gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane, TRUE, TRUE, 0);
3392 gtk_paned_pack1(GTK_PANED(status_pane), info_bar, FALSE, FALSE);
3393 gtk_paned_pack2(GTK_PANED(status_pane), packets_bar, FALSE, FALSE);
3395 /* hide widgets on users recent settings */
3396 main_widgets_show_or_hide();
3398 gtk_widget_show(main_vbox);
3402 is_widget_visible(GtkWidget *widget, gpointer data)
3404 gboolean *is_visible = data;
3407 if (GTK_WIDGET_VISIBLE(widget))
3413 #ifdef SHOW_WELCOME_PAGE
3414 /* XXX - There seems to be some disagreement about if and how this feature should be implemented.
3415 As I currently don't have the time to continue this, it's temporarily disabled. - ULFL */
3417 welcome_item(gchar *stock_item, gchar * label, gchar * message, GtkSignalFunc callback, void *callback_data)
3419 GtkWidget *w, *item_hb;
3420 #if GTK_MAJOR_VERSION >= 2
3421 gchar *formatted_message;
3425 item_hb = gtk_hbox_new(FALSE, 1);
3427 w = BUTTON_NEW_FROM_STOCK(stock_item);
3428 WIDGET_SET_SIZE(w, 60, 60);
3429 #if GTK_MAJOR_VERSION >= 2
3430 gtk_button_set_label(GTK_BUTTON(w), label);
3432 gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 0);
3433 SIGNAL_CONNECT(w, "clicked", callback, callback_data);
3435 w = gtk_label_new(message);
3436 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3437 #if GTK_MAJOR_VERSION >= 2
3438 formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\">%s</span>", message);
3439 gtk_label_set_markup(GTK_LABEL(w), formatted_message);
3440 g_free(formatted_message);
3443 gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 10);
3449 /* XXX - the layout has to be improved */
3453 GtkWidget *welcome_scrollw, *welcome_hb, *welcome_vb, *item_hb;
3454 GtkWidget *w, *icon;
3458 welcome_scrollw = scrolled_window_new(NULL, NULL);
3460 welcome_hb = gtk_hbox_new(FALSE, 1);
3461 /*gtk_container_border_width(GTK_CONTAINER(welcome_hb), 20);*/
3463 welcome_vb = gtk_vbox_new(FALSE, 1);
3465 item_hb = gtk_hbox_new(FALSE, 1);
3467 icon = xpm_to_widget_from_parent(top_level, wsicon64_xpm);
3468 gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 5);
3470 #if GTK_MAJOR_VERSION < 2
3471 message = "Welcome to Wireshark!";
3473 message = "<span weight=\"bold\" size=\"25000\">" "Welcome to Wireshark!" "</span>";
3475 w = gtk_label_new(message);
3476 #if GTK_MAJOR_VERSION >= 2
3477 gtk_label_set_markup(GTK_LABEL(w), message);
3479 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3480 gtk_box_pack_start(GTK_BOX(item_hb), w, TRUE, TRUE, 5);
3482 gtk_box_pack_start(GTK_BOX(welcome_vb), item_hb, TRUE, FALSE, 5);
3484 w = gtk_label_new("What would you like to do?");
3485 gtk_box_pack_start(GTK_BOX(welcome_vb), w, FALSE, FALSE, 10);
3486 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3489 item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_START,
3491 "Capture live data from your network",
3492 GTK_SIGNAL_FUNC(capture_prep_cb), NULL);
3493 gtk_box_pack_start(GTK_BOX(welcome_vb), item_hb, TRUE, FALSE, 5);
3496 item_hb = welcome_item(GTK_STOCK_OPEN,
3498 "Open a previously captured file",
3499 GTK_SIGNAL_FUNC(file_open_cmd_cb), NULL);
3500 gtk_box_pack_start(GTK_BOX(welcome_vb), item_hb, TRUE, FALSE, 5);
3502 #if (GLIB_MAJOR_VERSION >= 2)
3503 item_hb = welcome_item(GTK_STOCK_HOME,
3505 "Visit the Wireshark homepage",
3506 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_HOME));
3507 gtk_box_pack_start(GTK_BOX(welcome_vb), item_hb, TRUE, FALSE, 5);
3509 item_hb = welcome_item(WIRESHARK_STOCK_WEB_SUPPORT,
3511 "Open the Wireshark User's Guide",
3512 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3513 gtk_box_pack_start(GTK_BOX(welcome_vb), item_hb, TRUE, FALSE, 5);
3517 w = gtk_label_new("");
3518 gtk_box_pack_start(GTK_BOX(welcome_vb), w, TRUE, TRUE, 0);
3520 w = gtk_label_new("");
3521 gtk_box_pack_start(GTK_BOX(welcome_hb), w, TRUE, TRUE, 0);
3523 gtk_box_pack_start(GTK_BOX(welcome_hb), welcome_vb, TRUE, TRUE, 0);
3525 w = gtk_label_new("");
3526 gtk_box_pack_start(GTK_BOX(welcome_hb), w, TRUE, TRUE, 0);
3528 gtk_widget_show_all(welcome_hb);
3530 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(welcome_scrollw),
3532 gtk_widget_show_all(welcome_scrollw);
3534 return welcome_scrollw;
3540 /* this is just a dummy to fill up window space, simply showing nothing */
3541 return scrolled_window_new(NULL, NULL);
3548 * XXX - this doesn't appear to work with the paned widgets in
3549 * GTK+ 1.2[.x]; if you hide one of the panes, the splitter remains
3550 * and the other pane doesn't grow to take up the rest of the pane.
3551 * It does appear to work with GTK+ 2.x.
3554 main_widgets_show_or_hide(void)
3556 gboolean main_second_pane_show;
3558 if (recent.main_toolbar_show) {
3559 gtk_widget_show(main_tb);
3561 gtk_widget_hide(main_tb);
3565 * Show the status hbox if either:
3567 * 1) we're showing the filter toolbar and we want it in the status
3572 * 2) we're showing the status bar.
3574 if ((recent.filter_toolbar_show && prefs.filter_toolbar_show_in_statusbar) ||
3575 recent.statusbar_show) {
3576 gtk_widget_show(stat_hbox);
3578 gtk_widget_hide(stat_hbox);
3581 if (recent.statusbar_show) {
3582 gtk_widget_show(status_pane);
3584 gtk_widget_hide(status_pane);
3587 if (recent.filter_toolbar_show) {
3588 gtk_widget_show(filter_tb);
3590 gtk_widget_hide(filter_tb);
3594 if (recent.airpcap_toolbar_show) {
3595 gtk_widget_show(airpcap_tb);
3597 gtk_widget_hide(airpcap_tb);
3601 if (recent.packet_list_show && have_capture_file) {
3602 gtk_widget_show(pkt_scrollw);
3604 gtk_widget_hide(pkt_scrollw);
3607 if (recent.tree_view_show && have_capture_file) {
3608 gtk_widget_show(tv_scrollw);
3610 gtk_widget_hide(tv_scrollw);
3613 if (recent.byte_view_show && have_capture_file) {
3614 gtk_widget_show(byte_nb_ptr);
3616 gtk_widget_hide(byte_nb_ptr);
3619 if (have_capture_file) {
3620 gtk_widget_show(main_first_pane);
3622 gtk_widget_hide(main_first_pane);
3626 * Is anything in "main_second_pane" visible?
3627 * If so, show it, otherwise hide it.
3629 main_second_pane_show = FALSE;
3630 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3631 &main_second_pane_show);
3632 if (main_second_pane_show) {
3633 gtk_widget_show(main_second_pane);
3635 gtk_widget_hide(main_second_pane);
3638 if (!have_capture_file) {
3640 gtk_widget_show(welcome_pane);
3643 gtk_widget_hide(welcome_pane);
3646 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
3647 packet_list_freeze ();
3648 packet_list_thaw ();
3652 #if GTK_MAJOR_VERSION >= 2
3653 /* called, when the window state changes (minimized, maximized, ...) */
3655 window_state_event_cb (GtkWidget *widget _U_,
3659 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3661 if( (event->type) == (GDK_WINDOW_STATE)) {
3662 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3663 /* we might have dialogs popped up while we where iconified,
3665 display_queued_messages();
3674 * Changed callback for the channel combobox
3677 airpcap_toolbar_channel_changed_cb(GtkWidget *w _U_, gpointer data)
3679 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
3684 s = gtk_entry_get_text(GTK_ENTRY(data));
3686 if ((data != NULL) && (w != NULL) ) {
3687 s = gtk_entry_get_text(GTK_ENTRY(data));
3688 if ((g_strcasecmp("",s))) {
3689 sscanf(s,"%d",&ch_num);
3690 if (airpcap_if_active != NULL) {
3691 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list, airpcap_if_active->description), ebuf);
3694 airpcap_if_set_device_channel(ad,ch_num);
3695 airpcap_if_active->channel = ch_num;
3696 airpcap_if_close(ad);
3704 * Callback for the wrong crc combo
3707 airpcap_toolbar_wrong_crc_combo_cb(GtkWidget *entry, gpointer user_data)
3709 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
3712 if( !block_toolbar_signals && (airpcap_if_active != NULL)) {
3713 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,airpcap_if_active->description), ebuf);
3716 airpcap_if_active->CrcValidationOn = airpcap_get_validation_type(gtk_entry_get_text(GTK_ENTRY(entry)));
3717 airpcap_if_set_fcs_validation(ad,airpcap_if_active->CrcValidationOn);
3718 /* Save configuration */
3719 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
3720 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.");
3722 airpcap_if_close(ad);
3728 airpcap_toolbar_encryption_cb(GtkWidget *entry, gpointer user_data)
3730 /* We need to directly access the .ddl functions here... */
3731 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
3736 airpcap_if_info_t* curr_if = NULL;
3738 /* Apply changes to the current adapter */
3739 if( (airpcap_if_active != NULL)) {
3740 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,airpcap_if_active->description), ebuf);
3743 if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON) {
3744 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_OFF;
3745 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
3746 /* Save configuration */
3747 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
3748 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.");
3750 airpcap_if_close(ad);
3752 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_ON;
3753 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
3754 /* Save configuration */
3755 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
3756 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.");
3758 airpcap_if_close(ad);
3762 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No active AirPcap Adapter selected!");
3766 n = g_list_length(airpcap_if_list);
3768 /* The same kind of settings should be propagated to all the adapters */
3769 /* Apply this change to all the adapters !!! */
3770 for(i = 0; i < n; i++) {
3771 curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
3773 if( (curr_if != NULL) && (curr_if != airpcap_if_selected) ) {
3774 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,curr_if->description), ebuf);
3776 curr_if->DecryptionOn = airpcap_if_selected->DecryptionOn;
3777 airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
3778 /* Save configuration for the curr_if */
3779 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
3780 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.");
3782 airpcap_if_close(ad);
3789 * Callback for the Advanced Wireless Settings button
3792 toolbar_display_airpcap_advanced_cb(GtkWidget *w, gpointer data)
3796 from_widget = (gint*)g_malloc(sizeof(gint));
3797 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
3798 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
3800 display_airpcap_advanced_cb(w,data);
3804 * Callback for the Decryption Key Management button
3807 toolbar_display_airpcap_key_management_cb(GtkWidget *w, gpointer data)
3811 from_widget = (gint*)g_malloc(sizeof(gint));
3812 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
3813 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
3815 display_airpcap_key_management_cb(w,data);
3817 #endif /* HAVE_AIRPCAP */
3819 #if GTK_MAJOR_VERSION >= 2
3821 top_level_key_pressed_cb(GtkCTree *ctree _U_, GdkEventKey *event, gpointer user_data _U_)
3823 if (event->keyval == GDK_F8) {
3826 } else if (event->keyval == GDK_F7) {
3830 * A comment in gdkkeysyms.h says that it's autogenerated from
3831 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3832 * don't explicitly say so, isprint() should work as expected
3835 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3836 /* Forward the keypress on to the display filter entry */
3837 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3838 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3839 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3848 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
3851 *filter_bt, *filter_cm, *filter_te,
3852 *filter_add_expr_bt,
3855 GList *dfilter_list = NULL;
3856 GtkTooltips *tooltips;
3858 GtkAccelGroup *accel;
3862 GtkWidget *advanced_bt,
3870 GtkWidget *enable_decryption_lb;
3871 GtkWidget *enable_decryption_cb;
3872 GList *enable_decryption_cb_items = NULL;
3873 GtkWidget *enable_decryption_en;
3875 GList *channel_list = NULL;
3876 GList *linktype_list = NULL;
3877 GList *link_list = NULL;
3878 GtkTooltips *airpcap_tooltips;
3879 gchar *if_label_text;
3880 gint *from_widget = NULL;
3883 /* Display filter construct dialog has an Apply button, and "OK" not
3884 only sets our text widget, it activates it (i.e., it causes us to
3885 filter the capture). */
3886 static construct_args_t args = {
3887 "Wireshark: Display Filter",
3893 /* use user-defined title if preference is set */
3894 title = create_user_window_title("The Wireshark Network Analyzer");
3897 top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
3900 tooltips = gtk_tooltips_new();
3903 airpcap_tooltips = gtk_tooltips_new();
3907 #if GTK_MAJOR_VERSION < 2
3908 /* has to be done, after top_level window is created */
3909 app_font_gtk1_init(top_level);
3913 gtk_widget_set_name(top_level, "main window");
3914 SIGNAL_CONNECT(top_level, "delete_event", main_window_delete_event_cb,
3916 #if GTK_MAJOR_VERSION >= 2
3917 SIGNAL_CONNECT(GTK_OBJECT(top_level), "window_state_event",
3918 G_CALLBACK (window_state_event_cb), NULL);
3919 SIGNAL_CONNECT(GTK_OBJECT(top_level), "key-press-event",
3920 G_CALLBACK (top_level_key_pressed_cb), NULL );
3923 gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
3925 /* Container for menu bar, toolbar(s), paned windows and progress/info box */
3926 main_vbox = gtk_vbox_new(FALSE, 1);
3927 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
3928 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3929 gtk_widget_show(main_vbox);
3932 menubar = main_menu_new(&accel);
3933 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3934 gtk_widget_show(menubar);
3937 main_tb = toolbar_new();
3938 gtk_widget_show (main_tb);
3941 pkt_scrollw = packet_list_new(prefs);
3942 WIDGET_SET_SIZE(packet_list, -1, pl_size);
3943 gtk_widget_show(pkt_scrollw);
3946 tv_scrollw = main_tree_view_new(prefs, &tree_view);
3947 WIDGET_SET_SIZE(tv_scrollw, -1, tv_size);
3948 gtk_widget_show(tv_scrollw);
3950 #if GTK_MAJOR_VERSION < 2
3951 SIGNAL_CONNECT(tree_view, "tree-select-row", tree_view_select_row_cb, NULL);
3952 SIGNAL_CONNECT(tree_view, "tree-unselect-row", tree_view_unselect_row_cb,
3955 SIGNAL_CONNECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
3956 "changed", tree_view_selection_changed_cb, NULL);
3958 SIGNAL_CONNECT(tree_view, "button_press_event", popup_menu_handler,
3959 OBJECT_GET_DATA(popup_menu_object, PM_TREE_VIEW_KEY));
3960 gtk_widget_show(tree_view);
3963 byte_nb_ptr = byte_view_new();
3964 WIDGET_SET_SIZE(byte_nb_ptr, -1, bv_size);
3965 gtk_widget_show(byte_nb_ptr);
3967 SIGNAL_CONNECT(byte_nb_ptr, "button_press_event", popup_menu_handler,
3968 OBJECT_GET_DATA(popup_menu_object, PM_HEXDUMP_KEY));
3971 /* Panes for the packet list, tree, and byte view */
3972 main_pane_v1 = gtk_vpaned_new();
3973 gtk_widget_show(main_pane_v1);
3974 main_pane_v2 = gtk_vpaned_new();
3975 gtk_widget_show(main_pane_v2);
3976 main_pane_h1 = gtk_hpaned_new();
3977 gtk_widget_show(main_pane_h1);
3978 main_pane_h2 = gtk_hpaned_new();
3979 gtk_widget_show(main_pane_h2);
3982 /* airpcap toolbar */
3983 #if GTK_MAJOR_VERSION < 2
3984 airpcap_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
3987 airpcap_tb = gtk_toolbar_new();
3988 gtk_toolbar_set_orientation(GTK_TOOLBAR(airpcap_tb),
3989 GTK_ORIENTATION_HORIZONTAL);
3990 #endif /* GTK_MAJOR_VERSION */
3991 gtk_widget_show(airpcap_tb);
3993 /* Interface Label */
3994 if(airpcap_if_active != NULL) {
3995 if_label_text = g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_active));
3996 interface_lb = gtk_label_new(if_label_text);
3997 g_free(if_label_text);
3999 interface_lb = gtk_label_new("No Wireless Interface Found ");
4002 /* Add the label to the toolbar */
4003 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), interface_lb,
4004 "Current Wireless Interface", "Private");
4005 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_INTERFACE_KEY,interface_lb);
4006 gtk_widget_show(interface_lb);
4007 gtk_toolbar_insert_space(GTK_TOOLBAR(airpcap_tb),1);
4010 /* Create the "802.11 Channel:" label */
4011 channel_lb = gtk_label_new(" 802.11 Channel: ");
4012 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_LABEL_KEY,channel_lb);
4013 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_lb,
4014 "Current 802.11 Channel", "Private");
4015 gtk_widget_show(channel_lb);
4017 WIDGET_SET_SIZE(channel_lb, 100, 28);
4019 /* Create the channel combo box */
4020 channel_cm = gtk_combo_new();
4021 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(channel_cm)->entry),FALSE);
4022 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_KEY,channel_cm);
4024 channel_list = g_list_append(channel_list, "1");
4025 channel_list = g_list_append(channel_list, "2");
4026 channel_list = g_list_append(channel_list, "3");
4027 channel_list = g_list_append(channel_list, "4");
4028 channel_list = g_list_append(channel_list, "5");
4029 channel_list = g_list_append(channel_list, "6");
4030 channel_list = g_list_append(channel_list, "7");
4031 channel_list = g_list_append(channel_list, "8");
4032 channel_list = g_list_append(channel_list, "9");
4033 channel_list = g_list_append(channel_list, "10");
4034 channel_list = g_list_append(channel_list, "11");
4035 channel_list = g_list_append(channel_list, "12");
4036 channel_list = g_list_append(channel_list, "13");
4037 channel_list = g_list_append(channel_list, "14");
4039 gtk_combo_set_popdown_strings( GTK_COMBO(channel_cm), channel_list) ;
4041 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(channel_cm)->entry),
4042 "Change the 802.11 RF channel", NULL);
4044 WIDGET_SET_SIZE(channel_cm, 90, 28);
4046 if(airpcap_if_active != NULL)
4047 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry), airpcap_get_channel_name(airpcap_if_active->channel));
4049 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry),"");
4051 /* callback for channel combo box */
4052 SIGNAL_CONNECT(GTK_COMBO(channel_cm)->entry,"changed",airpcap_toolbar_channel_changed_cb,GTK_COMBO(channel_cm)->entry);
4053 gtk_widget_show(channel_cm);
4055 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_cm,
4056 "802.11 Channel", "Private");
4058 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4060 /* Wrong CRC Label */
4061 wrong_crc_lb = gtk_label_new(" FCS Filter: ");
4062 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_LABEL_KEY,wrong_crc_lb);
4063 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_lb,
4065 gtk_widget_show(wrong_crc_lb);
4067 /* Wrong CRC combo */
4068 wrong_crc_cm = gtk_combo_new();
4069 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(wrong_crc_cm)->entry),FALSE);
4070 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_KEY,wrong_crc_cm);
4071 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_cm,
4074 WIDGET_SET_SIZE(wrong_crc_cm, 100, -1);
4076 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_ALL);
4077 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRECT);
4078 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRUPT);
4080 gtk_combo_set_popdown_strings( GTK_COMBO(wrong_crc_cm), linktype_list) ;
4081 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(wrong_crc_cm)->entry),
4082 "Select the 802.11 FCS filter that the wireless adapter will apply.",
4085 if(airpcap_if_active != NULL)
4086 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry), airpcap_get_validation_name(airpcap_if_active->CrcValidationOn));
4088 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry),"");
4090 SIGNAL_CONNECT(GTK_COMBO(wrong_crc_cm)->entry,"changed",airpcap_toolbar_wrong_crc_combo_cb,airpcap_tb);
4091 gtk_widget_show(wrong_crc_cm);
4093 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4095 /* Decryption mode combo box */
4096 enable_decryption_lb = gtk_label_new ("Decryption Mode: ");
4097 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_LABEL_KEY,enable_decryption_lb);
4098 gtk_widget_set_name (enable_decryption_lb, "enable_decryption_lb");
4099 gtk_widget_show (enable_decryption_lb);
4100 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_lb,
4103 enable_decryption_cb = gtk_combo_new ();
4104 gtk_widget_set_name (enable_decryption_cb, "enable_decryption_cb");
4105 gtk_widget_show (enable_decryption_cb);
4106 WIDGET_SET_SIZE (enable_decryption_cb, 83, -1);
4107 update_decryption_mode_list(enable_decryption_cb);
4109 enable_decryption_en = GTK_COMBO (enable_decryption_cb)->entry;
4110 gtk_widget_set_name (enable_decryption_en, "enable_decryption_en");
4111 gtk_widget_show (enable_decryption_en);
4112 gtk_editable_set_editable (GTK_EDITABLE (enable_decryption_en), FALSE);
4113 GTK_WIDGET_UNSET_FLAGS (enable_decryption_en, GTK_CAN_FOCUS);
4115 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_cb,
4116 "Choose a Decryption Mode", "Private");
4118 /* Set current decryption mode!!!! */
4119 update_decryption_mode_cm(enable_decryption_cb);
4120 SIGNAL_CONNECT (enable_decryption_en, "changed",on_enable_decryption_en_changed, airpcap_tb);
4121 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_KEY,enable_decryption_cb);
4123 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4125 /* Advanced button */
4126 advanced_bt = gtk_button_new_with_label("Wireless Settings...");
4127 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_ADVANCED_KEY,advanced_bt);
4129 SIGNAL_CONNECT(advanced_bt, "clicked", toolbar_display_airpcap_advanced_cb, airpcap_tb);
4130 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), advanced_bt,
4131 "Set Advanced Wireless Settings", "Private");
4132 gtk_widget_show(advanced_bt);
4134 /* Key Management button */
4135 key_management_bt = gtk_button_new_with_label("Decryption Keys...");
4136 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY,key_management_bt);
4138 SIGNAL_CONNECT(key_management_bt, "clicked", toolbar_display_airpcap_key_management_cb, airpcap_tb);
4139 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), key_management_bt,
4140 "Manage Decryption Keys", "Private");
4141 gtk_widget_show(key_management_bt);
4143 /* select the default interface */
4144 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
4146 /* If no airpcap interface is present, gray everything */
4147 if(airpcap_if_active == NULL) {
4148 if(airpcap_if_list == NULL) {
4149 /*No airpcap device found */
4150 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4151 //recent.airpcap_toolbar_show = TRUE;
4153 /* default adapter is not airpcap... or is airpcap but is not found*/
4154 airpcap_set_toolbar_stop_capture(airpcap_if_active);
4155 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4156 //recent.airpcap_toolbar_show = TRUE;
4159 airpcap_set_toolbar_stop_capture(airpcap_if_active);
4160 //recent.airpcap_toolbar_show = TRUE;
4164 /* filter toolbar */
4165 #if GTK_MAJOR_VERSION < 2
4166 filter_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
4169 filter_tb = gtk_toolbar_new();
4170 gtk_toolbar_set_orientation(GTK_TOOLBAR(filter_tb),
4171 GTK_ORIENTATION_HORIZONTAL);
4172 #endif /* GTK_MAJOR_VERSION */
4173 gtk_widget_show(filter_tb);
4175 /* Create the "Filter:" button */
4176 filter_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
4177 SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
4178 gtk_widget_show(filter_bt);
4179 OBJECT_SET_DATA(top_level, E_FILT_BT_PTR_KEY, filter_bt);
4181 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_bt,
4182 "Open the \"Display Filter\" dialog, to edit/apply filters", "Private");
4184 /* Create the filter combobox */
4185 filter_cm = gtk_combo_new();
4186 dfilter_list = NULL;
4187 gtk_combo_disable_activate(GTK_COMBO(filter_cm));
4188 gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
4189 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
4190 filter_te = GTK_COMBO(filter_cm)->entry;
4191 main_display_filter_widget=filter_te;
4192 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
4193 OBJECT_SET_DATA(filter_te, E_DFILTER_CM_KEY, filter_cm);
4194 OBJECT_SET_DATA(top_level, E_DFILTER_CM_KEY, filter_cm);
4195 SIGNAL_CONNECT(filter_te, "activate", filter_activate_cb, filter_te);
4196 SIGNAL_CONNECT(filter_te, "changed", filter_te_syntax_check_cb, NULL);
4197 WIDGET_SET_SIZE(filter_cm, 400, -1);
4198 gtk_widget_show(filter_cm);
4199 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_cm,
4201 /* setting a tooltip for a combobox will do nothing, so add it to the corresponding text entry */
4202 gtk_tooltips_set_tip(tooltips, filter_te,
4203 "Enter a display filter, or choose one of your recently used filters. "
4204 "The background color of this field is changed by a continuous syntax check (green is valid, red is invalid).",
4207 /* Create the "Add Expression..." button, to pop up a dialog
4208 for constructing filter comparison expressions. */
4209 filter_add_expr_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_ADD_EXPRESSION);
4210 OBJECT_SET_DATA(filter_tb, E_FILT_FILTER_TE_KEY, filter_te);
4211 SIGNAL_CONNECT(filter_add_expr_bt, "clicked", filter_add_expr_bt_cb, filter_tb);
4212 gtk_widget_show(filter_add_expr_bt);
4213 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_add_expr_bt,
4214 "Add an expression to this filter string", "Private");
4216 /* Create the "Clear" button */
4217 filter_reset = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLEAR);
4218 OBJECT_SET_DATA(filter_reset, E_DFILTER_TE_KEY, filter_te);
4219 SIGNAL_CONNECT(filter_reset, "clicked", filter_reset_cb, NULL);
4220 gtk_widget_show(filter_reset);
4221 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_reset,
4222 "Clear this filter string and update the display", "Private");
4224 /* Create the "Apply" button */
4225 filter_apply = BUTTON_NEW_FROM_STOCK(GTK_STOCK_APPLY);
4226 OBJECT_SET_DATA(filter_apply, E_DFILTER_CM_KEY, filter_cm);
4227 SIGNAL_CONNECT(filter_apply, "clicked", filter_activate_cb, filter_te);
4228 gtk_widget_show(filter_apply);
4229 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_apply,
4230 "Apply this filter string to the display", "Private");
4232 /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data
4233 * of any widget that ends up calling a callback which needs
4234 * that text entry pointer */
4235 set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te);
4236 set_menu_object_data("/Analyze/Display Filters...", E_FILT_TE_PTR_KEY,
4238 set_menu_object_data("/Analyze/Follow TCP Stream", E_DFILTER_TE_KEY,
4240 set_menu_object_data("/Analyze/Follow SSL Stream", E_DFILTER_TE_KEY,
4242 set_menu_object_data("/Analyze/Apply as Filter/Selected", E_DFILTER_TE_KEY,
4244 set_menu_object_data("/Analyze/Apply as Filter/Not Selected", E_DFILTER_TE_KEY,
4246 set_menu_object_data("/Analyze/Apply as Filter/... and Selected", E_DFILTER_TE_KEY,
4248 set_menu_object_data("/Analyze/Apply as Filter/... or Selected", E_DFILTER_TE_KEY,
4250 set_menu_object_data("/Analyze/Apply as Filter/... and not Selected", E_DFILTER_TE_KEY,
4252 set_menu_object_data("/Analyze/Apply as Filter/... or not Selected", E_DFILTER_TE_KEY,
4254 set_menu_object_data("/Analyze/Prepare a Filter/Selected", E_DFILTER_TE_KEY,
4256 set_menu_object_data("/Analyze/Prepare a Filter/Not Selected", E_DFILTER_TE_KEY,
4258 set_menu_object_data("/Analyze/Prepare a Filter/... and Selected", E_DFILTER_TE_KEY,
4260 set_menu_object_data("/Analyze/Prepare a Filter/... or Selected", E_DFILTER_TE_KEY,
4262 set_menu_object_data("/Analyze/Prepare a Filter/... and not Selected", E_DFILTER_TE_KEY,
4264 set_menu_object_data("/Analyze/Prepare a Filter/... or not Selected", E_DFILTER_TE_KEY,
4266 set_menu_object_data("/Conversation Filter/Ethernet", E_DFILTER_TE_KEY,
4268 set_menu_object_data("/Conversation Filter/IP", E_DFILTER_TE_KEY,
4270 set_menu_object_data("/Conversation Filter/TCP", E_DFILTER_TE_KEY,
4272 set_menu_object_data("/Conversation Filter/UDP", E_DFILTER_TE_KEY,
4274 set_menu_object_data("/Conversation Filter/PN-CBA Server", E_DFILTER_TE_KEY,
4276 set_toolbar_object_data(E_DFILTER_TE_KEY, filter_te);
4277 OBJECT_SET_DATA(popup_menu_object, E_DFILTER_TE_KEY, filter_te);
4278 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_KEY, packet_list);
4280 /* info (main) statusbar */
4281 info_bar = info_bar_new();
4282 gtk_widget_show(info_bar);
4284 /* packets statusbar */
4285 packets_bar = packets_bar_new();
4286 gtk_widget_show(packets_bar);
4288 /* Filter/status hbox */
4289 stat_hbox = gtk_hbox_new(FALSE, 1);
4290 gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
4291 gtk_widget_show(stat_hbox);
4293 /* Pane for the statusbar */
4294 status_pane = gtk_hpaned_new();
4295 gtk_widget_show(status_pane);
4297 /* Pane for the welcome screen */
4298 welcome_pane = welcome_new();
4299 gtk_widget_show(welcome_pane);
4304 driver_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
4308 r = simple_dialog_check_get(dialog);
4309 recent.airpcap_driver_check_show = !r;
4314 show_main_window(gboolean doing_work)
4316 main_set_for_capture_file(doing_work);
4318 /*** we have finished all init things, show the main window ***/
4319 gtk_widget_show(top_level);
4321 /* the window can be maximized only, if it's visible, so do it after show! */
4322 main_load_window_geometry(top_level);
4324 /* process all pending GUI events before continue */
4325 while (gtk_events_pending()) gtk_main_iteration();
4327 /* Pop up any queued-up alert boxes. */
4328 display_queued_messages();
4332 * This will read the decryption keys from the preferences file, and will
4333 * store them into the registry...
4335 if(!airpcap_check_decryption_keys(airpcap_if_list)) {
4336 /* Ask the user what to do ...*/
4337 airpcap_keys_check_w(NULL,NULL);
4339 /* Keys from lists are equals, or wireshark has got no keys */
4340 airpcap_load_decryption_keys(airpcap_if_list);
4343 switch (airpcap_dll_ret_val) {
4345 case AIRPCAP_DLL_OK:
4348 case AIRPCAP_DLL_OLD:
4349 if(recent.airpcap_driver_check_show) {
4350 driver_warning_dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
4351 "WARNING: The version of AirPcap on this system\n"
4352 "does not support driver-level decryption. Please\n"
4353 "download a more recent version from\n" "http://www.cacetech.com/support/downloads.htm \n");
4354 simple_dialog_check_set(driver_warning_dialog,"Don't show this message again.");
4355 simple_dialog_set_cb(driver_warning_dialog, driver_warning_dialog_cb, (gpointer) driver_warning_dialog);
4361 * XXX - Maybe we need to warn the user if one of the following happens???
4363 case AIRPCAP_DLL_ERROR:
4364 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
4367 case AIRPCAP_DLL_NOT_FOUND:
4368 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
4372 #endif /* HAVE_AIRPCAP */
4375 /* Fill in capture options with values from the preferences */
4377 prefs_to_capture_opts(void)
4380 /* Set promiscuous mode from the preferences setting. */
4381 /* the same applies to other preferences settings as well. */
4382 capture_opts->promisc_mode = prefs.capture_prom_mode;
4383 capture_opts->show_info = prefs.capture_show_info;
4384 capture_opts->real_time_mode = prefs.capture_real_time;
4385 auto_scroll_live = prefs.capture_auto_scroll;
4386 #endif /* HAVE_LIBPCAP */
4388 /* Set the name resolution code's flags from the preferences. */
4389 g_resolv_flags = prefs.name_resolve;