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 #if GTK_MAJOR_VERSION >= 2
158 #include "../image/wsicon16.xpm"
159 #include "../image/wsicon32.xpm"
160 #include "../image/wsicon48.xpm"
161 #include "../image/wsicon64.xpm"
162 #include "../image/wsiconcap16.xpm"
163 #include "../image/wsiconcap32.xpm"
164 #include "../image/wsiconcap48.xpm"
166 #ifdef SHOW_WELCOME_PAGE
167 #include "../image/wssplash.xpm"
172 #include "airpcap_loader.h"
173 #include "airpcap_dlg.h"
174 #include "airpcap_gui_utils.h"
176 #include "./gtk/toolbar.h"
178 #include "./image/toolbar/wep_closed_24.xpm"
182 /* Davide Schiera (2006-11-22): including AirPDcap project */
183 #include <epan/crypt/airpdcap_ws.h>
184 /* Davide Schiera (2006-11-22) ---------------------------------------------- */
188 * Files under personal and global preferences directories in which
189 * GTK settings for Wireshark are stored.
191 #define RC_FILE "gtkrc"
194 #define DEF_READY_MESSAGE " Ready to load or capture"
196 #define DEF_READY_MESSAGE " Ready to load file"
200 GtkWidget *main_display_filter_widget=NULL;
201 GtkWidget *top_level = NULL, *tree_view, *byte_nb_ptr, *tv_scrollw;
202 static GtkWidget *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
203 static GtkWidget *main_first_pane, *main_second_pane;
204 static GtkWidget *status_pane;
205 static GtkWidget *menubar, *main_vbox, *main_tb, *pkt_scrollw, *stat_hbox, *filter_tb;
208 GtkWidget *airpcap_tb;
209 static GtkWidget *driver_warning_dialog;
210 static int airpcap_dll_ret_val = -1;
213 static GtkWidget *info_bar;
214 static GtkWidget *packets_bar = NULL;
215 static GtkWidget *welcome_pane;
216 static guint main_ctx, file_ctx, help_ctx;
217 static guint packets_ctx;
218 static gchar *packets_str = NULL;
219 GString *comp_info_str, *runtime_info_str;
220 gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
223 static gboolean has_console; /* TRUE if app has console */
224 static void destroy_console(void);
226 static void console_log_handler(const char *log_domain,
227 GLogLevelFlags log_level, const char *message, gpointer user_data);
230 static gboolean list_link_layer_types;
231 capture_options global_capture_opts;
232 capture_options *capture_opts = &global_capture_opts;
235 gboolean block_toolbar_signals = FALSE;
237 static void create_main_window(gint, gint, gint, e_prefs*);
238 static void show_main_window(gboolean);
239 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
240 static void main_save_window_geometry(GtkWidget *widget);
242 #define E_DFILTER_CM_KEY "display_filter_combo"
243 #define E_DFILTER_FL_KEY "display_filter_list"
245 /* Match selected byte pattern */
247 match_selected_cb_do(gpointer data, int action, gchar *text)
249 GtkWidget *filter_te;
250 char *cur_filter, *new_filter;
252 if ((!text) || (0 == strlen(text))) {
253 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
258 filter_te = OBJECT_GET_DATA(data, E_DFILTER_TE_KEY);
261 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
263 switch (action&MATCH_SELECTED_MASK) {
265 case MATCH_SELECTED_REPLACE:
266 new_filter = g_strdup(text);
269 case MATCH_SELECTED_AND:
270 if ((!cur_filter) || (0 == strlen(cur_filter)))
271 new_filter = g_strdup(text);
273 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
276 case MATCH_SELECTED_OR:
277 if ((!cur_filter) || (0 == strlen(cur_filter)))
278 new_filter = g_strdup(text);
280 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
283 case MATCH_SELECTED_NOT:
284 new_filter = g_strconcat("!(", text, ")", NULL);
287 case MATCH_SELECTED_AND_NOT:
288 if ((!cur_filter) || (0 == strlen(cur_filter)))
289 new_filter = g_strconcat("!(", text, ")", NULL);
291 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
294 case MATCH_SELECTED_OR_NOT:
295 if ((!cur_filter) || (0 == strlen(cur_filter)))
296 new_filter = g_strconcat("!(", text, ")", NULL);
298 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
302 g_assert_not_reached();
307 /* Free up the copy we got of the old filter text. */
310 /* Don't change the current display filter if we only want to copy the filter */
311 if (action&MATCH_SELECTED_COPY_ONLY) {
312 GString *gtk_text_str = g_string_new("");
313 g_string_sprintfa(gtk_text_str, "%s", new_filter);
314 copy_to_clipboard(gtk_text_str);
315 g_string_free(gtk_text_str, TRUE);
317 /* create a new one and set the display filter entry accordingly */
318 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
320 /* Run the display filter so it goes in effect. */
321 if (action&MATCH_SELECTED_APPLY_NOW)
322 main_filter_packets(&cfile, new_filter, FALSE);
325 /* Free up the new filter text. */
330 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
334 if (cfile.finfo_selected) {
335 filter = proto_construct_match_selected_string(cfile.finfo_selected,
337 match_selected_cb_do((data ? data : w), action, filter);
342 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
344 gchar *selected_proto_url;
345 gchar *proto_abbrev = data;
350 if (cfile.finfo_selected) {
351 /* open wiki page using the protocol abbreviation */
352 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
353 browser_open_url(selected_proto_url);
354 g_free(selected_proto_url);
357 case(ESD_BTN_CANCEL):
360 g_assert_not_reached();
366 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
369 const gchar *proto_abbrev;
373 if (cfile.finfo_selected) {
374 /* convert selected field to protocol abbreviation */
375 /* XXX - could this conversion be simplified? */
376 field_id = cfile.finfo_selected->hfinfo->id;
377 /* if the selected field isn't a protocol, get it's parent */
378 if(!proto_registrar_is_protocol(field_id)) {
379 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
382 proto_abbrev = proto_registrar_get_abbrev(field_id);
384 /* ask the user if the wiki page really should be opened */
385 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
386 PRIMARY_TEXT_START "Open Wireshark Wiki page of protocol \"%s\"?" PRIMARY_TEXT_END "\n"
388 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
390 "The Wireshark Wiki is a collaborative approach to provide information\n"
391 "about Wireshark in several ways (not limited to protocol specifics).\n"
393 "This Wiki is new, so the page of the selected protocol\n"
394 "may not exist and/or may not contain valuable information.\n"
396 "As everyone can edit the Wiki and add new content (or extend existing),\n"
397 "you are encouraged to add information if you can.\n"
399 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
401 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate,\n"
402 "which will save you a lot of editing and will give a consistent look over the pages.",
403 proto_abbrev, proto_abbrev);
404 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer) proto_abbrev);
410 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
413 const gchar *proto_abbrev;
414 gchar *selected_proto_url;
417 if (cfile.finfo_selected) {
418 /* convert selected field to protocol abbreviation */
419 /* XXX - could this conversion be simplified? */
420 field_id = cfile.finfo_selected->hfinfo->id;
421 /* if the selected field isn't a protocol, get it's parent */
422 if(!proto_registrar_is_protocol(field_id)) {
423 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
426 proto_abbrev = proto_registrar_get_abbrev(field_id);
428 /* open reference page using the protocol abbreviation */
429 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s.html", proto_abbrev[0], proto_abbrev);
430 browser_open_url(selected_proto_url);
431 g_free(selected_proto_url);
436 get_text_from_packet_list(gpointer data)
438 gint row = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_ROW_KEY));
439 gint column = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_COL_KEY));
440 frame_data *fdata = (frame_data *)packet_list_get_row_data(row);
448 if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
449 cfile.pd, fdata->cap_len, &err, &err_info)) {
450 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
451 cf_read_error_message(err, err_info), cfile.filename);
455 edt = epan_dissect_new(FALSE, FALSE);
456 epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata,
458 epan_dissect_fill_in_columns(edt);
460 if (strlen(cfile.cinfo.col_expr[column]) != 0 &&
461 strlen(cfile.cinfo.col_expr_val[column]) != 0) {
462 len = strlen(cfile.cinfo.col_expr[column]) +
463 strlen(cfile.cinfo.col_expr_val[column]) + 5;
464 buf = ep_alloc0(len);
465 g_snprintf(buf, len, "%s == %s", cfile.cinfo.col_expr[column],
466 cfile.cinfo.col_expr_val[column]);
469 epan_dissect_free(edt);
476 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
478 match_selected_cb_do(data,
480 get_text_from_packet_list(data));
483 /* This function allows users to right click in the details window and copy the text
484 * information to the operating systems clipboard.
486 * We first check to see if a string representation is setup in the tree and then
487 * read the string. If not available then we try to grab the value. If all else
488 * fails we display a message to the user to indicate the copy could not be completed.
491 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_)
493 GString *gtk_text_str = g_string_new("");
494 char labelstring[256];
495 char *stringpointer = labelstring;
497 if (cfile.finfo_selected->rep->representation != 0) {
498 g_string_sprintfa(gtk_text_str, "%s", cfile.finfo_selected->rep->representation); /* Get the represented data */
500 if (gtk_text_str->len == 0) { /* If no representation then... */
501 proto_item_fill_label(cfile.finfo_selected, stringpointer); /* Try to read the value */
502 g_string_sprintfa(gtk_text_str, "%s", stringpointer);
504 if (gtk_text_str->len == 0) { /* Could not get item so display error msg */
505 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
509 copy_to_clipboard(gtk_text_str); /* Copy string to clipboard */
511 g_string_free(gtk_text_str, TRUE); /* Free the memory */
515 /* XXX: use a preference for this setting! */
516 static guint dfilter_combo_max_recent = 10;
518 /* add a display filter to the combo box */
519 /* Note: a new filter string will replace an old identical one */
521 dfilter_combo_add(GtkWidget *filter_cm, char *s) {
523 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
526 /* GtkCombos don't let us get at their list contents easily, so we maintain
527 our own filter list, and feed it to gtk_combo_set_popdown_strings when
528 a new filter is added. */
529 li = g_list_first(dfilter_list);
531 /* If the filter is already in the list, remove the old one and
532 * append the new one at the latest position (at g_list_append() below) */
533 if (li->data && strcmp(s, li->data) == 0) {
534 dfilter_list = g_list_remove(dfilter_list, li->data);
540 dfilter_list = g_list_append(dfilter_list, s);
541 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
542 gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), dfilter_list);
543 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), g_list_last(dfilter_list)->data);
549 /* write all non empty display filters (until maximum count)
550 * of the combo box GList to the user's recent file */
552 dfilter_recent_combo_write_all(FILE *rf) {
553 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
554 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
559 /* write all non empty display filter strings to the recent file (until max count) */
560 li = g_list_first(dfilter_list);
561 while ( li && (max_count++ <= dfilter_combo_max_recent) ) {
562 if (strlen(li->data)) {
563 fprintf (rf, RECENT_KEY_DISPLAY_FILTER ": %s\n", (char *)li->data);
569 /* empty the combobox entry field */
571 dfilter_combo_add_empty(void) {
572 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
574 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), "");
578 /* add a display filter coming from the user's recent file to the dfilter combo box */
580 dfilter_combo_add_recent(gchar *s) {
581 GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
585 if (!dfilter_combo_add(filter_cm, dup)) {
594 /* call cf_filter_packets() and add this filter string to the recent filter list */
596 main_filter_packets(capture_file *cf, const gchar *dftext, gboolean force)
598 GtkCombo *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
599 GList *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
601 gboolean add_filter = TRUE;
602 gboolean free_filter = TRUE;
604 cf_status_t cf_status;
606 s = g_strdup(dftext);
608 cf_status = cf_filter_packets(cf, s, force);
610 return (cf_status == CF_OK);
612 /* GtkCombos don't let us get at their list contents easily, so we maintain
613 our own filter list, and feed it to gtk_combo_set_popdown_strings when
614 a new filter is added. */
615 if (cf_status == CF_OK) {
616 li = g_list_first(dfilter_list);
618 if (li->data && strcmp(s, li->data) == 0)
624 /* trim list size first */
625 while (g_list_length(dfilter_list) >= dfilter_combo_max_recent) {
626 dfilter_list = g_list_remove(dfilter_list, g_list_first(dfilter_list)->data);
630 dfilter_list = g_list_append(dfilter_list, s);
631 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
632 gtk_combo_set_popdown_strings(filter_cm, dfilter_list);
633 gtk_entry_set_text(GTK_ENTRY(filter_cm->entry), g_list_last(dfilter_list)->data);
639 return (cf_status == CF_OK);
643 /* Run the current display filter on the current packet set, and
646 filter_activate_cb(GtkWidget *w _U_, gpointer data)
650 s = gtk_entry_get_text(GTK_ENTRY(data));
652 main_filter_packets(&cfile, s, FALSE);
655 /* redisplay with no display filter */
657 filter_reset_cb(GtkWidget *w, gpointer data _U_)
659 GtkWidget *filter_te = NULL;
661 if ((filter_te = OBJECT_GET_DATA(w, E_DFILTER_TE_KEY))) {
662 gtk_entry_set_text(GTK_ENTRY(filter_te), "");
664 main_filter_packets(&cfile, NULL, FALSE);
667 /* mark as reference time frame */
669 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
673 frame->flags.ref_time=1;
675 frame->flags.ref_time=0;
677 cf_reftime_packets(&cfile);
681 GtkWidget *reftime_dialog = NULL;
683 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
687 timestamp_set_type(TS_RELATIVE);
688 recent.gui_time_format = TS_RELATIVE;
689 cf_change_time_formats(&cfile);
694 g_assert_not_reached();
697 if (cfile.current_frame) {
698 /* XXX hum, should better have a "cfile->current_row" here ... */
699 set_frame_reftime(!cfile.current_frame->flags.ref_time,
701 packet_list_find_row_from_data(cfile.current_frame));
707 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
712 if (cfile.current_frame) {
713 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
714 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
715 PRIMARY_TEXT_START "Switch to the appropriate Time Display Format?" PRIMARY_TEXT_END "\n\n"
716 "Time References don't work well with the currently selected Time Display Format.\n\n"
717 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?");
718 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
720 /* XXX hum, should better have a "cfile->current_row" here ... */
721 set_frame_reftime(!cfile.current_frame->flags.ref_time,
723 packet_list_find_row_from_data(cfile.current_frame));
727 case REFTIME_FIND_NEXT:
728 find_previous_next_frame_with_filter("frame.ref_time", FALSE);
730 case REFTIME_FIND_PREV:
731 find_previous_next_frame_with_filter("frame.ref_time", TRUE);
737 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
739 find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
743 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
745 find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
748 #if GTK_MAJOR_VERSION < 2
750 tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_,
751 gpointer user_data _U_)
754 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
758 gchar *help_str = NULL;
759 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
761 gboolean has_blurb = FALSE;
762 guint length = 0, byte_len;
763 GtkWidget *byte_view;
764 const guint8 *byte_data;
765 #if GTK_MAJOR_VERSION >= 2
770 #if GTK_MAJOR_VERSION >= 2
771 /* if nothing is selected */
772 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
775 * Which byte view is displaying the current protocol tree
778 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
779 if (byte_view == NULL)
782 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
783 if (byte_data == NULL)
786 cf_unselect_field(&cfile);
787 packet_hex_print(byte_view, byte_data,
788 cfile.current_frame, NULL, byte_len);
791 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
794 finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
798 set_notebook_page(byte_nb_ptr, finfo->ds_tvb);
800 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
801 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
802 g_assert(byte_data != NULL);
804 cfile.finfo_selected = finfo;
805 set_menus_for_selected_tree_row(&cfile);
808 if (finfo->hfinfo->blurb != NULL &&
809 finfo->hfinfo->blurb[0] != '\0') {
811 length = strlen(finfo->hfinfo->blurb);
813 length = strlen(finfo->hfinfo->name);
815 if (finfo->length == 0) {
817 } else if (finfo->length == 1) {
818 strcpy (len_str, ", 1 byte");
820 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo->length);
822 statusbar_pop_field_msg(); /* get rid of current help msg */
824 help_str = g_strdup_printf("%s (%s)%s",
825 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
826 finfo->hfinfo->abbrev, len_str);
827 statusbar_push_field_msg(help_str);
831 * Don't show anything if the field name is zero-length;
832 * the pseudo-field for "proto_tree_add_text()" is such
833 * a field, and we don't want "Text (text)" showing up
834 * on the status line if you've selected such a field.
836 * XXX - there are zero-length fields for which we *do*
837 * want to show the field name.
839 * XXX - perhaps the name and abbrev field should be null
840 * pointers rather than null strings for that pseudo-field,
841 * but we'd have to add checks for null pointers in some
842 * places if we did that.
844 * Or perhaps protocol tree items added with
845 * "proto_tree_add_text()" should have -1 as the field index,
846 * with no pseudo-field being used, but that might also
847 * require special checks for -1 to be added.
849 statusbar_push_field_msg("");
853 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
857 #if GTK_MAJOR_VERSION < 2
859 tree_view_unselect_row_cb(GtkCTree *ctree _U_, GList *node _U_, gint column _U_,
860 gpointer user_data _U_)
862 GtkWidget *byte_view;
867 * Which byte view is displaying the current protocol tree
870 byte_view = get_notebook_bv_ptr(byte_nb_ptr);
871 if (byte_view == NULL)
874 data = get_byte_view_data_and_length(byte_view, &len);
878 cf_unselect_field(&cfile);
879 packet_hex_print(byte_view, data, cfile.current_frame, NULL, len);
883 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
885 collapse_all_tree(cfile.edt->tree, tree_view);
888 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
890 expand_all_tree(cfile.edt->tree, tree_view);
893 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
894 #if GTK_MAJOR_VERSION < 2
900 #if GTK_MAJOR_VERSION < 2
901 node = gtk_ctree_find_by_row_data(GTK_CTREE(tree_view), NULL, cfile.finfo_selected);
903 /* the mouse position is at an entry, expand that one */
904 gtk_ctree_expand_recursive(GTK_CTREE(tree_view), node);
907 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view), cfile.finfo_selected);
909 /* the mouse position is at an entry, expand that one */
910 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view), path, TRUE);
911 gtk_tree_path_free(path);
916 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
917 if (cfile.edt->tree) {
918 guint32 tmp = g_resolv_flags;
919 g_resolv_flags = RESOLV_ALL;
920 proto_tree_draw(cfile.edt->tree, tree_view);
921 g_resolv_flags = tmp;
926 * Push a message referring to file access onto the statusbar.
929 statusbar_push_file_msg(const gchar *msg)
931 /*g_warning("statusbar_push: %s", msg);*/
932 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
936 * Pop a message referring to file access off the statusbar.
939 statusbar_pop_file_msg(void)
941 /*g_warning("statusbar_pop");*/
942 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
946 * XXX - do we need multiple statusbar contexts?
950 * Push a message referring to the currently-selected field onto the statusbar.
953 statusbar_push_field_msg(const gchar *msg)
955 gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
959 * Pop a message referring to the currently-selected field off the statusbar.
962 statusbar_pop_field_msg(void)
964 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
968 * update the packets statusbar to the current values
970 void packets_bar_update(void)
974 /* remove old status */
977 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
980 /* do we have any packets? */
982 if(cfile.drops_known) {
983 packets_str = g_strdup_printf(" P: %u D: %u M: %u Drops: %u",
984 cfile.count, cfile.displayed_count, cfile.marked_count, cfile.drops);
986 packets_str = g_strdup_printf(" P: %u D: %u M: %u",
987 cfile.count, cfile.displayed_count, cfile.marked_count);
990 packets_str = g_strdup(" No Packets");
992 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str);
997 main_set_for_capture_file(gboolean have_capture_file_in)
999 have_capture_file = have_capture_file_in;
1001 main_widgets_show_or_hide();
1007 /* get the current geometry, before writing it to disk */
1008 main_save_window_geometry(top_level);
1010 /* write user's recent file to disk
1011 * It is no problem to write this file, even if we do not quit */
1014 /* XXX - should we check whether the capture file is an
1015 unsaved temporary file for a live capture and, if so,
1016 pop up a "do you want to exit without saving the capture
1017 file?" dialog, and then just return, leaving said dialog
1018 box to forcibly quit if the user clicks "OK"?
1020 If so, note that this should be done in a subroutine that
1021 returns TRUE if we do so, and FALSE otherwise, and if it
1022 returns TRUE we should return TRUE without nuking anything.
1024 Note that, if we do that, we might also want to check if
1025 an "Update list of packets in real time" capture is in
1026 progress and, if so, ask whether they want to terminate
1027 the capture and discard it, and return TRUE, before nuking
1028 any child capture, if they say they don't want to do so. */
1031 /* Nuke any child capture in progress. */
1032 capture_kill_child(capture_opts);
1035 /* Are we in the middle of reading a capture? */
1036 if (cfile.state == FILE_READ_IN_PROGRESS) {
1037 /* Yes, so we can't just close the file and quit, as
1038 that may yank the rug out from under the read in
1039 progress; instead, just set the state to
1040 "FILE_READ_ABORTED" and return - the code doing the read
1041 will check for that and, if it sees that, will clean
1043 cfile.state = FILE_READ_ABORTED;
1045 /* Say that the window should *not* be deleted;
1046 that'll be done by the code that cleans up. */
1049 /* Close any capture file we have open; on some OSes, you
1050 can't unlink a temporary capture file if you have it
1052 "cf_close()" will unlink it after closing it if
1053 it's a temporary file.
1055 We do this here, rather than after the main loop returns,
1056 as, after the main loop returns, the main window may have
1057 been destroyed (if this is called due to a "destroy"
1058 even on the main window rather than due to the user
1059 selecting a menu item), and there may be a crash
1060 or other problem when "cf_close()" tries to
1061 clean up stuff in the main window.
1063 XXX - is there a better place to put this?
1064 Or should we have a routine that *just* closes the
1065 capture file, and doesn't do anything with the UI,
1066 which we'd call here, and another routine that
1067 calls that routine and also cleans up the UI, which
1068 we'd call elsewhere? */
1071 /* Exit by leaving the main loop, so that any quit functions
1072 we registered get called. */
1075 /* Say that the window should be deleted. */
1081 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1085 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1086 #if GTK_MAJOR_VERSION >= 2
1087 gtk_window_present(GTK_WINDOW(top_level));
1089 /* user didn't saved his current file, ask him */
1090 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1091 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1092 "If you quit the program without saving, your capture data will be discarded.");
1093 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1096 /* unchanged file, just exit */
1097 /* "main_do_quit()" indicates whether the main window should be deleted. */
1098 return main_do_quit();
1105 main_load_window_geometry(GtkWidget *widget)
1107 window_geometry_t geom;
1109 geom.set_pos = prefs.gui_geometry_save_position;
1110 geom.x = recent.gui_geometry_main_x;
1111 geom.y = recent.gui_geometry_main_y;
1112 geom.set_size = prefs.gui_geometry_save_size;
1113 if (recent.gui_geometry_main_width > 0 &&
1114 recent.gui_geometry_main_height > 0) {
1115 geom.width = recent.gui_geometry_main_width;
1116 geom.height = recent.gui_geometry_main_height;
1117 geom.set_maximized = prefs.gui_geometry_save_maximized;
1119 /* We assume this means the width and height weren't set in
1120 the "recent" file (or that there is no "recent" file),
1121 and weren't set to a default value, so we don't set the
1122 size. (The "recent" file code rejects non-positive width
1123 and height values.) */
1124 geom.set_size = FALSE;
1126 geom.maximized = recent.gui_geometry_main_maximized;
1128 window_set_geometry(widget, &geom);
1130 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1131 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1132 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
1133 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1134 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_status_pane)
1135 gtk_paned_set_position(GTK_PANED(status_pane), recent.gui_geometry_status_pane);
1140 main_save_window_geometry(GtkWidget *widget)
1142 window_geometry_t geom;
1144 window_get_geometry(widget, &geom);
1146 if (prefs.gui_geometry_save_position) {
1147 recent.gui_geometry_main_x = geom.x;
1148 recent.gui_geometry_main_y = geom.y;
1151 if (prefs.gui_geometry_save_size) {
1152 recent.gui_geometry_main_width = geom.width,
1153 recent.gui_geometry_main_height = geom.height;
1156 #if GTK_MAJOR_VERSION >= 2
1157 if(prefs.gui_geometry_save_maximized) {
1158 recent.gui_geometry_main_maximized = geom.maximized;
1161 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1162 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1163 recent.gui_geometry_status_pane = gtk_paned_get_position(GTK_PANED(status_pane));
1167 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1171 /* save file first */
1172 file_save_as_cmd(after_save_exit, NULL);
1174 case(ESD_BTN_DONT_SAVE):
1177 case(ESD_BTN_CANCEL):
1180 g_assert_not_reached();
1185 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1189 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1190 /* user didn't saved his current file, ask him */
1191 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1192 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1193 "If you quit the program without saving, your capture data will be discarded.");
1194 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1196 /* unchanged file, just exit */
1202 print_usage(gboolean print_ver) {
1212 fprintf(output, "Wireshark " VERSION "%s\n"
1213 "Interactively dump and analyze network traffic.\n"
1214 "See http://www.wireshark.org for more information.\n"
1217 wireshark_svnversion, get_copyright_info());
1221 fprintf(output, "\n");
1222 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1223 fprintf(output, "\n");
1226 fprintf(output, "Capture interface:\n");
1227 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1228 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1229 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1230 fprintf(output, " -p don't capture in promiscuous mode\n");
1231 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1232 fprintf(output, " -Q quit Wireshark after capturing\n");
1233 fprintf(output, " -S update packet display when new packets are captured\n");
1234 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1236 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1238 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1239 fprintf(output, " -D print list of interfaces and exit\n");
1240 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1241 fprintf(output, "\n");
1242 fprintf(output, "Capture stop conditions:\n");
1243 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1244 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1245 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1246 fprintf(output, " files:NUM - stop after NUM files\n");
1247 /*fprintf(output, "\n");*/
1248 fprintf(output, "Capture output:\n");
1249 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1250 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1251 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1252 #endif /* HAVE_LIBPCAP */
1254 /*fprintf(output, "\n");*/
1255 fprintf(output, "Input file:\n");
1256 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1258 fprintf(output, "\n");
1259 fprintf(output, "Processing:\n");
1260 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1261 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1262 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1264 fprintf(output, "\n");
1265 fprintf(output, "User interface:\n");
1266 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1267 fprintf(output, " -m <font> set the font name used for most text\n");
1268 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1269 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1270 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1272 fprintf(output, "\n");
1273 fprintf(output, "Output:\n");
1274 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1276 fprintf(output, "\n");
1277 fprintf(output, "Miscellaneous:\n");
1278 fprintf(output, " -h display this help and exit\n");
1279 fprintf(output, " -v display version info and exit\n");
1280 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1281 fprintf(output, " persdata:path - personal data files\n");
1282 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1284 fprintf(output, " --display=DISPLAY X display to use\n");
1299 printf(PACKAGE " " VERSION "%s\n"
1306 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1307 runtime_info_str->str);
1315 * Report an error in command-line arguments.
1316 * Creates a console on Windows.
1317 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1318 * terminal isn't the standard error?
1321 cmdarg_err(const char *fmt, ...)
1329 fprintf(stderr, "wireshark: ");
1330 vfprintf(stderr, fmt, ap);
1331 fprintf(stderr, "\n");
1336 * Report additional information for an error in command-line arguments.
1337 * Creates a console on Windows.
1338 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1339 * terminal isn't the standard error?
1342 cmdarg_err_cont(const char *fmt, ...)
1350 vfprintf(stderr, fmt, ap);
1351 fprintf(stderr, "\n");
1355 #if defined(_WIN32) || GTK_MAJOR_VERSION < 2 || ! defined USE_THREADS
1357 Once every 3 seconds we get a callback here which we use to update
1358 the tap extensions. Since Gtk1 is single threaded we dont have to
1359 worry about any locking or critical regions.
1362 update_cb(gpointer data _U_)
1364 draw_tap_listeners(FALSE);
1369 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1370 use threads all updte_thread_mutex can be dropped and protect/unprotect
1371 would just be empty functions.
1373 This allows gtk2-rpcstat.c and friends to be copied unmodified to
1374 gtk1-wireshark and it will just work.
1376 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1378 update_thread(gpointer data _U_)
1382 g_get_current_time(&tv1);
1383 g_static_mutex_lock(&update_thread_mutex);
1384 gdk_threads_enter();
1385 draw_tap_listeners(FALSE);
1386 gdk_threads_leave();
1387 g_static_mutex_unlock(&update_thread_mutex);
1389 g_get_current_time(&tv2);
1390 if( ((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) >
1391 (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1392 g_usleep(((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) -
1393 (tv2.tv_sec * 1000000 + tv2.tv_usec));
1400 protect_thread_critical_region(void)
1402 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1403 g_static_mutex_lock(&update_thread_mutex);
1407 unprotect_thread_critical_region(void)
1409 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1410 g_static_mutex_unlock(&update_thread_mutex);
1414 /* Set the file name in the status line, in the name for the main window,
1415 and in the name for the main window's icon. */
1417 set_display_filename(capture_file *cf)
1419 const gchar *name_ptr;
1424 name_ptr = cf_get_display_name(cf);
1426 if (!cf->is_tempfile && cf->filename) {
1427 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1428 add_menu_recent_capture_file(cf->filename);
1431 /* convert file size */
1432 if (cf->f_datalen/1024/1024 > 10) {
1433 size_str = g_strdup_printf("%lld MB", cf->f_datalen/1024/1024);
1434 } else if (cf->f_datalen/1024 > 10) {
1435 size_str = g_strdup_printf("%lld KB", cf->f_datalen/1024);
1437 size_str = g_strdup_printf("%lld Bytes", cf->f_datalen);
1442 /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1443 status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu [Expert: %s]",
1444 (cf->filename) ? cf->filename : "", size_str,
1445 (long)cf->elapsed_time.secs/3600,
1446 (long)cf->elapsed_time.secs%3600/60,
1447 (long)cf->elapsed_time.secs%60,
1448 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1450 status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu",
1451 (cf->filename) ? cf->filename : "", size_str,
1452 (long)cf->elapsed_time.secs/3600,
1453 (long)cf->elapsed_time.secs%3600/60,
1454 (long)cf->elapsed_time.secs%60);
1456 statusbar_push_file_msg(status_msg);
1460 win_name = g_strdup_printf("%s - Wireshark", name_ptr);
1461 set_main_window_name(win_name);
1465 GtkWidget *close_dlg = NULL;
1468 main_cf_cb_file_closing(capture_file *cf)
1471 /* if we have more than 10000 packets, show a splash screen while closing */
1472 /* XXX - don't know a better way to decide wether to show or not,
1473 * as most of the time is spend in a single eth_clist_clear function,
1474 * so we can't use a progress bar here! */
1475 if(cf->count > 10000) {
1476 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1477 "%sClosing file!%s\n\nPlease wait ...",
1478 simple_dialog_primary_start(),
1479 simple_dialog_primary_end());
1480 #if GTK_MAJOR_VERSION >= 2
1481 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1483 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER);
1487 /* Destroy all windows, which refer to the
1488 capture file we're closing. */
1489 destroy_packet_wins();
1490 file_save_as_destroy();
1492 /* Clear any file-related status bar messages.
1493 XXX - should be "clear *ALL* file-related status bar messages;
1494 will there ever be more than one on the stack? */
1495 statusbar_pop_file_msg();
1497 /* Restore the standard title bar message. */
1498 set_main_window_name("The Wireshark Network Analyzer");
1500 /* Disable all menu items that make sense only if you have a capture. */
1501 set_menus_for_capture_file(NULL);
1502 set_menus_for_captured_packets(FALSE);
1503 set_menus_for_selected_packet(cf);
1504 set_menus_for_capture_in_progress(FALSE);
1505 set_menus_for_selected_tree_row(cf);
1507 /* Set up main window for no capture file. */
1508 main_set_for_capture_file(FALSE);
1510 main_window_update();
1514 main_cf_cb_file_closed(capture_file *cf _U_)
1516 if(close_dlg != NULL) {
1517 splash_destroy(close_dlg);
1521 /* go back to "No packets" */
1522 packets_bar_update();
1526 main_cf_cb_file_read_start(capture_file *cf)
1528 const gchar *name_ptr;
1531 name_ptr = get_basename(cf->filename);
1533 load_msg = g_strdup_printf(" Loading: %s", name_ptr);
1534 statusbar_push_file_msg(load_msg);
1537 /* Set up main window for a capture file. */
1538 main_set_for_capture_file(TRUE);
1542 main_cf_cb_file_read_finished(capture_file *cf)
1544 statusbar_pop_file_msg();
1545 set_display_filename(cf);
1547 /* Enable menu items that make sense if you have a capture file you've
1548 finished reading. */
1549 set_menus_for_capture_file(cf);
1551 /* Enable menu items that make sense if you have some captured packets. */
1552 set_menus_for_captured_packets(TRUE);
1555 #if GTK_MAJOR_VERSION >= 2
1556 GList *icon_list_create(
1557 const char **icon16_xpm,
1558 const char **icon32_xpm,
1559 const char **icon48_xpm,
1560 const char **icon64_xpm)
1562 GList *icon_list = NULL;
1563 GdkPixbuf * pixbuf16;
1564 GdkPixbuf * pixbuf32;
1565 GdkPixbuf * pixbuf48;
1566 GdkPixbuf * pixbuf64;
1569 if(icon16_xpm != NULL) {
1570 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1572 icon_list = g_list_append(icon_list, pixbuf16);
1575 if(icon32_xpm != NULL) {
1576 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1578 icon_list = g_list_append(icon_list, pixbuf32);
1581 if(icon48_xpm != NULL) {
1582 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1584 icon_list = g_list_append(icon_list, pixbuf48);
1587 if(icon64_xpm != NULL) {
1588 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1590 icon_list = g_list_append(icon_list, pixbuf64);
1599 main_cf_cb_live_capture_prepared(capture_options *capture_opts)
1602 #if GTK_MAJOR_VERSION >= 2
1603 static GList *icon_list = NULL;
1607 if(capture_opts->iface) {
1608 title = g_strdup_printf("%s: Capturing - Wireshark",
1609 get_interface_descriptive_name(capture_opts->iface));
1611 title = g_strdup_printf("Capturing - Wireshark");
1613 set_main_window_name(title);
1616 #if GTK_MAJOR_VERSION >= 2
1617 if(icon_list == NULL) {
1618 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1620 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1623 /* Disable menu items that make no sense if you're currently running
1625 set_menus_for_capture_in_progress(TRUE);
1627 /* update statusbar */
1628 statusbar_push_file_msg("Waiting for capture input data ...");
1630 /* Don't set up main window for a capture file. */
1631 main_set_for_capture_file(FALSE);
1635 main_cf_cb_live_capture_update_started(capture_options *capture_opts)
1640 /* We've done this in "prepared" above, but it will be cleared while
1641 switching to the next multiple file. */
1642 if(capture_opts->iface) {
1643 title = g_strdup_printf("%s: Capturing - Wireshark",
1644 get_interface_descriptive_name(capture_opts->iface));
1646 title = g_strdup_printf("Capturing - Wireshark");
1648 set_main_window_name(title);
1651 set_menus_for_capture_in_progress(TRUE);
1653 /* Enable menu items that make sense if you have some captured
1654 packets (yes, I know, we don't have any *yet*). */
1655 set_menus_for_captured_packets(TRUE);
1657 statusbar_pop_file_msg();
1659 if(capture_opts->iface) {
1660 capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1661 get_interface_descriptive_name(capture_opts->iface),
1662 (capture_opts->save_file) ? capture_opts->save_file : "");
1664 capture_msg = g_strdup_printf(" <live capture in progress> to file: %s",
1665 (capture_opts->save_file) ? capture_opts->save_file : "");
1668 statusbar_push_file_msg(capture_msg);
1670 g_free(capture_msg);
1672 /* Set up main window for a capture file. */
1673 main_set_for_capture_file(TRUE);
1677 main_cf_cb_live_capture_update_continue(capture_file *cf)
1682 statusbar_pop_file_msg();
1685 /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1686 if (cf->f_datalen/1024/1024 > 10) {
1687 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB [Expert: %s]",
1688 get_interface_descriptive_name(capture_opts->iface),
1689 capture_opts->save_file,
1690 cf->f_datalen/1024/1024,
1691 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1692 } else if (cf->f_datalen/1024 > 10) {
1693 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB [Expert: %s]",
1694 get_interface_descriptive_name(capture_opts->iface),
1695 capture_opts->save_file,
1697 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1699 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes [Expert: %s]",
1700 get_interface_descriptive_name(capture_opts->iface),
1701 capture_opts->save_file,
1703 val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1706 if (cf->f_datalen/1024/1024 > 10) {
1707 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB",
1708 get_interface_descriptive_name(capture_opts->iface),
1709 capture_opts->save_file,
1710 cf->f_datalen/1024/1024);
1711 } else if (cf->f_datalen/1024 > 10) {
1712 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB",
1713 get_interface_descriptive_name(capture_opts->iface),
1714 capture_opts->save_file,
1715 cf->f_datalen/1024);
1717 capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes",
1718 get_interface_descriptive_name(capture_opts->iface),
1719 capture_opts->save_file,
1723 statusbar_push_file_msg(capture_msg);
1726 GtkWidget * stop_dlg = NULL;
1729 main_cf_cb_live_capture_update_finished(capture_file *cf)
1731 #if GTK_MAJOR_VERSION >= 2
1732 static GList *icon_list = NULL;
1735 if(stop_dlg != NULL) {
1736 simple_dialog_close(stop_dlg);
1740 /* Pop the "<live capture in progress>" message off the status bar. */
1741 statusbar_pop_file_msg();
1743 set_display_filename(cf);
1745 /* Enable menu items that make sense if you're not currently running
1747 set_menus_for_capture_in_progress(FALSE);
1749 /* Enable menu items that make sense if you have a capture file
1750 you've finished reading. */
1751 set_menus_for_capture_file(cf);
1753 /* Set up main window for a capture file. */
1754 main_set_for_capture_file(TRUE);
1756 #if GTK_MAJOR_VERSION >= 2
1757 if(icon_list == NULL) {
1758 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1760 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1763 if(capture_opts->quit_after_cap) {
1764 /* command line asked us to quit after the capture */
1765 /* don't pop up a dialog to ask for unsaved files etc. */
1771 main_cf_cb_live_capture_fixed_started(capture_options *capture_opts)
1776 /* Enable menu items that make sense if you have some captured
1777 packets (yes, I know, we don't have any *yet*). */
1778 /*set_menus_for_captured_packets(TRUE);*/
1780 statusbar_pop_file_msg();
1782 capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1783 get_interface_descriptive_name(capture_opts->iface),
1784 (capture_opts->save_file) ? capture_opts->save_file : "");
1786 statusbar_push_file_msg(capture_msg);
1787 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " P: 0");
1789 g_free(capture_msg);
1791 /* Don't set up main window for a capture file. */
1792 main_set_for_capture_file(FALSE);
1796 main_cf_cb_live_capture_fixed_continue(capture_file *cf)
1801 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1803 capture_msg = g_strdup_printf(" P: %u",
1804 cf_get_packet_count(cf));
1806 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, capture_msg);
1808 g_free(capture_msg);
1812 main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_)
1814 #if GTK_MAJOR_VERSION >= 2
1815 static GList *icon_list = NULL;
1818 if(stop_dlg != NULL) {
1819 simple_dialog_close(stop_dlg);
1823 /* Pop the "<live capture in progress>" message off the status bar. */
1824 statusbar_pop_file_msg();
1826 /* Pop the "<capturing>" message off the status bar */
1827 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1829 /*set_display_filename(cf);*/
1831 /* Enable menu items that make sense if you're not currently running
1833 set_menus_for_capture_in_progress(FALSE);
1835 /* Restore the standard title bar message */
1836 /* (just in case we have trouble opening the capture file). */
1837 set_main_window_name("The Wireshark Network Analyzer");
1839 #if GTK_MAJOR_VERSION >= 2
1840 if(icon_list == NULL) {
1841 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1843 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1846 /* We don't have loaded the capture file, this will be done later.
1847 * For now we still have simply a blank screen. */
1849 if(capture_opts->quit_after_cap) {
1850 /* command line asked us to quit after the capture */
1851 /* don't pop up a dialog to ask for unsaved files etc. */
1857 main_cf_cb_live_capture_stopping(capture_file *cf _U_)
1859 /* Beware: this state won't be called, if the capture child
1860 * closes the capturing on it's own! */
1862 /* XXX - the time to stop the capture has been reduced (this was only a
1863 * problem on Win32 because of the capture piping), so showing a splash
1864 * isn't really necessary any longer. Unfortunately, the GTKClist packet
1865 * list seems to have problems updating after the dialog is closed, so
1866 * this was disabled here. */
1867 stop_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE, "%sCapture stop!%s\n\nPlease wait ...",
1868 simple_dialog_primary_start(), simple_dialog_primary_end());
1869 #if GTK_MAJOR_VERSION >= 2
1870 gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1872 gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER);
1880 main_cf_cb_packet_selected(gpointer data)
1882 capture_file *cf = data;
1884 /* Display the GUI protocol tree and hex dump.
1885 XXX - why do we dump core if we call "proto_tree_draw()"
1886 before calling "add_byte_views()"? */
1887 add_main_byte_views(cf->edt);
1888 main_proto_tree_draw(cf->edt->tree);
1890 /* The user is searching for a string in the data or a hex value,
1891 * highlight the field that is found in the tree and hex displays. */
1892 #if GTK_MAJOR_VERSION < 2
1893 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1894 highlight_field(cf->edt->tvb, cfile.search_pos,
1895 (GtkCTree *)tree_view, cf->edt->tree);
1897 if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1898 highlight_field(cf->edt->tvb, cfile.search_pos,
1899 (GtkTreeView *)tree_view, cf->edt->tree);
1901 cfile.search_pos = 0; /* Reset the position */
1904 /* A packet is selected. */
1905 set_menus_for_selected_packet(cf);
1909 main_cf_cb_packet_unselected(capture_file *cf)
1911 /* Clear out the display of that packet. */
1912 clear_tree_and_hex_views();
1914 /* No packet is selected. */
1915 set_menus_for_selected_packet(cf);
1919 main_cf_cb_field_unselected(capture_file *cf)
1921 statusbar_pop_field_msg();
1922 set_menus_for_selected_tree_row(cf);
1926 main_cf_cb_file_safe_started(gchar * filename)
1928 const gchar *name_ptr;
1931 name_ptr = get_basename(filename);
1933 save_msg = g_strdup_printf(" Saving: %s...", name_ptr);
1935 statusbar_push_file_msg(save_msg);
1940 main_cf_cb_file_safe_finished(gpointer data _U_)
1942 /* Pop the "Saving:" message off the status bar. */
1943 statusbar_pop_file_msg();
1947 main_cf_cb_file_safe_failed(gpointer data _U_)
1949 /* Pop the "Saving:" message off the status bar. */
1950 statusbar_pop_file_msg();
1954 main_cf_cb_file_safe_reload_finished(gpointer data _U_)
1956 set_menus_for_capture_file(&cfile);
1959 static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1962 case(cf_cb_file_closing):
1963 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1964 main_cf_cb_file_closing(data);
1966 case(cf_cb_file_closed):
1967 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1968 main_cf_cb_file_closed(data);
1970 case(cf_cb_file_read_start):
1971 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read start");
1972 main_cf_cb_file_read_start(data);
1974 case(cf_cb_file_read_finished):
1975 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1976 main_cf_cb_file_read_finished(data);
1979 case(cf_cb_live_capture_prepared):
1980 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1981 main_cf_cb_live_capture_prepared(data);
1983 case(cf_cb_live_capture_update_started):
1984 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1985 main_cf_cb_live_capture_update_started(data);
1987 case(cf_cb_live_capture_update_continue):
1988 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1989 main_cf_cb_live_capture_update_continue(data);
1991 case(cf_cb_live_capture_update_finished):
1992 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1993 main_cf_cb_live_capture_update_finished(data);
1995 case(cf_cb_live_capture_fixed_started):
1996 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1997 main_cf_cb_live_capture_fixed_started(data);
1999 case(cf_cb_live_capture_fixed_continue):
2000 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");
2001 main_cf_cb_live_capture_fixed_continue(data);
2003 case(cf_cb_live_capture_fixed_finished):
2004 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
2005 main_cf_cb_live_capture_fixed_finished(data);
2007 case(cf_cb_live_capture_stopping):
2008 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
2009 main_cf_cb_live_capture_stopping(data);
2012 case(cf_cb_packet_selected):
2013 main_cf_cb_packet_selected(data);
2015 case(cf_cb_packet_unselected):
2016 main_cf_cb_packet_unselected(data);
2018 case(cf_cb_field_unselected):
2019 main_cf_cb_field_unselected(data);
2021 case(cf_cb_file_safe_started):
2022 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe started");
2023 main_cf_cb_file_safe_started(data);
2025 case(cf_cb_file_safe_finished):
2026 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe finished");
2027 main_cf_cb_file_safe_finished(data);
2029 case(cf_cb_file_safe_reload_finished):
2030 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: reload finished");
2031 main_cf_cb_file_safe_reload_finished(data);
2033 case(cf_cb_file_safe_failed):
2034 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe failed");
2035 main_cf_cb_file_safe_failed(data);
2038 g_warning("main_cf_callback: event %u unknown", event);
2039 g_assert_not_reached();
2044 get_gui_compiled_info(GString *str)
2046 get_epan_compiled_version_info(str);
2048 g_string_append(str, ", ");
2049 #ifdef HAVE_LIBPORTAUDIO
2050 #ifdef PORTAUDIO_API_1
2051 g_string_append(str, "with PortAudio <= V18");
2052 #else /* PORTAUDIO_API_1 */
2053 g_string_append(str, "with PortAudio ");
2054 g_string_append(str, Pa_GetVersionText());
2055 #endif /* PORTAUDIO_API_1 */
2056 #else /* HAVE_LIBPORTAUDIO */
2057 g_string_append(str, "without PortAudio");
2058 #endif /* HAVE_LIBPORTAUDIO */
2060 g_string_append(str, ", ");
2062 get_compiled_airpcap_version(str);
2064 g_string_append(str, "without AirPcap");
2069 get_gui_runtime_info(GString *str
2070 #ifndef HAVE_AIRPCAP
2076 g_string_append(str, ", ");
2077 get_runtime_airpcap_version(str);
2081 g_string_append(str, ", ");
2082 u3_runtime_info(str);
2087 /* And now our feature presentation... [ fade to music ] */
2089 main(int argc, char *argv[])
2091 char *init_progfile_dir_error;
2095 extern char *optarg;
2096 gboolean arg_error = FALSE;
2104 char *gpf_path, *pf_path;
2105 char *cf_path, *df_path;
2106 char *gdp_path, *dp_path;
2107 int gpf_open_errno, gpf_read_errno;
2108 int pf_open_errno, pf_read_errno;
2109 int cf_open_errno, df_open_errno;
2110 int gdp_open_errno, gdp_read_errno;
2111 int dp_open_errno, dp_read_errno;
2114 gboolean start_capture = FALSE;
2116 gboolean capture_option_specified = FALSE;
2118 gint pl_size = 280, tv_size = 95, bv_size = 75;
2119 gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
2120 dfilter_t *rfcode = NULL;
2121 gboolean rfilter_parse_failed = FALSE;
2124 GtkWidget *splash_win = NULL;
2125 GLogLevelFlags log_flags;
2126 guint go_to_packet = 0;
2132 /*gchar *cant_get_if_list_errstr;*/
2135 #define OPTSTRING_INIT "a:b:c:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
2137 #if defined HAVE_LIBPCAP && defined _WIN32
2138 #define OPTSTRING_WIN32 "B:"
2140 #define OPTSTRING_WIN32 ""
2143 char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
2144 OPTSTRING_INIT OPTSTRING_WIN32;
2146 #ifdef HAVE_AIRPDCAP
2147 /* Davide Schiera (2006-11-18): init AirPDcap context */
2148 AirPDcapInitContext(&airpdcap_ctx);
2149 /* Davide Schiera (2006-11-18) ------------------------------------------- */
2153 * Get credential information for later use.
2155 get_credential_info();
2158 * Attempt to get the pathname of the executable file.
2160 init_progfile_dir_error = init_progfile_dir(argv[0]);
2162 /* initialize the funnel mini-api */
2163 initialize_funnel_ops();
2166 /* Load wpcap if possible. Do this before collecting the run-time version information */
2169 /* ... and also load the packet.dll from wpcap */
2170 wpcap_packet_load();
2173 /* Load the airpcap.dll. This must also be done before collecting
2174 * run-time version information. */
2175 airpcap_dll_ret_val = load_airpcap();
2177 switch (airpcap_dll_ret_val) {
2178 case AIRPCAP_DLL_OK:
2179 /* load the airpcap interfaces */
2180 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2182 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2183 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2184 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2187 airpcap_if_active = NULL;
2191 /* select the first ad default (THIS SHOULD BE CHANGED) */
2192 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2197 * XXX - Maybe we need to warn the user if one of the following happens???
2199 case AIRPCAP_DLL_OLD:
2200 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2203 case AIRPCAP_DLL_ERROR:
2204 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2207 case AIRPCAP_DLL_NOT_FOUND:
2208 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2212 #endif /* HAVE_AIRPCAP */
2214 /* Start windows sockets */
2215 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2218 /* Assemble the compile-time version information string */
2219 comp_info_str = g_string_new("Compiled ");
2221 g_string_append(comp_info_str, "with ");
2222 g_string_sprintfa(comp_info_str,
2223 #ifdef GTK_MAJOR_VERSION
2224 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
2227 "GTK+ (version unknown)");
2229 g_string_append(comp_info_str, ", ");
2231 get_compiled_version_info(comp_info_str, get_gui_compiled_info);
2233 /* Assemble the run-time version information string */
2234 runtime_info_str = g_string_new("Running ");
2235 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2238 /* "pre-scan" the command line parameters, if we have "console only"
2239 parameters. We do this so we don't start GTK+ if we're only showing
2240 command-line help or version information.
2242 XXX - this pre-scan is doen before we start GTK+, so we haven't
2243 run gtk_init() on the arguments. That means that GTK+ arguments
2244 have not been removed from the argument list; those arguments
2245 begin with "--", and will be treated as an error by getopt().
2247 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2250 optind_initial = optind;
2251 while ((opt = getopt(argc, argv, optstring)) != -1) {
2253 case 'h': /* Print help and exit */
2257 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2258 status = filesystem_opt(opt, optarg);
2260 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2264 case 'v': /* Show version and exit */
2270 * Extension command line options have to be processed before
2271 * we call epan_init() as they are supposed to be used by dissectors
2272 * or taps very early in the registration process.
2276 case '?': /* Ignore errors - the "real" scan will catch them. */
2281 /* Init the "Open file" dialog directory */
2282 /* (do this after the path settings are processed) */
2283 set_last_open_dir(get_persdatafile_dir());
2285 /* Set getopt index back to initial value, so it will start with the
2286 first command line parameter again. Also reset opterr to 1, so that
2287 error messages are printed by getopt().
2289 XXX - this seems to work on most platforms, but time will tell.
2290 The Single UNIX Specification says "The getopt() function need
2291 not be reentrant", so this isn't guaranteed to work. The Mac
2292 OS X 10.4[.x] getopt() man page says
2294 In order to use getopt() to evaluate multiple sets of arguments, or to
2295 evaluate a single set of arguments multiple times, the variable optreset
2296 must be set to 1 before the second and each additional set of calls to
2297 getopt(), and the variable optind must be reinitialized.
2301 The optreset variable was added to make it possible to call the getopt()
2302 function multiple times. This is an extension to the IEEE Std 1003.2
2303 (``POSIX.2'') specification.
2305 which I think comes from one of the other BSDs.
2307 XXX - if we want to control all the command-line option errors, so
2308 that we can display them where we choose (e.g., in a window), we'd
2309 want to leave opterr as 0, and produce our own messages using optopt.
2310 We'd have to check the value of optopt to see if it's a valid option
2311 letter, in which case *presumably* the error is "this option requires
2312 an argument but none was specified", or not a valid option letter,
2313 in which case *presumably* the error is "this option isn't valid".
2314 Some versions of getopt() let you supply a option string beginning
2315 with ':', which means that getopt() will return ':' rather than '?'
2316 for "this option requires an argument but none was specified", but
2318 optind = optind_initial;
2321 /* Set the current locale according to the program environment.
2322 * We haven't localized anything, but some GTK widgets are localized
2323 * (the file selection dialogue, for example).
2324 * This also sets the C-language locale to the native environment. */
2327 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2328 gtk_init (&argc, &argv);
2330 cf_callback_add(main_cf_callback, NULL);
2332 #if GTK_MAJOR_VERSION < 2 && GTK_MINOR_VERSION < 3
2333 /* initialize our GTK eth_clist_type */
2334 init_eth_clist_type();
2337 /* Arrange that if we have no console window, and a GLib message logging
2338 routine is called to log a message, we pop up a console window.
2340 We do that by inserting our own handler for all messages logged
2341 to the default domain; that handler pops up a console if necessary,
2342 and then calls the default handler. */
2344 /* We might want to have component specific log levels later ... */
2348 G_LOG_LEVEL_CRITICAL|
2349 G_LOG_LEVEL_WARNING|
2350 G_LOG_LEVEL_MESSAGE|
2353 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2355 g_log_set_handler(NULL,
2357 console_log_handler, NULL /* user_data */);
2358 g_log_set_handler(LOG_DOMAIN_MAIN,
2360 console_log_handler, NULL /* user_data */);
2363 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2365 console_log_handler, NULL /* user_data */);
2366 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2368 console_log_handler, NULL /* user_data */);
2370 /* Set the initial values in the capture_opts. This might be overwritten
2371 by preference settings and then again by the command line parameters. */
2372 capture_opts_init(capture_opts, &cfile);
2374 capture_opts->snaplen = MIN_PACKET_SIZE;
2375 capture_opts->has_ring_num_files = TRUE;
2378 /* We won't come till here, if we had a "console only" command line parameter. */
2379 splash_win = splash_new("Loading Wireshark ...");
2380 if (init_progfile_dir_error != NULL) {
2381 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2382 "Can't get pathname of Wireshark: %s.\n"
2383 "It won't be possible to capture traffic.\n"
2384 "Report this to the Wireshark developers.",
2385 init_progfile_dir_error);
2386 g_free(init_progfile_dir_error);
2389 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2391 /* Register all dissectors; we must do this before checking for the
2392 "-G" flag, as the "-G" flag dumps information registered by the
2393 dissectors, and we must do it before we read the preferences, in
2394 case any dissectors register preferences. */
2395 epan_init(register_all_protocols,register_all_protocol_handoffs,
2396 splash_update, (gpointer) splash_win,
2397 failure_alert_box,open_failure_alert_box,read_failure_alert_box);
2399 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2401 /* Register all tap listeners; we do this before we parse the arguments,
2402 as the "-z" argument can specify a registered tap. */
2404 /* we register the plugin taps before the other taps because
2405 stats_tree taps plugins will be registered as tap listeners
2406 by stats_tree_stat.c and need to registered before that */
2409 register_all_plugin_tap_listeners();
2410 register_all_wiretap_modules();
2413 register_all_tap_listeners();
2415 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2417 /* Now register the preferences for any non-dissector modules.
2418 We must do that before we read the preferences as well. */
2419 prefs_register_modules();
2421 /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2422 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined(G_THREADS_ENABLED) && defined USE_THREADS
2425 g_thread_init(NULL);
2427 ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2428 g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2430 #else /* _WIN32 || GTK1.2 || !G_THREADS_ENABLED || !USE_THREADS */
2431 /* this is to keep tap extensions updating once every 3 seconds */
2432 gtk_timeout_add(3000, (GtkFunction)update_cb,(gpointer)NULL);
2433 #endif /* !_WIN32 && GTK2 && G_THREADS_ENABLED */
2436 gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
2439 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2441 /* Read the preference files. */
2442 prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2443 &pf_open_errno, &pf_read_errno, &pf_path);
2445 if (gpf_path != NULL) {
2446 if (gpf_open_errno != 0) {
2447 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2448 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2449 strerror(gpf_open_errno));
2451 if (gpf_read_errno != 0) {
2452 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2453 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2454 strerror(gpf_read_errno));
2457 if (pf_path != NULL) {
2458 if (pf_open_errno != 0) {
2459 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2460 "Could not open your preferences file\n\"%s\": %s.", pf_path,
2461 strerror(pf_open_errno));
2463 if (pf_read_errno != 0) {
2464 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2465 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2466 strerror(pf_read_errno));
2473 /* if the user wants a console to be always there, well, we should open one for him */
2474 if (prefs->gui_console_open == console_open_always) {
2479 /* Fill in capture options with values from the preferences */
2480 prefs_to_capture_opts();
2482 /* Read the capture filter file. */
2483 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2484 if (cf_path != NULL) {
2485 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2486 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2487 strerror(cf_open_errno));
2491 /* Read the display filter file. */
2492 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2493 if (df_path != NULL) {
2494 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2495 "Could not open your display filter file\n\"%s\": %s.", df_path,
2496 strerror(df_open_errno));
2500 /* Read the disabled protocols file. */
2501 read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
2502 &dp_path, &dp_open_errno, &dp_read_errno);
2503 if (gdp_path != NULL) {
2504 if (gdp_open_errno != 0) {
2505 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2506 "Could not open global disabled protocols file\n\"%s\": %s.",
2507 gdp_path, strerror(gdp_open_errno));
2509 if (gdp_read_errno != 0) {
2510 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2511 "I/O error reading global disabled protocols file\n\"%s\": %s.",
2512 gdp_path, strerror(gdp_read_errno));
2516 if (dp_path != NULL) {
2517 if (dp_open_errno != 0) {
2518 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2519 "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
2520 strerror(dp_open_errno));
2522 if (dp_read_errno != 0) {
2523 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2524 "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
2525 strerror(dp_read_errno));
2530 /* Read the (static part) of the recent file. Only the static part of it will be read, */
2531 /* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
2532 /* We have to do this already here, so command line parameters can overwrite these values. */
2533 recent_read_static(&rf_path, &rf_open_errno);
2535 init_cap_file(&cfile);
2537 /* Now get our args */
2538 while ((opt = getopt(argc, argv, optstring)) != -1) {
2540 /*** capture option specific ***/
2541 case 'a': /* autostop criteria */
2542 case 'b': /* Ringbuffer option */
2543 case 'c': /* Capture xxx packets */
2544 case 'f': /* capture filter */
2545 case 'k': /* Start capture immediately */
2546 case 'H': /* Hide capture info dialog box */
2547 case 'i': /* Use interface xxx */
2548 case 'p': /* Don't capture in promiscuous mode */
2549 case 'Q': /* Quit after capture (just capture to file) */
2550 case 's': /* Set the snapshot (capture) length */
2551 case 'S': /* "Sync" mode: used for following file ala tail -f */
2552 case 'w': /* Write to capture file xxx */
2553 case 'y': /* Set the pcap data link type */
2555 case 'B': /* Buffer size */
2558 status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
2563 capture_option_specified = TRUE;
2568 /*** all non capture option specific ***/
2569 case 'D': /* Print a list of capture devices and exit */
2571 capture_opts_list_interfaces();
2574 capture_option_specified = TRUE;
2578 case 'g': /* Go to packet */
2579 go_to_packet = get_positive_int(optarg, "go to packet");
2581 case 'l': /* Automatic scrolling in live capture mode */
2583 auto_scroll_live = TRUE;
2585 capture_option_specified = TRUE;
2589 case 'L': /* Print list of link-layer types and exit */
2591 list_link_layer_types = TRUE;
2593 capture_option_specified = TRUE;
2597 case 'm': /* Fixed-width font for the display */
2598 if (prefs->PREFS_GUI_FONT_NAME != NULL)
2599 g_free(prefs->PREFS_GUI_FONT_NAME);
2600 prefs->PREFS_GUI_FONT_NAME = g_strdup(optarg);
2602 case 'n': /* No name resolution */
2603 g_resolv_flags = RESOLV_NONE;
2605 case 'N': /* Select what types of addresses/port #s to resolve */
2606 if (g_resolv_flags == RESOLV_ALL)
2607 g_resolv_flags = RESOLV_NONE;
2608 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2609 if (badopt != '\0') {
2610 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2615 case 'o': /* Override preference from command line */
2616 switch (prefs_set_pref(optarg)) {
2619 case PREFS_SET_SYNTAX_ERR:
2620 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2623 case PREFS_SET_NO_SUCH_PREF:
2624 /* not a preference, might be a recent setting */
2625 switch (recent_set_arg(optarg)) {
2628 case PREFS_SET_SYNTAX_ERR:
2629 /* shouldn't happen, checked already above */
2630 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2633 case PREFS_SET_NO_SUCH_PREF:
2634 case PREFS_SET_OBSOLETE:
2635 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2640 g_assert_not_reached();
2643 case PREFS_SET_OBSOLETE:
2644 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2649 g_assert_not_reached();
2653 /* Path settings were already processed just ignore them this time*/
2655 case 'r': /* Read capture file xxx */
2656 /* We may set "last_open_dir" to "cf_name", and if we change
2657 "last_open_dir" later, we free the old value, so we have to
2658 set "cf_name" to something that's been allocated. */
2659 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2660 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2661 cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2663 cf_name = g_strdup(optarg);
2666 case 'R': /* Read file filter */
2669 case 't': /* Time stamp type */
2670 if (strcmp(optarg, "r") == 0)
2671 timestamp_set_type(TS_RELATIVE);
2672 else if (strcmp(optarg, "a") == 0)
2673 timestamp_set_type(TS_ABSOLUTE);
2674 else if (strcmp(optarg, "ad") == 0)
2675 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2676 else if (strcmp(optarg, "d") == 0)
2677 timestamp_set_type(TS_DELTA);
2678 else if (strcmp(optarg, "dd") == 0)
2679 timestamp_set_type(TS_DELTA_DIS);
2680 else if (strcmp(optarg, "e") == 0)
2681 timestamp_set_type(TS_EPOCH);
2683 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2684 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2685 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2690 /* ext ops were already processed just ignore them this time*/
2693 /* We won't call the init function for the stat this soon
2694 as it would disallow MATE's fields (which are registered
2695 by the preferences set callback) from being used as
2696 part of a tap filter. Instead, we just add the argument
2697 to a list of stat arguments. */
2698 if (!process_stat_cmd_arg(optarg)) {
2699 cmdarg_err("Invalid -z argument.");
2700 cmdarg_err_cont(" -z argument must be one of :");
2701 list_stat_cmd_args();
2706 case '?': /* Bad flag - print usage message */
2714 if (cf_name != NULL) {
2716 * Input file name specified with "-r" *and* specified as a regular
2717 * command-line argument.
2719 cmdarg_err("File name specified both with -r and regular argument");
2723 * Input file name not specified with "-r", and a command-line argument
2724 * was specified; treat it as the input file name.
2726 * Yes, this is different from tshark, where non-flag command-line
2727 * arguments are a filter, but this works better on GUI desktops
2728 * where a command can be specified to be run to open a particular
2729 * file - yes, you could have "-r" as the last part of the command,
2730 * but that's a bit ugly.
2732 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2733 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2734 cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2736 cf_name = g_strdup(argv[0]);
2747 * Extra command line arguments were specified; complain.
2749 cmdarg_err("Invalid argument: %s", argv[0]);
2754 #ifndef HAVE_LIBPCAP
2755 if (capture_option_specified) {
2756 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2764 if (start_capture && list_link_layer_types) {
2765 /* Specifying *both* is bogus. */
2766 cmdarg_err("You can't specify both -L and a live capture.");
2770 if (list_link_layer_types) {
2771 /* We're supposed to list the link-layer types for an interface;
2772 did the user also specify a capture file to be read? */
2774 /* Yes - that's bogus. */
2775 cmdarg_err("You can't specify -L and a capture file to be read.");
2778 /* No - did they specify a ring buffer option? */
2779 if (capture_opts->multi_files_on) {
2780 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2784 /* We're supposed to do a live capture; did the user also specify
2785 a capture file to be read? */
2786 if (start_capture && cf_name) {
2787 /* Yes - that's bogus. */
2788 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2792 /* No - was the ring buffer option specified and, if so, does it make
2794 if (capture_opts->multi_files_on) {
2795 /* Ring buffer works only under certain conditions:
2796 a) ring buffer does not work with temporary files;
2797 b) real_time_mode and multi_files_on are mutually exclusive -
2798 real_time_mode takes precedence;
2799 c) it makes no sense to enable the ring buffer if the maximum
2800 file size is set to "infinite". */
2801 if (capture_opts->save_file == NULL) {
2802 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2803 capture_opts->multi_files_on = FALSE;
2805 /* if (capture_opts->real_time_mode) {
2806 cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2807 capture_opts->multi_files_on = FALSE;
2809 if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
2810 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2811 /* XXX - this must be redesigned as the conditions changed */
2812 /* capture_opts->multi_files_on = FALSE;*/
2817 if (start_capture || list_link_layer_types) {
2818 /* Did the user specify an interface to use? */
2819 if (!capture_opts_trim_iface(capture_opts,
2820 (prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
2825 if (list_link_layer_types) {
2826 status = capture_opts_list_link_layer_types(capture_opts);
2830 capture_opts_trim_snaplen(capture_opts, MIN_PACKET_SIZE);
2831 capture_opts_trim_ring_num_files(capture_opts);
2832 #endif /* HAVE_LIBPCAP */
2834 /* Notify all registered modules that have had any of their preferences
2835 changed either from one of the preferences file or from the command
2836 line that their preferences have changed. */
2839 /* disabled protocols as per configuration file */
2840 if (gdp_path == NULL && dp_path == NULL) {
2841 set_disabled_protos_list();
2844 /* Build the column format array */
2845 col_setup(&cfile.cinfo, prefs->num_cols);
2846 for (i = 0; i < cfile.cinfo.num_cols; i++) {
2847 cfile.cinfo.col_fmt[i] = get_column_format(i);
2848 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
2849 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
2851 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
2852 cfile.cinfo.col_data[i] = NULL;
2853 if (cfile.cinfo.col_fmt[i] == COL_INFO)
2854 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
2856 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2857 cfile.cinfo.col_fence[i] = 0;
2858 cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2859 cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2862 for (i = 0; i < cfile.cinfo.num_cols; i++) {
2865 for (j = 0; j < NUM_COL_FMTS; j++) {
2866 if (!cfile.cinfo.fmt_matx[i][j])
2869 if (cfile.cinfo.col_first[j] == -1)
2870 cfile.cinfo.col_first[j] = i;
2871 cfile.cinfo.col_last[j] = i;
2875 /* read in rc file from global and personal configuration paths. */
2876 rc_file = get_datafile_path(RC_FILE);
2877 gtk_rc_parse(rc_file);
2878 rc_file = get_persconffile_path(RC_FILE, FALSE);
2879 gtk_rc_parse(rc_file);
2883 /* close the splash screen, as we are going to open the main window now */
2884 splash_destroy(splash_win);
2886 /************************************************************************/
2887 /* Everything is prepared now, preferences and command line was read in */
2889 /* Pop up the main window. */
2890 create_main_window(pl_size, tv_size, bv_size, prefs);
2892 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2893 recent_read_dynamic(&rf_path, &rf_open_errno);
2894 color_filters_enable(recent.packet_list_colorize);
2896 /* rearrange all the widgets as we now have all recent settings ready for this */
2897 main_widgets_rearrange();
2899 /* Fill in column titles. This must be done after the top level window
2902 XXX - is that still true, with fixed-width columns? */
2903 packet_list_set_column_titles();
2905 menu_recent_read_finished();
2907 switch (user_font_apply()) {
2910 case FA_FONT_NOT_RESIZEABLE:
2911 /* "user_font_apply()" popped up an alert box. */
2912 /* turn off zooming - font can't be resized */
2913 case FA_FONT_NOT_AVAILABLE:
2914 /* XXX - did we successfully load the un-zoomed version earlier?
2915 If so, this *probably* means the font is available, but not at
2916 this particular zoom level, but perhaps some other failure
2917 occurred; I'm not sure you can determine which is the case,
2919 /* turn off zooming - zoom level is unavailable */
2921 /* in any other case than FA_SUCCESS, turn off zooming */
2922 recent.gui_zoom_level = 0;
2923 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2926 dnd_init(top_level);
2929 color_filters_init();
2932 /* the window can be sized only, if it's not already shown, so do it now! */
2933 main_load_window_geometry(top_level);
2935 /* If we were given the name of a capture file, read it in now;
2936 we defer it until now, so that, if we can't open it, and pop
2937 up an alert box, the alert box is more likely to come up on
2938 top of the main window - but before the preference-file-error
2939 alert box, so, if we get one of those, it's more likely to come
2942 show_main_window(TRUE);
2943 if (rfilter != NULL) {
2944 if (!dfilter_compile(rfilter, &rfcode)) {
2945 bad_dfilter_alert_box(rfilter);
2946 rfilter_parse_failed = TRUE;
2949 if (!rfilter_parse_failed) {
2950 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2951 /* "cf_open()" succeeded, so it closed the previous
2952 capture file, and thus destroyed any previous read filter
2953 attached to "cf". */
2955 cfile.rfcode = rfcode;
2956 /* Open stat windows; we do so after creating the main window,
2957 to avoid GTK warnings, and after successfully opening the
2958 capture file, so we know we have something to compute stats
2959 on, and after registering all dissectors, so that MATE will
2960 have registered its field array and we can have a tap filter
2961 with one of MATE's late-registered fields as part of the
2963 start_requested_stats();
2965 /* Read the capture file. */
2966 switch (cf_read(&cfile)) {
2970 /* Just because we got an error, that doesn't mean we were unable
2971 to read any of the file; we handle what we could get from the
2973 /* if the user told us to jump to a specific packet, do it now */
2974 if(go_to_packet != 0) {
2975 cf_goto_frame(&cfile, go_to_packet);
2979 case CF_READ_ABORTED:
2984 /* Save the name of the containing directory specified in the
2985 path name, if any; we can write over cf_name, which is a
2986 good thing, given that "get_dirname()" does write over its
2988 s = get_dirname(cf_name);
2989 set_last_open_dir(s);
2994 dfilter_free(rfcode);
2995 cfile.rfcode = NULL;
2996 show_main_window(FALSE);
2997 set_menus_for_capture_in_progress(FALSE);
3002 if (start_capture) {
3003 if (capture_opts->save_file != NULL) {
3004 /* Save the directory name for future file dialogs. */
3005 /* (get_dirname overwrites filename) */
3006 s = get_dirname(g_strdup(capture_opts->save_file));
3007 set_last_open_dir(s);
3010 /* "-k" was specified; start a capture. */
3011 show_main_window(TRUE);
3012 if (capture_start(capture_opts)) {
3013 /* The capture started. Open stat windows; we do so after creating
3014 the main window, to avoid GTK warnings, and after successfully
3015 opening the capture file, so we know we have something to compute
3016 stats on, and after registering all dissectors, so that MATE will
3017 have registered its field array and we can have a tap filter with
3018 one of MATE's late-registered fields as part of the filter. */
3019 start_requested_stats();
3023 show_main_window(FALSE);
3024 set_menus_for_capture_in_progress(FALSE);
3027 /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
3028 if (!start_capture && strlen(capture_opts->cfilter) == 0) {
3029 g_free(capture_opts->cfilter);
3030 capture_opts->cfilter = g_strdup(get_conn_cfilter());
3032 #else /* HAVE_LIBPCAP */
3033 show_main_window(FALSE);
3034 set_menus_for_capture_in_progress(FALSE);
3035 #endif /* HAVE_LIBPCAP */
3038 /* register our pid if we are being run from a U3 device */
3041 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3043 /* ... back from GTK, we're going down now! */
3045 /* deregister our pid */
3046 u3_deregister_pid();
3051 #ifdef HAVE_AIRPDCAP
3052 /* Davide Schiera (2006-11-18): destroy AirPDcap context */
3053 AirPDcapDestroyContext(&airpdcap_ctx);
3054 /* Davide Schiera (2006-11-18) ------------------------------------------- */
3058 /* hide the (unresponsive) main window, while asking the user to close the console window */
3059 gtk_widget_hide(top_level);
3061 /* Shutdown windows sockets */
3064 /* For some unknown reason, the "atexit()" call in "create_console()"
3065 doesn't arrange that "destroy_console()" be called when we exit,
3066 so we call it here if a console was created. */
3072 /* This isn't reached, but we need it to keep GCC from complaining
3073 that "main()" returns without returning a value - it knows that
3074 "exit()" never returns, but it doesn't know that "gtk_exit()"
3075 doesn't, as GTK+ doesn't declare it with the attribute
3077 return 0; /* not reached */
3082 /* We build this as a GUI subsystem application on Win32, so
3083 "WinMain()", not "main()", gets called.
3085 Hack shamelessly stolen from the Win32 port of the GIMP. */
3087 #define _stdcall __attribute__((stdcall))
3091 WinMain (struct HINSTANCE__ *hInstance,
3092 struct HINSTANCE__ *hPrevInstance,
3096 #if GTK_MAJOR_VERSION >= 2
3097 INITCOMMONCONTROLSEX comm_ctrl;
3099 /* Initialize our controls. Required for native Windows file dialogs. */
3100 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3101 comm_ctrl.dwSize = sizeof(comm_ctrl);
3102 /* Includes the animate, header, hot key, list view, progress bar,
3103 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3106 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3107 InitCommonControlsEx(&comm_ctrl);
3109 /* RichEd20.DLL is needed for filter entries. */
3110 LoadLibrary(_T("riched20.dll"));
3111 #endif /* GTK_MAJOR_VERSION >= 2 */
3113 has_console = FALSE;
3114 return main (__argc, __argv);
3118 * If this application has no console window to which its standard output
3119 * would go, create one.
3122 create_console(void)
3125 /* We have no console to which to print the version string, so
3126 create one and make it the standard input, output, and error. */
3127 if (!AllocConsole())
3128 return; /* couldn't create console */
3129 eth_freopen("CONIN$", "r", stdin);
3130 eth_freopen("CONOUT$", "w", stdout);
3131 eth_freopen("CONOUT$", "w", stderr);
3133 /* Well, we have a console now. */
3136 /* Now register "destroy_console()" as a routine to be called just
3137 before the application exits, so that we can destroy the console
3138 after the user has typed a key (so that the console doesn't just
3139 disappear out from under them, giving the user no chance to see
3140 the message(s) we put in there). */
3141 atexit(destroy_console);
3143 SetConsoleTitle(_T("Wireshark Debug Console"));
3148 destroy_console(void)
3151 printf("\n\nPress any key to exit\n");
3159 /* This routine should not be necessary, at least as I read the GLib
3160 source code, as it looks as if GLib is, on Win32, *supposed* to
3161 create a console window into which to display its output.
3163 That doesn't happen, however. I suspect there's something completely
3164 broken about that code in GLib-for-Win32, and that it may be related
3165 to the breakage that forces us to just call "printf()" on the message
3166 rather than passing the message on to "g_log_default_handler()"
3167 (which is the routine that does the aforementioned non-functional
3168 console window creation). */
3170 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3171 const char *message, gpointer user_data _U_)
3178 /* ignore log message, if log_level isn't interesting.
3179 If preferences aren't loaded yet, display message anyway */
3180 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3181 prefs.console_log_level != 0) {
3185 /* create a "timestamp" */
3187 today = localtime(&curr);
3190 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3191 /* the user wants a console or the application will terminate immediately */
3195 /* For some unknown reason, the above doesn't appear to actually cause
3196 anything to be sent to the standard output, so we'll just splat the
3197 message out directly, just to make sure it gets out. */
3199 switch(log_level & G_LOG_LEVEL_MASK) {
3200 case G_LOG_LEVEL_ERROR:
3203 case G_LOG_LEVEL_CRITICAL:
3206 case G_LOG_LEVEL_WARNING:
3209 case G_LOG_LEVEL_MESSAGE:
3212 case G_LOG_LEVEL_INFO:
3215 case G_LOG_LEVEL_DEBUG:
3219 fprintf(stderr, "unknown log_level %u\n", log_level);
3221 g_assert_not_reached();
3224 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3225 today->tm_hour, today->tm_min, today->tm_sec,
3226 log_domain != NULL ? log_domain : "",
3229 if(log_level & G_LOG_LEVEL_ERROR) {
3230 /* wait for a key press before the following error handler will terminate the program
3231 this way the user at least can read the error message */
3232 printf("\n\nPress any key to exit\n");
3236 g_log_default_handler(log_domain, log_level, message, user_data);
3242 static GtkWidget *info_bar_new(void)
3244 /* tip: tooltips don't work on statusbars! */
3245 info_bar = gtk_statusbar_new();
3246 main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
3247 file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
3248 help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
3249 #if GTK_MAJOR_VERSION >= 2
3250 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(info_bar), FALSE);
3252 gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
3257 static GtkWidget *packets_bar_new(void)
3259 /* tip: tooltips don't work on statusbars! */
3260 packets_bar = gtk_statusbar_new();
3261 packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
3262 packets_bar_update();
3269 * Helper for main_widgets_rearrange()
3271 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3272 gtk_container_remove(GTK_CONTAINER(data), widget);
3275 static GtkWidget *main_widget_layout(gint layout_content)
3277 switch(layout_content) {
3278 case(layout_pane_content_none):
3281 case(layout_pane_content_plist):
3284 case(layout_pane_content_pdetails):
3287 case(layout_pane_content_pbytes):
3291 g_assert_not_reached();
3298 * Rearrange the main window widgets
3300 void main_widgets_rearrange(void) {
3301 GtkWidget *first_pane_widget1, *first_pane_widget2;
3302 GtkWidget *second_pane_widget1, *second_pane_widget2;
3303 gboolean split_top_left;
3305 /* be a bit faster */
3306 gtk_widget_hide(main_vbox);
3308 /* be sure, we don't loose a widget while rearranging */
3309 gtk_widget_ref(menubar);
3310 gtk_widget_ref(main_tb);
3311 gtk_widget_ref(filter_tb);
3314 gtk_widget_ref(airpcap_tb);
3317 gtk_widget_ref(pkt_scrollw);
3318 gtk_widget_ref(tv_scrollw);
3319 gtk_widget_ref(byte_nb_ptr);
3320 gtk_widget_ref(stat_hbox);
3321 gtk_widget_ref(info_bar);
3322 gtk_widget_ref(packets_bar);
3323 gtk_widget_ref(status_pane);
3324 gtk_widget_ref(main_pane_v1);
3325 gtk_widget_ref(main_pane_v2);
3326 gtk_widget_ref(main_pane_h1);
3327 gtk_widget_ref(main_pane_h2);
3328 gtk_widget_ref(welcome_pane);
3330 /* empty all containers participating */
3331 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3332 gtk_container_foreach(GTK_CONTAINER(stat_hbox), foreach_remove_a_child, stat_hbox);
3333 gtk_container_foreach(GTK_CONTAINER(status_pane), foreach_remove_a_child, status_pane);
3334 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3335 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3336 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3337 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3339 /* add the menubar always at the top */
3340 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3343 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3345 /* filter toolbar in toolbar area */
3346 if (!prefs.filter_toolbar_show_in_statusbar) {
3347 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3351 /* airpcap toolbar */
3352 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3355 /* fill the main layout panes */
3356 switch(prefs.gui_layout_type) {
3357 case(layout_type_5):
3358 main_first_pane = main_pane_v1;
3359 main_second_pane = main_pane_v2;
3360 split_top_left = FALSE;
3362 case(layout_type_2):
3363 main_first_pane = main_pane_v1;
3364 main_second_pane = main_pane_h1;
3365 split_top_left = FALSE;
3367 case(layout_type_1):
3368 main_first_pane = main_pane_v1;
3369 main_second_pane = main_pane_h1;
3370 split_top_left = TRUE;
3372 case(layout_type_4):
3373 main_first_pane = main_pane_h1;
3374 main_second_pane = main_pane_v1;
3375 split_top_left = FALSE;
3377 case(layout_type_3):
3378 main_first_pane = main_pane_h1;
3379 main_second_pane = main_pane_v1;
3380 split_top_left = TRUE;
3382 case(layout_type_6):
3383 main_first_pane = main_pane_h1;
3384 main_second_pane = main_pane_h2;
3385 split_top_left = FALSE;
3388 main_first_pane = NULL;
3389 main_second_pane = NULL;
3390 split_top_left = FALSE;
3391 g_assert_not_reached();
3393 if (split_top_left) {
3394 first_pane_widget1 = main_second_pane;
3395 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3396 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3397 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3399 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3400 first_pane_widget2 = main_second_pane;
3401 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3402 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3404 if (first_pane_widget1 != NULL)
3405 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3406 if (first_pane_widget2 != NULL)
3407 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3408 if (second_pane_widget1 != NULL)
3409 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3410 if (second_pane_widget2 != NULL)
3411 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3413 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3416 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3418 /* statusbar hbox */
3419 gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0);
3421 /* filter toolbar in statusbar hbox */
3422 if (prefs.filter_toolbar_show_in_statusbar) {
3423 gtk_box_pack_start(GTK_BOX(stat_hbox), filter_tb, FALSE, TRUE, 1);
3427 /* airpcap toolbar */
3428 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3432 gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane, TRUE, TRUE, 0);
3433 gtk_paned_pack1(GTK_PANED(status_pane), info_bar, FALSE, FALSE);
3434 gtk_paned_pack2(GTK_PANED(status_pane), packets_bar, FALSE, FALSE);
3436 /* hide widgets on users recent settings */
3437 main_widgets_show_or_hide();
3439 gtk_widget_show(main_vbox);
3443 is_widget_visible(GtkWidget *widget, gpointer data)
3445 gboolean *is_visible = data;
3448 if (GTK_WIDGET_VISIBLE(widget))
3453 /*#define SHOW_WELCOME_PAGE*/
3454 #ifdef SHOW_WELCOME_PAGE
3455 /* XXX - There seems to be some disagreement about if and how this feature should be implemented.
3456 As I currently don't have the time to continue this, it's temporarily disabled. - ULFL */
3458 welcome_item(const gchar *stock_item, const gchar * label, const gchar * message, const gchar * tooltip,
3459 GtkSignalFunc callback, void *callback_data)
3461 GtkWidget *w, *item_hb;
3462 #if GTK_MAJOR_VERSION >= 2
3463 gchar *formatted_message;
3464 GtkTooltips *tooltips;
3466 tooltips = gtk_tooltips_new();
3469 item_hb = gtk_hbox_new(FALSE, 1);
3471 w = BUTTON_NEW_FROM_STOCK(stock_item);
3472 WIDGET_SET_SIZE(w, 80, 40);
3473 #if GTK_MAJOR_VERSION >= 2
3474 gtk_button_set_label(GTK_BUTTON(w), label);
3475 gtk_tooltips_set_tip(tooltips, w, tooltip, NULL);
3477 gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 0);
3478 SIGNAL_CONNECT(w, "clicked", callback, callback_data);
3480 w = gtk_label_new(message);
3481 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3482 #if GTK_MAJOR_VERSION >= 2
3483 formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\">%s</span>", message);
3484 gtk_label_set_markup(GTK_LABEL(w), formatted_message);
3485 g_free(formatted_message);
3488 gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 10);
3495 welcome_header_new(void)
3506 /* background color of the header bar */
3509 bg.green = 210 * 255;
3510 bg.blue = 229 * 255;
3512 item_vb = gtk_vbox_new(FALSE, 0);
3516 eb = gtk_event_box_new();
3517 gtk_container_add(GTK_CONTAINER(eb), item_vb);
3518 #if GTK_MAJOR_VERSION >= 2
3519 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &bg);
3522 item_hb = gtk_hbox_new(FALSE, 0);
3523 gtk_box_pack_start(GTK_BOX(item_vb), item_hb, FALSE, FALSE, 10);
3525 icon = xpm_to_widget_from_parent(top_level, wssplash_xpm);
3526 /*icon = xpm_to_widget_from_parent(top_level, wsicon64_xpm);*/
3527 gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 10);
3529 #if GTK_MAJOR_VERSION < 2
3530 message = "The World's Most Popular Network Protocol Analyzer";
3532 message = "<span weight=\"bold\" size=\"x-large\">" "The World's Most Popular Network Protocol Analyzer" "</span>";
3534 w = gtk_label_new(message);
3535 #if GTK_MAJOR_VERSION >= 2
3536 gtk_label_set_markup(GTK_LABEL(w), message);
3538 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3539 gtk_box_pack_start(GTK_BOX(item_hb), w, TRUE, TRUE, 5);
3541 gtk_widget_show_all(eb);
3547 welcome_topic_header_new(const char *header)
3552 #if GTK_MAJOR_VERSION >= 2
3553 gchar *formatted_message;
3557 w = gtk_label_new(header);
3558 #if GTK_MAJOR_VERSION >= 2
3559 formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\">%s</span>", header);
3560 gtk_label_set_markup(GTK_LABEL(w), formatted_message);
3561 g_free(formatted_message);
3564 /* topic header background color */
3567 bg.green = 151 * 255;
3568 bg.blue = 192 * 255;
3572 eb = gtk_event_box_new();
3573 gtk_container_add(GTK_CONTAINER(eb), w);
3574 #if GTK_MAJOR_VERSION >= 2
3575 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &bg);
3583 welcome_topic_new(const char *header, GtkWidget **to_fill)
3585 GtkWidget *topic_vb;
3586 GtkWidget *layout_vb;
3587 GtkWidget *topic_eb;
3588 GtkWidget *topic_header;
3591 topic_vb = gtk_vbox_new(FALSE, 0);
3593 /* topic content background color */
3596 bg.green = 226 * 255;
3597 bg.blue = 228 * 255;
3599 topic_header = welcome_topic_header_new(header);
3600 gtk_box_pack_start(GTK_BOX(topic_vb), topic_header, FALSE, FALSE, 0);
3602 layout_vb = gtk_vbox_new(FALSE, 5);
3603 gtk_container_border_width(GTK_CONTAINER(layout_vb), 10);
3604 gtk_box_pack_start(GTK_BOX(topic_vb), layout_vb, FALSE, FALSE, 0);
3606 /* colorize vbox (we need an event box for this!) */
3608 topic_eb = gtk_event_box_new();
3609 gtk_container_add(GTK_CONTAINER(topic_eb), topic_vb);
3610 #if GTK_MAJOR_VERSION >= 2
3611 gtk_widget_modify_bg(topic_eb, GTK_STATE_NORMAL, &bg);
3613 *to_fill = layout_vb;
3619 #if GTK_MAJOR_VERSION >= 2
3621 welcome_link_enter_cb(GtkWidget *widget _U_, GdkEventCrossing *event _U_, gpointer user_data)
3624 GtkWidget *w = user_data;
3626 message = g_strdup_printf("<span foreground='blue' underline='single'>%s</span>", OBJECT_GET_DATA(w,"TEXT"));
3627 #if GTK_MAJOR_VERSION >= 2
3628 gtk_label_set_markup(GTK_LABEL(w), message);
3636 welcome_link_leave_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer user_data)
3639 GtkWidget *w = user_data;
3641 message = g_strdup_printf("<span foreground='blue'>%s</span>", OBJECT_GET_DATA(w,"TEXT"));
3642 #if GTK_MAJOR_VERSION >= 2
3643 gtk_label_set_markup(GTK_LABEL(w), message);
3653 welcome_link_press_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_) {
3655 g_warning("TBD: link pressed");
3661 welcome_link_new(const gchar *text, GtkWidget **label /*, void *callback, void *private_data */)
3667 #if GTK_MAJOR_VERSION < 2
3668 message = g_strdup(text);
3670 message = g_strdup_printf("<span foreground='blue'>%s</span>", text);
3672 w = gtk_label_new(message);
3674 #if GTK_MAJOR_VERSION >= 2
3675 gtk_label_set_markup(GTK_LABEL(w), message);
3680 eb = gtk_event_box_new();
3681 gtk_container_add(GTK_CONTAINER(eb), w);
3683 #if GTK_MAJOR_VERSION >= 2
3684 SIGNAL_CONNECT(eb, "enter-notify-event", welcome_link_enter_cb, w);
3685 SIGNAL_CONNECT(eb, "leave-notify-event", welcome_link_leave_cb, w);
3687 SIGNAL_CONNECT(eb, "button-press-event", welcome_link_press_cb, w);
3690 OBJECT_SET_DATA(w, "TEXT", g_strdup(text));
3696 welcome_filename_link_new(const char *filename, GtkWidget **label)
3700 const unsigned int max = 60;
3703 str = g_string_new(filename);
3705 if(str->len > max) {
3706 g_string_erase(str, 0, str->len-max /*cut*/);
3707 g_string_prepend(str, "... ");
3710 w = welcome_link_new(str->str, label);
3712 g_string_free(str, TRUE);
3719 welcome_if_new(const char *if_name, GdkColor *topic_bg, gboolean active)
3721 GtkWidget *interface_hb;
3724 GtkTooltips *tooltips;
3728 tooltips = gtk_tooltips_new();
3730 interface_hb = gtk_hbox_new(FALSE, 5);
3732 w = welcome_link_new("START", &label);
3733 gtk_tooltips_set_tip(tooltips, w, "Immediately start a capture on 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("OPTIONS", &label);
3741 gtk_tooltips_set_tip(tooltips, w, "Show the capture options of 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 w = welcome_link_new("DETAILS", &label);
3749 gtk_tooltips_set_tip(tooltips, w, "Show detailed information about this interface", NULL);
3750 #if GTK_MAJOR_VERSION >= 2
3751 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, topic_bg);
3753 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3754 gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3756 message = g_string_new(if_name);
3758 /* truncate string if it's too long */
3759 if(message->len > 38) {
3760 g_string_truncate(message, 35);
3761 g_string_append (message, " ...");
3763 #if GTK_MAJOR_VERSION >= 2
3764 /* if this is the "active" interface, display it bold */
3766 g_string_prepend(message, "<span weight=\"bold\">");
3767 g_string_append (message, "</span>");
3770 w = gtk_label_new(message->str);
3771 #if GTK_MAJOR_VERSION >= 2
3772 gtk_label_set_markup(GTK_LABEL(w), message->str);
3774 g_string_free(message, TRUE);
3776 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3777 gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3779 return interface_hb;
3782 /* XXX - the layout has to be improved */
3786 GtkWidget *welcome_scrollw;
3787 GtkWidget *welcome_vb;
3788 GtkWidget *welcome_hb;
3789 GtkWidget *column_vb;
3794 GtkWidget *topic_vb;
3795 GtkWidget *topic_to_fill;
3796 GtkWidget *interface_hb;
3800 /* topic content background color */
3802 topic_bg.red = 221 * 255;
3803 topic_bg.green = 226 * 255;
3804 topic_bg.blue = 228 * 255;
3806 welcome_scrollw = scrolled_window_new(NULL, NULL);
3808 welcome_vb = gtk_vbox_new(FALSE, 0);
3811 header = welcome_header_new();
3812 gtk_box_pack_start(GTK_BOX(welcome_vb), header, FALSE, FALSE, 0);
3815 welcome_hb = gtk_hbox_new(FALSE, 10);
3816 gtk_container_border_width(GTK_CONTAINER(welcome_hb), 10);
3817 gtk_box_pack_start(GTK_BOX(welcome_vb), welcome_hb, TRUE, TRUE, 0);
3819 /* column capture */
3820 column_vb = gtk_vbox_new(FALSE, 10);
3821 gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
3824 topic_vb = welcome_topic_new("Capture", &topic_to_fill);
3825 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3828 item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_INTERFACES,
3830 "Interface Life List",
3831 "Show a life list of the available capture interfaces",
3832 GTK_SIGNAL_FUNC(capture_if_cb), NULL);
3833 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3836 w = gtk_label_new("Available Interfaces:");
3837 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3838 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
3840 interface_hb = welcome_if_new("Generic dialup adapter", &topic_bg, FALSE);
3841 gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3843 /* Marvell interface (currently "active") */
3844 interface_hb = welcome_if_new("Marvell Gigabit Ethernet Controller", &topic_bg, TRUE);
3845 gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3847 /* Wireless interface */
3848 interface_hb = welcome_if_new("Intel(R) PRO/Wireless 3945ABG Network Connection", &topic_bg, FALSE);
3849 gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3852 /* capture help topic */
3853 topic_vb = welcome_topic_new("Capture Help", &topic_to_fill);
3854 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3857 item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_START,
3859 "How To: Setup a Capture",
3860 "How To: Setup a Capture (online from the Wiki)",
3861 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3862 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3864 item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_START,
3866 "Capture Filter Examples",
3867 "Capture Filter Examples (online from the Wiki)",
3868 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3869 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3872 /* fill bottom space */
3873 w = gtk_label_new("");
3874 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3878 topic_vb = welcome_topic_new("Files", &topic_to_fill);
3879 gtk_box_pack_start(GTK_BOX(welcome_hb), topic_vb, TRUE, TRUE, 0);
3881 item_hb = welcome_item(GTK_STOCK_OPEN,
3883 "Open a Capture File",
3884 "Open a previously captured file",
3885 GTK_SIGNAL_FUNC(file_open_cmd_cb), NULL);
3886 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3888 item_hb = welcome_item(GTK_STOCK_OPEN,
3890 "Download Examples",
3891 "Download Example Capture Files (from the Wiki)",
3892 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3893 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3895 w = gtk_label_new("Recent Files:");
3896 gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3897 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
3899 w = welcome_link_new("C:\\Testfiles\\hello.pcap", &label);
3900 #if GTK_MAJOR_VERSION >= 2
3901 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3903 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3904 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3906 w = welcome_filename_link_new("C:\\Testfiles\\hello2.pcap", &label);
3907 #if GTK_MAJOR_VERSION >= 2
3908 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3910 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3911 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3913 w = welcome_filename_link_new(
3914 "C:\\Testfiles\\to avoid screen garbage\\Unfortunately this is a very long filename which had to be truncated.pcap",
3916 #if GTK_MAJOR_VERSION >= 2
3917 gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3919 gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3920 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3922 w = gtk_label_new("");
3923 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3927 column_vb = gtk_vbox_new(FALSE, 10);
3928 gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
3931 topic_vb = welcome_topic_new("Online", &topic_to_fill);
3932 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3934 #if (GLIB_MAJOR_VERSION >= 2)
3935 item_hb = welcome_item(WIRESHARK_STOCK_WEB_SUPPORT,
3937 "Show the User's Guide",
3938 "Show the User's Guide (local version, if available)",
3939 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3940 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3942 item_hb = welcome_item(GTK_STOCK_HOME,
3944 "Projects Home Page",
3945 "Visit www.wireshark.org, the project's home page",
3946 GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_HOME));
3947 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3951 topic_vb = welcome_topic_new("Updates", &topic_to_fill);
3952 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3954 w = gtk_label_new("No updates available!");
3955 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3959 gtk_widget_show_all(welcome_vb);
3961 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(welcome_scrollw),
3963 gtk_widget_show_all(welcome_scrollw);
3965 return welcome_scrollw;
3971 /* this is just a dummy to fill up window space, simply showing nothing */
3972 return scrolled_window_new(NULL, NULL);
3979 * XXX - this doesn't appear to work with the paned widgets in
3980 * GTK+ 1.2[.x]; if you hide one of the panes, the splitter remains
3981 * and the other pane doesn't grow to take up the rest of the pane.
3982 * It does appear to work with GTK+ 2.x.
3985 main_widgets_show_or_hide(void)
3987 gboolean main_second_pane_show;
3989 if (recent.main_toolbar_show) {
3990 gtk_widget_show(main_tb);
3992 gtk_widget_hide(main_tb);
3996 * Show the status hbox if either:
3998 * 1) we're showing the filter toolbar and we want it in the status
4003 * 2) we're showing the status bar.
4005 if ((recent.filter_toolbar_show && prefs.filter_toolbar_show_in_statusbar) ||
4006 recent.statusbar_show) {
4007 gtk_widget_show(stat_hbox);
4009 gtk_widget_hide(stat_hbox);
4012 if (recent.statusbar_show) {
4013 gtk_widget_show(status_pane);
4015 gtk_widget_hide(status_pane);
4018 if (recent.filter_toolbar_show) {
4019 gtk_widget_show(filter_tb);
4021 gtk_widget_hide(filter_tb);
4025 if (recent.airpcap_toolbar_show) {
4026 gtk_widget_show(airpcap_tb);
4028 gtk_widget_hide(airpcap_tb);
4032 if (recent.packet_list_show && have_capture_file) {
4033 gtk_widget_show(pkt_scrollw);
4035 gtk_widget_hide(pkt_scrollw);
4038 if (recent.tree_view_show && have_capture_file) {
4039 gtk_widget_show(tv_scrollw);
4041 gtk_widget_hide(tv_scrollw);
4044 if (recent.byte_view_show && have_capture_file) {
4045 gtk_widget_show(byte_nb_ptr);
4047 gtk_widget_hide(byte_nb_ptr);
4050 if (have_capture_file) {
4051 gtk_widget_show(main_first_pane);
4053 gtk_widget_hide(main_first_pane);
4057 * Is anything in "main_second_pane" visible?
4058 * If so, show it, otherwise hide it.
4060 main_second_pane_show = FALSE;
4061 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
4062 &main_second_pane_show);
4063 if (main_second_pane_show) {
4064 gtk_widget_show(main_second_pane);
4066 gtk_widget_hide(main_second_pane);
4069 if (!have_capture_file) {
4071 gtk_widget_show(welcome_pane);
4074 gtk_widget_hide(welcome_pane);
4077 /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
4078 packet_list_freeze ();
4079 packet_list_thaw ();
4083 #if GTK_MAJOR_VERSION >= 2
4084 /* called, when the window state changes (minimized, maximized, ...) */
4086 window_state_event_cb (GtkWidget *widget _U_,
4090 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
4092 if( (event->type) == (GDK_WINDOW_STATE)) {
4093 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
4094 /* we might have dialogs popped up while we where iconified,
4096 display_queued_messages();
4105 * Changed callback for the channel combobox
4108 airpcap_toolbar_channel_changed_cb(GtkWidget *w _U_, gpointer data)
4113 if ((data != NULL) && (w != NULL) && change_airpcap_settings) {
4114 s = gtk_entry_get_text(GTK_ENTRY(w));
4115 if ((g_strcasecmp("",s))) {
4116 ch_freq = airpcap_get_frequency_from_str(s);
4117 if (airpcap_if_active != NULL) {
4118 airpcap_if_active->channelInfo.Frequency = ch_freq;
4119 airpcap_update_channel_offset_cb(airpcap_if_active, ch_freq, GTK_WIDGET(data));
4126 * Changed callback for the channel offset combobox
4129 on_channel_offset_cb_changed(GtkWidget *w _U_, gpointer data)
4134 if ((data != NULL) && (w != NULL) && change_airpcap_settings)
4136 s = gtk_entry_get_text(GTK_ENTRY(w));
4137 if ((g_strcasecmp("",s)))
4139 if (airpcap_if_active != NULL)
4141 sscanf(s,"%d",&offset);
4142 airpcap_if_active->channelInfo.ExtChannel = offset;
4143 if (change_airpcap_settings != NULL)
4145 airpcap_update_frequency_and_offset(airpcap_if_active);
4153 * Callback for the wrong crc combo
4156 airpcap_toolbar_wrong_crc_combo_cb(GtkWidget *entry, gpointer user_data)
4158 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4161 if( !block_toolbar_signals && (airpcap_if_active != NULL)) {
4162 ad = airpcap_if_open(airpcap_if_active->name, ebuf);
4165 airpcap_if_active->CrcValidationOn = airpcap_get_validation_type(gtk_entry_get_text(GTK_ENTRY(entry)));
4166 airpcap_if_set_fcs_validation(ad,airpcap_if_active->CrcValidationOn);
4167 /* Save configuration */
4168 airpcap_if_store_cur_config_as_adapter_default(ad);
4169 airpcap_if_close(ad);
4175 airpcap_toolbar_encryption_cb(GtkWidget *entry, gpointer user_data)
4177 /* We need to directly access the .ddl functions here... */
4178 gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4183 airpcap_if_info_t* curr_if = NULL;
4185 /* Apply changes to the current adapter */
4186 if( (airpcap_if_active != NULL)) {
4187 ad = airpcap_if_open(airpcap_if_active->name, ebuf);
4190 if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON) {
4191 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_OFF;
4192 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
4193 /* Save configuration */
4194 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4195 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.");
4197 airpcap_if_close(ad);
4199 airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_ON;
4200 airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
4201 /* Save configuration */
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);
4209 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No active AirPcap Adapter selected!");
4213 if (!(airpcap_if_list == NULL)){
4214 n = g_list_length(airpcap_if_list);
4216 /* The same kind of settings should be propagated to all the adapters */
4217 /* Apply this change to all the adapters !!! */
4218 for(i = 0; i < n; i++) {
4219 curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
4221 if( (curr_if != NULL) && (curr_if != airpcap_if_selected) ) {
4222 ad = airpcap_if_open(curr_if->name, ebuf);
4224 curr_if->DecryptionOn = airpcap_if_selected->DecryptionOn;
4225 airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
4226 /* Save configuration for the curr_if */
4227 if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4228 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.");
4230 airpcap_if_close(ad);
4235 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "AirPcap Adapter Error!");
4241 * Callback for the Advanced Wireless Settings button
4244 toolbar_display_airpcap_advanced_cb(GtkWidget *w, gpointer data)
4248 from_widget = (gint*)g_malloc(sizeof(gint));
4249 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
4250 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
4252 display_airpcap_advanced_cb(w,data);
4256 * Callback for the Decryption Key Management button
4259 toolbar_display_airpcap_key_management_cb(GtkWidget *w, gpointer data)
4263 from_widget = (gint*)g_malloc(sizeof(gint));
4264 *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
4265 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
4267 display_airpcap_key_management_cb(w,data);
4269 #endif /* HAVE_AIRPCAP */
4271 #if GTK_MAJOR_VERSION >= 2
4272 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_LOCK_MASK))
4274 top_level_key_pressed_cb(GtkCTree *ctree _U_, GdkEventKey *event, gpointer user_data _U_)
4276 if (event->keyval == GDK_F8) {
4279 } else if (event->keyval == GDK_F7) {
4282 } else if (event->state & NO_SHIFT_MOD_MASK) {
4283 return FALSE; /* Skip control, alt, and other modifiers */
4285 * A comment in gdkkeysyms.h says that it's autogenerated from
4286 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
4287 * don't explicitly say so, isprint() should work as expected
4290 } else if (isascii(event->keyval) && isprint(event->keyval)) {
4291 /* Forward the keypress on to the display filter entry */
4292 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
4293 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
4294 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
4303 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
4306 *filter_bt, *filter_cm, *filter_te,
4307 *filter_add_expr_bt,
4310 GList *dfilter_list = NULL;
4311 GtkTooltips *tooltips;
4313 GtkAccelGroup *accel;
4317 GtkWidget *key_management_bt = NULL,
4318 #if GTK_MAJOR_VERSION >= 2 /* For some reason this button's action crashes under GTK 1. */
4319 *advanced_bt = NULL,
4323 *channel_offset_lb = NULL,
4324 *channel_offset_cb = NULL,
4325 *wrong_crc_lb = NULL,
4326 *wrong_crc_cm = NULL;
4328 GtkWidget *enable_decryption_lb;
4329 GtkWidget *enable_decryption_cb;
4330 GList *enable_decryption_cb_items = NULL;
4331 GtkWidget *enable_decryption_en;
4333 GList *channel_list = NULL;
4334 GList *linktype_list = NULL;
4335 GList *link_list = NULL;
4336 GtkTooltips *airpcap_tooltips;
4337 /* gchar *if_label_text; */
4338 gint *from_widget = NULL;
4341 /* Display filter construct dialog has an Apply button, and "OK" not
4342 only sets our text widget, it activates it (i.e., it causes us to
4343 filter the capture). */
4344 static construct_args_t args = {
4345 "Wireshark: Display Filter",
4351 /* use user-defined title if preference is set */
4352 title = create_user_window_title("The Wireshark Network Analyzer");
4355 top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
4358 tooltips = gtk_tooltips_new();
4361 airpcap_tooltips = gtk_tooltips_new();
4365 #if GTK_MAJOR_VERSION < 2
4366 /* has to be done, after top_level window is created */
4367 app_font_gtk1_init(top_level);
4371 gtk_widget_set_name(top_level, "main window");
4372 SIGNAL_CONNECT(top_level, "delete_event", main_window_delete_event_cb,
4374 #if GTK_MAJOR_VERSION >= 2
4375 SIGNAL_CONNECT(GTK_OBJECT(top_level), "window_state_event",
4376 G_CALLBACK (window_state_event_cb), NULL);
4377 SIGNAL_CONNECT(GTK_OBJECT(top_level), "key-press-event",
4378 G_CALLBACK (top_level_key_pressed_cb), NULL );
4381 gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
4383 /* Container for menu bar, toolbar(s), paned windows and progress/info box */
4384 main_vbox = gtk_vbox_new(FALSE, 1);
4385 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
4386 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
4387 gtk_widget_show(main_vbox);
4390 menubar = main_menu_new(&accel);
4391 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
4392 gtk_widget_show(menubar);
4395 main_tb = toolbar_new();
4396 gtk_widget_show (main_tb);
4399 pkt_scrollw = packet_list_new(prefs);
4400 WIDGET_SET_SIZE(packet_list, -1, pl_size);
4401 gtk_widget_show(pkt_scrollw);
4404 tv_scrollw = main_tree_view_new(prefs, &tree_view);
4405 WIDGET_SET_SIZE(tv_scrollw, -1, tv_size);
4406 gtk_widget_show(tv_scrollw);
4408 #if GTK_MAJOR_VERSION < 2
4409 SIGNAL_CONNECT(tree_view, "tree-select-row", tree_view_select_row_cb, NULL);
4410 SIGNAL_CONNECT(tree_view, "tree-unselect-row", tree_view_unselect_row_cb,
4413 SIGNAL_CONNECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
4414 "changed", tree_view_selection_changed_cb, NULL);
4416 SIGNAL_CONNECT(tree_view, "button_press_event", popup_menu_handler,
4417 OBJECT_GET_DATA(popup_menu_object, PM_TREE_VIEW_KEY));
4418 gtk_widget_show(tree_view);
4421 byte_nb_ptr = byte_view_new();
4422 WIDGET_SET_SIZE(byte_nb_ptr, -1, bv_size);
4423 gtk_widget_show(byte_nb_ptr);
4425 SIGNAL_CONNECT(byte_nb_ptr, "button_press_event", popup_menu_handler,
4426 OBJECT_GET_DATA(popup_menu_object, PM_HEXDUMP_KEY));
4429 /* Panes for the packet list, tree, and byte view */
4430 main_pane_v1 = gtk_vpaned_new();
4431 gtk_widget_show(main_pane_v1);
4432 main_pane_v2 = gtk_vpaned_new();
4433 gtk_widget_show(main_pane_v2);
4434 main_pane_h1 = gtk_hpaned_new();
4435 gtk_widget_show(main_pane_h1);
4436 main_pane_h2 = gtk_hpaned_new();
4437 gtk_widget_show(main_pane_h2);
4440 /* airpcap toolbar */
4441 #if GTK_MAJOR_VERSION < 2
4442 airpcap_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
4445 airpcap_tb = gtk_toolbar_new();
4446 gtk_toolbar_set_orientation(GTK_TOOLBAR(airpcap_tb),
4447 GTK_ORIENTATION_HORIZONTAL);
4448 #endif /* GTK_MAJOR_VERSION */
4449 gtk_widget_show(airpcap_tb);
4451 /* Interface Label */
4452 /*if(airpcap_if_active != NULL) {
4453 if_label_text = g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_active));
4454 interface_lb = gtk_label_new(if_label_text);
4455 g_free(if_label_text);
4457 interface_lb = gtk_label_new("No Wireless Interface Found ");
4460 /* Add the label to the toolbar */
4461 /*gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), interface_lb,
4462 "Current Wireless Interface", "Private");
4463 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_INTERFACE_KEY,interface_lb);
4464 gtk_widget_show(interface_lb);
4465 gtk_toolbar_insert_space(GTK_TOOLBAR(airpcap_tb),1);*/
4468 /* Create the "802.11 Channel:" label */
4469 channel_lb = gtk_label_new("802.11 Channel: ");
4470 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_LABEL_KEY,channel_lb);
4471 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_lb,
4472 "Current 802.11 Channel", "Private");
4473 gtk_widget_show(channel_lb);
4475 WIDGET_SET_SIZE(channel_lb, 85, 28);
4477 /* Create the channel combo box */
4478 channel_cm = gtk_combo_new();
4479 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(channel_cm)->entry),FALSE);
4480 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_KEY,channel_cm);
4482 if (airpcap_if_active != NULL && airpcap_if_active->pSupportedChannels != NULL && airpcap_if_active->numSupportedChannels > 0){
4484 for (; i<airpcap_if_active->numSupportedChannels; i++){
4485 channel_list = g_list_append(channel_list, airpcap_get_channelstr_from_freq(airpcap_if_active->pSupportedChannels[i].Frequency));
4487 gtk_combo_set_popdown_strings( GTK_COMBO(channel_cm), channel_list) ;
4490 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(channel_cm)->entry),
4491 "Change the 802.11 RF channel", NULL);
4493 WIDGET_SET_SIZE(channel_cm, 120, 28);
4495 if(airpcap_if_active != NULL)
4496 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry), airpcap_get_channelstr_from_freq(airpcap_if_active->channelInfo.Frequency));
4498 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry),"");
4500 gtk_widget_show(channel_cm);
4502 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_cm,
4503 "802.11 Channel", "Private");
4505 /* gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb)); */
4507 /* Create the "Channel Offset:" label */
4508 channel_offset_lb = gtk_label_new("Channel Offset: ");
4509 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_OFFSET_LABEL_KEY,channel_offset_lb);
4510 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_offset_lb,
4511 "Current 802.11 Channel Offset", "Private");
4512 gtk_widget_show(channel_offset_lb);
4514 WIDGET_SET_SIZE(channel_offset_lb, 80, 28);
4516 /* Start: Channel offset combo box */
4517 channel_offset_cb = gtk_combo_new();
4518 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(channel_offset_cb)->entry),FALSE);
4519 OBJECT_SET_DATA(airpcap_tb, AIRPCAP_TOOLBAR_CHANNEL_OFFSET_KEY, channel_offset_cb);
4521 if(airpcap_if_active != NULL){
4522 airpcap_update_channel_offset_cb(airpcap_if_active, airpcap_if_active->channelInfo.Frequency, channel_offset_cb);
4523 airpcap_update_channel_offset_combo_entry(channel_offset_cb, airpcap_if_active->channelInfo.ExtChannel);
4525 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_offset_cb)->entry),"");
4528 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(channel_offset_cb)->entry),
4529 "Change channel offset", NULL);
4531 WIDGET_SET_SIZE(channel_offset_cb, 50, 28);
4533 gtk_widget_show(channel_offset_cb);
4535 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_offset_cb,
4536 "802.11 Channel Offset", "Private");
4538 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4540 /* callback for channel combo box */
4541 SIGNAL_CONNECT(GTK_COMBO(channel_cm)->entry,"changed", airpcap_toolbar_channel_changed_cb, channel_offset_cb);
4542 /* callback for channel offset combo box */
4543 SIGNAL_CONNECT(GTK_COMBO(channel_offset_cb)->entry,"changed", on_channel_offset_cb_changed, channel_offset_cb);
4544 /* End: Channel offset combo box */
4546 /* Wrong CRC Label */
4547 wrong_crc_lb = gtk_label_new(" FCS Filter: ");
4548 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_LABEL_KEY,wrong_crc_lb);
4549 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_lb,
4551 gtk_widget_show(wrong_crc_lb);
4553 /* Wrong CRC combo */
4554 wrong_crc_cm = gtk_combo_new();
4555 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(wrong_crc_cm)->entry),FALSE);
4556 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_KEY,wrong_crc_cm);
4557 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_cm,
4560 WIDGET_SET_SIZE(wrong_crc_cm, 100, -1);
4562 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_ALL);
4563 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRECT);
4564 linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRUPT);
4566 gtk_combo_set_popdown_strings( GTK_COMBO(wrong_crc_cm), linktype_list) ;
4567 gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(wrong_crc_cm)->entry),
4568 "Select the 802.11 FCS filter that the wireless adapter will apply.",
4571 if(airpcap_if_active != NULL)
4572 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry), airpcap_get_validation_name(airpcap_if_active->CrcValidationOn));
4574 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry),"");
4576 SIGNAL_CONNECT(GTK_COMBO(wrong_crc_cm)->entry,"changed",airpcap_toolbar_wrong_crc_combo_cb,airpcap_tb);
4577 gtk_widget_show(wrong_crc_cm);
4579 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4581 /* Decryption mode combo box */
4582 enable_decryption_lb = gtk_label_new ("Decryption Mode: ");
4583 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_LABEL_KEY,enable_decryption_lb);
4584 gtk_widget_set_name (enable_decryption_lb, "enable_decryption_lb");
4585 gtk_widget_show (enable_decryption_lb);
4586 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_lb,
4589 enable_decryption_cb = gtk_combo_new ();
4590 gtk_widget_set_name (enable_decryption_cb, "enable_decryption_cb");
4591 gtk_widget_show (enable_decryption_cb);
4592 WIDGET_SET_SIZE (enable_decryption_cb, 83, -1);
4593 update_decryption_mode_list(enable_decryption_cb);
4595 enable_decryption_en = GTK_COMBO (enable_decryption_cb)->entry;
4596 gtk_widget_set_name (enable_decryption_en, "enable_decryption_en");
4597 gtk_widget_show (enable_decryption_en);
4598 gtk_editable_set_editable (GTK_EDITABLE (enable_decryption_en), FALSE);
4599 GTK_WIDGET_UNSET_FLAGS (enable_decryption_en, GTK_CAN_FOCUS);
4601 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_cb,
4602 "Choose a Decryption Mode", "Private");
4604 /* Set current decryption mode!!!! */
4605 update_decryption_mode_cm(enable_decryption_cb);
4606 SIGNAL_CONNECT (enable_decryption_en, "changed",on_enable_decryption_en_changed, airpcap_tb);
4607 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_KEY,enable_decryption_cb);
4609 gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4611 #if GTK_MAJOR_VERSION >= 2 /* For some reason this button's action crashes under GTK 1. */
4612 /* Advanced button */
4613 advanced_bt = gtk_button_new_with_label("Wireless Settings...");
4614 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_ADVANCED_KEY,advanced_bt);
4616 SIGNAL_CONNECT(advanced_bt, "clicked", toolbar_display_airpcap_advanced_cb, airpcap_tb);
4617 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), advanced_bt,
4618 "Set Advanced Wireless Settings", "Private");
4621 gtk_widget_show(advanced_bt);
4622 #endif /* GTK_MAJOR_VERSION */
4624 /* Key Management button */
4625 key_management_bt = gtk_button_new_with_label("Decryption Keys...");
4626 OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY,key_management_bt);
4628 SIGNAL_CONNECT(key_management_bt, "clicked", toolbar_display_airpcap_key_management_cb, airpcap_tb);
4629 gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), key_management_bt,
4630 "Manage Decryption Keys", "Private");
4631 gtk_widget_show(key_management_bt);
4633 /* If no airpcap interface is present, gray everything */
4634 if(airpcap_if_active == NULL) {
4635 if(airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0) {
4636 /*No airpcap device found */
4637 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4638 /* recent.airpcap_toolbar_show = TRUE; */
4640 /* default adapter is not airpcap... or is airpcap but is not found*/
4641 airpcap_set_toolbar_stop_capture(airpcap_if_active);
4642 airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4643 /* recent.airpcap_toolbar_show = TRUE; */
4646 airpcap_set_toolbar_stop_capture(airpcap_if_active);
4647 /* recent.airpcap_toolbar_show = TRUE; */
4651 /* filter toolbar */
4652 #if GTK_MAJOR_VERSION < 2
4653 filter_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
4656 filter_tb = gtk_toolbar_new();
4657 gtk_toolbar_set_orientation(GTK_TOOLBAR(filter_tb),
4658 GTK_ORIENTATION_HORIZONTAL);
4659 #endif /* GTK_MAJOR_VERSION */
4660 gtk_widget_show(filter_tb);
4662 /* Create the "Filter:" button */
4663 filter_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
4664 SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
4665 gtk_widget_show(filter_bt);
4666 OBJECT_SET_DATA(top_level, E_FILT_BT_PTR_KEY, filter_bt);
4668 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_bt,
4669 "Open the \"Display Filter\" dialog, to edit/apply filters", "Private");
4671 /* Create the filter combobox */
4672 filter_cm = gtk_combo_new();
4673 dfilter_list = NULL;
4674 gtk_combo_disable_activate(GTK_COMBO(filter_cm));
4675 gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
4676 OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
4677 filter_te = GTK_COMBO(filter_cm)->entry;
4678 main_display_filter_widget=filter_te;
4679 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
4680 OBJECT_SET_DATA(filter_te, E_DFILTER_CM_KEY, filter_cm);
4681 OBJECT_SET_DATA(top_level, E_DFILTER_CM_KEY, filter_cm);
4682 SIGNAL_CONNECT(filter_te, "activate", filter_activate_cb, filter_te);
4683 SIGNAL_CONNECT(filter_te, "changed", filter_te_syntax_check_cb, NULL);
4684 WIDGET_SET_SIZE(filter_cm, 400, -1);
4685 gtk_widget_show(filter_cm);
4686 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_cm,
4688 /* setting a tooltip for a combobox will do nothing, so add it to the corresponding text entry */
4689 gtk_tooltips_set_tip(tooltips, filter_te,
4690 "Enter a display filter, or choose one of your recently used filters. "
4691 "The background color of this field is changed by a continuous syntax check (green is valid, red is invalid).",
4694 /* Create the "Add Expression..." button, to pop up a dialog
4695 for constructing filter comparison expressions. */
4696 filter_add_expr_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_ADD_EXPRESSION);
4697 OBJECT_SET_DATA(filter_tb, E_FILT_FILTER_TE_KEY, filter_te);
4698 SIGNAL_CONNECT(filter_add_expr_bt, "clicked", filter_add_expr_bt_cb, filter_tb);
4699 gtk_widget_show(filter_add_expr_bt);
4700 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_add_expr_bt,
4701 "Add an expression to this filter string", "Private");
4703 /* Create the "Clear" button */
4704 filter_reset = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLEAR);
4705 OBJECT_SET_DATA(filter_reset, E_DFILTER_TE_KEY, filter_te);
4706 SIGNAL_CONNECT(filter_reset, "clicked", filter_reset_cb, NULL);
4707 gtk_widget_show(filter_reset);
4708 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_reset,
4709 "Clear this filter string and update the display", "Private");
4711 /* Create the "Apply" button */
4712 filter_apply = BUTTON_NEW_FROM_STOCK(GTK_STOCK_APPLY);
4713 OBJECT_SET_DATA(filter_apply, E_DFILTER_CM_KEY, filter_cm);
4714 SIGNAL_CONNECT(filter_apply, "clicked", filter_activate_cb, filter_te);
4715 gtk_widget_show(filter_apply);
4716 gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_apply,
4717 "Apply this filter string to the display", "Private");
4719 /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data
4720 * of any widget that ends up calling a callback which needs
4721 * that text entry pointer */
4722 set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te);
4723 set_menu_object_data("/Edit/Copy/As Filter", E_DFILTER_TE_KEY,
4725 set_menu_object_data("/Analyze/Display Filters...", E_FILT_TE_PTR_KEY,
4727 set_menu_object_data("/Analyze/Follow TCP Stream", E_DFILTER_TE_KEY,
4729 set_menu_object_data("/Analyze/Follow SSL Stream", E_DFILTER_TE_KEY,
4731 set_menu_object_data("/Analyze/Apply as Filter/Selected", E_DFILTER_TE_KEY,
4733 set_menu_object_data("/Analyze/Apply as Filter/Not Selected", E_DFILTER_TE_KEY,
4735 set_menu_object_data("/Analyze/Apply as Filter/... and Selected", E_DFILTER_TE_KEY,
4737 set_menu_object_data("/Analyze/Apply as Filter/... or Selected", E_DFILTER_TE_KEY,
4739 set_menu_object_data("/Analyze/Apply as Filter/... and not Selected", E_DFILTER_TE_KEY,
4741 set_menu_object_data("/Analyze/Apply as Filter/... or not Selected", E_DFILTER_TE_KEY,
4743 set_menu_object_data("/Analyze/Prepare a Filter/Selected", E_DFILTER_TE_KEY,
4745 set_menu_object_data("/Analyze/Prepare a Filter/Not Selected", E_DFILTER_TE_KEY,
4747 set_menu_object_data("/Analyze/Prepare a Filter/... and Selected", E_DFILTER_TE_KEY,
4749 set_menu_object_data("/Analyze/Prepare a Filter/... or Selected", E_DFILTER_TE_KEY,
4751 set_menu_object_data("/Analyze/Prepare a Filter/... and not Selected", E_DFILTER_TE_KEY,
4753 set_menu_object_data("/Analyze/Prepare a Filter/... or not Selected", E_DFILTER_TE_KEY,
4755 set_menu_object_data("/Conversation Filter/Ethernet", E_DFILTER_TE_KEY,
4757 set_menu_object_data("/Conversation Filter/IP", E_DFILTER_TE_KEY,
4759 set_menu_object_data("/Conversation Filter/TCP", E_DFILTER_TE_KEY,
4761 set_menu_object_data("/Conversation Filter/UDP", E_DFILTER_TE_KEY,
4763 set_menu_object_data("/Conversation Filter/PN-CBA Server", E_DFILTER_TE_KEY,
4765 set_toolbar_object_data(E_DFILTER_TE_KEY, filter_te);
4766 OBJECT_SET_DATA(popup_menu_object, E_DFILTER_TE_KEY, filter_te);
4767 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_KEY, packet_list);
4769 /* info (main) statusbar */
4770 info_bar = info_bar_new();
4771 gtk_widget_show(info_bar);
4773 /* packets statusbar */
4774 packets_bar = packets_bar_new();
4775 gtk_widget_show(packets_bar);
4777 /* Filter/status hbox */
4778 stat_hbox = gtk_hbox_new(FALSE, 1);
4779 gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
4780 gtk_widget_show(stat_hbox);
4782 /* Pane for the statusbar */
4783 status_pane = gtk_hpaned_new();
4784 gtk_widget_show(status_pane);
4786 /* Pane for the welcome screen */
4787 welcome_pane = welcome_new();
4788 gtk_widget_show(welcome_pane);
4793 driver_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
4797 r = simple_dialog_check_get(dialog);
4798 recent.airpcap_driver_check_show = !r;
4803 show_main_window(gboolean doing_work)
4805 main_set_for_capture_file(doing_work);
4807 /*** we have finished all init things, show the main window ***/
4808 gtk_widget_show(top_level);
4810 /* the window can be maximized only, if it's visible, so do it after show! */
4811 main_load_window_geometry(top_level);
4813 /* process all pending GUI events before continue */
4814 while (gtk_events_pending()) gtk_main_iteration();
4816 /* Pop up any queued-up alert boxes. */
4817 display_queued_messages();
4821 * This will read the decryption keys from the preferences file, and will
4822 * store them into the registry...
4824 if(airpcap_if_list != NULL && g_list_length(airpcap_if_list) > 0){
4825 if (!airpcap_check_decryption_keys(airpcap_if_list)) {
4826 /* Ask the user what to do ...*/
4827 airpcap_keys_check_w(NULL,NULL);
4829 /* Keys from lists are equals, or wireshark has got no keys */
4830 airpcap_load_decryption_keys(airpcap_if_list);
4834 switch (airpcap_dll_ret_val) {
4836 case AIRPCAP_DLL_OK:
4839 case AIRPCAP_DLL_OLD:
4840 if(recent.airpcap_driver_check_show) {
4841 driver_warning_dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
4842 "WARNING: The version of AirPcap on this system\n"
4843 "does not support driver-level decryption. Please\n"
4844 "download a more recent version from\n" "http://www.cacetech.com/support/downloads.htm \n");
4845 simple_dialog_check_set(driver_warning_dialog,"Don't show this message again.");
4846 simple_dialog_set_cb(driver_warning_dialog, driver_warning_dialog_cb, (gpointer) driver_warning_dialog);
4852 * XXX - Maybe we need to warn the user if one of the following happens???
4854 case AIRPCAP_DLL_ERROR:
4855 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
4858 case AIRPCAP_DLL_NOT_FOUND:
4859 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
4863 #endif /* HAVE_AIRPCAP */
4866 /* Fill in capture options with values from the preferences */
4868 prefs_to_capture_opts(void)
4871 /* Set promiscuous mode from the preferences setting. */
4872 /* the same applies to other preferences settings as well. */
4873 capture_opts->promisc_mode = prefs.capture_prom_mode;
4874 capture_opts->show_info = prefs.capture_show_info;
4875 capture_opts->real_time_mode = prefs.capture_real_time;
4876 auto_scroll_live = prefs.capture_auto_scroll;
4877 #endif /* HAVE_LIBPCAP */
4879 /* Set the name resolution code's flags from the preferences. */
4880 g_resolv_flags = prefs.name_resolve;