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"
103 #include "capture-pcap-util.h"
105 #include "capture_sync.h"
109 #include "capture-wpcap.h"
110 #include "capture_wpcap_packet.h"
111 #include <tchar.h> /* Needed for Unicode */
112 #if GTK_MAJOR_VERSION >= 2
113 #include <commctrl.h>
114 #endif /* GTK_MAJOR_VERSION >= 2 */
117 #if GTK_MAJOR_VERSION < 2 && GTK_MINOR_VERSION < 3
118 #include "ethclist.h"
122 #include "statusbar.h"
123 #include "alert_box.h"
125 #include "dlg_utils.h"
127 #include "file_dlg.h"
128 #include "gtkglobals.h"
130 #include "gui_utils.h"
131 #include "compat_macros.h"
135 #include "../main_window.h"
137 #include "capture_file_dlg.h"
138 #include <epan/column.h>
139 #include "proto_draw.h"
141 #include "packet_win.h"
143 #include "find_dlg.h"
144 #include "packet_list.h"
146 #include "follow_dlg.h"
147 #include "font_utils.h"
148 #include "about_dlg.h"
149 #include "help_dlg.h"
150 #include "decode_as_dlg.h"
151 #include "webbrowser.h"
152 #include "capture_dlg.h"
153 #include "capture_ui_utils.h"
155 #include "../epan/emem.h"
156 #include "file_util.h"
157 #include "../image/wsicon16.xpm"
158 #include "../image/wsicon32.xpm"
159 #include "../image/wsicon48.xpm"
160 #include "../image/wsicon64.xpm"
161 #include "../image/wsiconcap16.xpm"
162 #include "../image/wsiconcap32.xpm"
163 #include "../image/wsiconcap48.xpm"
164 #ifdef SHOW_WELCOME_PAGE
165 #include "../image/wssplash.xpm"
170 #include "airpcap_loader.h"
171 #include "airpcap_dlg.h"
172 #include "airpcap_gui_utils.h"
174 #include "./gtk/toolbar.h"
176 #include "./image/toolbar/wep_closed_24.xpm"
180 /* Davide Schiera (2006-11-22): including AirPDcap project */
181 #include <epan/crypt/airpdcap_ws.h>
182 /* Davide Schiera (2006-11-22) ---------------------------------------------- */
186 * Files under personal and global preferences directories in which
187 * GTK settings for Wireshark are stored.
189 #define RC_FILE "gtkrc"
192 #define DEF_READY_MESSAGE " Ready to load or capture"
194 #define DEF_READY_MESSAGE " Ready to load file"
198 GtkWidget *main_display_filter_widget=NULL;
199 GtkWidget *top_level = NULL, *tree_view, *byte_nb_ptr, *tv_scrollw;
200 static GtkWidget *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
201 static GtkWidget *main_first_pane, *main_second_pane;
202 static GtkWidget *status_pane;
203 static GtkWidget *menubar, *main_vbox, *main_tb, *pkt_scrollw, *stat_hbox, *filter_tb;
206 GtkWidget *airpcap_tb;
207 static GtkWidget *driver_warning_dialog;
208 static int airpcap_dll_ret_val = -1;
211 static GtkWidget *info_bar;
212 static GtkWidget *packets_bar = NULL;
213 static GtkWidget *welcome_pane;
214 static guint main_ctx, file_ctx, help_ctx;
215 static guint packets_ctx;
216 static gchar *packets_str = NULL;
217 GString *comp_info_str, *runtime_info_str;
218 gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
221 static gboolean has_console; /* TRUE if app has console */
222 static void destroy_console(void);
224 static void console_log_handler(const char *log_domain,
225 GLogLevelFlags log_level, const char *message, gpointer user_data);
228 static gboolean list_link_layer_types;
229 capture_options global_capture_opts;
230 capture_options *capture_opts = &global_capture_opts;
233 gboolean block_toolbar_signals = FALSE;
235 static void create_main_window(gint, gint, gint, e_prefs*);
236 static void show_main_window(gboolean);
237 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
238 static void main_save_window_geometry(GtkWidget *widget);
240 #define E_DFILTER_CM_KEY "display_filter_combo"
241 #define E_DFILTER_FL_KEY "display_filter_list"
243 /* Match selected byte pattern */
245 match_selected_cb_do(gpointer data, int action, gchar *text)
247 GtkWidget *filter_te;
248 char *cur_filter, *new_filter;
250 if ((!text) || (0 == strlen(text))) {
251 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
256 filter_te = OBJECT_GET_DATA(data, E_DFILTER_TE_KEY);
259 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
261 switch (action&MATCH_SELECTED_MASK) {
263 case MATCH_SELECTED_REPLACE:
264 new_filter = g_strdup(text);
267 case MATCH_SELECTED_AND:
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_OR:
275 if ((!cur_filter) || (0 == strlen(cur_filter)))
276 new_filter = g_strdup(text);
278 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
281 case MATCH_SELECTED_NOT:
282 new_filter = g_strconcat("!(", text, ")", NULL);
285 case MATCH_SELECTED_AND_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);
292 case MATCH_SELECTED_OR_NOT:
293 if ((!cur_filter) || (0 == strlen(cur_filter)))
294 new_filter = g_strconcat("!(", text, ")", NULL);
296 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
300 g_assert_not_reached();
305 /* Free up the copy we got of the old filter text. */
308 /* Don't change the current display filter if we only want to copy the filter */
309 if (action&MATCH_SELECTED_COPY_ONLY) {
310 GString *gtk_text_str = g_string_new("");
311 g_string_sprintfa(gtk_text_str, "%s", new_filter);
312 copy_to_clipboard(gtk_text_str);
313 g_string_free(gtk_text_str, TRUE);
315 /* create a new one and set the display filter entry accordingly */
316 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
318 /* Run the display filter so it goes in effect. */
319 if (action&MATCH_SELECTED_APPLY_NOW)
320 main_filter_packets(&cfile, new_filter, FALSE);
323 /* Free up the new filter text. */
328 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
332 if (cfile.finfo_selected) {
333 filter = proto_construct_match_selected_string(cfile.finfo_selected,
335 match_selected_cb_do((data ? data : w), action, filter);
340 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
342 gchar *selected_proto_url;
343 gchar *proto_abbrev = data;
348 if (cfile.finfo_selected) {
349 /* open wiki page using the protocol abbreviation */
350 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
351 browser_open_url(selected_proto_url);
352 g_free(selected_proto_url);
355 case(ESD_BTN_CANCEL):
358 g_assert_not_reached();
364 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
367 const gchar *proto_abbrev;
371 if (cfile.finfo_selected) {
372 /* convert selected field to protocol abbreviation */
373 /* XXX - could this conversion be simplified? */
374 field_id = cfile.finfo_selected->hfinfo->id;
375 /* if the selected field isn't a protocol, get it's parent */
376 if(!proto_registrar_is_protocol(field_id)) {
377 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
380 proto_abbrev = proto_registrar_get_abbrev(field_id);
382 /* ask the user if the wiki page really should be opened */
383 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
384 PRIMARY_TEXT_START "Open Wireshark Wiki page of protocol \"%s\"?" PRIMARY_TEXT_END "\n"
386 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
388 "The Wireshark Wiki is a collaborative approach to provide information\n"
389 "about Wireshark in several ways (not limited to protocol specifics).\n"
391 "This Wiki is new, so the page of the selected protocol\n"
392 "may not exist and/or may not contain valuable information.\n"
394 "As everyone can edit the Wiki and add new content (or extend existing),\n"
395 "you are encouraged to add information if you can.\n"
397 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
399 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate,\n"
400 "which will save you a lot of editing and will give a consistent look over the pages.",
401 proto_abbrev, proto_abbrev);
402 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer) proto_abbrev);
408 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
411 const gchar *proto_abbrev;
412 gchar *selected_proto_url;
415 if (cfile.finfo_selected) {
416 /* convert selected field to protocol abbreviation */
417 /* XXX - could this conversion be simplified? */
418 field_id = cfile.finfo_selected->hfinfo->id;
419 /* if the selected field isn't a protocol, get it's parent */
420 if(!proto_registrar_is_protocol(field_id)) {
421 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
424 proto_abbrev = proto_registrar_get_abbrev(field_id);
426 /* open reference page using the protocol abbreviation */
427 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s.html", proto_abbrev[0], proto_abbrev);
428 browser_open_url(selected_proto_url);
429 g_free(selected_proto_url);
434 get_text_from_packet_list(gpointer data)
436 gint row = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_ROW_KEY));
437 gint column = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_COL_KEY));
438 frame_data *fdata = (frame_data *)packet_list_get_row_data(row);
446 if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
447 cfile.pd, fdata->cap_len, &err, &err_info)) {
448 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
449 cf_read_error_message(err, err_info), cfile.filename);
453 edt = epan_dissect_new(FALSE, FALSE);
454 epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata,
456 epan_dissect_fill_in_columns(edt);
458 if (strlen(cfile.cinfo.col_expr[column]) != 0 &&
459 strlen(cfile.cinfo.col_expr_val[column]) != 0) {
460 len = strlen(cfile.cinfo.col_expr[column]) +
461 strlen(cfile.cinfo.col_expr_val[column]) + 5;
462 buf = ep_alloc0(len);
463 g_snprintf(buf, len, "%s == %s", cfile.cinfo.col_expr[column],
464 cfile.cinfo.col_expr_val[column]);
467 epan_dissect_free(edt);
474 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
476 match_selected_cb_do(data,
478 get_text_from_packet_list(data));
481 /* This function allows users to right click in the details window and copy the text
482 * information to the operating systems clipboard.
484 * We first check to see if a string representation is setup in the tree and then
485 * read the string. If not available then we try to grab the value. If all else
486 * fails we display a message to the user to indicate the copy could not be completed.
489 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_)
491 GString *gtk_text_str = g_string_new("");
492 char labelstring[256];
493 char *stringpointer = labelstring;
495 if (cfile.finfo_selected->rep->representation != 0) {
496 g_string_sprintfa(gtk_text_str, "%s", cfile.finfo_selected->rep->representation); /* Get the represented data */
498 if (gtk_text_str->len == 0) { /* If no representation then... */
499 proto_item_fill_label(cfile.finfo_selected, stringpointer); /* Try to read the value */
500 g_string_sprintfa(gtk_text_str, "%s", stringpointer);
502 if (gtk_text_str->len == 0) { /* Could not get item so display error msg */
503 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
507 copy_to_clipboard(gtk_text_str); /* Copy string to clipboard */
509 g_string_free(gtk_text_str, TRUE); /* Free the memory */
513 /* XXX: use a preference for this setting! */
514 static guint dfilter_combo_max_recent = 10;
516 /* add a display filter to the combo box */
517 /* Note: a new filter string will replace an old identical one */
519 dfilter_combo_add(GtkWidget *filter_cm, char *s) {
521 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
524 /* GtkCombos don't let us get at their list contents easily, so we maintain
525 our own filter list, and feed it to gtk_combo_set_popdown_strings when
526 a new filter is added. */
527 li = g_list_first(dfilter_list);
529 /* If the filter is already in the list, remove the old one and
530 * append the new one at the latest position (at g_list_append() below) */
531 if (li->data && strcmp(s, li->data) == 0) {
532 dfilter_list = g_list_remove(dfilter_list, li->data);
538 dfilter_list = g_list_append(dfilter_list, s);
539 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
540 gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), dfilter_list);
541 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), g_list_last(dfilter_list)->data);
547 /* write all non empty display filters (until maximum count)
548 * of the combo box GList to the user's recent file */
550 dfilter_recent_combo_write_all(FILE *rf) {
551 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
552 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
557 /* write all non empty display filter strings to the recent file (until max count) */
558 li = g_list_first(dfilter_list);
559 while ( li && (max_count++ <= dfilter_combo_max_recent) ) {
560 if (strlen(li->data)) {
561 fprintf (rf, RECENT_KEY_DISPLAY_FILTER ": %s\n", (char *)li->data);
567 /* empty the combobox entry field */
569 dfilter_combo_add_empty(void) {
570 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
572 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), "");
576 /* add a display filter coming from the user's recent file to the dfilter combo box */
578 dfilter_combo_add_recent(gchar *s) {
579 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
583 if (!dfilter_combo_add(filter_cm, dup)) {
592 /* call cf_filter_packets() and add this filter string to the recent filter list */
594 main_filter_packets(capture_file *cf, const gchar *dftext, gboolean force)
596 GtkCombo *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
597 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
599 gboolean add_filter = TRUE;
600 gboolean free_filter = TRUE;
602 cf_status_t cf_status;
604 /* we'll crash later on if dftext is NULL */
605 g_assert(dftext != NULL);
607 s = g_strdup(dftext);
609 /* GtkCombos don't let us get at their list contents easily, so we maintain
610 our own filter list, and feed it to gtk_combo_set_popdown_strings when
611 a new filter is added. */
612 cf_status = cf_filter_packets(cf, s, force);
613 if (cf_status == CF_OK) {
614 li = g_list_first(dfilter_list);
616 if (li->data && strcmp(s, li->data) == 0)
622 /* trim list size first */
623 while (g_list_length(dfilter_list) >= dfilter_combo_max_recent) {
624 dfilter_list = g_list_remove(dfilter_list, g_list_first(dfilter_list)->data);
628 dfilter_list = g_list_append(dfilter_list, s);
629 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
630 gtk_combo_set_popdown_strings(filter_cm, dfilter_list);
631 gtk_entry_set_text(GTK_ENTRY(filter_cm->entry), g_list_last(dfilter_list)->data);
637 return (cf_status == CF_OK);
641 /* Run the current display filter on the current packet set, and
644 filter_activate_cb(GtkWidget *w _U_, gpointer data)
648 s = gtk_entry_get_text(GTK_ENTRY(data));
650 main_filter_packets(&cfile, s, FALSE);
653 /* redisplay with no display filter */
655 filter_reset_cb(GtkWidget *w, gpointer data _U_)
657 GtkWidget *filter_te = NULL;
659 if ((filter_te = OBJECT_GET_DATA(w, E_DFILTER_TE_KEY))) {
660 gtk_entry_set_text(GTK_ENTRY(filter_te), "");
662 main_filter_packets(&cfile, "", FALSE);
665 /* mark as reference time frame */
667 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
671 frame->flags.ref_time=1;
673 frame->flags.ref_time=0;
675 cf_reftime_packets(&cfile);
679 GtkWidget *reftime_dialog = NULL;
681 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
685 timestamp_set_type(TS_RELATIVE);
686 recent.gui_time_format = TS_RELATIVE;
687 cf_change_time_formats(&cfile);
692 g_assert_not_reached();
695 if (cfile.current_frame) {
696 /* XXX hum, should better have a "cfile->current_row" here ... */
697 set_frame_reftime(!cfile.current_frame->flags.ref_time,
699 packet_list_find_row_from_data(cfile.current_frame));
705 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
710 if (cfile.current_frame) {
711 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
712 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
713 PRIMARY_TEXT_START "Switch to the appropriate Time Display Format?" PRIMARY_TEXT_END "\n\n"
714 "Time References don't work well with the currently selected Time Display Format.\n\n"
715 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?");
716 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
718 /* XXX hum, should better have a "cfile->current_row" here ... */
719 set_frame_reftime(!cfile.current_frame->flags.ref_time,
721 packet_list_find_row_from_data(cfile.current_frame));
725 case REFTIME_FIND_NEXT:
726 find_previous_next_frame_with_filter("frame.ref_time", FALSE);
728 case REFTIME_FIND_PREV:
729 find_previous_next_frame_with_filter("frame.ref_time", TRUE);
735 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
737 find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
741 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
743 find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
746 #if GTK_MAJOR_VERSION < 2
748 tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_,
749 gpointer user_data _U_)
752 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
756 gchar *help_str = NULL;
757 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
759 gboolean has_blurb = FALSE;
760 guint length = 0, byte_len;
761 GtkWidget *byte_view;
762 const guint8 *byte_data;
763 #if GTK_MAJOR_VERSION >= 2
768 #if GTK_MAJOR_VERSION >= 2
769 /* if nothing is selected */
770 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
773 * Which byte view is displaying the current protocol tree
776 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
777 if (byte_view == NULL)
780 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
781 if (byte_data == NULL)
784 cf_unselect_field(&cfile);
785 packet_hex_print(byte_view, byte_data,
786 cfile.current_frame, NULL, byte_len);
789 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
792 finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
796 set_notebook_page(byte_nb_ptr, finfo->ds_tvb);
798 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
799 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
800 g_assert(byte_data != NULL);
802 cfile.finfo_selected = finfo;
803 set_menus_for_selected_tree_row(&cfile);
806 if (finfo->hfinfo->blurb != NULL &&
807 finfo->hfinfo->blurb[0] != '\0') {
809 length = strlen(finfo->hfinfo->blurb);
811 length = strlen(finfo->hfinfo->name);
813 if (finfo->length == 0) {
815 } else if (finfo->length == 1) {
816 strcpy (len_str, ", 1 byte");
818 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo->length);
820 statusbar_pop_field_msg(); /* get rid of current help msg */
822 help_str = g_strdup_printf("%s (%s)%s",
823 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
824 finfo->hfinfo->abbrev, len_str);
825 statusbar_push_field_msg(help_str);
829 * Don't show anything if the field name is zero-length;
830 * the pseudo-field for "proto_tree_add_text()" is such
831 * a field, and we don't want "Text (text)" showing up
832 * on the status line if you've selected such a field.
834 * XXX - there are zero-length fields for which we *do*
835 * want to show the field name.
837 * XXX - perhaps the name and abbrev field should be null
838 * pointers rather than null strings for that pseudo-field,
839 * but we'd have to add checks for null pointers in some
840 * places if we did that.
842 * Or perhaps protocol tree items added with
843 * "proto_tree_add_text()" should have -1 as the field index,
844 * with no pseudo-field being used, but that might also
845 * require special checks for -1 to be added.
847 statusbar_push_field_msg("");
851 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
855 #if GTK_MAJOR_VERSION < 2
857 tree_view_unselect_row_cb(GtkCTree *ctree _U_, GList *node _U_, gint column _U_,
858 gpointer user_data _U_)
860 GtkWidget *byte_view;
865 * Which byte view is displaying the current protocol tree
868 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
869 if (byte_view == NULL)
872 data = get_byte_view_data_and_length(byte_view, &len);
876 cf_unselect_field(&cfile);
877 packet_hex_print(byte_view, data, cfile.current_frame, NULL, len);
881 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
883 collapse_all_tree(cfile.edt->tree, tree_view);
886 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
888 expand_all_tree(cfile.edt->tree, tree_view);
891 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
892 #if GTK_MAJOR_VERSION < 2
898 #if GTK_MAJOR_VERSION < 2
899 node = gtk_ctree_find_by_row_data(GTK_CTREE(tree_view), NULL, cfile.finfo_selected);
901 /* the mouse position is at an entry, expand that one */
902 gtk_ctree_expand_recursive(GTK_CTREE(tree_view), node);
905 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view), cfile.finfo_selected);
907 /* the mouse position is at an entry, expand that one */
908 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view), path, TRUE);
909 gtk_tree_path_free(path);
914 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
915 if (cfile.edt->tree) {
916 guint32 tmp = g_resolv_flags;
917 g_resolv_flags = RESOLV_ALL;
918 proto_tree_draw(cfile.edt->tree, tree_view);
919 g_resolv_flags = tmp;
924 * Push a message referring to file access onto the statusbar.
927 statusbar_push_file_msg(gchar *msg)
929 /*g_warning("statusbar_push: %s", msg);*/
930 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
934 * Pop a message referring to file access off the statusbar.
937 statusbar_pop_file_msg(void)
939 /*g_warning("statusbar_pop");*/
940 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
944 * XXX - do we need multiple statusbar contexts?
948 * Push a message referring to the currently-selected field onto the statusbar.
951 statusbar_push_field_msg(gchar *msg)
953 gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
957 * Pop a message referring to the currently-selected field off the statusbar.
960 statusbar_pop_field_msg(void)
962 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
966 * update the packets statusbar to the current values
968 void packets_bar_update(void)
972 /* remove old status */
975 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
978 /* do we have any packets? */
980 if(cfile.drops_known) {
981 packets_str = g_strdup_printf(" P: %u D: %u M: %u Drops: %u",
982 cfile.count, cfile.displayed_count, cfile.marked_count, cfile.drops);
984 packets_str = g_strdup_printf(" P: %u D: %u M: %u",
985 cfile.count, cfile.displayed_count, cfile.marked_count);
988 packets_str = g_strdup(" No Packets");
990 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str);
995 main_set_for_capture_file(gboolean have_capture_file_in)
997 have_capture_file = have_capture_file_in;
999 main_widgets_show_or_hide();
1005 /* get the current geometry, before writing it to disk */
1006 main_save_window_geometry(top_level);
1008 /* write user's recent file to disk
1009 * It is no problem to write this file, even if we do not quit */
1012 /* XXX - should we check whether the capture file is an
1013 unsaved temporary file for a live capture and, if so,
1014 pop up a "do you want to exit without saving the capture
1015 file?" dialog, and then just return, leaving said dialog
1016 box to forcibly quit if the user clicks "OK"?
1018 If so, note that this should be done in a subroutine that
1019 returns TRUE if we do so, and FALSE otherwise, and if it
1020 returns TRUE we should return TRUE without nuking anything.
1022 Note that, if we do that, we might also want to check if
1023 an "Update list of packets in real time" capture is in
1024 progress and, if so, ask whether they want to terminate
1025 the capture and discard it, and return TRUE, before nuking
1026 any child capture, if they say they don't want to do so. */
1029 /* Nuke any child capture in progress. */
1030 capture_kill_child(capture_opts);
1033 /* Are we in the middle of reading a capture? */
1034 if (cfile.state == FILE_READ_IN_PROGRESS) {
1035 /* Yes, so we can't just close the file and quit, as
1036 that may yank the rug out from under the read in
1037 progress; instead, just set the state to
1038 "FILE_READ_ABORTED" and return - the code doing the read
1039 will check for that and, if it sees that, will clean
1041 cfile.state = FILE_READ_ABORTED;
1043 /* Say that the window should *not* be deleted;
1044 that'll be done by the code that cleans up. */
1047 /* Close any capture file we have open; on some OSes, you
1048 can't unlink a temporary capture file if you have it
1050 "cf_close()" will unlink it after closing it if
1051 it's a temporary file.
1053 We do this here, rather than after the main loop returns,
1054 as, after the main loop returns, the main window may have
1055 been destroyed (if this is called due to a "destroy"
1056 even on the main window rather than due to the user
1057 selecting a menu item), and there may be a crash
1058 or other problem when "cf_close()" tries to
1059 clean up stuff in the main window.
1061 XXX - is there a better place to put this?
1062 Or should we have a routine that *just* closes the
1063 capture file, and doesn't do anything with the UI,
1064 which we'd call here, and another routine that
1065 calls that routine and also cleans up the UI, which
1066 we'd call elsewhere? */
1069 /* Exit by leaving the main loop, so that any quit functions
1070 we registered get called. */
1073 /* Say that the window should be deleted. */
1079 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1083 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1084 #if GTK_MAJOR_VERSION >= 2
1085 gtk_window_present(GTK_WINDOW(top_level));
1087 /* user didn't saved his current file, ask him */
1088 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1089 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1090 "If you quit the program without saving, your capture data will be discarded.");
1091 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1094 /* unchanged file, just exit */
1095 /* "main_do_quit()" indicates whether the main window should be deleted. */
1096 return main_do_quit();
1103 main_load_window_geometry(GtkWidget *widget)
1105 window_geometry_t geom;
1107 geom.set_pos = prefs.gui_geometry_save_position;
1108 geom.x = recent.gui_geometry_main_x;
1109 geom.y = recent.gui_geometry_main_y;
1110 geom.set_size = prefs.gui_geometry_save_size;
1111 if (recent.gui_geometry_main_width > 0 &&
1112 recent.gui_geometry_main_height > 0) {
1113 geom.width = recent.gui_geometry_main_width;
1114 geom.height = recent.gui_geometry_main_height;
1115 geom.set_maximized = prefs.gui_geometry_save_maximized;
1117 /* We assume this means the width and height weren't set in
1118 the "recent" file (or that there is no "recent" file),
1119 and weren't set to a default value, so we don't set the
1120 size. (The "recent" file code rejects non-positive width
1121 and height values.) */
1122 geom.set_size = FALSE;
1124 geom.maximized = recent.gui_geometry_main_maximized;
1126 window_set_geometry(widget, &geom);
1128 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1129 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1130 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
1131 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1132 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_status_pane)
1133 gtk_paned_set_position(GTK_PANED(status_pane), recent.gui_geometry_status_pane);
1138 main_save_window_geometry(GtkWidget *widget)
1140 window_geometry_t geom;
1142 window_get_geometry(widget, &geom);
1144 if (prefs.gui_geometry_save_position) {
1145 recent.gui_geometry_main_x = geom.x;
1146 recent.gui_geometry_main_y = geom.y;
1149 if (prefs.gui_geometry_save_size) {
1150 recent.gui_geometry_main_width = geom.width,
1151 recent.gui_geometry_main_height = geom.height;
1154 #if GTK_MAJOR_VERSION >= 2
1155 if(prefs.gui_geometry_save_maximized) {
1156 recent.gui_geometry_main_maximized = geom.maximized;
1159 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1160 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1161 recent.gui_geometry_status_pane = gtk_paned_get_position(GTK_PANED(status_pane));
1165 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1169 /* save file first */
1170 file_save_as_cmd(after_save_exit, NULL);
1172 case(ESD_BTN_DONT_SAVE):
1175 case(ESD_BTN_CANCEL):
1178 g_assert_not_reached();
1183 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1187 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1188 /* user didn't saved his current file, ask him */
1189 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1190 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1191 "If you quit the program without saving, your capture data will be discarded.");
1192 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1194 /* unchanged file, just exit */
1200 print_usage(gboolean print_ver) {
1210 fprintf(output, "Wireshark " VERSION "%s\n"
1211 "Interactively dump and analyze network traffic.\n"
1212 "See http://www.wireshark.org for more information.\n"
1215 wireshark_svnversion, get_copyright_info());
1219 fprintf(output, "\n");
1220 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1221 fprintf(output, "\n");
1224 fprintf(output, "Capture interface:\n");
1225 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1226 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1227 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1228 fprintf(output, " -p don't capture in promiscuous mode\n");
1229 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1230 fprintf(output, " -Q quit Wireshark after capturing\n");
1231 fprintf(output, " -S update packet display when new packets are captured\n");
1232 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1234 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1236 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1237 fprintf(output, " -D print list of interfaces and exit\n");
1238 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1239 fprintf(output, "\n");
1240 fprintf(output, "Capture stop conditions:\n");
1241 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1242 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1243 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1244 fprintf(output, " files:NUM - stop after NUM files\n");
1245 /*fprintf(output, "\n");*/
1246 fprintf(output, "Capture output:\n");
1247 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1248 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1249 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1250 #endif /* HAVE_LIBPCAP */
1252 /*fprintf(output, "\n");*/
1253 fprintf(output, "Input file:\n");
1254 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1256 fprintf(output, "\n");
1257 fprintf(output, "Processing:\n");
1258 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1259 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1260 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1262 fprintf(output, "\n");
1263 fprintf(output, "User interface:\n");
1264 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1265 fprintf(output, " -m <font> set the font name used for most text\n");
1266 fprintf(output, " -t ad|a|r|d|e output format of time stamps (def: r: rel. to first)\n");
1267 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1268 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1270 fprintf(output, "\n");
1271 fprintf(output, "Output:\n");
1272 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1274 fprintf(output, "\n");
1275 fprintf(output, "Miscellaneous:\n");
1276 fprintf(output, " -h display this help and exit\n");
1277 fprintf(output, " -v display version info and exit\n");
1278 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1280 fprintf(output, " --display=DISPLAY X display to use\n");
1295 printf(PACKAGE " " VERSION "%s\n"
1302 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1303 runtime_info_str->str);
1311 * Report an error in command-line arguments.
1312 * Creates a console on Windows.
1313 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1314 * terminal isn't the standard error?
1317 cmdarg_err(const char *fmt, ...)
1325 fprintf(stderr, "wireshark: ");
1326 vfprintf(stderr, fmt, ap);
1327 fprintf(stderr, "\n");
1332 * Report additional information for an error in command-line arguments.
1333 * Creates a console on Windows.
1334 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1335 * terminal isn't the standard error?
1338 cmdarg_err_cont(const char *fmt, ...)
1346 vfprintf(stderr, fmt, ap);
1347 fprintf(stderr, "\n");
1351 #if defined(_WIN32) || GTK_MAJOR_VERSION < 2 || ! defined USE_THREADS
1353 Once every 3 seconds we get a callback here which we use to update
1354 the tap extensions. Since Gtk1 is single threaded we dont have to
1355 worry about any locking or critical regions.
1358 update_cb(gpointer data _U_)
1360 draw_tap_listeners(FALSE);
1365 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1366 use threads all updte_thread_mutex can be dropped and protect/unprotect
1367 would just be empty functions.
1369 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1370 gtk1-wireshark and it will just work.
1372 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1374 update_thread(gpointer data _U_)
1378 g_get_current_time(&tv1);
1379 g_static_mutex_lock(&update_thread_mutex);
1380 gdk_threads_enter();
1381 draw_tap_listeners(FALSE);
1382 gdk_threads_leave();
1383 g_static_mutex_unlock(&update_thread_mutex);
1385 g_get_current_time(&tv2);
1386 if( ((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) >
1387 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1388 g_usleep(((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) -
1389 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1396 protect_thread_critical_region(void)
1398 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1399 g_static_mutex_lock(&update_thread_mutex);
1403 unprotect_thread_critical_region(void)
1405 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1406 g_static_mutex_unlock(&update_thread_mutex);
1410 /* Set the file name in the status line, in the name for the main window,
1411 and in the name for the main window's icon. */
1413 set_display_filename(capture_file *cf)
1415 const gchar *name_ptr;
1420 name_ptr = cf_get_display_name(cf);
1422 if (!cf->is_tempfile && cf->filename) {
1423 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1424 add_menu_recent_capture_file(cf->filename);
1427 /* convert file size */
1428 if (cf->f_datalen/1024/1024 > 10) {
1429 size_str = g_strdup_printf("%lld MB", cf->f_datalen/1024/1024);
1430 } else if (cf->f_datalen/1024 > 10) {
1431 size_str = g_strdup_printf("%lld KB", cf->f_datalen/1024);
1433 size_str = g_strdup_printf("%lld Bytes", cf->f_datalen);
1438 /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1439 status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu [Expert: %s]",
1440 (cf->filename) ? cf->filename : "", size_str,
1441 (long)cf->elapsed_time.secs/3600,
1442 (long)cf->elapsed_time.secs%3600/60,
1443 (long)cf->elapsed_time.secs%60,
1444 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1446 status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu",
1447 (cf->filename) ? cf->filename : "", size_str,
1448 (long)cf->elapsed_time.secs/3600,
1449 (long)cf->elapsed_time.secs%3600/60,
1450 (long)cf->elapsed_time.secs%60);
1452 statusbar_push_file_msg(status_msg);
1456 win_name = g_strdup_printf("%s - Wireshark", name_ptr);
1457 set_main_window_name(win_name);
1461 GtkWidget *close_dlg = NULL;
1464 main_cf_cb_file_closing(capture_file *cf)
1467 /* if we have more than 10000 packets, show a splash screen while closing */
1468 /* XXX - don't know a better way to decide wether to show or not,
1469 * as most of the time is spend in a single eth_clist_clear function,
1470 * so we can't use a progress bar here! */
1471 if(cf->count > 10000) {
1472 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1473 "%sClosing file!%s\n\nPlease wait ...",
1474 simple_dialog_primary_start(),
1475 simple_dialog_primary_end());
1476 #if GTK_MAJOR_VERSION >= 2
1477 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1479 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER);
1483 /* Destroy all windows, which refer to the
1484 capture file we're closing. */
1485 destroy_packet_wins();
1486 file_save_as_destroy();
1488 /* Clear any file-related status bar messages.
1489 XXX - should be "clear *ALL* file-related status bar messages;
1490 will there ever be more than one on the stack? */
1491 statusbar_pop_file_msg();
1493 /* Restore the standard title bar message. */
1494 set_main_window_name("The Wireshark Network Analyzer");
1496 /* Disable all menu items that make sense only if you have a capture. */
1497 set_menus_for_capture_file(NULL);
1498 set_menus_for_captured_packets(FALSE);
1499 set_menus_for_selected_packet(cf);
1500 set_menus_for_capture_in_progress(FALSE);
1501 set_menus_for_selected_tree_row(cf);
1503 /* Set up main window for no capture file. */
1504 main_set_for_capture_file(FALSE);
1506 main_window_update();
1510 main_cf_cb_file_closed(capture_file *cf _U_)
1512 if(close_dlg != NULL) {
1513 splash_destroy(close_dlg);
1517 /* go back to "No packets" */
1518 packets_bar_update();
1522 main_cf_cb_file_read_start(capture_file *cf)
1524 const gchar *name_ptr;
1527 name_ptr = get_basename(cf->filename);
1529 load_msg = g_strdup_printf(" Loading: %s", name_ptr);
1530 statusbar_push_file_msg(load_msg);
1533 /* Set up main window for a capture file. */
1534 main_set_for_capture_file(TRUE);
1538 main_cf_cb_file_read_finished(capture_file *cf)
1540 statusbar_pop_file_msg();
1541 set_display_filename(cf);
1543 /* Enable menu items that make sense if you have a capture file you've
1544 finished reading. */
1545 set_menus_for_capture_file(cf);
1547 /* Enable menu items that make sense if you have some captured packets. */
1548 set_menus_for_captured_packets(TRUE);
1551 #if GTK_MAJOR_VERSION >= 2
1552 GList *icon_list_create(
1553 const char **icon16_xpm,
1554 const char **icon32_xpm,
1555 const char **icon48_xpm,
1556 const char **icon64_xpm)
1558 GList *icon_list = NULL;
1559 GdkPixbuf * pixbuf16;
1560 GdkPixbuf * pixbuf32;
1561 GdkPixbuf * pixbuf48;
1562 GdkPixbuf * pixbuf64;
1565 if(icon16_xpm != NULL) {
1566 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1568 icon_list = g_list_append(icon_list, pixbuf16);
1571 if(icon32_xpm != NULL) {
1572 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1574 icon_list = g_list_append(icon_list, pixbuf32);
1577 if(icon48_xpm != NULL) {
1578 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1580 icon_list = g_list_append(icon_list, pixbuf48);
1583 if(icon64_xpm != NULL) {
1584 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1586 icon_list = g_list_append(icon_list, pixbuf64);
1595 main_cf_cb_live_capture_prepared(capture_options *capture_opts)
1598 #if GTK_MAJOR_VERSION >= 2
1599 static GList *icon_list = NULL;
1603 if(capture_opts->iface) {
1604 title = g_strdup_printf("%s: Capturing - Wireshark",
1605 get_interface_descriptive_name(capture_opts->iface));
1607 title = g_strdup_printf("Capturing - Wireshark");
1609 set_main_window_name(title);
1612 #if GTK_MAJOR_VERSION >= 2
1613 if(icon_list == NULL) {
1614 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1616 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1619 /* Disable menu items that make no sense if you're currently running
1621 set_menus_for_capture_in_progress(TRUE);
1623 /* update statusbar */
1624 statusbar_push_file_msg("Waiting for capture input data ...");
1626 /* Don't set up main window for a capture file. */
1627 main_set_for_capture_file(FALSE);
1631 main_cf_cb_live_capture_update_started(capture_options *capture_opts)
1636 /* We've done this in "prepared" above, but it will be cleared while
1637 switching to the next multiple file. */
1638 if(capture_opts->iface) {
1639 title = g_strdup_printf("%s: Capturing - Wireshark",
1640 get_interface_descriptive_name(capture_opts->iface));
1642 title = g_strdup_printf("Capturing - Wireshark");
1644 set_main_window_name(title);
1647 set_menus_for_capture_in_progress(TRUE);
1649 /* Enable menu items that make sense if you have some captured
1650 packets (yes, I know, we don't have any *yet*). */
1651 set_menus_for_captured_packets(TRUE);
1653 statusbar_pop_file_msg();
1655 if(capture_opts->iface) {
1656 capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1657 get_interface_descriptive_name(capture_opts->iface),
1658 (capture_opts->save_file) ? capture_opts->save_file : "");
1660 capture_msg = g_strdup_printf(" <live capture in progress> to file: %s",
1661 (capture_opts->save_file) ? capture_opts->save_file : "");
1664 statusbar_push_file_msg(capture_msg);
1666 g_free(capture_msg);
1668 /* Set up main window for a capture file. */
1669 main_set_for_capture_file(TRUE);
1673 main_cf_cb_live_capture_update_continue(capture_file *cf)
1678 statusbar_pop_file_msg();
1681 /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1682 if (cf->f_datalen/1024/1024 > 10) {
1683 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB [Expert: %s]",
1684 get_interface_descriptive_name(capture_opts->iface),
1685 capture_opts->save_file,
1686 cf->f_datalen/1024/1024,
1687 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1688 } else if (cf->f_datalen/1024 > 10) {
1689 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB [Expert: %s]",
1690 get_interface_descriptive_name(capture_opts->iface),
1691 capture_opts->save_file,
1693 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1695 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes [Expert: %s]",
1696 get_interface_descriptive_name(capture_opts->iface),
1697 capture_opts->save_file,
1699 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1702 if (cf->f_datalen/1024/1024 > 10) {
1703 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB",
1704 get_interface_descriptive_name(capture_opts->iface),
1705 capture_opts->save_file,
1706 cf->f_datalen/1024/1024);
1707 } else if (cf->f_datalen/1024 > 10) {
1708 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB",
1709 get_interface_descriptive_name(capture_opts->iface),
1710 capture_opts->save_file,
1711 cf->f_datalen/1024);
1713 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes",
1714 get_interface_descriptive_name(capture_opts->iface),
1715 capture_opts->save_file,
1719 statusbar_push_file_msg(capture_msg);
1722 GtkWidget * stop_dlg = NULL;
1725 main_cf_cb_live_capture_update_finished(capture_file *cf)
1727 #if GTK_MAJOR_VERSION >= 2
1728 static GList *icon_list = NULL;
1731 if(stop_dlg != NULL) {
1732 simple_dialog_close(stop_dlg);
1736 /* Pop the "<live capture in progress>" message off the status bar. */
1737 statusbar_pop_file_msg();
1739 set_display_filename(cf);
1741 /* Enable menu items that make sense if you're not currently running
1743 set_menus_for_capture_in_progress(FALSE);
1745 /* Enable menu items that make sense if you have a capture file
1746 you've finished reading. */
1747 set_menus_for_capture_file(cf);
1749 /* Set up main window for a capture file. */
1750 main_set_for_capture_file(TRUE);
1752 #if GTK_MAJOR_VERSION >= 2
1753 if(icon_list == NULL) {
1754 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1756 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1759 if(capture_opts->quit_after_cap) {
1760 /* command line asked us to quit after the capture */
1761 /* don't pop up a dialog to ask for unsaved files etc. */
1767 main_cf_cb_live_capture_fixed_started(capture_options *capture_opts)
1772 /* Enable menu items that make sense if you have some captured
1773 packets (yes, I know, we don't have any *yet*). */
1774 /*set_menus_for_captured_packets(TRUE);*/
1776 statusbar_pop_file_msg();
1778 capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1779 get_interface_descriptive_name(capture_opts->iface),
1780 (capture_opts->save_file) ? capture_opts->save_file : "");
1782 statusbar_push_file_msg(capture_msg);
1783 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " P: 0");
1785 g_free(capture_msg);
1787 /* Don't set up main window for a capture file. */
1788 main_set_for_capture_file(FALSE);
1792 main_cf_cb_live_capture_fixed_continue(capture_file *cf)
1797 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1799 capture_msg = g_strdup_printf(" P: %u",
1800 cf_get_packet_count(cf));
1802 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, capture_msg);
1804 g_free(capture_msg);
1808 main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_)
1810 #if GTK_MAJOR_VERSION >= 2
1811 static GList *icon_list = NULL;
1814 if(stop_dlg != NULL) {
1815 simple_dialog_close(stop_dlg);
1819 /* Pop the "<live capture in progress>" message off the status bar. */
1820 statusbar_pop_file_msg();
1822 /* Pop the "<capturing>" message off the status bar */
1823 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1825 /*set_display_filename(cf);*/
1827 /* Enable menu items that make sense if you're not currently running
1829 set_menus_for_capture_in_progress(FALSE);
1831 /* Restore the standard title bar message */
1832 /* (just in case we have trouble opening the capture file). */
1833 set_main_window_name("The Wireshark Network Analyzer");
1835 #if GTK_MAJOR_VERSION >= 2
1836 if(icon_list == NULL) {
1837 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1839 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1842 /* We don't have loaded the capture file, this will be done later.
1843 * For now we still have simply a blank screen. */
1845 if(capture_opts->quit_after_cap) {
1846 /* command line asked us to quit after the capture */
1847 /* don't pop up a dialog to ask for unsaved files etc. */
1853 main_cf_cb_live_capture_stopping(capture_file *cf _U_)
1855 /* Beware: this state won't be called, if the capture child
1856 * closes the capturing on it's own! */
1858 /* XXX - the time to stop the capture has been reduced (this was only a
1859 * problem on Win32 because of the capture piping), so showing a splash
1860 * isn't really necessary any longer. Unfortunately, the GTKClist packet
1861 * list seems to have problems updating after the dialog is closed, so
1862 * this was disabled here. */
1863 stop_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE, "%sCapture stop!%s\n\nPlease wait ...",
1864 simple_dialog_primary_start(), simple_dialog_primary_end());
1865 #if GTK_MAJOR_VERSION >= 2
1866 gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1868 gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER);
1876 main_cf_cb_packet_selected(gpointer data)
1878 capture_file *cf = data;
1880 /* Display the GUI protocol tree and hex dump.
1881 XXX - why do we dump core if we call "proto_tree_draw()"
1882 before calling "add_byte_views()"? */
1883 add_main_byte_views(cf->edt);
1884 main_proto_tree_draw(cf->edt->tree);
1886 /* The user is searching for a string in the data or a hex value,
1887 * highlight the field that is found in the tree and hex displays. */
1888 #if GTK_MAJOR_VERSION < 2
1889 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1890 highlight_field(cf->edt->tvb, cfile.search_pos,
1891 (GtkCTree *)tree_view, cf->edt->tree);
1893 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1894 highlight_field(cf->edt->tvb, cfile.search_pos,
1895 (GtkTreeView *)tree_view, cf->edt->tree);
1897 cfile.search_pos = 0; /* Reset the position */
1900 /* A packet is selected. */
1901 set_menus_for_selected_packet(cf);
1905 main_cf_cb_packet_unselected(capture_file *cf)
1907 /* Clear out the display of that packet. */
1908 clear_tree_and_hex_views();
1910 /* No packet is selected. */
1911 set_menus_for_selected_packet(cf);
1915 main_cf_cb_field_unselected(capture_file *cf)
1917 statusbar_pop_field_msg();
1918 set_menus_for_selected_tree_row(cf);
1922 main_cf_cb_file_safe_started(gchar * filename)
1924 const gchar *name_ptr;
1927 name_ptr = get_basename(filename);
1929 save_msg = g_strdup_printf(" Saving: %s...", name_ptr);
1931 statusbar_push_file_msg(save_msg);
1936 main_cf_cb_file_safe_finished(gpointer data _U_)
1938 /* Pop the "Saving:" message off the status bar. */
1939 statusbar_pop_file_msg();
1943 main_cf_cb_file_safe_failed(gpointer data _U_)
1945 /* Pop the "Saving:" message off the status bar. */
1946 statusbar_pop_file_msg();
1950 main_cf_cb_file_safe_reload_finished(gpointer data _U_)
1952 set_menus_for_capture_file(&cfile);
1955 static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1958 case(cf_cb_file_closing):
1959 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1960 main_cf_cb_file_closing(data);
1962 case(cf_cb_file_closed):
1963 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1964 main_cf_cb_file_closed(data);
1966 case(cf_cb_file_read_start):
1967 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read start");
1968 main_cf_cb_file_read_start(data);
1970 case(cf_cb_file_read_finished):
1971 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1972 main_cf_cb_file_read_finished(data);
1975 case(cf_cb_live_capture_prepared):
1976 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1977 main_cf_cb_live_capture_prepared(data);
1979 case(cf_cb_live_capture_update_started):
1980 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1981 main_cf_cb_live_capture_update_started(data);
1983 case(cf_cb_live_capture_update_continue):
1984 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1985 main_cf_cb_live_capture_update_continue(data);
1987 case(cf_cb_live_capture_update_finished):
1988 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1989 main_cf_cb_live_capture_update_finished(data);
1991 case(cf_cb_live_capture_fixed_started):
1992 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1993 main_cf_cb_live_capture_fixed_started(data);
1995 case(cf_cb_live_capture_fixed_continue):
1996 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");
1997 main_cf_cb_live_capture_fixed_continue(data);
1999 case(cf_cb_live_capture_fixed_finished):
2000 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
2001 main_cf_cb_live_capture_fixed_finished(data);
2003 case(cf_cb_live_capture_stopping):
2004 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
2005 main_cf_cb_live_capture_stopping(data);
2008 case(cf_cb_packet_selected):
2009 main_cf_cb_packet_selected(data);
2011 case(cf_cb_packet_unselected):
2012 main_cf_cb_packet_unselected(data);
2014 case(cf_cb_field_unselected):
2015 main_cf_cb_field_unselected(data);
2017 case(cf_cb_file_safe_started):
2018 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe started");
2019 main_cf_cb_file_safe_started(data);
2021 case(cf_cb_file_safe_finished):
2022 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe finished");
2023 main_cf_cb_file_safe_finished(data);
2025 case(cf_cb_file_safe_reload_finished):
2026 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: reload finished");
2027 main_cf_cb_file_safe_reload_finished(data);
2029 case(cf_cb_file_safe_failed):
2030 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe failed");
2031 main_cf_cb_file_safe_failed(data);
2034 g_warning("main_cf_callback: event %u unknown", event);
2035 g_assert_not_reached();
2040 get_gui_compiled_info(GString *str)
2042 get_epan_compiled_version_info(str);
2044 g_string_append(str, ", ");
2045 #ifdef HAVE_LIBPORTAUDIO
2046 #ifdef PORTAUDIO_API_1
2047 g_string_append(str, "with PortAudio <= V18");
2048 #else /* PORTAUDIO_API_1 */
2049 g_string_append(str, "with PortAudio ");
2050 g_string_append(str, Pa_GetVersionText());
2051 #endif /* PORTAUDIO_API_1 */
2052 #else /* HAVE_LIBPORTAUDIO */
2053 g_string_append(str, "without PortAudio");
2054 #endif /* HAVE_LIBPORTAUDIO */
2056 g_string_append(str, ", ");
2058 get_compiled_airpcap_version(str);
2060 g_string_append(str, "without AirPcap");
2065 get_gui_runtime_info(GString *str
2066 #ifndef HAVE_AIRPCAP
2072 g_string_append(str, ", ");
2073 get_runtime_airpcap_version(str);
2077 g_string_append(str, ", ");
2078 u3_runtime_info(str);
2083 /* And now our feature presentation... [ fade to music ] */
2085 main(int argc, char *argv[])
2087 char *init_progfile_dir_error;
2091 extern char *optarg;
2092 gboolean arg_error = FALSE;
2100 char *gpf_path, *pf_path;
2101 char *cf_path, *df_path;
2102 char *gdp_path, *dp_path;
2103 int gpf_open_errno, gpf_read_errno;
2104 int pf_open_errno, pf_read_errno;
2105 int cf_open_errno, df_open_errno;
2106 int gdp_open_errno, gdp_read_errno;
2107 int dp_open_errno, dp_read_errno;
2110 gboolean start_capture = FALSE;
2112 gboolean capture_option_specified = FALSE;
2114 gint pl_size = 280, tv_size = 95, bv_size = 75;
2115 gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
2116 dfilter_t *rfcode = NULL;
2117 gboolean rfilter_parse_failed = FALSE;
2120 GtkWidget *splash_win = NULL;
2121 GLogLevelFlags log_flags;
2122 guint go_to_packet = 0;
2128 /*gchar *cant_get_if_list_errstr;*/
2131 #define OPTSTRING_INIT "a:b:c:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
2133 #if defined HAVE_LIBPCAP && defined _WIN32
2134 #define OPTSTRING_WIN32 "B:"
2136 #define OPTSTRING_WIN32 ""
2139 char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
2140 OPTSTRING_INIT OPTSTRING_WIN32;
2142 #ifdef HAVE_AIRPDCAP
2143 /* Davide Schiera (2006-11-18): init AirPDcap context */
2144 AirPDcapInitContext(&airpdcap_ctx);
2145 /* Davide Schiera (2006-11-18) ------------------------------------------- */
2149 * Attempt to get the pathname of the executable file.
2151 init_progfile_dir_error = init_progfile_dir(argv[0]);
2154 * Get credential information for later use.
2156 get_credential_info();
2159 * Now attempt to get the pathname of the plugins.
2163 /* initialize the funnel mini-api */
2164 initialize_funnel_ops();
2167 /* Load wpcap if possible. Do this before collecting the run-time version information */
2170 /* ... and also load the packet.dll from wpcap */
2171 wpcap_packet_load();
2174 /* Load the airpcap.dll. This must also be done before collecting
2175 * run-time version information. */
2176 airpcap_dll_ret_val = load_airpcap();
2178 switch (airpcap_dll_ret_val) {
2179 case AIRPCAP_DLL_OK:
2180 /* load the airpcap interfaces */
2181 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2183 if (airpcap_if_list == NULL && err == CANT_GET_AIRPCAP_INTERFACE_LIST) {
2184 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
2187 /* select the first ad default (THIS SHOULD BE CHANGED) */
2188 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2193 * XXX - Maybe we need to warn the user if one of the following happens???
2195 case AIRPCAP_DLL_OLD:
2196 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2199 case AIRPCAP_DLL_ERROR:
2200 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2203 case AIRPCAP_DLL_NOT_FOUND:
2204 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2208 #endif /* HAVE_AIRPCAP */
2210 /* Start windows sockets */
2211 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2214 /* Assemble the compile-time version information string */
2215 comp_info_str = g_string_new("Compiled ");
2217 g_string_append(comp_info_str, "with ");
2218 g_string_sprintfa(comp_info_str,
2219 #ifdef GTK_MAJOR_VERSION
2220 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
2223 "GTK+ (version unknown)");
2225 g_string_append(comp_info_str, ", ");
2227 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
2229 /* Assemble the run-time version information string */
2230 runtime_info_str = g_string_new("Running ");
2231 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2234 /* "pre-scan" the command line parameters, if we have "console only"
2235 parameters. We do this so we don't start GTK+ if we're only showing
2236 command-line help or version information.
2238 XXX - this pre-scan is doen before we start GTK+, so we haven't
2239 run gtk_init() on the arguments. That means that GTK+ arguments
2240 have not been removed from the argument list; those arguments
2241 begin with "--", and will be treated as an error by getopt().
2243 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2246 optind_initial = optind;
2247 while ((opt = getopt(argc, argv, optstring)) != -1) {
2249 case 'h': /* Print help and exit */
2253 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2254 status = filesystem_opt(opt, optarg);
2256 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2260 case 'v': /* Show version and exit */
2266 * Extension command line options have to be processed before
2267 * we call epan_init() as they are supposed to be used by dissectors
2268 * or taps very early in the registration process.
2272 case '?': /* Ignore errors - the "real" scan will catch them. */
2277 /* Init the "Open file" dialog directory */
2278 /* (do this after the path settings are processed) */
2279 set_last_open_dir(get_persdatafile_dir());
2281 /* Set getopt index back to initial value, so it will start with the
2282 first command line parameter again. Also reset opterr to 1, so that
2283 error messages are printed by getopt().
2285 XXX - this seems to work on most platforms, but time will tell.
2286 The Single UNIX Specification says "The getopt() function need
2287 not be reentrant", so this isn't guaranteed to work. The Mac
2288 OS X 10.4[.x] getopt() man page says
2290 In order to use getopt() to evaluate multiple sets of arguments, or to
2291 evaluate a single set of arguments multiple times, the variable optreset
2292 must be set to 1 before the second and each additional set of calls to
2293 getopt(), and the variable optind must be reinitialized.
2297 The optreset variable was added to make it possible to call the getopt()
2298 function multiple times. This is an extension to the IEEE Std 1003.2
2299 (``POSIX.2'') specification.
2301 which I think comes from one of the other BSDs.
2303 XXX - if we want to control all the command-line option errors, so
2304 that we can display them where we choose (e.g., in a window), we'd
2305 want to leave opterr as 0, and produce our own messages using optopt.
2306 We'd have to check the value of optopt to see if it's a valid option
2307 letter, in which case *presumably* the error is "this option requires
2308 an argument but none was specified", or not a valid option letter,
2309 in which case *presumably* the error is "this option isn't valid".
2310 Some versions of getopt() let you supply a option string beginning
2311 with ':', which means that getopt() will return ':' rather than '?'
2312 for "this option requires an argument but none was specified", but
2314 optind = optind_initial;
2317 /* Set the current locale according to the program environment.
2318 * We haven't localized anything, but some GTK widgets are localized
2319 * (the file selection dialogue, for example).
2320 * This also sets the C-language locale to the native environment. */
2323 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2324 gtk_init (&argc, &argv);
2326 cf_callback_add(main_cf_callback, NULL);
2328 #if GTK_MAJOR_VERSION < 2 && GTK_MINOR_VERSION < 3
2329 /* initialize our GTK eth_clist_type */
2330 init_eth_clist_type();
2333 /* Arrange that if we have no console window, and a GLib message logging
2334 routine is called to log a message, we pop up a console window.
2336 We do that by inserting our own handler for all messages logged
2337 to the default domain; that handler pops up a console if necessary,
2338 and then calls the default handler. */
2340 /* We might want to have component specific log levels later ... */
2344 G_LOG_LEVEL_CRITICAL|
2345 G_LOG_LEVEL_WARNING|
2346 G_LOG_LEVEL_MESSAGE|
2349 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2351 g_log_set_handler(NULL,
2353 console_log_handler, NULL /* user_data */);
2354 g_log_set_handler(LOG_DOMAIN_MAIN,
2356 console_log_handler, NULL /* user_data */);
2359 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2361 console_log_handler, NULL /* user_data */);
2362 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2364 console_log_handler, NULL /* user_data */);
2366 /* Set the initial values in the capture_opts. This might be overwritten
2367 by preference settings and then again by the command line parameters. */
2368 capture_opts_init(capture_opts, &cfile);
2370 capture_opts->snaplen = MIN_PACKET_SIZE;
2371 capture_opts->has_ring_num_files = TRUE;
2374 /* We won't come till here, if we had a "console only" command line parameter. */
2375 splash_win = splash_new("Loading Wireshark ...");
2376 if (init_progfile_dir_error != NULL) {
2377 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2378 "Can't get pathname of Wireshark: %s.\n"
2379 "It won't be possible to capture traffic.\n"
2380 "Report this to the Wireshark developers.",
2381 init_progfile_dir_error);
2382 g_free(init_progfile_dir_error);
2385 splash_update(splash_win, "Init dissectors ...");
2387 /* Register all dissectors; we must do this before checking for the
2388 "-G" flag, as the "-G" flag dumps information registered by the
2389 dissectors, and we must do it before we read the preferences, in
2390 case any dissectors register preferences. */
2391 epan_init(register_all_protocols,register_all_protocol_handoffs,
2392 failure_alert_box,open_failure_alert_box,read_failure_alert_box);
2394 splash_update(splash_win, "Init tap listeners ...");
2396 /* Register all tap listeners; we do this before we parse the arguments,
2397 as the "-z" argument can specify a registered tap. */
2399 /* we register the plugin taps before the other taps because
2400 stats_tree taps plugins will be registered as tap listeners
2401 by stats_tree_stat.c and need to registered before that */
2404 register_all_plugin_tap_listeners();
2407 register_all_tap_listeners();
2409 splash_update(splash_win, "Loading module preferences ...");
2411 /* Now register the preferences for any non-dissector modules.
2412 We must do that before we read the preferences as well. */
2413 prefs_register_modules();
2415 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2416 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined(G_THREADS_ENABLED) && defined USE_THREADS
2419 g_thread_init(NULL);
2421 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2422 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2424 #else /* _WIN32 || GTK1.2 || !G_THREADS_ENABLED || !USE_THREADS */
2425 /* this is to keep tap extensions updating once every 3 seconds */
2426 gtk_timeout_add(3000, (GtkFunction)update_cb,(gpointer)NULL);
2427 #endif /* !_WIN32 && GTK2 && G_THREADS_ENABLED */
2430 gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
2433 splash_update(splash_win, "Loading configuration files ...");
2435 /* Read the preference files. */
2436 prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2437 &pf_open_errno, &pf_read_errno, &pf_path);
2439 if (gpf_path != NULL) {
2440 if (gpf_open_errno != 0) {
2441 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2442 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2443 strerror(gpf_open_errno));
2445 if (gpf_read_errno != 0) {
2446 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2447 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2448 strerror(gpf_read_errno));
2451 if (pf_path != NULL) {
2452 if (pf_open_errno != 0) {
2453 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2454 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2455 strerror(pf_open_errno));
2457 if (pf_read_errno != 0) {
2458 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2459 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2460 strerror(pf_read_errno));
2467 /* if the user wants a console to be always there, well, we should open one for him */
2468 if (prefs->gui_console_open == console_open_always) {
2473 /* Fill in capture options with values from the preferences */
2474 prefs_to_capture_opts();
2476 /* Read the capture filter file. */
2477 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2478 if (cf_path != NULL) {
2479 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2480 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2481 strerror(cf_open_errno));
2485 /* Read the display filter file. */
2486 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2487 if (df_path != NULL) {
2488 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2489 "Could not open your display filter file\n\"%s\": %s.", df_path,
2490 strerror(df_open_errno));
2494 /* Read the disabled protocols file. */
2495 read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
2496 &dp_path, &dp_open_errno, &dp_read_errno);
2497 if (gdp_path != NULL) {
2498 if (gdp_open_errno != 0) {
2499 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2500 "Could not open global disabled protocols file\n\"%s\": %s.",
2501 gdp_path, strerror(gdp_open_errno));
2503 if (gdp_read_errno != 0) {
2504 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2505 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2506 gdp_path, strerror(gdp_read_errno));
2510 if (dp_path != NULL) {
2511 if (dp_open_errno != 0) {
2512 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2513 "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
2514 strerror(dp_open_errno));
2516 if (dp_read_errno != 0) {
2517 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2518 "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
2519 strerror(dp_read_errno));
2524 /* Read the (static part) of the recent file. Only the static part of it will be read, */
2525 /* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
2526 /* We have to do this already here, so command line parameters can overwrite these values. */
2527 recent_read_static(&rf_path, &rf_open_errno);
2529 init_cap_file(&cfile);
2531 /* Now get our args */
2532 while ((opt = getopt(argc, argv, optstring)) != -1) {
2534 /*** capture option specific ***/
2535 case 'a': /* autostop criteria */
2536 case 'b': /* Ringbuffer option */
2537 case 'c': /* Capture xxx packets */
2538 case 'f': /* capture filter */
2539 case 'k': /* Start capture immediately */
2540 case 'H': /* Hide capture info dialog box */
2541 case 'i': /* Use interface xxx */
2542 case 'p': /* Don't capture in promiscuous mode */
2543 case 'Q': /* Quit after capture (just capture to file) */
2544 case 's': /* Set the snapshot (capture) length */
2545 case 'S': /* "Sync" mode: used for following file ala tail -f */
2546 case 'w': /* Write to capture file xxx */
2547 case 'y': /* Set the pcap data link type */
2549 case 'B': /* Buffer size */
2552 status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
2557 capture_option_specified = TRUE;
2562 /*** all non capture option specific ***/
2563 case 'D': /* Print a list of capture devices and exit */
2565 capture_opts_list_interfaces();
2568 capture_option_specified = TRUE;
2572 case 'g': /* Go to packet */
2573 go_to_packet = get_positive_int(optarg, "go to packet");
2575 case 'l': /* Automatic scrolling in live capture mode */
2577 auto_scroll_live = TRUE;
2579 capture_option_specified = TRUE;
2583 case 'L': /* Print list of link-layer types and exit */
2585 list_link_layer_types = TRUE;
2587 capture_option_specified = TRUE;
2591 case 'm': /* Fixed-width font for the display */
2592 if (prefs->PREFS_GUI_FONT_NAME != NULL)
2593 g_free(prefs->PREFS_GUI_FONT_NAME);
2594 prefs->PREFS_GUI_FONT_NAME = g_strdup(optarg);
2596 case 'n': /* No name resolution */
2597 g_resolv_flags = RESOLV_NONE;
2599 case 'N': /* Select what types of addresses/port #s to resolve */
2600 if (g_resolv_flags == RESOLV_ALL)
2601 g_resolv_flags = RESOLV_NONE;
2602 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2603 if (badopt != '\0') {
2604 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2609 case 'o': /* Override preference from command line */
2610 switch (prefs_set_pref(optarg)) {
2613 case PREFS_SET_SYNTAX_ERR:
2614 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2617 case PREFS_SET_NO_SUCH_PREF:
2618 /* not a preference, might be a recent setting */
2619 switch (recent_set_arg(optarg)) {
2622 case PREFS_SET_SYNTAX_ERR:
2623 /* shouldn't happen, checked already above */
2624 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2627 case PREFS_SET_NO_SUCH_PREF:
2628 case PREFS_SET_OBSOLETE:
2629 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2634 g_assert_not_reached();
2637 case PREFS_SET_OBSOLETE:
2638 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2643 g_assert_not_reached();
2647 /* Path settings were already processed just ignore them this time*/
2649 case 'r': /* Read capture file xxx */
2650 /* We may set "last_open_dir" to "cf_name", and if we change
2651 "last_open_dir" later, we free the old value, so we have to
2652 set "cf_name" to something that's been allocated. */
2653 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2654 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2655 cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2657 cf_name = g_strdup(optarg);
2660 case 'R': /* Read file filter */
2663 case 't': /* Time stamp type */
2664 if (strcmp(optarg, "r") == 0)
2665 timestamp_set_type(TS_RELATIVE);
2666 else if (strcmp(optarg, "a") == 0)
2667 timestamp_set_type(TS_ABSOLUTE);
2668 else if (strcmp(optarg, "ad") == 0)
2669 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2670 else if (strcmp(optarg, "d") == 0)
2671 timestamp_set_type(TS_DELTA);
2672 else if (strcmp(optarg, "e") == 0)
2673 timestamp_set_type(TS_EPOCH);
2675 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2676 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2677 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2682 /* ext ops were already processed just ignore them this time*/
2685 /* We won't call the init function for the stat this soon
2686 as it would disallow MATE's fields (which are registered
2687 by the preferences set callback) from being used as
2688 part of a tap filter. Instead, we just add the argument
2689 to a list of stat arguments. */
2690 if (!process_stat_cmd_arg(optarg)) {
2691 cmdarg_err("Invalid -z argument.");
2692 cmdarg_err_cont(" -z argument must be one of :");
2693 list_stat_cmd_args();
2698 case '?': /* Bad flag - print usage message */
2706 if (cf_name != NULL) {
2708 * Input file name specified with "-r" *and* specified as a regular
2709 * command-line argument.
2711 cmdarg_err("File name specified both with -r and regular argument");
2715 * Input file name not specified with "-r", and a command-line argument
2716 * was specified; treat it as the input file name.
2718 * Yes, this is different from tshark, where non-flag command-line
2719 * arguments are a filter, but this works better on GUI desktops
2720 * where a command can be specified to be run to open a particular
2721 * file - yes, you could have "-r" as the last part of the command,
2722 * but that's a bit ugly.
2724 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2725 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2726 cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2728 cf_name = g_strdup(argv[0]);
2739 * Extra command line arguments were specified; complain.
2741 cmdarg_err("Invalid argument: %s", argv[0]);
2746 #ifndef HAVE_LIBPCAP
2747 if (capture_option_specified) {
2748 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2756 if (start_capture && list_link_layer_types) {
2757 /* Specifying *both* is bogus. */
2758 cmdarg_err("You can't specify both -L and a live capture.");
2762 if (list_link_layer_types) {
2763 /* We're supposed to list the link-layer types for an interface;
2764 did the user also specify a capture file to be read? */
2766 /* Yes - that's bogus. */
2767 cmdarg_err("You can't specify -L and a capture file to be read.");
2770 /* No - did they specify a ring buffer option? */
2771 if (capture_opts->multi_files_on) {
2772 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2776 /* We're supposed to do a live capture; did the user also specify
2777 a capture file to be read? */
2778 if (start_capture && cf_name) {
2779 /* Yes - that's bogus. */
2780 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2784 /* No - was the ring buffer option specified and, if so, does it make
2786 if (capture_opts->multi_files_on) {
2787 /* Ring buffer works only under certain conditions:
2788 a) ring buffer does not work with temporary files;
2789 b) real_time_mode and multi_files_on are mutually exclusive -
2790 real_time_mode takes precedence;
2791 c) it makes no sense to enable the ring buffer if the maximum
2792 file size is set to "infinite". */
2793 if (capture_opts->save_file == NULL) {
2794 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2795 capture_opts->multi_files_on = FALSE;
2797 /* if (capture_opts->real_time_mode) {
2798 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2799 capture_opts->multi_files_on = FALSE;
2801 if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
2802 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2803 /* XXX - this must be redesigned as the conditions changed */
2804 /* capture_opts->multi_files_on = FALSE;*/
2809 if (start_capture || list_link_layer_types) {
2810 /* Did the user specify an interface to use? */
2811 if (!capture_opts_trim_iface(capture_opts,
2812 (prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
2817 if (list_link_layer_types) {
2818 status = capture_opts_list_link_layer_types(capture_opts);
2822 capture_opts_trim_snaplen(capture_opts, MIN_PACKET_SIZE);
2823 capture_opts_trim_ring_num_files(capture_opts);
2824 #endif /* HAVE_LIBPCAP */
2826 /* Notify all registered modules that have had any of their preferences
2827 changed either from one of the preferences file or from the command
2828 line that their preferences have changed. */
2831 /* disabled protocols as per configuration file */
2832 if (gdp_path == NULL && dp_path == NULL) {
2833 set_disabled_protos_list();
2836 /* Build the column format array */
2837 col_setup(&cfile.cinfo, prefs->num_cols);
2838 for (i = 0; i < cfile.cinfo.num_cols; i++) {
2839 cfile.cinfo.col_fmt[i] = get_column_format(i);
2840 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
2841 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
2843 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
2844 cfile.cinfo.col_data[i] = NULL;
2845 if (cfile.cinfo.col_fmt[i] == COL_INFO)
2846 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
2848 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2849 cfile.cinfo.col_fence[i] = 0;
2850 cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2851 cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2854 for (i = 0; i < cfile.cinfo.num_cols; i++) {
2857 for (j = 0; j < NUM_COL_FMTS; j++) {
2858 if (!cfile.cinfo.fmt_matx[i][j])
2861 if (cfile.cinfo.col_first[j] == -1)
2862 cfile.cinfo.col_first[j] = i;
2863 cfile.cinfo.col_last[j] = i;
2867 /* read in rc file from global and personal configuration paths. */
2868 rc_file = get_datafile_path(RC_FILE);
2869 gtk_rc_parse(rc_file);
2870 rc_file = get_persconffile_path(RC_FILE, FALSE);
2871 gtk_rc_parse(rc_file);
2875 /* close the splash screen, as we are going to open the main window now */
2876 splash_destroy(splash_win);
2878 /************************************************************************/
2879 /* Everything is prepared now, preferences and command line was read in */
2881 /* Pop up the main window. */
2882 create_main_window(pl_size, tv_size, bv_size, prefs);
2884 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2885 recent_read_dynamic(&rf_path, &rf_open_errno);
2886 color_filters_enable(recent.packet_list_colorize);
2888 /* rearrange all the widgets as we now have all recent settings ready for this */
2889 main_widgets_rearrange();
2891 /* Fill in column titles. This must be done after the top level window
2894 XXX - is that still true, with fixed-width columns? */
2895 packet_list_set_column_titles();
2897 menu_recent_read_finished();
2899 switch (user_font_apply()) {
2902 case FA_FONT_NOT_RESIZEABLE:
2903 /* "user_font_apply()" popped up an alert box. */
2904 /* turn off zooming - font can't be resized */
2905 case FA_FONT_NOT_AVAILABLE:
2906 /* XXX - did we successfully load the un-zoomed version earlier?
2907 If so, this *probably* means the font is available, but not at
2908 this particular zoom level, but perhaps some other failure
2909 occurred; I'm not sure you can determine which is the case,
2911 /* turn off zooming - zoom level is unavailable */
2913 /* in any other case than FA_SUCCESS, turn off zooming */
2914 recent.gui_zoom_level = 0;
2915 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2918 dnd_init(top_level);
2921 color_filters_init();
2924 /* the window can be sized only, if it's not already shown, so do it now! */
2925 main_load_window_geometry(top_level);
2927 /* If we were given the name of a capture file, read it in now;
2928 we defer it until now, so that, if we can't open it, and pop
2929 up an alert box, the alert box is more likely to come up on
2930 top of the main window - but before the preference-file-error
2931 alert box, so, if we get one of those, it's more likely to come
2934 show_main_window(TRUE);
2935 if (rfilter != NULL) {
2936 if (!dfilter_compile(rfilter, &rfcode)) {
2937 bad_dfilter_alert_box(rfilter);
2938 rfilter_parse_failed = TRUE;
2941 if (!rfilter_parse_failed) {
2942 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2943 /* "cf_open()" succeeded, so it closed the previous
2944 capture file, and thus destroyed any previous read filter
2945 attached to "cf". */
2947 cfile.rfcode = rfcode;
2948 /* Open stat windows; we do so after creating the main window,
2949 to avoid GTK warnings, and after successfully opening the
2950 capture file, so we know we have something to compute stats
2951 on, and after registering all dissectors, so that MATE will
2952 have registered its field array and we can have a tap filter
2953 with one of MATE's late-registered fields as part of the
2955 start_requested_stats();
2957 /* Read the capture file. */
2958 switch (cf_read(&cfile)) {
2962 /* Just because we got an error, that doesn't mean we were unable
2963 to read any of the file; we handle what we could get from the
2965 /* if the user told us to jump to a specific packet, do it now */
2966 if(go_to_packet != 0) {
2967 cf_goto_frame(&cfile, go_to_packet);
2971 case CF_READ_ABORTED:
2976 /* Save the name of the containing directory specified in the
2977 path name, if any; we can write over cf_name, which is a
2978 good thing, given that "get_dirname()" does write over its
2980 s = get_dirname(cf_name);
2981 set_last_open_dir(s);
2986 dfilter_free(rfcode);
2987 cfile.rfcode = NULL;
2988 show_main_window(FALSE);
2989 set_menus_for_capture_in_progress(FALSE);
2994 if (start_capture) {
2995 if (capture_opts->save_file != NULL) {
2996 /* Save the directory name for future file dialogs. */
2997 /* (get_dirname overwrites filename) */
2998 s = get_dirname(g_strdup(capture_opts->save_file));
2999 set_last_open_dir(s);
3002 /* "-k" was specified; start a capture. */
3003 show_main_window(TRUE);
3004 if (capture_start(capture_opts)) {
3005 /* The capture started. Open stat windows; we do so after creating
3006 the main window, to avoid GTK warnings, and after successfully
3007 opening the capture file, so we know we have something to compute
3008 stats on, and after registering all dissectors, so that MATE will
3009 have registered its field array and we can have a tap filter with
3010 one of MATE's late-registered fields as part of the filter. */
3011 start_requested_stats();
3015 show_main_window(FALSE);
3016 set_menus_for_capture_in_progress(FALSE);
3019 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
3020 if (!start_capture && strlen(capture_opts->cfilter) == 0) {
3021 g_free(capture_opts->cfilter);
3022 capture_opts->cfilter = g_strdup(get_conn_cfilter());
3024 #else /* HAVE_LIBPCAP */
3025 show_main_window(FALSE);
3026 set_menus_for_capture_in_progress(FALSE);
3027 #endif /* HAVE_LIBPCAP */
3030 /* register our pid if we are being run from a U3 device */
3033 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3035 /* ... back from GTK, we're going down now! */
3037 /* deregister our pid */
3038 u3_deregister_pid();
3043 #ifdef HAVE_AIRPDCAP
3044 /* Davide Schiera (2006-11-18): destroy AirPDcap context */
3045 AirPDcapDestroyContext(&airpdcap_ctx);
3046 /* Davide Schiera (2006-11-18) ------------------------------------------- */
3050 /* hide the (unresponsive) main window, while asking the user to close the console window */
3051 gtk_widget_hide(top_level);
3053 /* Shutdown windows sockets */
3056 /* For some unknown reason, the "atexit()" call in "create_console()"
3057 doesn't arrange that "destroy_console()" be called when we exit,
3058 so we call it here if a console was created. */
3064 /* This isn't reached, but we need it to keep GCC from complaining
3065 that "main()" returns without returning a value - it knows that
3066 "exit()" never returns, but it doesn't know that "gtk_exit()"
3067 doesn't, as GTK+ doesn't declare it with the attribute
3069 return 0; /* not reached */
3074 /* We build this as a GUI subsystem application on Win32, so
3075 "WinMain()", not "main()", gets called.
3077 Hack shamelessly stolen from the Win32 port of the GIMP. */
3079 #define _stdcall __attribute__((stdcall))
3083 WinMain (struct HINSTANCE__ *hInstance,
3084 struct HINSTANCE__ *hPrevInstance,
3088 #if GTK_MAJOR_VERSION >= 2
3089 INITCOMMONCONTROLSEX comm_ctrl;
3091 /* Initialize our controls. Required for native Windows file dialogs. */
3092 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3093 comm_ctrl.dwSize = sizeof(comm_ctrl);
3094 /* Includes the animate, header, hot key, list view, progress bar,
3095 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3098 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3099 InitCommonControlsEx(&comm_ctrl);
3101 /* RichEd20.DLL is needed for filter entries. */
3102 LoadLibrary(_T("riched20.dll"));
3103 #endif /* GTK_MAJOR_VERSION >= 2 */
3105 has_console = FALSE;
3106 return main (__argc, __argv);
3110 * If this application has no console window to which its standard output
3111 * would go, create one.
3114 create_console(void)
3117 /* We have no console to which to print the version string, so
3118 create one and make it the standard input, output, and error. */
3119 if (!AllocConsole())
3120 return; /* couldn't create console */
3121 eth_freopen("CONIN$", "r", stdin);
3122 eth_freopen("CONOUT$", "w", stdout);
3123 eth_freopen("CONOUT$", "w", stderr);
3125 /* Well, we have a console now. */
3128 /* Now register "destroy_console()" as a routine to be called just
3129 before the application exits, so that we can destroy the console
3130 after the user has typed a key (so that the console doesn't just
3131 disappear out from under them, giving the user no chance to see
3132 the message(s) we put in there). */
3133 atexit(destroy_console);
3135 SetConsoleTitle(_T("Wireshark Debug Console"));
3140 destroy_console(void)
3143 printf("\n\nPress any key to exit\n");
3151 /* This routine should not be necessary, at least as I read the GLib
3152 source code, as it looks as if GLib is, on Win32, *supposed* to
3153 create a console window into which to display its output.
3155 That doesn't happen, however. I suspect there's something completely
3156 broken about that code in GLib-for-Win32, and that it may be related
3157 to the breakage that forces us to just call "printf()" on the message
3158 rather than passing the message on to "g_log_default_handler()"
3159 (which is the routine that does the aforementioned non-functional
3160 console window creation). */
3162 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3163 const char *message, gpointer user_data _U_)
3170 /* ignore log message, if log_level isn't interesting.
3171 If preferences aren't loaded yet, display message anyway */
3172 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3173 prefs.console_log_level != 0) {
3177 /* create a "timestamp" */
3179 today = localtime(&curr);
3182 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3183 /* the user wants a console or the application will terminate immediately */
3187 /* For some unknown reason, the above doesn't appear to actually cause
3188 anything to be sent to the standard output, so we'll just splat the
3189 message out directly, just to make sure it gets out. */
3191 switch(log_level & G_LOG_LEVEL_MASK) {
3192 case G_LOG_LEVEL_ERROR:
3195 case G_LOG_LEVEL_CRITICAL:
3198 case G_LOG_LEVEL_WARNING:
3201 case G_LOG_LEVEL_MESSAGE:
3204 case G_LOG_LEVEL_INFO:
3207 case G_LOG_LEVEL_DEBUG:
3211 fprintf(stderr, "unknown log_level %u\n", log_level);
3213 g_assert_not_reached();
3216 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3217 today->tm_hour, today->tm_min, today->tm_sec,
3218 log_domain != NULL ? log_domain : "",
3221 if(log_level & G_LOG_LEVEL_ERROR) {
3222 /* wait for a key press before the following error handler will terminate the program
3223 this way the user at least can read the error message */
3224 printf("\n\nPress any key to exit\n");
3228 g_log_default_handler(log_domain, log_level, message, user_data);
3234 static GtkWidget *info_bar_new(void)
3236 /* tip: tooltips don't work on statusbars! */
3237 info_bar = gtk_statusbar_new();
3238 main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
3239 file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
3240 help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
3241 #if GTK_MAJOR_VERSION >= 2
3242 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(info_bar), FALSE);
3244 gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
3249 static GtkWidget *packets_bar_new(void)
3251 /* tip: tooltips don't work on statusbars! */
3252 packets_bar = gtk_statusbar_new();
3253 packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
3254 packets_bar_update();
3261 * Helper for main_widgets_rearrange()
3263 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3264 gtk_container_remove(GTK_CONTAINER(data), widget);
3267 static GtkWidget *main_widget_layout(gint layout_content)
3269 switch(layout_content) {
3270 case(layout_pane_content_none):
3273 case(layout_pane_content_plist):
3276 case(layout_pane_content_pdetails):
3279 case(layout_pane_content_pbytes):
3283 g_assert_not_reached();
3290 * Rearrange the main window widgets
3292 void main_widgets_rearrange(void) {
3293 GtkWidget *first_pane_widget1, *first_pane_widget2;
3294 GtkWidget *second_pane_widget1, *second_pane_widget2;
3295 gboolean split_top_left;
3297 /* be a bit faster */
3298 gtk_widget_hide(main_vbox);
3300 /* be sure, we don't loose a widget while rearranging */
3301 gtk_widget_ref(menubar);
3302 gtk_widget_ref(main_tb);
3303 gtk_widget_ref(filter_tb);
3306 gtk_widget_ref(airpcap_tb);
3309 gtk_widget_ref(pkt_scrollw);
3310 gtk_widget_ref(tv_scrollw);
3311 gtk_widget_ref(byte_nb_ptr);
3312 gtk_widget_ref(stat_hbox);
3313 gtk_widget_ref(info_bar);
3314 gtk_widget_ref(packets_bar);
3315 gtk_widget_ref(status_pane);
3316 gtk_widget_ref(main_pane_v1);
3317 gtk_widget_ref(main_pane_v2);
3318 gtk_widget_ref(main_pane_h1);
3319 gtk_widget_ref(main_pane_h2);
3320 gtk_widget_ref(welcome_pane);
3322 /* empty all containers participating */
3323 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3324 gtk_container_foreach(GTK_CONTAINER(stat_hbox), foreach_remove_a_child, stat_hbox);
3325 gtk_container_foreach(GTK_CONTAINER(status_pane), foreach_remove_a_child, status_pane);
3326 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3327 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3328 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3329 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3331 /* add the menubar always at the top */
3332 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3335 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3337 /* filter toolbar in toolbar area */
3338 if (!prefs.filter_toolbar_show_in_statusbar) {
3339 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3343 /* airpcap toolbar */
3344 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3347 /* fill the main layout panes */
3348 switch(prefs.gui_layout_type) {
3349 case(layout_type_5):
3350 main_first_pane = main_pane_v1;
3351 main_second_pane = main_pane_v2;
3352 split_top_left = FALSE;
3354 case(layout_type_2):
3355 main_first_pane = main_pane_v1;
3356 main_second_pane = main_pane_h1;
3357 split_top_left = FALSE;
3359 case(layout_type_1):
3360 main_first_pane = main_pane_v1;
3361 main_second_pane = main_pane_h1;
3362 split_top_left = TRUE;
3364 case(layout_type_4):
3365 main_first_pane = main_pane_h1;
3366 main_second_pane = main_pane_v1;
3367 split_top_left = FALSE;
3369 case(layout_type_3):
3370 main_first_pane = main_pane_h1;
3371 main_second_pane = main_pane_v1;
3372 split_top_left = TRUE;
3374 case(layout_type_6):
3375 main_first_pane = main_pane_h1;
3376 main_second_pane = main_pane_h2;
3377 split_top_left = FALSE;
3380 main_first_pane = NULL;
3381 main_second_pane = NULL;
3382 split_top_left = FALSE;
3383 g_assert_not_reached();
3385 if (split_top_left) {
3386 first_pane_widget1 = main_second_pane;
3387 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3388 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3389 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3391 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3392 first_pane_widget2 = main_second_pane;
3393 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3394 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3396 if (first_pane_widget1 != NULL)
3397 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3398 if (first_pane_widget2 != NULL)
3399 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3400 if (second_pane_widget1 != NULL)
3401 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3402 if (second_pane_widget2 != NULL)
3403 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3405 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3408 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3410 /* statusbar hbox */
3411 gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0);
3413 /* filter toolbar in statusbar hbox */
3414 if (prefs.filter_toolbar_show_in_statusbar) {
3415 gtk_box_pack_start(GTK_BOX(stat_hbox), filter_tb, FALSE, TRUE, 1);
3419 /* airpcap toolbar */
3420 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3424 gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane, TRUE, TRUE, 0);
3425 gtk_paned_pack1(GTK_PANED(status_pane), info_bar, FALSE, FALSE);
3426 gtk_paned_pack2(GTK_PANED(status_pane), packets_bar, FALSE, FALSE);
3428 /* hide widgets on users recent settings */
3429 main_widgets_show_or_hide();
3431 gtk_widget_show(main_vbox);
3435 is_widget_visible(GtkWidget *widget, gpointer data)
3437 gboolean *is_visible = data;
3440 if (GTK_WIDGET_VISIBLE(widget))
3445 /*#define SHOW_WELCOME_PAGE*/
3446 #ifdef SHOW_WELCOME_PAGE
3447 /* XXX - There seems to be some disagreement about if and how this feature should be implemented.
3448 As I currently don't have the time to continue this, it's temporarily disabled. - ULFL */
3450 welcome_item(const gchar *stock_item, const gchar * label, const gchar * message, const gchar * tooltip,
3451 GtkSignalFunc callback, void *callback_data)
3453 GtkWidget *w, *item_hb;
3454 #if GTK_MAJOR_VERSION >= 2
3455 gchar *formatted_message;
3456 GtkTooltips *tooltips;
3458 tooltips = gtk_tooltips_new();
3461 item_hb = gtk_hbox_new(FALSE, 1);
3463 w = BUTTON_NEW_FROM_STOCK(stock_item);
3464 WIDGET_SET_SIZE(w, 80, 40);
3465 #if GTK_MAJOR_VERSION >= 2
3466 gtk_button_set_label(GTK_BUTTON(w), label);
3467 gtk_tooltips_set_tip(tooltips, w, tooltip, NULL);
3469 gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 0);
3470 SIGNAL_CONNECT(w, "clicked", callback, callback_data);
3472 w = gtk_label_new(message);
3473 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3474 #if GTK_MAJOR_VERSION >= 2
3475 formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\">%s</span>", message);
3476 gtk_label_set_markup(GTK_LABEL(w), formatted_message);
3477 g_free(formatted_message);
3480 gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 10);
3487 welcome_header_new(void)
3498 /* background color of the header bar */
3501 bg.green = 210 * 255;
3502 bg.blue = 229 * 255;
3504 item_vb = gtk_vbox_new(FALSE, 0);
3508 eb = gtk_event_box_new();
3509 gtk_container_add(GTK_CONTAINER(eb), item_vb);
3510 #if GTK_MAJOR_VERSION >= 2
3511 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &bg);
3514 item_hb = gtk_hbox_new(FALSE, 0);
3515 gtk_box_pack_start(GTK_BOX(item_vb), item_hb, FALSE, FALSE, 10);
3517 icon = xpm_to_widget_from_parent(top_level, wssplash_xpm);
3518 /*icon = xpm_to_widget_from_parent(top_level, wsicon64_xpm);*/
3519 gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 10);
3521 #if GTK_MAJOR_VERSION < 2
3522 message = "The World's Most Popular Network Protocol Analyzer";
3524 message = "<span weight=\"bold\" size=\"x-large\">" "The World's Most Popular Network Protocol Analyzer" "</span>";
3526 w = gtk_label_new(message);
3527 #if GTK_MAJOR_VERSION >= 2
3528 gtk_label_set_markup(GTK_LABEL(w), message);
3530 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3531 gtk_box_pack_start(GTK_BOX(item_hb), w, TRUE, TRUE, 5);
3533 gtk_widget_show_all(eb);
3539 welcome_topic_header_new(const char *header)
3544 #if GTK_MAJOR_VERSION >= 2
3545 gchar *formatted_message;
3549 w = gtk_label_new(header);
3550 #if GTK_MAJOR_VERSION >= 2
3551 formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\">%s</span>", header);
3552 gtk_label_set_markup(GTK_LABEL(w), formatted_message);
3553 g_free(formatted_message);
3556 /* topic header background color */
3559 bg.green = 151 * 255;
3560 bg.blue = 192 * 255;
3564 eb = gtk_event_box_new();
3565 gtk_container_add(GTK_CONTAINER(eb), w);
3566 #if GTK_MAJOR_VERSION >= 2
3567 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &bg);
3575 welcome_topic_new(const char *header, GtkWidget **to_fill)
3577 GtkWidget *topic_vb;
3578 GtkWidget *layout_vb;
3579 GtkWidget *topic_eb;
3580 GtkWidget *topic_header;
3583 topic_vb = gtk_vbox_new(FALSE, 0);
3585 /* topic content background color */
3588 bg.green = 226 * 255;
3589 bg.blue = 228 * 255;
3591 topic_header = welcome_topic_header_new(header);
3592 gtk_box_pack_start(GTK_BOX(topic_vb), topic_header, FALSE, FALSE, 0);
3594 layout_vb = gtk_vbox_new(FALSE, 5);
3595 gtk_container_border_width(GTK_CONTAINER(layout_vb), 10);
3596 gtk_box_pack_start(GTK_BOX(topic_vb), layout_vb, FALSE, FALSE, 0);
3598 /* colorize vbox (we need an event box for this!) */
3600 topic_eb = gtk_event_box_new();
3601 gtk_container_add(GTK_CONTAINER(topic_eb), topic_vb);
3602 #if GTK_MAJOR_VERSION >= 2
3603 gtk_widget_modify_bg(topic_eb, GTK_STATE_NORMAL, &bg);
3605 *to_fill = layout_vb;
3611 #if GTK_MAJOR_VERSION >= 2
3613 welcome_link_enter_cb(GtkWidget *widget _U_, GdkEventCrossing *event _U_, gpointer user_data)
3616 GtkWidget *w = user_data;
3618 message = g_strdup_printf("<span foreground='blue' underline='single'>%s</span>", OBJECT_GET_DATA(w,"TEXT"));
3619 #if GTK_MAJOR_VERSION >= 2
3620 gtk_label_set_markup(GTK_LABEL(w), message);
3628 welcome_link_leave_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer user_data)
3631 GtkWidget *w = user_data;
3633 message = g_strdup_printf("<span foreground='blue'>%s</span>", OBJECT_GET_DATA(w,"TEXT"));
3634 #if GTK_MAJOR_VERSION >= 2
3635 gtk_label_set_markup(GTK_LABEL(w), message);
3645 welcome_link_press_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_) {
3647 g_warning("TBD: link pressed");
3653 welcome_link_new(const gchar *text, GtkWidget **label /*, void *callback, void *private_data */)
3659 #if GTK_MAJOR_VERSION < 2
3660 message = g_strdup(text);
3662 message = g_strdup_printf("<span foreground='blue'>%s</span>", text);
3664 w = gtk_label_new(message);
3666 #if GTK_MAJOR_VERSION >= 2
3667 gtk_label_set_markup(GTK_LABEL(w), message);
3672 eb = gtk_event_box_new();
3673 gtk_container_add(GTK_CONTAINER(eb), w);
3675 #if GTK_MAJOR_VERSION >= 2
3676 SIGNAL_CONNECT(eb, "enter-notify-event", welcome_link_enter_cb, w);
3677 SIGNAL_CONNECT(eb, "leave-notify-event", welcome_link_leave_cb, w);
3679 SIGNAL_CONNECT(eb, "button-press-event", welcome_link_press_cb, w);
3682 OBJECT_SET_DATA(w, "TEXT", g_strdup(text));
3688 welcome_filename_link_new(const char *filename, GtkWidget **label)
3692 const unsigned int max = 60;
3695 str = g_string_new(filename);
3697 if(str->len > max) {
3698 g_string_erase(str, 0, str->len-max /*cut*/);
3699 g_string_prepend(str, "... ");
3702 w = welcome_link_new(str->str, label);
3704 g_string_free(str, TRUE);
3711 welcome_if_new(const char *if_name, GdkColor *topic_bg, gboolean active)
3713 GtkWidget *interface_hb;
3716 GtkTooltips *tooltips;
3720 tooltips = gtk_tooltips_new();
3722 interface_hb = gtk_hbox_new(FALSE, 5);
3724 w = welcome_link_new("START", &label);
3725 gtk_tooltips_set_tip(tooltips, w, "Immediately start a capture on this interface", NULL);
3726 #if GTK_MAJOR_VERSION >= 2
3727 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, topic_bg);
3729 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3730 gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3732 w = welcome_link_new("OPTIONS", &label);
3733 gtk_tooltips_set_tip(tooltips, w, "Show the capture options of this interface", NULL);
3734 #if GTK_MAJOR_VERSION >= 2
3735 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, topic_bg);
3737 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3738 gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3740 w = welcome_link_new("DETAILS", &label);
3741 gtk_tooltips_set_tip(tooltips, w, "Show detailed information about this interface", NULL);
3742 #if GTK_MAJOR_VERSION >= 2
3743 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, topic_bg);
3745 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3746 gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3748 message = g_string_new(if_name);
3750 /* truncate string if it's too long */
3751 if(message->len > 38) {
3752 g_string_truncate(message, 35);
3753 g_string_append (message, " ...");
3755 #if GTK_MAJOR_VERSION >= 2
3756 /* if this is the "active" interface, display it bold */
3758 g_string_prepend(message, "<span weight=\"bold\">");
3759 g_string_append (message, "</span>");
3762 w = gtk_label_new(message->str);
3763 #if GTK_MAJOR_VERSION >= 2
3764 gtk_label_set_markup(GTK_LABEL(w), message->str);
3766 g_string_free(message, TRUE);
3768 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3769 gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3771 return interface_hb;
3774 /* XXX - the layout has to be improved */
3778 GtkWidget *welcome_scrollw;
3779 GtkWidget *welcome_vb;
3780 GtkWidget *welcome_hb;
3781 GtkWidget *column_vb;
3786 GtkWidget *topic_vb;
3787 GtkWidget *topic_to_fill;
3788 GtkWidget *interface_hb;
3792 /* topic content background color */
3794 topic_bg.red = 221 * 255;
3795 topic_bg.green = 226 * 255;
3796 topic_bg.blue = 228 * 255;
3798 welcome_scrollw = scrolled_window_new(NULL, NULL);
3800 welcome_vb = gtk_vbox_new(FALSE, 0);
3803 header = welcome_header_new();
3804 gtk_box_pack_start(GTK_BOX(welcome_vb), header, FALSE, FALSE, 0);
3807 welcome_hb = gtk_hbox_new(FALSE, 10);
3808 gtk_container_border_width(GTK_CONTAINER(welcome_hb), 10);
3809 gtk_box_pack_start(GTK_BOX(welcome_vb), welcome_hb, TRUE, TRUE, 0);
3811 /* column capture */
3812 column_vb = gtk_vbox_new(FALSE, 10);
3813 gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
3816 topic_vb = welcome_topic_new("Capture", &topic_to_fill);
3817 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3820 item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_INTERFACES,
3822 "Interface Life List",
3823 "Show a life list of the available capture interfaces",
3824 GTK_SIGNAL_FUNC(capture_if_cb), NULL);
3825 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3828 w = gtk_label_new("Available Interfaces:");
3829 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3830 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
3832 interface_hb = welcome_if_new("Generic dialup adapter", &topic_bg, FALSE);
3833 gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3835 /* Marvell interface (currently "active") */
3836 interface_hb = welcome_if_new("Marvell Gigabit Ethernet Controller", &topic_bg, TRUE);
3837 gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3839 /* Wireless interface */
3840 interface_hb = welcome_if_new("Intel(R) PRO/Wireless 3945ABG Network Connection", &topic_bg, FALSE);
3841 gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3844 /* capture help topic */
3845 topic_vb = welcome_topic_new("Capture Help", &topic_to_fill);
3846 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3849 item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_START,
3851 "How To: Setup a Capture",
3852 "How To: Setup a Capture (online from the Wiki)",
3853 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3854 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3856 item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_START,
3858 "Capture Filter Examples",
3859 "Capture Filter Examples (online from the Wiki)",
3860 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3861 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3864 /* fill bottom space */
3865 w = gtk_label_new("");
3866 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3870 topic_vb = welcome_topic_new("Files", &topic_to_fill);
3871 gtk_box_pack_start(GTK_BOX(welcome_hb), topic_vb, TRUE, TRUE, 0);
3873 item_hb = welcome_item(GTK_STOCK_OPEN,
3875 "Open a Capture File",
3876 "Open a previously captured file",
3877 GTK_SIGNAL_FUNC(file_open_cmd_cb), NULL);
3878 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3880 item_hb = welcome_item(GTK_STOCK_OPEN,
3882 "Download Examples",
3883 "Download Example Capture Files (from the Wiki)",
3884 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3885 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3887 w = gtk_label_new("Recent Files:");
3888 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3889 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
3891 w = welcome_link_new("C:\\Testfiles\\hello.pcap", &label);
3892 #if GTK_MAJOR_VERSION >= 2
3893 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3895 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3896 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3898 w = welcome_filename_link_new("C:\\Testfiles\\hello2.pcap", &label);
3899 #if GTK_MAJOR_VERSION >= 2
3900 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3902 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3903 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3905 w = welcome_filename_link_new(
3906 "C:\\Testfiles\\to avoid screen garbage\\Unfortunately this is a very long filename which had to be truncated.pcap",
3908 #if GTK_MAJOR_VERSION >= 2
3909 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3911 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3912 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3914 w = gtk_label_new("");
3915 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3919 column_vb = gtk_vbox_new(FALSE, 10);
3920 gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
3923 topic_vb = welcome_topic_new("Online", &topic_to_fill);
3924 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3926 #if (GLIB_MAJOR_VERSION >= 2)
3927 item_hb = welcome_item(WIRESHARK_STOCK_WEB_SUPPORT,
3929 "Show the User's Guide",
3930 "Show the User's Guide (local version, if available)",
3931 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3932 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3934 item_hb = welcome_item(GTK_STOCK_HOME,
3936 "Projects Home Page",
3937 "Visit www.wireshark.org, the project's home page",
3938 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_HOME));
3939 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3943 topic_vb = welcome_topic_new("Updates", &topic_to_fill);
3944 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3946 w = gtk_label_new("No updates available!");
3947 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3951 gtk_widget_show_all(welcome_vb);
3953 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(welcome_scrollw),
3955 gtk_widget_show_all(welcome_scrollw);
3957 return welcome_scrollw;
3963 /* this is just a dummy to fill up window space, simply showing nothing */
3964 return scrolled_window_new(NULL, NULL);
3971 * XXX - this doesn't appear to work with the paned widgets in
3972 * GTK+ 1.2[.x]; if you hide one of the panes, the splitter remains
3973 * and the other pane doesn't grow to take up the rest of the pane.
3974 * It does appear to work with GTK+ 2.x.
3977 main_widgets_show_or_hide(void)
3979 gboolean main_second_pane_show;
3981 if (recent.main_toolbar_show) {
3982 gtk_widget_show(main_tb);
3984 gtk_widget_hide(main_tb);
3988 * Show the status hbox if either:
3990 * 1) we're showing the filter toolbar and we want it in the status
3995 * 2) we're showing the status bar.
3997 if ((recent.filter_toolbar_show && prefs.filter_toolbar_show_in_statusbar) ||
3998 recent.statusbar_show) {
3999 gtk_widget_show(stat_hbox);
4001 gtk_widget_hide(stat_hbox);
4004 if (recent.statusbar_show) {
4005 gtk_widget_show(status_pane);
4007 gtk_widget_hide(status_pane);
4010 if (recent.filter_toolbar_show) {
4011 gtk_widget_show(filter_tb);
4013 gtk_widget_hide(filter_tb);
4017 if (recent.airpcap_toolbar_show) {
4018 gtk_widget_show(airpcap_tb);
4020 gtk_widget_hide(airpcap_tb);
4024 if (recent.packet_list_show && have_capture_file) {
4025 gtk_widget_show(pkt_scrollw);
4027 gtk_widget_hide(pkt_scrollw);
4030 if (recent.tree_view_show && have_capture_file) {
4031 gtk_widget_show(tv_scrollw);
4033 gtk_widget_hide(tv_scrollw);
4036 if (recent.byte_view_show && have_capture_file) {
4037 gtk_widget_show(byte_nb_ptr);
4039 gtk_widget_hide(byte_nb_ptr);
4042 if (have_capture_file) {
4043 gtk_widget_show(main_first_pane);
4045 gtk_widget_hide(main_first_pane);
4049 * Is anything in "main_second_pane" visible?
4050 * If so, show it, otherwise hide it.
4052 main_second_pane_show = FALSE;
4053 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
4054 &main_second_pane_show);
4055 if (main_second_pane_show) {
4056 gtk_widget_show(main_second_pane);
4058 gtk_widget_hide(main_second_pane);
4061 if (!have_capture_file) {
4063 gtk_widget_show(welcome_pane);
4066 gtk_widget_hide(welcome_pane);
4069 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
4070 packet_list_freeze ();
4071 packet_list_thaw ();
4075 #if GTK_MAJOR_VERSION >= 2
4076 /* called, when the window state changes (minimized, maximized, ...) */
4078 window_state_event_cb (GtkWidget *widget _U_,
4082 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
4084 if( (event->type) == (GDK_WINDOW_STATE)) {
4085 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
4086 /* we might have dialogs popped up while we where iconified,
4088 display_queued_messages();
4097 * Changed callback for the channel combobox
4100 airpcap_toolbar_channel_changed_cb(GtkWidget *w _U_, gpointer data)
4102 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4107 s = gtk_entry_get_text(GTK_ENTRY(data));
4109 if ((data != NULL) && (w != NULL) ) {
4110 s = gtk_entry_get_text(GTK_ENTRY(data));
4111 if ((g_strcasecmp("",s))) {
4112 sscanf(s,"%d",&ch_num);
4113 if (airpcap_if_active != NULL) {
4114 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list, airpcap_if_active->description), ebuf);
4117 airpcap_if_set_device_channel(ad,ch_num);
4118 airpcap_if_active->channel = ch_num;
4119 airpcap_if_close(ad);
4127 * Callback for the wrong crc combo
4130 airpcap_toolbar_wrong_crc_combo_cb(GtkWidget *entry, gpointer user_data)
4132 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4135 if( !block_toolbar_signals && (airpcap_if_active != NULL)) {
4136 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,airpcap_if_active->description), ebuf);
4139 airpcap_if_active->CrcValidationOn = airpcap_get_validation_type(gtk_entry_get_text(GTK_ENTRY(entry)));
4140 airpcap_if_set_fcs_validation(ad,airpcap_if_active->CrcValidationOn);
4141 /* Save configuration */
4142 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4143 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.");
4145 airpcap_if_close(ad);
4151 airpcap_toolbar_encryption_cb(GtkWidget *entry, gpointer user_data)
4153 /* We need to directly access the .ddl functions here... */
4154 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4159 airpcap_if_info_t* curr_if = NULL;
4161 /* Apply changes to the current adapter */
4162 if( (airpcap_if_active != NULL)) {
4163 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,airpcap_if_active->description), ebuf);
4166 if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON) {
4167 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_OFF;
4168 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
4169 /* Save configuration */
4170 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4171 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.");
4173 airpcap_if_close(ad);
4175 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_ON;
4176 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
4177 /* Save configuration */
4178 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4179 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.");
4181 airpcap_if_close(ad);
4185 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No active AirPcap Adapter selected!");
4189 n = g_list_length(airpcap_if_list);
4191 /* The same kind of settings should be propagated to all the adapters */
4192 /* Apply this change to all the adapters !!! */
4193 for(i = 0; i < n; i++) {
4194 curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
4196 if( (curr_if != NULL) && (curr_if != airpcap_if_selected) ) {
4197 ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,curr_if->description), ebuf);
4199 curr_if->DecryptionOn = airpcap_if_selected->DecryptionOn;
4200 airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
4201 /* Save configuration for the curr_if */
4202 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4203 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.");
4205 airpcap_if_close(ad);
4212 * Callback for the Advanced Wireless Settings button
4215 toolbar_display_airpcap_advanced_cb(GtkWidget *w, gpointer data)
4219 from_widget = (gint*)g_malloc(sizeof(gint));
4220 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
4221 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
4223 display_airpcap_advanced_cb(w,data);
4227 * Callback for the Decryption Key Management button
4230 toolbar_display_airpcap_key_management_cb(GtkWidget *w, gpointer data)
4234 from_widget = (gint*)g_malloc(sizeof(gint));
4235 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
4236 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
4238 display_airpcap_key_management_cb(w,data);
4240 #endif /* HAVE_AIRPCAP */
4242 #if GTK_MAJOR_VERSION >= 2
4244 top_level_key_pressed_cb(GtkCTree *ctree _U_, GdkEventKey *event, gpointer user_data _U_)
4246 if (event->keyval == GDK_F8) {
4249 } else if (event->keyval == GDK_F7) {
4253 * A comment in gdkkeysyms.h says that it's autogenerated from
4254 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
4255 * don't explicitly say so, isprint() should work as expected
4258 } else if (isascii(event->keyval) && isprint(event->keyval)) {
4259 /* Forward the keypress on to the display filter entry */
4260 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
4261 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
4262 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
4271 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
4274 *filter_bt, *filter_cm, *filter_te,
4275 *filter_add_expr_bt,
4278 GList *dfilter_list = NULL;
4279 GtkTooltips *tooltips;
4281 GtkAccelGroup *accel;
4285 GtkWidget *advanced_bt,
4293 GtkWidget *enable_decryption_lb;
4294 GtkWidget *enable_decryption_cb;
4295 GList *enable_decryption_cb_items = NULL;
4296 GtkWidget *enable_decryption_en;
4298 GList *channel_list = NULL;
4299 GList *linktype_list = NULL;
4300 GList *link_list = NULL;
4301 GtkTooltips *airpcap_tooltips;
4302 gchar *if_label_text;
4303 gint *from_widget = NULL;
4306 /* Display filter construct dialog has an Apply button, and "OK" not
4307 only sets our text widget, it activates it (i.e., it causes us to
4308 filter the capture). */
4309 static construct_args_t args = {
4310 "Wireshark: Display Filter",
4316 /* use user-defined title if preference is set */
4317 title = create_user_window_title("The Wireshark Network Analyzer");
4320 top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
4323 tooltips = gtk_tooltips_new();
4326 airpcap_tooltips = gtk_tooltips_new();
4330 #if GTK_MAJOR_VERSION < 2
4331 /* has to be done, after top_level window is created */
4332 app_font_gtk1_init(top_level);
4336 gtk_widget_set_name(top_level, "main window");
4337 SIGNAL_CONNECT(top_level, "delete_event", main_window_delete_event_cb,
4339 #if GTK_MAJOR_VERSION >= 2
4340 SIGNAL_CONNECT(GTK_OBJECT(top_level), "window_state_event",
4341 G_CALLBACK (window_state_event_cb), NULL);
4342 SIGNAL_CONNECT(GTK_OBJECT(top_level), "key-press-event",
4343 G_CALLBACK (top_level_key_pressed_cb), NULL );
4346 gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
4348 /* Container for menu bar, toolbar(s), paned windows and progress/info box */
4349 main_vbox = gtk_vbox_new(FALSE, 1);
4350 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
4351 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
4352 gtk_widget_show(main_vbox);
4355 menubar = main_menu_new(&accel);
4356 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
4357 gtk_widget_show(menubar);
4360 main_tb = toolbar_new();
4361 gtk_widget_show (main_tb);
4364 pkt_scrollw = packet_list_new(prefs);
4365 WIDGET_SET_SIZE(packet_list, -1, pl_size);
4366 gtk_widget_show(pkt_scrollw);
4369 tv_scrollw = main_tree_view_new(prefs, &tree_view);
4370 WIDGET_SET_SIZE(tv_scrollw, -1, tv_size);
4371 gtk_widget_show(tv_scrollw);
4373 #if GTK_MAJOR_VERSION < 2
4374 SIGNAL_CONNECT(tree_view, "tree-select-row", tree_view_select_row_cb, NULL);
4375 SIGNAL_CONNECT(tree_view, "tree-unselect-row", tree_view_unselect_row_cb,
4378 SIGNAL_CONNECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
4379 "changed", tree_view_selection_changed_cb, NULL);
4381 SIGNAL_CONNECT(tree_view, "button_press_event", popup_menu_handler,
4382 OBJECT_GET_DATA(popup_menu_object, PM_TREE_VIEW_KEY));
4383 gtk_widget_show(tree_view);
4386 byte_nb_ptr = byte_view_new();
4387 WIDGET_SET_SIZE(byte_nb_ptr, -1, bv_size);
4388 gtk_widget_show(byte_nb_ptr);
4390 SIGNAL_CONNECT(byte_nb_ptr, "button_press_event", popup_menu_handler,
4391 OBJECT_GET_DATA(popup_menu_object, PM_HEXDUMP_KEY));
4394 /* Panes for the packet list, tree, and byte view */
4395 main_pane_v1 = gtk_vpaned_new();
4396 gtk_widget_show(main_pane_v1);
4397 main_pane_v2 = gtk_vpaned_new();
4398 gtk_widget_show(main_pane_v2);
4399 main_pane_h1 = gtk_hpaned_new();
4400 gtk_widget_show(main_pane_h1);
4401 main_pane_h2 = gtk_hpaned_new();
4402 gtk_widget_show(main_pane_h2);
4405 /* airpcap toolbar */
4406 #if GTK_MAJOR_VERSION < 2
4407 airpcap_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
4410 airpcap_tb = gtk_toolbar_new();
4411 gtk_toolbar_set_orientation(GTK_TOOLBAR(airpcap_tb),
4412 GTK_ORIENTATION_HORIZONTAL);
4413 #endif /* GTK_MAJOR_VERSION */
4414 gtk_widget_show(airpcap_tb);
4416 /* Interface Label */
4417 if(airpcap_if_active != NULL) {
4418 if_label_text = g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_active));
4419 interface_lb = gtk_label_new(if_label_text);
4420 g_free(if_label_text);
4422 interface_lb = gtk_label_new("No Wireless Interface Found ");
4425 /* Add the label to the toolbar */
4426 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), interface_lb,
4427 "Current Wireless Interface", "Private");
4428 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_INTERFACE_KEY,interface_lb);
4429 gtk_widget_show(interface_lb);
4430 gtk_toolbar_insert_space(GTK_TOOLBAR(airpcap_tb),1);
4433 /* Create the "802.11 Channel:" label */
4434 channel_lb = gtk_label_new(" 802.11 Channel: ");
4435 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_LABEL_KEY,channel_lb);
4436 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_lb,
4437 "Current 802.11 Channel", "Private");
4438 gtk_widget_show(channel_lb);
4440 WIDGET_SET_SIZE(channel_lb, 100, 28);
4442 /* Create the channel combo box */
4443 channel_cm = gtk_combo_new();
4444 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(channel_cm)->entry),FALSE);
4445 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_KEY,channel_cm);
4447 channel_list = g_list_append(channel_list, "1 (2412MHz)");
4448 channel_list = g_list_append(channel_list, "2 (2417MHz)");
4449 channel_list = g_list_append(channel_list, "3 (2422MHz)");
4450 channel_list = g_list_append(channel_list, "4 (2427MHz)");
4451 channel_list = g_list_append(channel_list, "5 (2432MHz)");
4452 channel_list = g_list_append(channel_list, "6 (2437MHz)");
4453 channel_list = g_list_append(channel_list, "7 (2442MHz)");
4454 channel_list = g_list_append(channel_list, "8 (2447MHz)");
4455 channel_list = g_list_append(channel_list, "9 (2452MHz)");
4456 channel_list = g_list_append(channel_list, "10 (2457MHz)");
4457 channel_list = g_list_append(channel_list, "11 (2462MHz)");
4458 channel_list = g_list_append(channel_list, "12 (2467MHz)");
4459 channel_list = g_list_append(channel_list, "13 (2472MHz)");
4460 channel_list = g_list_append(channel_list, "14 (2484MHz)");
4462 gtk_combo_set_popdown_strings( GTK_COMBO(channel_cm), channel_list) ;
4464 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(channel_cm)->entry),
4465 "Change the 802.11 RF channel", NULL);
4467 WIDGET_SET_SIZE(channel_cm, 100, 28);
4469 if(airpcap_if_active != NULL)
4470 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry), airpcap_get_channel_name(airpcap_if_active->channel));
4472 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry),"");
4474 /* callback for channel combo box */
4475 SIGNAL_CONNECT(GTK_COMBO(channel_cm)->entry,"changed",airpcap_toolbar_channel_changed_cb,GTK_COMBO(channel_cm)->entry);
4476 gtk_widget_show(channel_cm);
4478 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_cm,
4479 "802.11 Channel", "Private");
4481 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4483 /* Wrong CRC Label */
4484 wrong_crc_lb = gtk_label_new(" FCS Filter: ");
4485 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_LABEL_KEY,wrong_crc_lb);
4486 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_lb,
4488 gtk_widget_show(wrong_crc_lb);
4490 /* Wrong CRC combo */
4491 wrong_crc_cm = gtk_combo_new();
4492 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(wrong_crc_cm)->entry),FALSE);
4493 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_KEY,wrong_crc_cm);
4494 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_cm,
4497 WIDGET_SET_SIZE(wrong_crc_cm, 100, -1);
4499 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_ALL);
4500 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRECT);
4501 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRUPT);
4503 gtk_combo_set_popdown_strings( GTK_COMBO(wrong_crc_cm), linktype_list) ;
4504 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(wrong_crc_cm)->entry),
4505 "Select the 802.11 FCS filter that the wireless adapter will apply.",
4508 if(airpcap_if_active != NULL)
4509 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry), airpcap_get_validation_name(airpcap_if_active->CrcValidationOn));
4511 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry),"");
4513 SIGNAL_CONNECT(GTK_COMBO(wrong_crc_cm)->entry,"changed",airpcap_toolbar_wrong_crc_combo_cb,airpcap_tb);
4514 gtk_widget_show(wrong_crc_cm);
4516 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4518 /* Decryption mode combo box */
4519 enable_decryption_lb = gtk_label_new ("Decryption Mode: ");
4520 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_LABEL_KEY,enable_decryption_lb);
4521 gtk_widget_set_name (enable_decryption_lb, "enable_decryption_lb");
4522 gtk_widget_show (enable_decryption_lb);
4523 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_lb,
4526 enable_decryption_cb = gtk_combo_new ();
4527 gtk_widget_set_name (enable_decryption_cb, "enable_decryption_cb");
4528 gtk_widget_show (enable_decryption_cb);
4529 WIDGET_SET_SIZE (enable_decryption_cb, 83, -1);
4530 update_decryption_mode_list(enable_decryption_cb);
4532 enable_decryption_en = GTK_COMBO (enable_decryption_cb)->entry;
4533 gtk_widget_set_name (enable_decryption_en, "enable_decryption_en");
4534 gtk_widget_show (enable_decryption_en);
4535 gtk_editable_set_editable (GTK_EDITABLE (enable_decryption_en), FALSE);
4536 GTK_WIDGET_UNSET_FLAGS (enable_decryption_en, GTK_CAN_FOCUS);
4538 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_cb,
4539 "Choose a Decryption Mode", "Private");
4541 /* Set current decryption mode!!!! */
4542 update_decryption_mode_cm(enable_decryption_cb);
4543 SIGNAL_CONNECT (enable_decryption_en, "changed",on_enable_decryption_en_changed, airpcap_tb);
4544 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_KEY,enable_decryption_cb);
4546 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4548 /* Advanced button */
4549 advanced_bt = gtk_button_new_with_label("Wireless Settings...");
4550 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_ADVANCED_KEY,advanced_bt);
4552 SIGNAL_CONNECT(advanced_bt, "clicked", toolbar_display_airpcap_advanced_cb, airpcap_tb);
4553 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), advanced_bt,
4554 "Set Advanced Wireless Settings", "Private");
4555 gtk_widget_show(advanced_bt);
4557 /* Key Management button */
4558 key_management_bt = gtk_button_new_with_label("Decryption Keys...");
4559 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY,key_management_bt);
4561 SIGNAL_CONNECT(key_management_bt, "clicked", toolbar_display_airpcap_key_management_cb, airpcap_tb);
4562 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), key_management_bt,
4563 "Manage Decryption Keys", "Private");
4564 gtk_widget_show(key_management_bt);
4566 /* select the default interface */
4567 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
4569 /* If no airpcap interface is present, gray everything */
4570 if(airpcap_if_active == NULL) {
4571 if(airpcap_if_list == NULL) {
4572 /*No airpcap device found */
4573 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4574 /* recent.airpcap_toolbar_show = TRUE; */
4576 /* default adapter is not airpcap... or is airpcap but is not found*/
4577 airpcap_set_toolbar_stop_capture(airpcap_if_active);
4578 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4579 /* recent.airpcap_toolbar_show = TRUE; */
4582 airpcap_set_toolbar_stop_capture(airpcap_if_active);
4583 /* recent.airpcap_toolbar_show = TRUE; */
4587 /* filter toolbar */
4588 #if GTK_MAJOR_VERSION < 2
4589 filter_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
4592 filter_tb = gtk_toolbar_new();
4593 gtk_toolbar_set_orientation(GTK_TOOLBAR(filter_tb),
4594 GTK_ORIENTATION_HORIZONTAL);
4595 #endif /* GTK_MAJOR_VERSION */
4596 gtk_widget_show(filter_tb);
4598 /* Create the "Filter:" button */
4599 filter_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
4600 SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
4601 gtk_widget_show(filter_bt);
4602 OBJECT_SET_DATA(top_level, E_FILT_BT_PTR_KEY, filter_bt);
4604 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_bt,
4605 "Open the \"Display Filter\" dialog, to edit/apply filters", "Private");
4607 /* Create the filter combobox */
4608 filter_cm = gtk_combo_new();
4609 dfilter_list = NULL;
4610 gtk_combo_disable_activate(GTK_COMBO(filter_cm));
4611 gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
4612 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
4613 filter_te = GTK_COMBO(filter_cm)->entry;
4614 main_display_filter_widget=filter_te;
4615 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
4616 OBJECT_SET_DATA(filter_te, E_DFILTER_CM_KEY, filter_cm);
4617 OBJECT_SET_DATA(top_level, E_DFILTER_CM_KEY, filter_cm);
4618 SIGNAL_CONNECT(filter_te, "activate", filter_activate_cb, filter_te);
4619 SIGNAL_CONNECT(filter_te, "changed", filter_te_syntax_check_cb, NULL);
4620 WIDGET_SET_SIZE(filter_cm, 400, -1);
4621 gtk_widget_show(filter_cm);
4622 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_cm,
4624 /* setting a tooltip for a combobox will do nothing, so add it to the corresponding text entry */
4625 gtk_tooltips_set_tip(tooltips, filter_te,
4626 "Enter a display filter, or choose one of your recently used filters. "
4627 "The background color of this field is changed by a continuous syntax check (green is valid, red is invalid).",
4630 /* Create the "Add Expression..." button, to pop up a dialog
4631 for constructing filter comparison expressions. */
4632 filter_add_expr_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_ADD_EXPRESSION);
4633 OBJECT_SET_DATA(filter_tb, E_FILT_FILTER_TE_KEY, filter_te);
4634 SIGNAL_CONNECT(filter_add_expr_bt, "clicked", filter_add_expr_bt_cb, filter_tb);
4635 gtk_widget_show(filter_add_expr_bt);
4636 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_add_expr_bt,
4637 "Add an expression to this filter string", "Private");
4639 /* Create the "Clear" button */
4640 filter_reset = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLEAR);
4641 OBJECT_SET_DATA(filter_reset, E_DFILTER_TE_KEY, filter_te);
4642 SIGNAL_CONNECT(filter_reset, "clicked", filter_reset_cb, NULL);
4643 gtk_widget_show(filter_reset);
4644 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_reset,
4645 "Clear this filter string and update the display", "Private");
4647 /* Create the "Apply" button */
4648 filter_apply = BUTTON_NEW_FROM_STOCK(GTK_STOCK_APPLY);
4649 OBJECT_SET_DATA(filter_apply, E_DFILTER_CM_KEY, filter_cm);
4650 SIGNAL_CONNECT(filter_apply, "clicked", filter_activate_cb, filter_te);
4651 gtk_widget_show(filter_apply);
4652 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_apply,
4653 "Apply this filter string to the display", "Private");
4655 /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data
4656 * of any widget that ends up calling a callback which needs
4657 * that text entry pointer */
4658 set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te);
4659 set_menu_object_data("/Edit/Copy/As Filter", E_DFILTER_TE_KEY,
4661 set_menu_object_data("/Analyze/Display Filters...", E_FILT_TE_PTR_KEY,
4663 set_menu_object_data("/Analyze/Follow TCP Stream", E_DFILTER_TE_KEY,
4665 set_menu_object_data("/Analyze/Follow SSL Stream", E_DFILTER_TE_KEY,
4667 set_menu_object_data("/Analyze/Apply as Filter/Selected", E_DFILTER_TE_KEY,
4669 set_menu_object_data("/Analyze/Apply as Filter/Not Selected", E_DFILTER_TE_KEY,
4671 set_menu_object_data("/Analyze/Apply as Filter/... and Selected", E_DFILTER_TE_KEY,
4673 set_menu_object_data("/Analyze/Apply as Filter/... or Selected", E_DFILTER_TE_KEY,
4675 set_menu_object_data("/Analyze/Apply as Filter/... and not Selected", E_DFILTER_TE_KEY,
4677 set_menu_object_data("/Analyze/Apply as Filter/... or not Selected", E_DFILTER_TE_KEY,
4679 set_menu_object_data("/Analyze/Prepare a Filter/Selected", E_DFILTER_TE_KEY,
4681 set_menu_object_data("/Analyze/Prepare a Filter/Not Selected", E_DFILTER_TE_KEY,
4683 set_menu_object_data("/Analyze/Prepare a Filter/... and Selected", E_DFILTER_TE_KEY,
4685 set_menu_object_data("/Analyze/Prepare a Filter/... or Selected", E_DFILTER_TE_KEY,
4687 set_menu_object_data("/Analyze/Prepare a Filter/... and not Selected", E_DFILTER_TE_KEY,
4689 set_menu_object_data("/Analyze/Prepare a Filter/... or not Selected", E_DFILTER_TE_KEY,
4691 set_menu_object_data("/Conversation Filter/Ethernet", E_DFILTER_TE_KEY,
4693 set_menu_object_data("/Conversation Filter/IP", E_DFILTER_TE_KEY,
4695 set_menu_object_data("/Conversation Filter/TCP", E_DFILTER_TE_KEY,
4697 set_menu_object_data("/Conversation Filter/UDP", E_DFILTER_TE_KEY,
4699 set_menu_object_data("/Conversation Filter/PN-CBA Server", E_DFILTER_TE_KEY,
4701 set_toolbar_object_data(E_DFILTER_TE_KEY, filter_te);
4702 OBJECT_SET_DATA(popup_menu_object, E_DFILTER_TE_KEY, filter_te);
4703 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_KEY, packet_list);
4705 /* info (main) statusbar */
4706 info_bar = info_bar_new();
4707 gtk_widget_show(info_bar);
4709 /* packets statusbar */
4710 packets_bar = packets_bar_new();
4711 gtk_widget_show(packets_bar);
4713 /* Filter/status hbox */
4714 stat_hbox = gtk_hbox_new(FALSE, 1);
4715 gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
4716 gtk_widget_show(stat_hbox);
4718 /* Pane for the statusbar */
4719 status_pane = gtk_hpaned_new();
4720 gtk_widget_show(status_pane);
4722 /* Pane for the welcome screen */
4723 welcome_pane = welcome_new();
4724 gtk_widget_show(welcome_pane);
4729 driver_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
4733 r = simple_dialog_check_get(dialog);
4734 recent.airpcap_driver_check_show = !r;
4739 show_main_window(gboolean doing_work)
4741 main_set_for_capture_file(doing_work);
4743 /*** we have finished all init things, show the main window ***/
4744 gtk_widget_show(top_level);
4746 /* the window can be maximized only, if it's visible, so do it after show! */
4747 main_load_window_geometry(top_level);
4749 /* process all pending GUI events before continue */
4750 while (gtk_events_pending()) gtk_main_iteration();
4752 /* Pop up any queued-up alert boxes. */
4753 display_queued_messages();
4757 * This will read the decryption keys from the preferences file, and will
4758 * store them into the registry...
4760 if(!airpcap_check_decryption_keys(airpcap_if_list)) {
4761 /* Ask the user what to do ...*/
4762 airpcap_keys_check_w(NULL,NULL);
4764 /* Keys from lists are equals, or wireshark has got no keys */
4765 airpcap_load_decryption_keys(airpcap_if_list);
4768 switch (airpcap_dll_ret_val) {
4770 case AIRPCAP_DLL_OK:
4773 case AIRPCAP_DLL_OLD:
4774 if(recent.airpcap_driver_check_show) {
4775 driver_warning_dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
4776 "WARNING: The version of AirPcap on this system\n"
4777 "does not support driver-level decryption. Please\n"
4778 "download a more recent version from\n" "http://www.cacetech.com/support/downloads.htm \n");
4779 simple_dialog_check_set(driver_warning_dialog,"Don't show this message again.");
4780 simple_dialog_set_cb(driver_warning_dialog, driver_warning_dialog_cb, (gpointer) driver_warning_dialog);
4786 * XXX - Maybe we need to warn the user if one of the following happens???
4788 case AIRPCAP_DLL_ERROR:
4789 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
4792 case AIRPCAP_DLL_NOT_FOUND:
4793 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
4797 #endif /* HAVE_AIRPCAP */
4800 /* Fill in capture options with values from the preferences */
4802 prefs_to_capture_opts(void)
4805 /* Set promiscuous mode from the preferences setting. */
4806 /* the same applies to other preferences settings as well. */
4807 capture_opts->promisc_mode = prefs.capture_prom_mode;
4808 capture_opts->show_info = prefs.capture_show_info;
4809 capture_opts->real_time_mode = prefs.capture_real_time;
4810 auto_scroll_live = prefs.capture_auto_scroll;
4811 #endif /* HAVE_LIBPCAP */
4813 /* Set the name resolution code's flags from the preferences. */
4814 g_resolv_flags = prefs.name_resolve;