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>
35 #if GTK_CHECK_VERSION(3,0,0)
36 # include <gdk/gdkkeysyms-compat.h>
49 #include "wsutil/wsgetopt.h"
52 #ifdef _WIN32 /* Needed for console I/O */
54 /* AttachConsole() needs this #define! */
55 #define _WIN32_WINNT 0x0501
61 #ifdef HAVE_LIBPORTAUDIO
62 #include <portaudio.h>
63 #endif /* HAVE_LIBPORTAUDIO */
65 #include <epan/epan.h>
66 #include <epan/filesystem.h>
67 #include <wsutil/privileges.h>
68 #include <epan/epan_dissect.h>
69 #include <epan/timestamp.h>
70 #include <epan/packet.h>
71 #include <epan/plugins.h>
72 #include <epan/dfilter/dfilter.h>
73 #include <epan/strutil.h>
74 #include <epan/addr_resolv.h>
75 #include <epan/emem.h>
76 #include <epan/ex-opt.h>
77 #include <epan/funnel.h>
78 #include <epan/expert.h>
79 #include <epan/frequency-utils.h>
80 #include <epan/prefs.h>
81 #include <epan/prefs-int.h>
83 #include <epan/stat_cmd_args.h>
85 #include <epan/column.h>
87 /* general (not GTK specific) */
89 #include "../summary.h"
90 #include "../filters.h"
91 #include "../disabled_protos.h"
93 #include "../color_filters.h"
95 #include "../register.h"
96 #include "../ringbuffer.h"
98 #include "../clopts_common.h"
99 #include "../console_io.h"
100 #include "../cmdarg_err.h"
101 #include "../version_info.h"
102 #include "../merge.h"
106 #include "ui/alert_box.h"
107 #include "ui/main_statusbar.h"
108 #include "ui/recent.h"
109 #include "ui/recent_utils.h"
110 #include "ui/simple_dialog.h"
111 #include "ui/ui_util.h"
113 #include <wsutil/file_util.h>
116 #include "../capture_ui_utils.h"
117 #include "../capture-pcap-util.h"
118 #include "../capture_ifinfo.h"
119 #include "../capture.h"
120 #include "../capture_sync.h"
121 extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg);
125 #include "../capture-wpcap.h"
126 #include "../capture_wpcap_packet.h"
127 #include <tchar.h> /* Needed for Unicode */
128 #include <wsutil/unicode-utils.h>
129 #include <commctrl.h>
130 #include <shellapi.h>
134 #include "ui/gtk/file_dlg.h"
135 #include "ui/gtk/gtkglobals.h"
136 #include "ui/gtk/color_utils.h"
137 #include "ui/gtk/gui_utils.h"
138 #include "ui/gtk/color_dlg.h"
139 #include "ui/gtk/filter_dlg.h"
140 #include "ui/gtk/uat_gui.h"
141 #include "ui/gtk/main.h"
142 #include "ui/gtk/main_airpcap_toolbar.h"
143 #include "ui/gtk/main_filter_toolbar.h"
144 #include "ui/gtk/menus.h"
145 #include "ui/gtk/macros_dlg.h"
146 #include "ui/gtk/main_statusbar_private.h"
147 #include "ui/gtk/main_toolbar.h"
148 #include "ui/gtk/main_welcome.h"
149 #include "ui/gtk/drag_and_drop.h"
150 #include "ui/gtk/capture_file_dlg.h"
151 #include "ui/gtk/main_proto_draw.h"
152 #include "ui/gtk/keys.h"
153 #include "ui/gtk/packet_win.h"
154 #include "ui/gtk/stock_icons.h"
155 #include "ui/gtk/find_dlg.h"
156 #include "ui/gtk/follow_tcp.h"
157 #include "ui/gtk/font_utils.h"
158 #include "ui/gtk/about_dlg.h"
159 #include "ui/gtk/help_dlg.h"
160 #include "ui/gtk/decode_as_dlg.h"
161 #include "ui/gtk/webbrowser.h"
162 #include "ui/gtk/capture_dlg.h"
163 #include "ui/gtk/capture_if_dlg.h"
164 #include "ui/gtk/tap_param_dlg.h"
165 #include "ui/gtk/prefs_column.h"
166 #include "ui/gtk/prefs_dlg.h"
167 #include "ui/gtk/proto_help.h"
168 #include "ui/gtk/new_packet_list.h"
169 #include "ui/gtk/filter_expression_save_dlg.h"
171 #include "ui/gtk/old-gtk-compat.h"
174 #include "../../image/wsicon16.xpm"
175 #include "../../image/wsicon32.xpm"
176 #include "../../image/wsicon48.xpm"
177 #include "../../image/wsicon64.xpm"
178 #include "../../image/wsiconcap16.xpm"
179 #include "../../image/wsiconcap32.xpm"
180 #include "../../image/wsiconcap48.xpm"
185 #include "airpcap_loader.h"
186 #include "airpcap_dlg.h"
187 #include "airpcap_gui_utils.h"
190 #include <epan/crypt/airpdcap_ws.h>
193 #ifdef HAVE_GTKOSXAPPLICATION
194 #include <igemacintegration/gtkosxapplication.h>
198 * Files under personal and global preferences directories in which
199 * GTK settings for Wireshark are stored.
201 #define RC_FILE "gtkrc"
205 /* "exported" main widgets */
206 GtkWidget *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
208 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
209 static GtkWidget *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
210 static GtkWidget *main_first_pane, *main_second_pane;
212 /* internally used widgets */
213 static GtkWidget *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
216 GtkWidget *airpcap_tb;
217 int airpcap_dll_ret_val = -1;
220 GString *comp_info_str, *runtime_info_str;
222 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
224 static guint tap_update_timer_id;
227 static gboolean has_console; /* TRUE if app has console */
228 static gboolean console_wait; /* "Press any key..." */
229 static void destroy_console(void);
230 static gboolean stdin_capture = FALSE; /* Don't grab stdin & stdout if TRUE */
232 static void console_log_handler(const char *log_domain,
233 GLogLevelFlags log_level, const char *message, gpointer user_data);
236 capture_options global_capture_opts;
240 static void create_main_window(gint, gint, gint, e_prefs*);
241 static void show_main_window(gboolean);
242 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
243 static void main_save_window_geometry(GtkWidget *widget);
246 /* Match selected byte pattern */
248 match_selected_cb_do(gpointer data, int action, gchar *text)
250 GtkWidget *filter_te;
251 char *cur_filter, *new_filter;
253 if ((!text) || (0 == strlen(text))) {
254 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
259 filter_te = g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY);
262 cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
264 switch (action&MATCH_SELECTED_MASK) {
266 case MATCH_SELECTED_REPLACE:
267 new_filter = g_strdup(text);
270 case MATCH_SELECTED_AND:
271 if ((!cur_filter) || (0 == strlen(cur_filter)))
272 new_filter = g_strdup(text);
274 new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
277 case MATCH_SELECTED_OR:
278 if ((!cur_filter) || (0 == strlen(cur_filter)))
279 new_filter = g_strdup(text);
281 new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
284 case MATCH_SELECTED_NOT:
285 new_filter = g_strconcat("!(", text, ")", NULL);
288 case MATCH_SELECTED_AND_NOT:
289 if ((!cur_filter) || (0 == strlen(cur_filter)))
290 new_filter = g_strconcat("!(", text, ")", NULL);
292 new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
295 case MATCH_SELECTED_OR_NOT:
296 if ((!cur_filter) || (0 == strlen(cur_filter)))
297 new_filter = g_strconcat("!(", text, ")", NULL);
299 new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
303 g_assert_not_reached();
308 /* Free up the copy we got of the old filter text. */
311 /* Don't change the current display filter if we only want to copy the filter */
312 if (action&MATCH_SELECTED_COPY_ONLY) {
313 GString *gtk_text_str = g_string_new("");
314 g_string_append(gtk_text_str, new_filter);
315 copy_to_clipboard(gtk_text_str);
316 g_string_free(gtk_text_str, TRUE);
318 /* create a new one and set the display filter entry accordingly */
319 gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
321 /* Run the display filter so it goes in effect. */
322 if (action&MATCH_SELECTED_APPLY_NOW)
323 main_filter_packets(&cfile, new_filter, FALSE);
326 /* Free up the new filter text. */
331 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
335 if (cfile.finfo_selected) {
336 filter = proto_construct_match_selected_string(cfile.finfo_selected,
338 match_selected_cb_do((data ? data : w), action, filter);
343 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
347 if (cfile.finfo_selected) {
348 filter = proto_construct_match_selected_string(cfile.finfo_selected,
350 if ((!filter) || (0 == strlen(filter))) {
351 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
352 "Could not acquire information to build a filter!\n"
353 "Try expanding or choosing another item.");
358 color_display_with_filter(filter);
361 color_filters_reset_tmp();
363 color_filters_set_tmp(filt_nr,filter, FALSE);
365 new_packet_list_colorize_packets();
371 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
373 gchar *selected_proto_url;
374 gchar *proto_abbrev = data;
379 if (cfile.finfo_selected) {
380 /* open wiki page using the protocol abbreviation */
381 selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
382 browser_open_url(selected_proto_url);
383 g_free(selected_proto_url);
386 case(ESD_BTN_CANCEL):
389 g_assert_not_reached();
395 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
398 const gchar *proto_abbrev;
402 if (cfile.finfo_selected) {
403 /* convert selected field to protocol abbreviation */
404 /* XXX - could this conversion be simplified? */
405 field_id = cfile.finfo_selected->hfinfo->id;
406 /* if the selected field isn't a protocol, get it's parent */
407 if(!proto_registrar_is_protocol(field_id)) {
408 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
411 proto_abbrev = proto_registrar_get_abbrev(field_id);
413 if (!proto_is_private(field_id)) {
414 /* ask the user if the wiki page really should be opened */
415 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
416 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
418 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
420 "The Wireshark Wiki is a collaborative approach to provide information "
421 "about Wireshark in several ways (not limited to protocol specifics).\n"
423 "This Wiki is new, so the page of the selected protocol "
424 "may not exist and/or may not contain valuable information.\n"
426 "As everyone can edit the Wiki and add new content (or extend existing), "
427 "you are encouraged to add information if you can.\n"
429 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
431 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
432 "which will save you a lot of editing and will give a consistent look over the pages.",
433 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
434 simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
436 /* appologize to the user that the wiki page cannot be opened */
437 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
438 "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
440 "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
442 "Since this is a private protocol, such information is not available in "
443 "a public wiki. Therefore this wiki entry is blocked.\n"
445 "Sorry for the inconvenience.\n",
446 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
451 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
453 gchar *selected_proto_url;
454 gchar *proto_abbrev = data;
458 if (cfile.finfo_selected) {
459 /* open reference page using the protocol abbreviation */
460 selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
461 browser_open_url(selected_proto_url);
462 g_free(selected_proto_url);
465 case(ESD_BTN_CANCEL):
468 g_assert_not_reached();
473 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
476 const gchar *proto_abbrev;
480 if (cfile.finfo_selected) {
481 /* convert selected field to protocol abbreviation */
482 /* XXX - could this conversion be simplified? */
483 field_id = cfile.finfo_selected->hfinfo->id;
484 /* if the selected field isn't a protocol, get it's parent */
485 if(!proto_registrar_is_protocol(field_id)) {
486 field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
489 proto_abbrev = proto_registrar_get_abbrev(field_id);
491 if (!proto_is_private(field_id)) {
492 /* ask the user if the wiki page really should be opened */
493 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
494 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
496 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
498 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
499 simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
501 /* appologize to the user that the wiki page cannot be opened */
502 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
503 "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
505 "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
507 "Since this is a private protocol, such information is not available on "
508 "a public website. Therefore this filter entry is blocked.\n"
510 "Sorry for the inconvenience.\n",
511 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
517 is_address_column (gint column)
519 if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
520 (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
521 (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
522 (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
523 strlen(cfile.cinfo.col_expr.col_expr_val[column]))
532 get_ip_address_list_from_packet_list_row(gpointer data)
534 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
535 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
538 GList *addr_list = NULL;
540 fdata = (frame_data *) new_packet_list_get_row_data(row);
545 if (!cf_read_frame (&cfile, fdata))
546 return NULL; /* error reading the frame */
548 epan_dissect_init(&edt, FALSE, FALSE);
549 col_custom_prime_edt(&edt, &cfile.cinfo);
551 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
552 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
554 /* First check selected column */
555 if (is_address_column (column)) {
556 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
559 for (col = 0; col < cfile.cinfo.num_cols; col++) {
560 /* Then check all columns except the selected */
561 if ((col != column) && (is_address_column (col))) {
562 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
566 epan_dissect_cleanup(&edt);
573 get_filter_from_packet_list_row_and_column(gpointer data)
575 gint row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
576 gint column = new_packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
580 fdata = (frame_data *) new_packet_list_get_row_data(row);
585 if (!cf_read_frame(&cfile, fdata))
586 return NULL; /* error reading the frame */
587 /* proto tree, visible. We need a proto tree if there's custom columns */
588 epan_dissect_init(&edt, have_custom_cols(&cfile.cinfo), FALSE);
589 col_custom_prime_edt(&edt, &cfile.cinfo);
591 epan_dissect_run(&edt, &cfile.pseudo_header, cfile.pd, fdata,
593 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
595 if ((cfile.cinfo.col_custom_occurrence[column]) ||
596 (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
598 /* Only construct the filter when a single occurrence is displayed
599 * otherwise we might end up with a filter like "ip.proto==1,6".
601 * Or do we want to be able to filter on multiple occurrences so that
602 * the filter might be calculated as "ip.proto==1 && ip.proto==6"
605 if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
606 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
607 /* leak a little but safer than ep_ here */
608 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
609 header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
610 if (hfi->parent == -1) {
612 buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
613 } else if (hfi->type == FT_STRING) {
614 /* Custom string, add quotes */
615 buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
616 cfile.cinfo.col_expr.col_expr_val[column]);
620 buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
621 cfile.cinfo.col_expr.col_expr_val[column]);
626 epan_dissect_cleanup(&edt);
633 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
635 match_selected_cb_do(data,
637 get_filter_from_packet_list_row_and_column(data));
640 /* This function allows users to right click in the details window and copy the text
641 * information to the operating systems clipboard.
643 * We first check to see if a string representation is setup in the tree and then
644 * read the string. If not available then we try to grab the value. If all else
645 * fails we display a message to the user to indicate the copy could not be completed.
648 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
650 GString *gtk_text_str = g_string_new("");
651 char labelstring[256];
652 char *stringpointer = labelstring;
656 case COPY_SELECTED_DESCRIPTION:
657 if (cfile.finfo_selected->rep &&
658 strlen (cfile.finfo_selected->rep->representation) > 0) {
659 g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
662 case COPY_SELECTED_FIELDNAME:
663 if (cfile.finfo_selected->hfinfo->abbrev != 0) {
664 g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
667 case COPY_SELECTED_VALUE:
668 if (cfile.edt !=0 ) {
669 g_string_append(gtk_text_str,
670 get_node_field_value(cfile.finfo_selected, cfile.edt));
677 if (gtk_text_str->len == 0) {
678 /* If no representation then... Try to read the value */
679 proto_item_fill_label(cfile.finfo_selected, stringpointer);
680 g_string_append(gtk_text_str, stringpointer);
683 if (gtk_text_str->len == 0) {
684 /* Could not get item so display error msg */
685 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
687 /* Copy string to clipboard */
688 copy_to_clipboard(gtk_text_str);
690 g_string_free(gtk_text_str, TRUE); /* Free the memory */
694 /* mark as reference time frame */
696 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
700 frame->flags.ref_time=1;
701 cfile.ref_time_count++;
703 frame->flags.ref_time=0;
704 cfile.ref_time_count--;
706 cf_reftime_packets(&cfile);
707 if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
708 new_packet_list_freeze();
709 cfile.displayed_count--;
710 new_packet_list_recreate_visible_rows();
711 new_packet_list_thaw();
713 new_packet_list_queue_draw();
717 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
721 timestamp_set_type(TS_RELATIVE);
722 recent.gui_time_format = TS_RELATIVE;
723 cf_timestamp_auto_precision(&cfile);
724 new_packet_list_queue_draw();
729 g_assert_not_reached();
732 if (cfile.current_frame) {
733 set_frame_reftime(!cfile.current_frame->flags.ref_time,
734 cfile.current_frame, cfile.current_row);
740 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
742 static GtkWidget *reftime_dialog = NULL;
746 if (cfile.current_frame) {
747 if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
748 reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
749 "%sSwitch to the appropriate Time Display Format?%s\n\n"
750 "Time References don't work well with the currently selected Time Display Format.\n\n"
751 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
752 simple_dialog_primary_start(), simple_dialog_primary_end());
753 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
755 set_frame_reftime(!cfile.current_frame->flags.ref_time,
756 cfile.current_frame, cfile.current_row);
760 case REFTIME_FIND_NEXT:
761 cf_find_packet_time_reference(&cfile, SD_FORWARD);
763 case REFTIME_FIND_PREV:
764 cf_find_packet_time_reference(&cfile, SD_BACKWARD);
770 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
772 cf_find_packet_marked(&cfile, SD_FORWARD);
776 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
778 cf_find_packet_marked(&cfile, SD_BACKWARD);
782 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
785 gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
787 gboolean has_blurb = FALSE;
788 guint length = 0, byte_len;
789 GtkWidget *byte_view;
790 const guint8 *byte_data;
795 /* if nothing is selected */
796 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
799 * Which byte view is displaying the current protocol tree
802 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
803 if (byte_view == NULL)
806 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
807 if (byte_data == NULL)
810 cf_unselect_field(&cfile);
811 packet_hex_print(byte_view, byte_data,
812 cfile.current_frame, NULL, byte_len);
813 proto_help_menu_modify(sel, &cfile);
816 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
819 set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
821 byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
822 byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
823 g_assert(byte_data != NULL);
825 cfile.finfo_selected = finfo;
826 set_menus_for_selected_tree_row(&cfile);
829 if (finfo->hfinfo->blurb != NULL &&
830 finfo->hfinfo->blurb[0] != '\0') {
832 length = (guint) strlen(finfo->hfinfo->blurb);
834 length = (guint) strlen(finfo->hfinfo->name);
836 finfo_length = finfo->length + finfo->appendix_length;
838 if (finfo_length == 0) {
840 } else if (finfo_length == 1) {
841 g_strlcpy (len_str, ", 1 byte", sizeof len_str);
843 g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
845 statusbar_pop_field_msg(); /* get rid of current help msg */
847 statusbar_push_field_msg(" %s (%s)%s",
848 (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
849 finfo->hfinfo->abbrev, len_str);
852 * Don't show anything if the field name is zero-length;
853 * the pseudo-field for "proto_tree_add_text()" is such
854 * a field, and we don't want "Text (text)" showing up
855 * on the status line if you've selected such a field.
857 * XXX - there are zero-length fields for which we *do*
858 * want to show the field name.
860 * XXX - perhaps the name and abbrev field should be null
861 * pointers rather than null strings for that pseudo-field,
862 * but we'd have to add checks for null pointers in some
863 * places if we did that.
865 * Or perhaps protocol tree items added with
866 * "proto_tree_add_text()" should have -1 as the field index,
867 * with no pseudo-field being used, but that might also
868 * require special checks for -1 to be added.
870 statusbar_push_field_msg("%s", "");
873 packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
875 proto_help_menu_modify(sel, &cfile);
878 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
880 collapse_all_tree(cfile.edt->tree, tree_view_gbl);
883 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
885 expand_all_tree(cfile.edt->tree, tree_view_gbl);
888 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
890 if (cfile.finfo_selected) {
891 column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
892 cfile.finfo_selected->hfinfo->abbrev,0);
893 /* Recreate the packet list according to new preferences */
894 new_packet_list_recreate ();
895 if (!prefs.gui_use_pref_save) {
898 cfile.cinfo.columns_changed = FALSE; /* Reset value */
902 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
905 path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
907 /* the mouse position is at an entry, expand that one */
908 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
909 gtk_tree_path_free(path);
913 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
914 if (cfile.edt->tree) {
915 guint32 tmp = gbl_resolv_flags;
916 gbl_resolv_flags = RESOLV_ALL;
917 proto_tree_draw(cfile.edt->tree, tree_view_gbl);
918 gbl_resolv_flags = tmp;
923 main_set_for_capture_file(gboolean have_capture_file_in)
925 have_capture_file = have_capture_file_in;
927 main_widgets_show_or_hide();
933 /* get the current geometry, before writing it to disk */
934 main_save_window_geometry(top_level);
936 /* write user's recent file to disk
937 * It is no problem to write this file, even if we do not quit */
938 write_profile_recent();
941 /* XXX - should we check whether the capture file is an
942 unsaved temporary file for a live capture and, if so,
943 pop up a "do you want to exit without saving the capture
944 file?" dialog, and then just return, leaving said dialog
945 box to forcibly quit if the user clicks "OK"?
947 If so, note that this should be done in a subroutine that
948 returns TRUE if we do so, and FALSE otherwise, and if it
949 returns TRUE we should return TRUE without nuking anything.
951 Note that, if we do that, we might also want to check if
952 an "Update list of packets in real time" capture is in
953 progress and, if so, ask whether they want to terminate
954 the capture and discard it, and return TRUE, before nuking
955 any child capture, if they say they don't want to do so. */
958 /* Nuke any child capture in progress. */
959 capture_kill_child(&global_capture_opts);
962 /* Are we in the middle of reading a capture? */
963 if (cfile.state == FILE_READ_IN_PROGRESS) {
964 /* Yes, so we can't just close the file and quit, as
965 that may yank the rug out from under the read in
966 progress; instead, just set the state to
967 "FILE_READ_ABORTED" and return - the code doing the read
968 will check for that and, if it sees that, will clean
970 cfile.state = FILE_READ_ABORTED;
972 /* Say that the window should *not* be deleted;
973 that'll be done by the code that cleans up. */
976 /* Close any capture file we have open; on some OSes, you
977 can't unlink a temporary capture file if you have it
979 "cf_close()" will unlink it after closing it if
980 it's a temporary file.
982 We do this here, rather than after the main loop returns,
983 as, after the main loop returns, the main window may have
984 been destroyed (if this is called due to a "destroy"
985 even on the main window rather than due to the user
986 selecting a menu item), and there may be a crash
987 or other problem when "cf_close()" tries to
988 clean up stuff in the main window.
990 XXX - is there a better place to put this?
991 Or should we have a routine that *just* closes the
992 capture file, and doesn't do anything with the UI,
993 which we'd call here, and another routine that
994 calls that routine and also cleans up the UI, which
995 we'd call elsewhere? */
998 /* Exit by leaving the main loop, so that any quit functions
999 we registered get called. */
1002 /* Say that the window should be deleted. */
1008 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1012 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1013 gtk_window_present(GTK_WINDOW(top_level));
1014 /* user didn't saved his current file, ask him */
1015 dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
1016 ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
1017 "%sSave capture file before program quit?%s\n\n"
1018 "If you quit the program without saving, your capture data will be discarded.",
1019 simple_dialog_primary_start(), simple_dialog_primary_end());
1020 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1023 /* unchanged file, just exit */
1024 /* "main_do_quit()" indicates whether the main window should be deleted. */
1025 return main_do_quit();
1031 main_pane_load_window_geometry(void)
1033 if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1034 gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1035 if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1036 gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1042 main_load_window_geometry(GtkWidget *widget)
1044 window_geometry_t geom;
1046 geom.set_pos = prefs.gui_geometry_save_position;
1047 geom.x = recent.gui_geometry_main_x;
1048 geom.y = recent.gui_geometry_main_y;
1049 geom.set_size = prefs.gui_geometry_save_size;
1050 if (recent.gui_geometry_main_width > 0 &&
1051 recent.gui_geometry_main_height > 0) {
1052 geom.width = recent.gui_geometry_main_width;
1053 geom.height = recent.gui_geometry_main_height;
1054 geom.set_maximized = prefs.gui_geometry_save_maximized;
1056 /* We assume this means the width and height weren't set in
1057 the "recent" file (or that there is no "recent" file),
1058 and weren't set to a default value, so we don't set the
1059 size. (The "recent" file code rejects non-positive width
1060 and height values.) */
1061 geom.set_size = FALSE;
1063 geom.maximized = recent.gui_geometry_main_maximized;
1065 window_set_geometry(widget, &geom);
1067 main_pane_load_window_geometry();
1068 statusbar_load_window_geometry();
1073 main_save_window_geometry(GtkWidget *widget)
1075 window_geometry_t geom;
1077 window_get_geometry(widget, &geom);
1079 if (prefs.gui_geometry_save_position) {
1080 recent.gui_geometry_main_x = geom.x;
1081 recent.gui_geometry_main_y = geom.y;
1084 if (prefs.gui_geometry_save_size) {
1085 recent.gui_geometry_main_width = geom.width;
1086 recent.gui_geometry_main_height = geom.height;
1089 if(prefs.gui_geometry_save_maximized) {
1090 recent.gui_geometry_main_maximized = geom.maximized;
1093 recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane));
1094 recent.gui_geometry_main_lower_pane = gtk_paned_get_position(GTK_PANED(main_second_pane));
1095 statusbar_save_window_geometry();
1098 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1102 /* save file first */
1103 file_save_as_cmd(after_save_exit, NULL, FALSE);
1105 case(ESD_BTN_QUIT_DONT_SAVE):
1108 case(ESD_BTN_CANCEL):
1111 g_assert_not_reached();
1116 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1120 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1121 /* user didn't saved his current file, ask him */
1122 dialog = simple_dialog(ESD_TYPE_CONFIRMATION,
1123 ((cfile.state == FILE_READ_IN_PROGRESS) ? ESD_BTNS_QUIT_DONTSAVE_CANCEL : ESD_BTNS_SAVE_QUIT_DONTSAVE_CANCEL),
1124 "%sSave capture file before program quit?%s\n\n"
1125 "If you quit the program without saving, your capture data will be discarded.",
1126 simple_dialog_primary_start(), simple_dialog_primary_end());
1127 simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1129 /* unchanged file, just exit */
1135 print_usage(gboolean print_ver) {
1145 fprintf(output, "Wireshark " VERSION "%s\n"
1146 "Interactively dump and analyze network traffic.\n"
1147 "See http://www.wireshark.org for more information.\n"
1150 wireshark_svnversion, get_copyright_info());
1154 fprintf(output, "\n");
1155 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1156 fprintf(output, "\n");
1159 fprintf(output, "Capture interface:\n");
1160 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
1161 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
1162 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
1163 fprintf(output, " -p don't capture in promiscuous mode\n");
1164 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
1165 fprintf(output, " -S update packet display when new packets are captured\n");
1166 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
1167 #ifdef HAVE_PCAP_CREATE
1168 fprintf(output, " -I capture in monitor mode, if available\n");
1170 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1171 fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
1173 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
1174 fprintf(output, " -D print list of interfaces and exit\n");
1175 fprintf(output, " -L print list of link-layer types of iface and exit\n");
1176 fprintf(output, "\n");
1177 fprintf(output, "Capture stop conditions:\n");
1178 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
1179 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
1180 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
1181 fprintf(output, " files:NUM - stop after NUM files\n");
1182 /*fprintf(output, "\n");*/
1183 fprintf(output, "Capture output:\n");
1184 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1185 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
1186 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
1187 #endif /* HAVE_LIBPCAP */
1189 /*fprintf(output, "\n");*/
1190 fprintf(output, "Input file:\n");
1191 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
1193 fprintf(output, "\n");
1194 fprintf(output, "Processing:\n");
1195 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
1196 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
1197 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
1199 fprintf(output, "\n");
1200 fprintf(output, "User interface:\n");
1201 fprintf(output, " -C <config profile> start with specified configuration profile\n");
1202 fprintf(output, " -d <display filter> start with the given display filter\n");
1203 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
1204 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
1205 fprintf(output, " filter\n");
1206 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
1207 fprintf(output, " -m <font> set the font name used for most text\n");
1208 fprintf(output, " -t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)\n");
1209 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
1210 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
1211 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
1213 fprintf(output, "\n");
1214 fprintf(output, "Output:\n");
1215 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
1217 fprintf(output, "\n");
1218 fprintf(output, "Miscellaneous:\n");
1219 fprintf(output, " -h display this help and exit\n");
1220 fprintf(output, " -v display version info and exit\n");
1221 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
1222 fprintf(output, " persdata:path - personal data files\n");
1223 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
1224 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
1226 fprintf(output, " --display=DISPLAY X display to use\n");
1241 printf(PACKAGE " " VERSION "%s\n"
1248 wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1249 runtime_info_str->str);
1257 * Print to the standard error. On Windows, create a console for the
1258 * standard error to show up on, if necessary.
1259 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1260 * terminal isn't the standard error?
1263 vfprintf_stderr(const char *fmt, va_list ap)
1268 vfprintf(stderr, fmt, ap);
1272 fprintf_stderr(const char *fmt, ...)
1277 vfprintf_stderr(fmt, ap);
1282 * Report an error in command-line arguments.
1283 * Creates a console on Windows.
1286 cmdarg_err(const char *fmt, ...)
1290 fprintf_stderr("wireshark: ");
1292 vfprintf_stderr(fmt, ap);
1294 fprintf_stderr("\n");
1298 * Report additional information for an error in command-line arguments.
1299 * Creates a console on Windows.
1300 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1301 * terminal isn't the standard error?
1304 cmdarg_err_cont(const char *fmt, ...)
1309 vfprintf_stderr(fmt, ap);
1310 fprintf_stderr("\n");
1315 Once every 3 seconds we get a callback here which we use to update
1319 tap_update_cb(gpointer data _U_)
1321 draw_tap_listeners(FALSE);
1325 /* Restart the tap update display timer with new configured interval */
1326 void reset_tap_update_timer(void)
1328 g_source_remove(tap_update_timer_id);
1329 tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1333 protect_thread_critical_region(void)
1335 /* Threading support for TAP:s removed
1336 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1337 * See the commit for removed code:
1338 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
1342 unprotect_thread_critical_region(void)
1344 /* Threading support for TAP:s removed
1345 * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1351 * Periodically process outstanding hostname lookups. If we have new items,
1352 * redraw the packet list and tree view.
1356 resolv_update_cb(gpointer data _U_)
1358 /* Anything new show up? */
1359 if (host_name_lookup_process(NULL)) {
1360 if (gtk_widget_get_window(pkt_scrollw))
1361 gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1362 if (gtk_widget_get_window(tv_scrollw))
1363 gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1366 /* Always check. Even if we don't do async lookups we could still get
1367 passive updates, e.g. from DNS packets. */
1372 /* Set main_window_name and it's icon title to the capture filename */
1374 set_display_filename(capture_file *cf)
1379 window_name = g_strdup_printf("%s", cf_get_display_name(cf));
1380 set_main_window_name(window_name);
1381 g_free(window_name);
1383 set_main_window_name("The Wireshark Network Analyzer");
1387 static GtkWidget *close_dlg = NULL;
1390 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1392 recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1397 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1399 recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1404 main_cf_cb_file_closing(capture_file *cf)
1410 /* if we have more than 10000 packets, show a splash screen while closing */
1411 /* XXX - don't know a better way to decide whether to show or not,
1412 * as most of the time is spend in a single eth_clist_clear function,
1413 * so we can't use a progress bar here! */
1414 if(cf->count > 10000) {
1415 close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1416 "%sClosing file!%s\n\nPlease wait ...",
1417 simple_dialog_primary_start(),
1418 simple_dialog_primary_end());
1419 gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1422 /* Destroy all windows, which refer to the
1423 capture file we're closing. */
1424 destroy_packet_wins();
1425 file_save_as_destroy();
1428 if (global_capture_opts.ifaces && global_capture_opts.ifaces->len > 0) {
1429 for (i = (int)global_capture_opts.ifaces->len-1; i >= 0; i--) {
1430 global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
1435 /* Restore the standard title bar message. */
1436 set_main_window_name("The Wireshark Network Analyzer");
1438 /* Disable all menu items that make sense only if you have a capture. */
1439 set_menus_for_capture_file(NULL);
1440 set_menus_for_captured_packets(FALSE);
1441 set_menus_for_selected_packet(cf);
1442 set_menus_for_capture_in_progress(FALSE);
1443 set_capture_if_dialog_for_capture_in_progress(FALSE);
1444 set_menus_for_selected_tree_row(cf);
1446 /* Set up main window for no capture file. */
1447 main_set_for_capture_file(FALSE);
1449 main_window_update();
1453 main_cf_cb_file_closed(capture_file *cf _U_)
1455 if(close_dlg != NULL) {
1456 splash_destroy(close_dlg);
1463 main_cf_cb_file_read_started(capture_file *cf _U_)
1465 tap_param_dlg_update();
1467 /* Set up main window for a capture file. */
1468 main_set_for_capture_file(TRUE);
1472 main_cf_cb_file_read_finished(capture_file *cf)
1476 if (!cf->is_tempfile && cf->filename) {
1477 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1478 add_menu_recent_capture_file(cf->filename);
1480 /* Remember folder for next Open dialog and save it in recent */
1481 dir_path = get_dirname(g_strdup(cf->filename));
1482 set_last_open_dir(dir_path);
1485 set_display_filename(cf);
1487 /* Enable menu items that make sense if you have a capture file you've
1488 finished reading. */
1489 set_menus_for_capture_file(cf);
1491 /* Enable menu items that make sense if you have some captured packets. */
1492 set_menus_for_captured_packets(TRUE);
1496 static GList *icon_list_create(
1497 const char **icon16_xpm,
1498 const char **icon32_xpm,
1499 const char **icon48_xpm,
1500 const char **icon64_xpm)
1502 GList *icon_list = NULL;
1503 GdkPixbuf * pixbuf16;
1504 GdkPixbuf * pixbuf32;
1505 GdkPixbuf * pixbuf48;
1506 GdkPixbuf * pixbuf64;
1509 if(icon16_xpm != NULL) {
1510 pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1512 icon_list = g_list_append(icon_list, pixbuf16);
1515 if(icon32_xpm != NULL) {
1516 pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1518 icon_list = g_list_append(icon_list, pixbuf32);
1521 if(icon48_xpm != NULL) {
1522 pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1524 icon_list = g_list_append(icon_list, pixbuf48);
1527 if(icon64_xpm != NULL) {
1528 pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1530 icon_list = g_list_append(icon_list, pixbuf64);
1537 main_capture_set_main_window_title(capture_options *capture_opts)
1539 GString *title = g_string_new("");
1541 g_string_append(title, "Capturing ");
1542 g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1543 set_main_window_name(title->str);
1544 g_string_free(title, TRUE);
1548 main_capture_cb_capture_prepared(capture_options *capture_opts)
1550 static GList *icon_list = NULL;
1552 main_capture_set_main_window_title(capture_opts);
1554 if(icon_list == NULL) {
1555 icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1557 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1559 /* Disable menu items that make no sense if you're currently running
1561 set_menus_for_capture_in_progress(TRUE);
1562 set_capture_if_dialog_for_capture_in_progress(TRUE);
1564 /* Don't set up main window for a capture file. */
1565 main_set_for_capture_file(FALSE);
1569 main_capture_cb_capture_update_started(capture_options *capture_opts)
1571 /* We've done this in "prepared" above, but it will be cleared while
1572 switching to the next multiple file. */
1573 main_capture_set_main_window_title(capture_opts);
1575 set_menus_for_capture_in_progress(TRUE);
1576 set_capture_if_dialog_for_capture_in_progress(TRUE);
1578 /* Enable menu items that make sense if you have some captured
1579 packets (yes, I know, we don't have any *yet*). */
1580 set_menus_for_captured_packets(TRUE);
1582 /* Set up main window for a capture file. */
1583 main_set_for_capture_file(TRUE);
1587 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1589 capture_file *cf = capture_opts->cf;
1590 static GList *icon_list = NULL;
1592 if (!cf->is_tempfile && cf->filename) {
1593 /* Add this filename to the list of recent files in the "Recent Files" submenu */
1594 add_menu_recent_capture_file(cf->filename);
1596 set_display_filename(cf);
1598 /* Enable menu items that make sense if you're not currently running
1600 set_menus_for_capture_in_progress(FALSE);
1601 set_capture_if_dialog_for_capture_in_progress(FALSE);
1603 /* Enable menu items that make sense if you have a capture file
1604 you've finished reading. */
1605 set_menus_for_capture_file(cf);
1607 /* Set up main window for a capture file. */
1608 main_set_for_capture_file(TRUE);
1610 if(icon_list == NULL) {
1611 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1613 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1615 if(global_capture_opts.quit_after_cap) {
1616 /* command line asked us to quit after the capture */
1617 /* don't pop up a dialog to ask for unsaved files etc. */
1623 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1625 /* Don't set up main window for a capture file. */
1626 main_set_for_capture_file(FALSE);
1630 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1633 capture_file *cf = capture_opts->cf;
1635 static GList *icon_list = NULL;
1637 /*set_display_filename(cf);*/
1639 /* Enable menu items that make sense if you're not currently running
1641 set_menus_for_capture_in_progress(FALSE);
1642 set_capture_if_dialog_for_capture_in_progress(FALSE);
1644 /* Restore the standard title bar message */
1645 /* (just in case we have trouble opening the capture file). */
1646 set_main_window_name("The Wireshark Network Analyzer");
1648 if(icon_list == NULL) {
1649 icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1651 gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1653 /* We don't have loaded the capture file, this will be done later.
1654 * For now we still have simply a blank screen. */
1656 if(global_capture_opts.quit_after_cap) {
1657 /* command line asked us to quit after the capture */
1658 /* don't pop up a dialog to ask for unsaved files etc. */
1663 #endif /* HAVE_LIBPCAP */
1666 main_cf_cb_packet_selected(gpointer data)
1668 capture_file *cf = data;
1670 /* Display the GUI protocol tree and packet bytes.
1671 XXX - why do we dump core if we call "proto_tree_draw()"
1672 before calling "add_byte_views()"? */
1673 add_main_byte_views(cf->edt);
1674 main_proto_tree_draw(cf->edt->tree);
1676 /* Note: Both string and hex value searches in the packet data produce a non-zero
1677 search_pos if successful */
1678 if(cf->search_in_progress &&
1679 (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1680 highlight_field(cf->edt->tvb, cf->search_pos,
1681 (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1684 /* A packet is selected. */
1685 set_menus_for_selected_packet(cf);
1689 main_cf_cb_packet_unselected(capture_file *cf)
1691 /* Clear out the display of that packet. */
1692 clear_tree_and_hex_views();
1694 /* No packet is selected. */
1695 set_menus_for_selected_packet(cf);
1699 main_cf_cb_field_unselected(capture_file *cf)
1701 set_menus_for_selected_tree_row(cf);
1705 main_cf_cb_file_save_reload_finished(gpointer data _U_)
1707 set_display_filename(&cfile);
1708 set_menus_for_capture_file(&cfile);
1712 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1715 case(cf_cb_file_closing):
1716 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1717 main_cf_cb_file_closing(data);
1719 case(cf_cb_file_closed):
1720 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1721 main_cf_cb_file_closed(data);
1723 case(cf_cb_file_read_started):
1724 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1725 main_cf_cb_file_read_started(data);
1727 case(cf_cb_file_read_finished):
1728 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1729 main_cf_cb_file_read_finished(data);
1731 case(cf_cb_packet_selected):
1732 main_cf_cb_packet_selected(data);
1734 case(cf_cb_packet_unselected):
1735 main_cf_cb_packet_unselected(data);
1737 case(cf_cb_field_unselected):
1738 main_cf_cb_field_unselected(data);
1740 case(cf_cb_file_save_started):
1741 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1743 case(cf_cb_file_save_finished):
1744 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1746 case(cf_cb_file_save_reload_finished):
1747 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1748 main_cf_cb_file_save_reload_finished(data);
1750 case(cf_cb_file_save_failed):
1751 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1754 g_warning("main_cf_callback: event %u unknown", event);
1755 g_assert_not_reached();
1761 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1763 #ifdef HAVE_GTKOSXAPPLICATION
1764 GtkOSXApplication *theApp;
1767 case(capture_cb_capture_prepared):
1768 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1769 main_capture_cb_capture_prepared(capture_opts);
1771 case(capture_cb_capture_update_started):
1772 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1773 main_capture_cb_capture_update_started(capture_opts);
1774 #ifdef HAVE_GTKOSXAPPLICATION
1775 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1776 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1779 case(capture_cb_capture_update_continue):
1780 /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1782 case(capture_cb_capture_update_finished):
1783 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1784 main_capture_cb_capture_update_finished(capture_opts);
1786 case(capture_cb_capture_fixed_started):
1787 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1788 main_capture_cb_capture_fixed_started(capture_opts);
1790 case(capture_cb_capture_fixed_continue):
1791 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1793 case(capture_cb_capture_fixed_finished):
1794 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1795 main_capture_cb_capture_fixed_finished(capture_opts);
1797 case(capture_cb_capture_stopping):
1798 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1799 /* Beware: this state won't be called, if the capture child
1800 * closes the capturing on it's own! */
1801 #ifdef HAVE_GTKOSXAPPLICATION
1802 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1803 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1807 g_warning("main_capture_callback: event %u unknown", event);
1808 g_assert_not_reached();
1814 get_gtk_compiled_info(GString *str)
1816 g_string_append(str, "with ");
1817 g_string_append_printf(str,
1818 #ifdef GTK_MAJOR_VERSION
1819 "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1822 "GTK+ (version unknown)");
1824 g_string_append(str, ", ");
1826 g_string_append(str, "with Cairo ");
1827 g_string_append(str, CAIRO_VERSION_STRING);
1828 g_string_append(str, ", ");
1831 g_string_append(str, "with Pango ");
1832 g_string_append(str, PANGO_VERSION_STRING);
1833 g_string_append(str, ", ");
1839 get_gui_compiled_info(GString *str)
1841 epan_get_compiled_version_info(str);
1843 g_string_append(str, ", ");
1844 #ifdef HAVE_LIBPORTAUDIO
1845 #ifdef PORTAUDIO_API_1
1846 g_string_append(str, "with PortAudio <= V18");
1847 #else /* PORTAUDIO_API_1 */
1848 g_string_append(str, "with ");
1849 g_string_append(str, Pa_GetVersionText());
1850 #endif /* PORTAUDIO_API_1 */
1851 #else /* HAVE_LIBPORTAUDIO */
1852 g_string_append(str, "without PortAudio");
1853 #endif /* HAVE_LIBPORTAUDIO */
1855 g_string_append(str, ", ");
1857 get_compiled_airpcap_version(str);
1859 g_string_append(str, "without AirPcap");
1864 get_gui_runtime_info(GString *str)
1866 epan_get_runtime_version_info(str);
1869 g_string_append(str, ", ");
1870 get_runtime_airpcap_version(str);
1874 g_string_append(str, ", ");
1875 u3_runtime_info(str);
1880 read_configuration_files(char **gdp_path, char **dp_path)
1882 int gpf_open_errno, gpf_read_errno;
1883 int cf_open_errno, df_open_errno;
1884 int gdp_open_errno, gdp_read_errno;
1885 int dp_open_errno, dp_read_errno;
1886 char *gpf_path, *pf_path;
1887 char *cf_path, *df_path;
1888 int pf_open_errno, pf_read_errno;
1891 /* load the decode as entries of this profile */
1892 load_decode_as_entries();
1894 /* Read the preference files. */
1895 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1896 &pf_open_errno, &pf_read_errno, &pf_path);
1898 if (gpf_path != NULL) {
1899 if (gpf_open_errno != 0) {
1900 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1901 "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1902 g_strerror(gpf_open_errno));
1904 if (gpf_read_errno != 0) {
1905 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1906 "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1907 g_strerror(gpf_read_errno));
1910 if (pf_path != NULL) {
1911 if (pf_open_errno != 0) {
1912 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1913 "Could not open your preferences file\n\"%s\": %s.", pf_path,
1914 g_strerror(pf_open_errno));
1916 if (pf_read_errno != 0) {
1917 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1918 "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1919 g_strerror(pf_read_errno));
1926 /* if the user wants a console to be always there, well, we should open one for him */
1927 if (prefs_p->gui_console_open == console_open_always) {
1932 /* Read the capture filter file. */
1933 read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1934 if (cf_path != NULL) {
1935 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1936 "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1937 g_strerror(cf_open_errno));
1941 /* Read the display filter file. */
1942 read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1943 if (df_path != NULL) {
1944 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1945 "Could not open your display filter file\n\"%s\": %s.", df_path,
1946 g_strerror(df_open_errno));
1950 /* Read the disabled protocols file. */
1951 read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1952 dp_path, &dp_open_errno, &dp_read_errno);
1953 if (*gdp_path != NULL) {
1954 if (gdp_open_errno != 0) {
1955 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1956 "Could not open global disabled protocols file\n\"%s\": %s.",
1957 *gdp_path, g_strerror(gdp_open_errno));
1959 if (gdp_read_errno != 0) {
1960 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1961 "I/O error reading global disabled protocols file\n\"%s\": %s.",
1962 *gdp_path, g_strerror(gdp_read_errno));
1967 if (*dp_path != NULL) {
1968 if (dp_open_errno != 0) {
1969 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1970 "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
1971 g_strerror(dp_open_errno));
1973 if (dp_read_errno != 0) {
1974 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1975 "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
1976 g_strerror(dp_read_errno));
1985 /* Check if there's something important to tell the user during startup.
1986 * We want to do this *after* showing the main window so that any windows
1987 * we pop up will be above the main window.
1991 check_and_warn_user_startup(gchar *cf_name)
1993 check_and_warn_user_startup(gchar *cf_name _U_)
1996 gchar *cur_user, *cur_group;
1997 gpointer priv_warning_dialog;
1999 /* Tell the user not to run as root. */
2000 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2001 cur_user = get_cur_username();
2002 cur_group = get_cur_groupname();
2003 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2004 "Running as user \"%s\" and group \"%s\".\n"
2005 "This could be dangerous.\n\n"
2006 "If you're running Wireshark this way in order to perform live capture, "
2007 "you may want to be aware that there is a better way documented at\n"
2008 "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2011 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2012 simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2016 /* Warn the user if npf.sys isn't loaded. */
2017 if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2018 priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2019 "The NPF driver isn't running. You may have trouble\n"
2020 "capturing or listing interfaces.");
2021 simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2022 simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2029 /* And now our feature presentation... [ fade to music ] */
2031 main(int argc, char *argv[])
2033 char *init_progfile_dir_error;
2036 gboolean arg_error = FALSE;
2038 extern int info_update_freq; /* Found in about_dlg.c. */
2039 const gchar *filter;
2047 char *gdp_path, *dp_path;
2051 gboolean start_capture = FALSE;
2052 gboolean list_link_layer_types = FALSE;
2056 gboolean capture_option_specified = FALSE;
2063 gint pl_size = 280, tv_size = 95, bv_size = 75;
2064 gchar *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2065 dfilter_t *rfcode = NULL;
2066 gboolean rfilter_parse_failed = FALSE;
2069 GtkWidget *splash_win = NULL;
2070 GLogLevelFlags log_flags;
2071 guint go_to_packet = 0;
2072 gboolean jump_backwards = FALSE;
2073 dfilter_t *jump_to_filter = NULL;
2076 #ifdef HAVE_GTKOSXAPPLICATION
2077 GtkOSXApplication *theApp;
2081 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2082 #define OPTSTRING_B "B:"
2084 #define OPTSTRING_B ""
2085 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2086 #else /* HAVE_LIBPCAP */
2087 #define OPTSTRING_B ""
2088 #endif /* HAVE_LIBPCAP */
2090 #ifdef HAVE_PCAP_CREATE
2091 #define OPTSTRING_I "I"
2093 #define OPTSTRING_I ""
2096 #define OPTSTRING "a:b:" OPTSTRING_B "c:C:d:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:z:"
2098 static const char optstring[] = OPTSTRING;
2100 /* Set the C-language locale to the native environment. */
2101 setlocale(LC_ALL, "");
2103 arg_list_utf_16to8(argc, argv);
2107 * Get credential information for later use, and drop privileges
2108 * before doing anything else.
2109 * Let the user know if anything happened.
2111 init_process_policies();
2112 relinquish_special_privs_perm();
2115 * Attempt to get the pathname of the executable file.
2117 init_progfile_dir_error = init_progfile_dir(argv[0], main);
2119 /* initialize the funnel mini-api */
2120 initialize_funnel_ops();
2122 AirPDcapInitContext(&airpdcap_ctx);
2125 /* Load wpcap if possible. Do this before collecting the run-time version information */
2128 /* ... and also load the packet.dll from wpcap */
2129 wpcap_packet_load();
2132 /* Load the airpcap.dll. This must also be done before collecting
2133 * run-time version information. */
2134 airpcap_dll_ret_val = load_airpcap();
2136 switch (airpcap_dll_ret_val) {
2137 case AIRPCAP_DLL_OK:
2138 /* load the airpcap interfaces */
2139 airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2141 if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2142 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2143 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2146 airpcap_if_active = NULL;
2150 /* select the first ad default (THIS SHOULD BE CHANGED) */
2151 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2156 * XXX - Maybe we need to warn the user if one of the following happens???
2158 case AIRPCAP_DLL_OLD:
2159 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2162 case AIRPCAP_DLL_ERROR:
2163 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2166 case AIRPCAP_DLL_NOT_FOUND:
2167 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2171 #endif /* HAVE_AIRPCAP */
2173 /* Start windows sockets */
2174 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2177 profile_store_persconffiles (TRUE);
2179 /* Assemble the compile-time version information string */
2180 comp_info_str = g_string_new("Compiled ");
2182 get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2184 /* Assemble the run-time version information string */
2185 runtime_info_str = g_string_new("Running ");
2186 get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2188 /* Read the profile independent recent file. We have to do this here so we can */
2189 /* set the profile before it can be set from the command line parameterts */
2190 recent_read_static(&rf_path, &rf_open_errno);
2191 if (rf_path != NULL && rf_open_errno != 0) {
2192 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2193 "Could not open common recent file\n\"%s\": %s.",
2194 rf_path, g_strerror(rf_open_errno));
2197 /* "pre-scan" the command line parameters, if we have "console only"
2198 parameters. We do this so we don't start GTK+ if we're only showing
2199 command-line help or version information.
2201 XXX - this pre-scan is done before we start GTK+, so we haven't
2202 run gtk_init() on the arguments. That means that GTK+ arguments
2203 have not been removed from the argument list; those arguments
2204 begin with "--", and will be treated as an error by getopt().
2206 We thus ignore errors - *and* set "opterr" to 0 to suppress the
2209 optind_initial = optind;
2210 while ((opt = getopt(argc, argv, optstring)) != -1) {
2212 case 'C': /* Configuration Profile */
2213 if (profile_exists (optarg, FALSE)) {
2214 set_profile_name (optarg);
2216 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2220 case 'D': /* Print a list of capture devices and exit */
2222 if_list = capture_interface_list(&err, &err_str);
2223 if (if_list == NULL) {
2225 case CANT_GET_INTERFACE_LIST:
2226 case DONT_HAVE_PCAP:
2227 cmdarg_err("%s", err_str);
2231 case NO_INTERFACES_FOUND:
2232 cmdarg_err("There are no interfaces on which a capture can be done");
2237 capture_opts_print_interfaces(if_list);
2238 free_interface_list(if_list);
2241 capture_option_specified = TRUE;
2245 case 'h': /* Print help and exit */
2251 if (strcmp(optarg, "-") == 0)
2252 stdin_capture = TRUE;
2255 case 'P': /* Path settings - change these before the Preferences and alike are processed */
2256 status = filesystem_opt(opt, optarg);
2258 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2262 case 'v': /* Show version and exit */
2268 * Extension command line options have to be processed before
2269 * we call epan_init() as they are supposed to be used by dissectors
2270 * or taps very early in the registration process.
2274 case '?': /* Ignore errors - the "real" scan will catch them. */
2279 /* Init the "Open file" dialog directory */
2280 /* (do this after the path settings are processed) */
2282 /* Read the profile dependent (static part) of the recent file. */
2283 /* Only the static part of it will be read, as we don't have the gui now to fill the */
2284 /* recent lists which is done in the dynamic part. */
2285 /* We have to do this already here, so command line parameters can overwrite these values. */
2286 recent_read_profile_static(&rf_path, &rf_open_errno);
2287 if (rf_path != NULL && rf_open_errno != 0) {
2288 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2289 "Could not open recent file\n\"%s\": %s.",
2290 rf_path, g_strerror(rf_open_errno));
2293 if (recent.gui_fileopen_remembered_dir &&
2294 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2295 set_last_open_dir(recent.gui_fileopen_remembered_dir);
2297 set_last_open_dir(get_persdatafile_dir());
2300 /* Set getopt index back to initial value, so it will start with the
2301 first command line parameter again. Also reset opterr to 1, so that
2302 error messages are printed by getopt().
2304 XXX - this seems to work on most platforms, but time will tell.
2305 The Single UNIX Specification says "The getopt() function need
2306 not be reentrant", so this isn't guaranteed to work. The Mac
2307 OS X 10.4[.x] getopt() man page says
2309 In order to use getopt() to evaluate multiple sets of arguments, or to
2310 evaluate a single set of arguments multiple times, the variable optreset
2311 must be set to 1 before the second and each additional set of calls to
2312 getopt(), and the variable optind must be reinitialized.
2316 The optreset variable was added to make it possible to call the getopt()
2317 function multiple times. This is an extension to the IEEE Std 1003.2
2318 (``POSIX.2'') specification.
2320 which I think comes from one of the other BSDs.
2322 XXX - if we want to control all the command-line option errors, so
2323 that we can display them where we choose (e.g., in a window), we'd
2324 want to leave opterr as 0, and produce our own messages using optopt.
2325 We'd have to check the value of optopt to see if it's a valid option
2326 letter, in which case *presumably* the error is "this option requires
2327 an argument but none was specified", or not a valid option letter,
2328 in which case *presumably* the error is "this option isn't valid".
2329 Some versions of getopt() let you supply a option string beginning
2330 with ':', which means that getopt() will return ':' rather than '?'
2331 for "this option requires an argument but none was specified", but
2333 optind = optind_initial;
2336 #if !GLIB_CHECK_VERSION(2,31,0)
2337 g_thread_init(NULL);
2340 /* Set the current locale according to the program environment.
2341 * We haven't localized anything, but some GTK widgets are localized
2342 * (the file selection dialogue, for example).
2343 * This also sets the C-language locale to the native environment. */
2344 setlocale (LC_ALL, "");
2346 /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2347 gtk_init (&argc, &argv);
2349 cf_callback_add(main_cf_callback, NULL);
2351 capture_callback_add(main_capture_callback, NULL);
2353 cf_callback_add(statusbar_cf_callback, NULL);
2355 capture_callback_add(statusbar_capture_callback, NULL);
2358 /* Arrange that if we have no console window, and a GLib message logging
2359 routine is called to log a message, we pop up a console window.
2361 We do that by inserting our own handler for all messages logged
2362 to the default domain; that handler pops up a console if necessary,
2363 and then calls the default handler. */
2365 /* We might want to have component specific log levels later ... */
2369 G_LOG_LEVEL_CRITICAL|
2370 G_LOG_LEVEL_WARNING|
2371 G_LOG_LEVEL_MESSAGE|
2374 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2376 g_log_set_handler(NULL,
2378 console_log_handler, NULL /* user_data */);
2379 g_log_set_handler(LOG_DOMAIN_MAIN,
2381 console_log_handler, NULL /* user_data */);
2384 g_log_set_handler(LOG_DOMAIN_CAPTURE,
2386 console_log_handler, NULL /* user_data */);
2387 g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2389 console_log_handler, NULL /* user_data */);
2391 /* Set the initial values in the capture options. This might be overwritten
2392 by preference settings and then again by the command line parameters. */
2393 capture_opts_init(&global_capture_opts, &cfile);
2396 /* Initialize whatever we need to allocate colors for GTK+ */
2399 /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2400 filter = get_conn_cfilter();
2401 if ( *filter != '\0' ) {
2402 info_update_freq = 1000; /* Milliseconds */
2405 /* We won't come till here, if we had a "console only" command line parameter. */
2406 splash_win = splash_new("Loading Wireshark ...");
2407 if (init_progfile_dir_error != NULL) {
2408 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2409 "Can't get pathname of Wireshark: %s.\n"
2410 "It won't be possible to capture traffic.\n"
2411 "Report this to the Wireshark developers.",
2412 init_progfile_dir_error);
2413 g_free(init_progfile_dir_error);
2416 splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2418 /* Register all dissectors; we must do this before checking for the
2419 "-G" flag, as the "-G" flag dumps information registered by the
2420 dissectors, and we must do it before we read the preferences, in
2421 case any dissectors register preferences. */
2422 epan_init(register_all_protocols,register_all_protocol_handoffs,
2423 splash_update, (gpointer) splash_win,
2424 failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2425 write_failure_alert_box);
2427 splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2429 /* Register all tap listeners; we do this before we parse the arguments,
2430 as the "-z" argument can specify a registered tap. */
2432 /* we register the plugin taps before the other taps because
2433 stats_tree taps plugins will be registered as tap listeners
2434 by stats_tree_stat.c and need to registered before that */
2437 register_all_plugin_tap_listeners();
2440 register_all_tap_listeners();
2442 splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2444 /* Now register the preferences for any non-dissector modules.
2445 We must do that before we read the preferences as well. */
2446 prefs_register_modules();
2448 prefs_p = read_configuration_files (&gdp_path, &dp_path);
2449 /* Removed thread code:
2450 * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2453 /* this is to keep tap extensions updating once every 3 seconds */
2454 tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2456 splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2458 cap_file_init(&cfile);
2460 /* Fill in capture options with values from the preferences */
2461 prefs_to_capture_opts();
2463 /*#ifdef HAVE_LIBPCAP
2464 if (global_capture_opts.all_ifaces->len == 0) {
2465 scan_local_interfaces(&global_capture_opts, &error);
2468 /* Now get our args */
2469 while ((opt = getopt(argc, argv, optstring)) != -1) {
2471 /*** capture option specific ***/
2472 case 'a': /* autostop criteria */
2473 case 'b': /* Ringbuffer option */
2474 case 'c': /* Capture xxx packets */
2475 case 'f': /* capture filter */
2476 case 'k': /* Start capture immediately */
2477 case 'H': /* Hide capture info dialog box */
2478 case 'p': /* Don't capture in promiscuous mode */
2479 #ifdef HAVE_PCAP_CREATE
2480 case 'I': /* Capture in monitor mode, if available */
2482 case 's': /* Set the snapshot (capture) length */
2483 case 'S': /* "Sync" mode: used for following file ala tail -f */
2484 case 'w': /* Write to capture file xxx */
2485 case 'y': /* Set the pcap data link type */
2486 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2487 case 'B': /* Buffer size */
2488 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2490 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2496 capture_option_specified = TRUE;
2501 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2502 case 'K': /* Kerberos keytab file */
2503 read_keytab_file(optarg);
2508 case 'i': /* Use interface xxx */
2509 status = capture_opts_add_iface_opt(&global_capture_opts, optarg);
2514 capture_option_specified = TRUE;
2519 /*** all non capture option specific ***/
2521 /* Configuration profile settings were already processed just ignore them this time*/
2526 case 'j': /* Search backwards for a matching packet from filter in option J */
2527 jump_backwards = TRUE;
2529 case 'g': /* Go to packet with the given packet number */
2530 go_to_packet = get_positive_int(optarg, "go to packet");
2532 case 'J': /* Jump to the first packet which matches the filter criteria */
2535 case 'l': /* Automatic scrolling in live capture mode */
2537 auto_scroll_live = TRUE;
2539 capture_option_specified = TRUE;
2543 case 'L': /* Print list of link-layer types and exit */
2545 list_link_layer_types = TRUE;
2547 capture_option_specified = TRUE;
2551 case 'm': /* Fixed-width font for the display */
2552 g_free(prefs_p->gui_font_name);
2553 prefs_p->gui_font_name = g_strdup(optarg);
2555 case 'n': /* No name resolution */
2556 gbl_resolv_flags = RESOLV_NONE;
2558 case 'N': /* Select what types of addresses/port #s to resolve */
2559 if (gbl_resolv_flags == RESOLV_ALL)
2560 gbl_resolv_flags = RESOLV_NONE;
2561 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2562 if (badopt != '\0') {
2563 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2568 case 'o': /* Override preference from command line */
2569 switch (prefs_set_pref(optarg)) {
2572 case PREFS_SET_SYNTAX_ERR:
2573 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2576 case PREFS_SET_NO_SUCH_PREF:
2577 /* not a preference, might be a recent setting */
2578 switch (recent_set_arg(optarg)) {
2581 case PREFS_SET_SYNTAX_ERR:
2582 /* shouldn't happen, checked already above */
2583 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2586 case PREFS_SET_NO_SUCH_PREF:
2587 case PREFS_SET_OBSOLETE:
2588 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2593 g_assert_not_reached();
2596 case PREFS_SET_OBSOLETE:
2597 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2602 g_assert_not_reached();
2606 /* Path settings were already processed just ignore them this time*/
2608 case 'r': /* Read capture file xxx */
2609 /* We may set "last_open_dir" to "cf_name", and if we change
2610 "last_open_dir" later, we free the old value, so we have to
2611 set "cf_name" to something that's been allocated. */
2612 cf_name = g_strdup(optarg);
2614 case 'R': /* Read file filter */
2617 case 't': /* Time stamp type */
2618 if (strcmp(optarg, "r") == 0)
2619 timestamp_set_type(TS_RELATIVE);
2620 else if (strcmp(optarg, "a") == 0)
2621 timestamp_set_type(TS_ABSOLUTE);
2622 else if (strcmp(optarg, "ad") == 0)
2623 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2624 else if (strcmp(optarg, "d") == 0)
2625 timestamp_set_type(TS_DELTA);
2626 else if (strcmp(optarg, "dd") == 0)
2627 timestamp_set_type(TS_DELTA_DIS);
2628 else if (strcmp(optarg, "e") == 0)
2629 timestamp_set_type(TS_EPOCH);
2630 else if (strcmp(optarg, "u") == 0)
2631 timestamp_set_type(TS_UTC);
2632 else if (strcmp(optarg, "ud") == 0)
2633 timestamp_set_type(TS_UTC_WITH_DATE);
2635 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2636 cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2637 cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2641 case 'u': /* Seconds type */
2642 if (strcmp(optarg, "s") == 0)
2643 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2644 else if (strcmp(optarg, "hms") == 0)
2645 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2647 cmdarg_err("Invalid seconds type \"%s\"", optarg);
2648 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2653 /* ext ops were already processed just ignore them this time*/
2656 /* We won't call the init function for the stat this soon
2657 as it would disallow MATE's fields (which are registered
2658 by the preferences set callback) from being used as
2659 part of a tap filter. Instead, we just add the argument
2660 to a list of stat arguments. */
2661 if (!process_stat_cmd_arg(optarg)) {
2662 cmdarg_err("Invalid -z argument.");
2663 cmdarg_err_cont(" -z argument must be one of :");
2664 list_stat_cmd_args();
2669 case '?': /* Bad flag - print usage message */
2678 if (cf_name != NULL) {
2680 * Input file name specified with "-r" *and* specified as a regular
2681 * command-line argument.
2683 cmdarg_err("File name specified both with -r and regular argument");
2687 * Input file name not specified with "-r", and a command-line argument
2688 * was specified; treat it as the input file name.
2690 * Yes, this is different from tshark, where non-flag command-line
2691 * arguments are a filter, but this works better on GUI desktops
2692 * where a command can be specified to be run to open a particular
2693 * file - yes, you could have "-r" as the last part of the command,
2694 * but that's a bit ugly.
2696 cf_name = g_strdup(argv[0]);
2704 * Extra command line arguments were specified; complain.
2706 cmdarg_err("Invalid argument: %s", argv[0]);
2711 #ifndef HAVE_LIBPCAP
2712 if (capture_option_specified) {
2713 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2721 if (global_capture_opts.all_ifaces->len == 0) {
2722 scan_local_interfaces(&global_capture_opts, &error);
2726 if (start_capture && list_link_layer_types) {
2727 /* Specifying *both* is bogus. */
2728 cmdarg_err("You can't specify both -L and a live capture.");
2732 if (list_link_layer_types) {
2733 /* We're supposed to list the link-layer types for an interface;
2734 did the user also specify a capture file to be read? */
2736 /* Yes - that's bogus. */
2737 cmdarg_err("You can't specify -L and a capture file to be read.");
2740 /* No - did they specify a ring buffer option? */
2741 if (global_capture_opts.multi_files_on) {
2742 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2746 /* We're supposed to do a live capture; did the user also specify
2747 a capture file to be read? */
2748 if (start_capture && cf_name) {
2749 /* Yes - that's bogus. */
2750 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2754 /* No - was the ring buffer option specified and, if so, does it make
2756 if (global_capture_opts.multi_files_on) {
2757 /* Ring buffer works only under certain conditions:
2758 a) ring buffer does not work with temporary files;
2759 b) real_time_mode and multi_files_on are mutually exclusive -
2760 real_time_mode takes precedence;
2761 c) it makes no sense to enable the ring buffer if the maximum
2762 file size is set to "infinite". */
2763 if (global_capture_opts.save_file == NULL) {
2764 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2765 global_capture_opts.multi_files_on = FALSE;
2767 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2768 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2769 /* XXX - this must be redesigned as the conditions changed */
2774 if (start_capture || list_link_layer_types) {
2775 /* Did the user specify an interface to use? */
2776 if (!capture_opts_trim_iface(&global_capture_opts,
2777 (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2782 if (list_link_layer_types) {
2783 /* Get the list of link-layer types for the capture devices. */
2784 if_capabilities_t *caps;
2787 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2789 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2790 if (device.selected) {
2791 #if defined(HAVE_PCAP_CREATE)
2792 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2794 caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2797 cmdarg_err("%s", err_str);
2801 if (caps->data_link_types == NULL) {
2802 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2805 #if defined(HAVE_PCAP_CREATE)
2806 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2808 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2810 free_if_capabilities(caps);
2816 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2817 capture_opts_trim_ring_num_files(&global_capture_opts);
2818 #endif /* HAVE_LIBPCAP */
2820 /* Notify all registered modules that have had any of their preferences
2821 changed either from one of the preferences file or from the command
2822 line that their preferences have changed. */
2826 if ((global_capture_opts.num_selected == 0) &&
2827 (prefs.capture_device != NULL)) {
2830 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2831 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2832 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2833 device.selected = TRUE;
2834 global_capture_opts.num_selected++;
2835 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2836 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2843 /* disabled protocols as per configuration file */
2844 if (gdp_path == NULL && dp_path == NULL) {
2845 set_disabled_protos_list();
2848 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2850 /* read in rc file from global and personal configuration paths. */
2851 rc_file = get_datafile_path(RC_FILE);
2852 #if GTK_CHECK_VERSION(3,0,0)
2853 /* XXX resolve later */
2855 gtk_rc_parse(rc_file);
2857 rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2858 gtk_rc_parse(rc_file);
2868 /* close the splash screen, as we are going to open the main window now */
2869 splash_destroy(splash_win);
2871 /************************************************************************/
2872 /* Everything is prepared now, preferences and command line was read in */
2874 /* Pop up the main window. */
2875 create_main_window(pl_size, tv_size, bv_size, prefs_p);
2877 /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2878 recent_read_dynamic(&rf_path, &rf_open_errno);
2879 if (rf_path != NULL && rf_open_errno != 0) {
2880 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2881 "Could not open recent file\n\"%s\": %s.",
2882 rf_path, g_strerror(rf_open_errno));
2885 color_filters_enable(recent.packet_list_colorize);
2887 /* rearrange all the widgets as we now have all recent settings ready for this */
2888 main_widgets_rearrange();
2890 /* Fill in column titles. This must be done after the top level window
2893 XXX - is that still true, with fixed-width columns? */
2895 menu_recent_read_finished();
2897 menu_auto_scroll_live_changed(auto_scroll_live);
2900 switch (user_font_apply()) {
2903 case FA_FONT_NOT_RESIZEABLE:
2904 /* "user_font_apply()" popped up an alert box. */
2905 /* turn off zooming - font can't be resized */
2906 case FA_FONT_NOT_AVAILABLE:
2907 /* XXX - did we successfully load the un-zoomed version earlier?
2908 If so, this *probably* means the font is available, but not at
2909 this particular zoom level, but perhaps some other failure
2910 occurred; I'm not sure you can determine which is the case,
2912 /* turn off zooming - zoom level is unavailable */
2914 /* in any other case than FA_SUCCESS, turn off zooming */
2915 recent.gui_zoom_level = 0;
2916 /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2919 dnd_init(top_level);
2921 color_filters_init();
2924 capture_filter_init();
2927 /* the window can be sized only, if it's not already shown, so do it now! */
2928 main_load_window_geometry(top_level);
2930 g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2933 GtkWidget *filter_te;
2934 filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
2935 gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
2937 /* Run the display filter so it goes in effect. */
2938 main_filter_packets(&cfile, dfilter, FALSE);
2941 /* If we were given the name of a capture file, read it in now;
2942 we defer it until now, so that, if we can't open it, and pop
2943 up an alert box, the alert box is more likely to come up on
2944 top of the main window - but before the preference-file-error
2945 alert box, so, if we get one of those, it's more likely to come
2948 show_main_window(TRUE);
2949 check_and_warn_user_startup(cf_name);
2950 if (rfilter != NULL) {
2951 if (!dfilter_compile(rfilter, &rfcode)) {
2952 bad_dfilter_alert_box(rfilter);
2953 rfilter_parse_failed = TRUE;
2956 if (!rfilter_parse_failed) {
2957 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2958 /* "cf_open()" succeeded, so it closed the previous
2959 capture file, and thus destroyed any previous read filter
2960 attached to "cf". */
2962 cfile.rfcode = rfcode;
2963 /* Open stat windows; we do so after creating the main window,
2964 to avoid GTK warnings, and after successfully opening the
2965 capture file, so we know we have something to compute stats
2966 on, and after registering all dissectors, so that MATE will
2967 have registered its field array and we can have a tap filter
2968 with one of MATE's late-registered fields as part of the
2970 start_requested_stats();
2972 /* Read the capture file. */
2973 switch (cf_read(&cfile, FALSE)) {
2977 /* Just because we got an error, that doesn't mean we were unable
2978 to read any of the file; we handle what we could get from the
2980 /* if the user told us to jump to a specific packet, do it now */
2981 if(go_to_packet != 0) {
2982 /* Jump to the specified frame number, kept for backward
2984 cf_goto_frame(&cfile, go_to_packet);
2985 } else if (jfilter != NULL) {
2986 /* try to compile given filter */
2987 if (!dfilter_compile(jfilter, &jump_to_filter)) {
2988 bad_dfilter_alert_box(jfilter);
2990 /* Filter ok, jump to the first packet matching the filter
2991 conditions. Default search direction is forward, but if
2992 option d was given, search backwards */
2993 cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
2998 case CF_READ_ABORTED:
3004 /* If the filename is not the absolute path, prepend the current dir. This happens
3005 when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3006 if (!g_path_is_absolute(cf_name)) {
3007 char *old_cf_name = cf_name;
3008 char *pwd = g_get_current_dir();
3009 cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3010 g_free(old_cf_name);
3014 /* Save the name of the containing directory specified in the
3015 path name, if any; we can write over cf_name, which is a
3016 good thing, given that "get_dirname()" does write over its
3018 s = get_dirname(cf_name);
3019 set_last_open_dir(s);
3024 dfilter_free(rfcode);
3025 cfile.rfcode = NULL;
3026 show_main_window(FALSE);
3027 /* Don't call check_and_warn_user_startup(): we did it above */
3028 set_menus_for_capture_in_progress(FALSE);
3029 set_capture_if_dialog_for_capture_in_progress(FALSE);
3034 if (start_capture) {
3035 if (global_capture_opts.save_file != NULL) {
3036 /* Save the directory name for future file dialogs. */
3037 /* (get_dirname overwrites filename) */
3038 s = get_dirname(g_strdup(global_capture_opts.save_file));
3039 set_last_open_dir(s);
3042 /* "-k" was specified; start a capture. */
3043 show_main_window(TRUE);
3044 check_and_warn_user_startup(cf_name);
3045 if (capture_start(&global_capture_opts)) {
3046 /* The capture started. Open stat windows; we do so after creating
3047 the main window, to avoid GTK warnings, and after successfully
3048 opening the capture file, so we know we have something to compute
3049 stats on, and after registering all dissectors, so that MATE will
3050 have registered its field array and we can have a tap filter with
3051 one of MATE's late-registered fields as part of the filter. */
3052 start_requested_stats();
3055 show_main_window(FALSE);
3056 check_and_warn_user_startup(cf_name);
3057 set_menus_for_capture_in_progress(FALSE);
3058 set_capture_if_dialog_for_capture_in_progress(FALSE);
3061 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3062 if (!start_capture && !global_capture_opts.default_options.cfilter) {
3063 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3065 #else /* HAVE_LIBPCAP */
3066 show_main_window(FALSE);
3067 check_and_warn_user_startup(cf_name);
3068 set_menus_for_capture_in_progress(FALSE);
3069 set_capture_if_dialog_for_capture_in_progress(FALSE);
3070 #endif /* HAVE_LIBPCAP */
3073 /* register our pid if we are being run from a U3 device */
3076 profile_store_persconffiles (FALSE);
3078 #ifdef HAVE_GTKOSXAPPLICATION
3079 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3080 gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3081 gtk_osxapplication_ready(theApp);
3084 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3086 /* we'll enter the GTK loop now and hand the control over to GTK ... */
3088 /* ... back from GTK, we're going down now! */
3090 /* deregister our pid */
3091 u3_deregister_pid();
3095 AirPDcapDestroyContext(&airpdcap_ctx);
3098 /* hide the (unresponsive) main window, while asking the user to close the console window */
3099 gtk_widget_hide(top_level);
3101 #ifdef HAVE_GTKOSXAPPLICATION
3102 g_object_unref(theApp);
3105 /* Shutdown windows sockets */
3108 /* For some unknown reason, the "atexit()" call in "create_console()"
3109 doesn't arrange that "destroy_console()" be called when we exit,
3110 so we call it here if a console was created. */
3119 /* We build this as a GUI subsystem application on Win32, so
3120 "WinMain()", not "main()", gets called.
3122 Hack shamelessly stolen from the Win32 port of the GIMP. */
3124 #define _stdcall __attribute__((stdcall))
3128 WinMain (struct HINSTANCE__ *hInstance,
3129 struct HINSTANCE__ *hPrevInstance,
3133 INITCOMMONCONTROLSEX comm_ctrl;
3136 * Initialize our DLL search path. MUST be called before LoadLibrary
3139 ws_init_dll_search_path();
3141 /* Initialize our controls. Required for native Windows file dialogs. */
3142 memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3143 comm_ctrl.dwSize = sizeof(comm_ctrl);
3144 /* Includes the animate, header, hot key, list view, progress bar,
3145 * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3148 comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3149 InitCommonControlsEx(&comm_ctrl);
3151 /* RichEd20.DLL is needed for filter entries. */
3152 ws_load_library("riched20.dll");
3154 has_console = FALSE;
3155 console_wait = FALSE;
3156 return main (__argc, __argv);
3159 /* The code to create and desstroy console windows should not be necessary,
3160 at least as I read the GLib source code, as it looks as if GLib is, on
3161 Win32, *supposed* to create a console window into which to display its
3164 That doesn't happen, however. I suspect there's something completely
3165 broken about that code in GLib-for-Win32, and that it may be related
3166 to the breakage that forces us to just call "printf()" on the message
3167 rather than passing the message on to "g_log_default_handler()"
3168 (which is the routine that does the aforementioned non-functional
3169 console window creation). */
3172 * If this application has no console window to which its standard output
3173 * would go, create one.
3176 create_console(void)
3178 if (stdin_capture) {
3179 /* We've been handed "-i -". Don't mess with stdio. */
3184 /* We have no console to which to print the version string, so
3185 create one and make it the standard input, output, and error. */
3188 * See if we have an existing console (i.e. we were run from a
3191 if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3192 if (AllocConsole()) {
3193 console_wait = TRUE;
3194 SetConsoleTitle(_T("Wireshark Debug Console"));
3196 return; /* couldn't create console */
3200 ws_freopen("CONIN$", "r", stdin);
3201 ws_freopen("CONOUT$", "w", stdout);
3202 ws_freopen("CONOUT$", "w", stderr);
3203 fprintf(stdout, "\n");
3204 fprintf(stderr, "\n");
3206 /* Now register "destroy_console()" as a routine to be called just
3207 before the application exits, so that we can destroy the console
3208 after the user has typed a key (so that the console doesn't just
3209 disappear out from under them, giving the user no chance to see
3210 the message(s) we put in there). */
3211 atexit(destroy_console);
3213 /* Well, we have a console now. */
3219 destroy_console(void)
3222 printf("\n\nPress any key to exit\n");
3231 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3232 const char *message, gpointer user_data _U_)
3239 /* ignore log message, if log_level isn't interesting based
3240 upon the console log preferences.
3241 If the preferences haven't been loaded loaded yet, display the
3244 The default console_log_level preference value is such that only
3245 ERROR, CRITICAL and WARNING level messages are processed;
3246 MESSAGE, INFO and DEBUG level messages are ignored. */
3247 if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3248 prefs.console_log_level != 0) {
3253 if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3254 /* the user wants a console or the application will terminate immediately */
3258 /* For some unknown reason, the above doesn't appear to actually cause
3259 anything to be sent to the standard output, so we'll just splat the
3260 message out directly, just to make sure it gets out. */
3262 switch(log_level & G_LOG_LEVEL_MASK) {
3263 case G_LOG_LEVEL_ERROR:
3266 case G_LOG_LEVEL_CRITICAL:
3269 case G_LOG_LEVEL_WARNING:
3272 case G_LOG_LEVEL_MESSAGE:
3275 case G_LOG_LEVEL_INFO:
3278 case G_LOG_LEVEL_DEBUG:
3282 fprintf(stderr, "unknown log_level %u\n", log_level);
3284 g_assert_not_reached();
3287 /* create a "timestamp" */
3289 today = localtime(&curr);
3291 fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3292 today->tm_hour, today->tm_min, today->tm_sec,
3293 log_domain != NULL ? log_domain : "",
3296 if(log_level & G_LOG_LEVEL_ERROR) {
3297 /* wait for a key press before the following error handler will terminate the program
3298 this way the user at least can read the error message */
3299 printf("\n\nPress any key to exit\n");
3303 /* XXX - on UN*X, should we just use g_log_default_handler()?
3304 We want the error messages to go to the standard output;
3305 on Mac OS X, that will cause them to show up in various
3306 per-user logs accessible through Console (details depend
3307 on whether you're running 10.0 through 10.4 or running
3308 10.5 and later), and, on other UN*X desktop environments,
3309 if they don't show up in some form of console log, that's
3310 a deficiency in that desktop environment. (Too bad
3311 Windows doesn't set the standard output and error for
3312 GUI apps to something that shows up in such a log.) */
3313 g_log_default_handler(log_domain, log_level, message, user_data);
3320 * Helper for main_widgets_rearrange()
3322 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3323 gtk_container_remove(GTK_CONTAINER(data), widget);
3326 static GtkWidget *main_widget_layout(gint layout_content)
3328 switch(layout_content) {
3329 case(layout_pane_content_none):
3331 case(layout_pane_content_plist):
3333 case(layout_pane_content_pdetails):
3335 case(layout_pane_content_pbytes):
3336 return byte_nb_ptr_gbl;
3338 g_assert_not_reached();
3345 * Rearrange the main window widgets
3347 void main_widgets_rearrange(void) {
3348 GtkWidget *first_pane_widget1, *first_pane_widget2;
3349 GtkWidget *second_pane_widget1, *second_pane_widget2;
3350 gboolean split_top_left = FALSE;
3352 /* be a bit faster */
3353 gtk_widget_hide(main_vbox);
3355 /* be sure we don't lose a widget while rearranging */
3356 g_object_ref(G_OBJECT(menubar));
3357 g_object_ref(G_OBJECT(main_tb));
3358 g_object_ref(G_OBJECT(filter_tb));
3360 g_object_ref(G_OBJECT(airpcap_tb));
3362 g_object_ref(G_OBJECT(pkt_scrollw));
3363 g_object_ref(G_OBJECT(tv_scrollw));
3364 g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3365 g_object_ref(G_OBJECT(statusbar));
3366 g_object_ref(G_OBJECT(main_pane_v1));
3367 g_object_ref(G_OBJECT(main_pane_v2));
3368 g_object_ref(G_OBJECT(main_pane_h1));
3369 g_object_ref(G_OBJECT(main_pane_h2));
3370 g_object_ref(G_OBJECT(welcome_pane));
3372 /* empty all containers participating */
3373 gtk_container_foreach(GTK_CONTAINER(main_vbox), foreach_remove_a_child, main_vbox);
3374 gtk_container_foreach(GTK_CONTAINER(main_pane_v1), foreach_remove_a_child, main_pane_v1);
3375 gtk_container_foreach(GTK_CONTAINER(main_pane_v2), foreach_remove_a_child, main_pane_v2);
3376 gtk_container_foreach(GTK_CONTAINER(main_pane_h1), foreach_remove_a_child, main_pane_h1);
3377 gtk_container_foreach(GTK_CONTAINER(main_pane_h2), foreach_remove_a_child, main_pane_h2);
3379 statusbar_widgets_emptying(statusbar);
3381 /* add the menubar always at the top */
3382 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3385 gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3387 /* filter toolbar in toolbar area */
3388 if (!prefs.filter_toolbar_show_in_statusbar) {
3389 gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3393 /* airpcap toolbar */
3394 gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3397 /* fill the main layout panes */
3398 switch(prefs.gui_layout_type) {
3399 case(layout_type_5):
3400 main_first_pane = main_pane_v1;
3401 main_second_pane = main_pane_v2;
3402 split_top_left = FALSE;
3404 case(layout_type_2):
3405 main_first_pane = main_pane_v1;
3406 main_second_pane = main_pane_h1;
3407 split_top_left = FALSE;
3409 case(layout_type_1):
3410 main_first_pane = main_pane_v1;
3411 main_second_pane = main_pane_h1;
3412 split_top_left = TRUE;
3414 case(layout_type_4):
3415 main_first_pane = main_pane_h1;
3416 main_second_pane = main_pane_v1;
3417 split_top_left = FALSE;
3419 case(layout_type_3):
3420 main_first_pane = main_pane_h1;
3421 main_second_pane = main_pane_v1;
3422 split_top_left = TRUE;
3424 case(layout_type_6):
3425 main_first_pane = main_pane_h1;
3426 main_second_pane = main_pane_h2;
3427 split_top_left = FALSE;
3430 main_first_pane = NULL;
3431 main_second_pane = NULL;
3432 g_assert_not_reached();
3434 if (split_top_left) {
3435 first_pane_widget1 = main_second_pane;
3436 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3437 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3438 first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3440 first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3441 first_pane_widget2 = main_second_pane;
3442 second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3443 second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3445 if (first_pane_widget1 != NULL)
3446 gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3447 if (first_pane_widget2 != NULL)
3448 gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3449 if (second_pane_widget1 != NULL)
3450 gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3451 if (second_pane_widget2 != NULL)
3452 gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3454 gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3457 gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3460 gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3462 /* filter toolbar in statusbar hbox */
3463 if (prefs.filter_toolbar_show_in_statusbar) {
3464 gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3467 /* statusbar widgets */
3468 statusbar_widgets_pack(statusbar);
3470 /* hide widgets on users recent settings */
3471 main_widgets_show_or_hide();
3473 gtk_widget_show(main_vbox);
3477 is_widget_visible(GtkWidget *widget, gpointer data)
3479 gboolean *is_visible = data;
3482 if (gtk_widget_get_visible(widget))
3489 main_widgets_show_or_hide(void)
3491 gboolean main_second_pane_show;
3493 if (recent.main_toolbar_show) {
3494 gtk_widget_show(main_tb);
3496 gtk_widget_hide(main_tb);
3499 statusbar_widgets_show_or_hide(statusbar);
3501 if (recent.filter_toolbar_show) {
3502 gtk_widget_show(filter_tb);
3504 gtk_widget_hide(filter_tb);
3508 if (recent.airpcap_toolbar_show) {
3509 gtk_widget_show(airpcap_tb);
3511 gtk_widget_hide(airpcap_tb);
3515 if (recent.packet_list_show && have_capture_file) {
3516 gtk_widget_show(pkt_scrollw);
3518 gtk_widget_hide(pkt_scrollw);
3521 if (recent.tree_view_show && have_capture_file) {
3522 gtk_widget_show(tv_scrollw);
3524 gtk_widget_hide(tv_scrollw);
3527 if (recent.byte_view_show && have_capture_file) {
3528 gtk_widget_show(byte_nb_ptr_gbl);
3530 gtk_widget_hide(byte_nb_ptr_gbl);
3533 if (have_capture_file) {
3534 gtk_widget_show(main_first_pane);
3536 gtk_widget_hide(main_first_pane);
3540 * Is anything in "main_second_pane" visible?
3541 * If so, show it, otherwise hide it.
3543 main_second_pane_show = FALSE;
3544 gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3545 &main_second_pane_show);
3546 if (main_second_pane_show) {
3547 gtk_widget_show(main_second_pane);
3549 gtk_widget_hide(main_second_pane);
3552 if (!have_capture_file) {
3554 gtk_widget_show(welcome_pane);
3557 gtk_widget_hide(welcome_pane);
3562 /* called, when the window state changes (minimized, maximized, ...) */
3564 window_state_event_cb (GtkWidget *widget _U_,
3568 GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3570 if( (event->type) == (GDK_WINDOW_STATE)) {
3571 if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3572 /* we might have dialogs popped up while we where iconified,
3574 display_queued_messages();
3582 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3584 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3586 if (event->keyval == GDK_F8) {
3587 new_packet_list_next();
3589 } else if (event->keyval == GDK_F7) {
3590 new_packet_list_prev();
3592 } else if (event->state & NO_SHIFT_MOD_MASK) {
3593 return FALSE; /* Skip control, alt, and other modifiers */
3595 * A comment in gdkkeysyms.h says that it's autogenerated from
3596 * freedesktop.org/x.org's keysymdef.h. Although the GDK docs
3597 * don't explicitly say so, isprint() should work as expected
3600 } else if (isascii(event->keyval) && isprint(event->keyval)) {
3601 /* Forward the keypress on to the display filter entry */
3602 if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3603 gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3604 gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3612 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3614 GtkAccelGroup *accel;
3617 top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3618 set_main_window_name("The Wireshark Network Analyzer");
3620 gtk_widget_set_name(top_level, "main window");
3621 g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3623 g_signal_connect(G_OBJECT(top_level), "window_state_event",
3624 G_CALLBACK(window_state_event_cb), NULL);
3625 g_signal_connect(G_OBJECT(top_level), "key-press-event",
3626 G_CALLBACK(top_level_key_pressed_cb), NULL );
3628 /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3629 main_vbox = gtk_vbox_new(FALSE, 1);
3630 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3631 gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3632 gtk_widget_show(main_vbox);
3635 menubar = main_menu_new(&accel);
3637 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3638 /* Mac OS X native menus are created and displayed by main_menu_new() */
3639 if(!prefs_p->gui_macosx_style) {
3641 gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3642 gtk_widget_show(menubar);
3643 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3648 main_tb = toolbar_new();
3649 gtk_widget_show (main_tb);
3651 /* Filter toolbar */
3652 filter_tb = filter_toolbar_new();
3655 pkt_scrollw = new_packet_list_create();
3656 gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3657 gtk_widget_show_all(pkt_scrollw);
3660 tv_scrollw = main_tree_view_new(prefs_p, &tree_view_gbl);
3661 gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3662 gtk_widget_show(tv_scrollw);
3664 g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3665 "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3666 g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3667 g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3668 gtk_widget_show(tree_view_gbl);
3671 byte_nb_ptr_gbl = byte_view_new();
3672 gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3673 gtk_widget_show(byte_nb_ptr_gbl);
3675 g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3676 g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3678 /* Panes for the packet list, tree, and byte view */
3679 main_pane_v1 = gtk_vpaned_new();
3680 gtk_widget_show(main_pane_v1);
3681 main_pane_v2 = gtk_vpaned_new();
3682 gtk_widget_show(main_pane_v2);
3683 main_pane_h1 = gtk_hpaned_new();
3684 gtk_widget_show(main_pane_h1);
3685 main_pane_h2 = gtk_hpaned_new();
3686 gtk_widget_show(main_pane_h2);
3688 airpcap_tb = airpcap_toolbar_new();
3689 gtk_widget_show(airpcap_tb);
3692 statusbar = statusbar_new();
3693 gtk_widget_show(statusbar);
3695 /* Pane for the welcome screen */
3696 welcome_pane = welcome_new();
3697 gtk_widget_show(welcome_pane);
3701 show_main_window(gboolean doing_work)
3703 main_set_for_capture_file(doing_work);
3705 /*** we have finished all init things, show the main window ***/
3706 gtk_widget_show(top_level);
3708 /* the window can be maximized only, if it's visible, so do it after show! */
3709 main_load_window_geometry(top_level);
3711 /* process all pending GUI events before continue */
3712 while (gtk_events_pending()) gtk_main_iteration();
3714 /* Pop up any queued-up alert boxes. */
3715 display_queued_messages();
3717 /* Move the main window to the front, in case it isn't already there */
3718 gdk_window_raise(gtk_widget_get_window(top_level));
3721 airpcap_toolbar_show(airpcap_tb);
3722 #endif /* HAVE_AIRPCAP */
3725 /* Fill in capture options with values from the preferences */
3727 prefs_to_capture_opts(void)
3730 /* Set promiscuous mode from the preferences setting. */
3731 /* the same applies to other preferences settings as well. */
3732 global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
3733 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
3734 global_capture_opts.show_info = prefs.capture_show_info;
3735 global_capture_opts.real_time_mode = prefs.capture_real_time;
3736 auto_scroll_live = prefs.capture_auto_scroll;
3737 #endif /* HAVE_LIBPCAP */
3739 /* Set the name resolution code's flags from the preferences. */
3740 gbl_resolv_flags = prefs.name_resolve;
3743 static void copy_global_profile (const gchar *profile_name)
3745 char *pf_dir_path, *pf_dir_path2, *pf_filename;
3747 if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3748 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3749 "Can't create directory\n\"%s\":\n%s.",
3750 pf_dir_path, g_strerror(errno));
3752 g_free(pf_dir_path);
3755 if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3756 &pf_dir_path, &pf_dir_path2) == -1) {
3757 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3758 "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3759 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3761 g_free(pf_filename);
3762 g_free(pf_dir_path);
3763 g_free(pf_dir_path2);
3767 /* Change configuration profile */
3768 void change_configuration_profile (const gchar *profile_name)
3770 char *gdp_path, *dp_path;
3774 /* First check if profile exists */
3775 if (!profile_exists(profile_name, FALSE)) {
3776 if (profile_exists(profile_name, TRUE)) {
3777 /* Copy from global profile */
3778 copy_global_profile (profile_name);
3780 /* No personal and no global profile exists */
3785 /* Then check if changing to another profile */
3786 if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3790 /* Get the current geometry, before writing it to disk */
3791 main_save_window_geometry(top_level);
3793 if (profile_exists(get_profile_name(), FALSE)) {
3794 /* Write recent file for profile we are leaving, if it still exists */
3795 write_profile_recent();
3798 /* Set profile name and update the status bar */
3799 set_profile_name (profile_name);
3800 profile_bar_update ();
3801 filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3803 /* Reset current preferences and apply the new */
3807 (void) read_configuration_files (&gdp_path, &dp_path);
3809 recent_read_profile_static(&rf_path, &rf_open_errno);
3810 if (rf_path != NULL && rf_open_errno != 0) {
3811 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3812 "Could not open common recent file\n\"%s\": %s.",
3813 rf_path, g_strerror(rf_open_errno));
3815 if (recent.gui_fileopen_remembered_dir &&
3816 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3817 set_last_open_dir(recent.gui_fileopen_remembered_dir);
3819 timestamp_set_type (recent.gui_time_format);
3820 timestamp_set_seconds_type (recent.gui_seconds_format);
3821 color_filters_enable(recent.packet_list_colorize);
3823 prefs_to_capture_opts();
3825 macros_post_update();
3827 /* Update window view and redraw the toolbar */
3828 update_main_window_title();
3829 filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3830 toolbar_redraw_all();
3832 /* Enable all protocols and disable from the disabled list */
3834 if (gdp_path == NULL && dp_path == NULL) {
3835 set_disabled_protos_list();
3838 /* Reload color filters */
3839 color_filters_reload();
3841 /* Reload list of interfaces on welcome page */
3842 welcome_if_panel_reload();
3844 /* Recreate the packet list according to new preferences */
3845 new_packet_list_recreate ();
3846 cfile.cinfo.columns_changed = FALSE; /* Reset value */
3849 /* Update menus with new recent values */
3850 menu_recent_read_finished();
3852 /* Reload pane geometry, must be done after recreating the list */
3853 main_pane_load_window_geometry();
3856 /** redissect packets and update UI */
3857 void redissect_packets(void)
3859 cf_redissect_packets(&cfile);
3860 status_expert_update();
3864 guint get_interface_type(gchar *name, gchar *description)
3866 #if defined(__linux__)
3868 char *wireless_path;
3872 * Much digging failed to reveal any obvious way to get something such
3873 * as the SNMP MIB-II ifType value for an interface:
3875 * http://www.iana.org/assignments/ianaiftype-mib
3877 * by making some NDIS request.
3879 if (description && (strstr(description,"generic dialup") != NULL ||
3880 strstr(description,"PPP/SLIP") != NULL )) {
3882 } else if (description && (strstr(description,"Wireless") != NULL ||
3883 strstr(description,"802.11") != NULL)) {
3885 } else if (description && strstr(description,"AirPcap") != NULL ||
3886 strstr(name,"airpcap")) {
3888 } else if (description && strstr(description, "Bluetooth") != NULL ) {
3889 return IF_BLUETOOTH;
3891 #elif defined(__APPLE__)
3893 * XXX - yes, fetching all the network addresses for an interface
3894 * gets you an AF_LINK address, of type "struct sockaddr_dl", and,
3895 * yes, that includes an SNMP MIB-II ifType value.
3897 * However, it's IFT_ETHER, i.e. Ethernet, for AirPort interfaces,
3898 * not IFT_IEEE80211 (which isn't defined in OS X in any case).
3900 * Perhaps some other BSD-flavored OSes won't make this mistake;
3901 * however, FreeBSD 7.0 and OpenBSD 4.2, at least, appear to have
3902 * made the same mistake, at least for my Belkin ZyDAS stick.
3904 * On Mac OS X, one might be able to get the information one wants from
3907 if (strcmp(name, "en1") == 0) {
3911 * XXX - PPP devices have names beginning with "ppp" and an IFT_ of
3912 * IFT_PPP, but they could be dial-up, or PPPoE, or mobile phone modem,
3913 * or VPN, or... devices. One might have to dive into the bowels of
3914 * IOKit to find out.
3918 * XXX - there's currently no support for raw Bluetooth capture,
3919 * and IP-over-Bluetooth devices just look like fake Ethernet
3920 * devices. There's also Bluetooth modem support, but that'll
3921 * probably just give you a device that looks like a PPP device.
3923 #elif defined(__linux__)
3925 * Look for /sys/class/net/{device}/wireless.
3927 wireless_path = g_strdup_printf("/sys/class/net/%s/wireless", name);
3928 if (wireless_path != NULL) {
3929 if (ws_stat64(wireless_path, &statb) == 0) {
3930 g_free(wireless_path);
3935 * Bluetooth devices.
3937 * XXX - this is for raw Bluetooth capture; what about IP-over-Bluetooth
3940 if ( strstr(name,"bluetooth") != NULL) {
3941 return IF_BLUETOOTH;
3947 if ( strstr(name,"usbmon") != NULL ) {
3952 * Bridge, NAT, or host-only interfaces on VMWare hosts have the name
3953 * vmnet[0-9]+ or VMnet[0-9+ on Windows. Guests might use a native
3954 * (LANCE or E1000) driver or the vmxnet driver. These devices have an
3955 * IFT_ of IFT_ETHER, so we have to check the name.
3957 if ( g_ascii_strncasecmp(name, "vmnet", 5) == 0) {
3961 if ( g_ascii_strncasecmp(name, "vmxnet", 6) == 0) {
3965 if (description && strstr(description, "VMware") != NULL ) {
3973 scan_local_interfaces(capture_options* capture_opts, int *error)
3975 GList *if_entry, *lt_entry, *if_list;
3976 if_info_t *if_info, *temp;
3978 gchar *descr, *str, *err_str = NULL;
3979 if_capabilities_t *caps=NULL;
3980 gint linktype_count;
3981 cap_settings_t cap_settings;
3983 int ips = 0, i, err;
3985 if_addr_t *addr, *temp_addr;
3986 link_row *link = NULL;
3987 data_link_info_t *data_link_info;
3990 interface_options interface_opts;
3991 gboolean found = FALSE;
3994 if (capture_opts->all_ifaces->len > 0) {
3995 for (i = (int)capture_opts->all_ifaces->len-1; i >= 0; i--) {
3996 device = g_array_index(capture_opts->all_ifaces, interface_t, i);
3998 capture_opts->all_ifaces = g_array_remove_index(capture_opts->all_ifaces, i);
4002 /* Scan through the list and build a list of strings to display. */
4003 if_list = capture_interface_list(&err, &err_str);
4006 for (if_entry = if_list; if_entry != NULL; if_entry = g_list_next(if_entry)) {
4007 if_info = if_entry->data;
4008 ip_str = g_string_new("");
4010 device.name = g_strdup(if_info->name);
4011 device.hidden = FALSE;
4012 device.locked = FALSE;
4013 temp = g_malloc0(sizeof(if_info_t));
4014 temp->name = g_strdup(if_info->name);
4015 temp->description = g_strdup(if_info->description);
4016 temp->loopback = if_info->loopback;
4017 /* Is this interface hidden and, if so, should we include it anyway? */
4019 /* Do we have a user-supplied description? */
4020 descr = capture_dev_user_descr_find(if_info->name);
4021 if (descr != NULL) {
4022 /* Yes, we have a user-supplied description; use it. */
4023 if_string = g_strdup_printf("%s: %s", descr, if_info->name);
4026 /* No, we don't have a user-supplied description; did we get
4027 one from the OS or libpcap? */
4028 if (if_info->description != NULL) {
4030 if_string = g_strdup_printf("%s: %s", if_info->description, if_info->name);
4033 if_string = g_strdup(if_info->name);
4036 if (if_info->loopback) {
4037 device.display_name = g_strdup_printf("%s (loopback)", if_string);
4039 device.display_name = g_strdup(if_string);
4041 device.selected = FALSE;
4042 if (prefs_is_capture_device_hidden(if_info->name)) {
4043 device.hidden = TRUE;
4045 device.type = get_interface_type(if_info->name, if_info->description);
4046 cap_settings = capture_get_cap_settings(if_info->name);
4047 caps = capture_get_if_capabilities(if_info->name, cap_settings.monitor_mode, NULL);
4048 for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
4049 temp_addr = g_malloc0(sizeof(if_addr_t));
4051 g_string_append(ip_str, "\n");
4053 addr = (if_addr_t *)curr_addr->data;
4055 temp_addr->ifat_type = addr->ifat_type;
4056 switch (addr->ifat_type) {
4058 temp_addr->addr.ip4_addr = addr->addr.ip4_addr;
4059 g_string_append(ip_str, ip_to_str((guint8 *)&addr->addr.ip4_addr));
4062 memcpy(temp_addr->addr.ip6_addr, addr->addr.ip6_addr, sizeof(addr->addr));
4063 g_string_append(ip_str, ip6_to_str((struct e_in6_addr *)&addr->addr.ip6_addr));
4066 /* In case we add non-IP addresses */
4074 temp->addrs = g_slist_append(temp->addrs, temp_addr);
4077 #ifdef HAVE_PCAP_REMOTE
4078 device.remote_opts.src_type = CAPTURE_IFLOCAL;
4081 device.links = NULL;
4083 #if defined(HAVE_PCAP_CREATE)
4084 device.monitor_mode_enabled = cap_settings.monitor_mode;
4085 device.monitor_mode_supported = caps->can_set_rfmon;
4087 for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
4088 data_link_info = lt_entry->data;
4089 if (data_link_info->description != NULL) {
4090 str = g_strdup_printf("%s", data_link_info->description);
4092 str = g_strdup_printf("%s (not supported)", data_link_info->name);
4094 if (linktype_count == 0) {
4095 device.active_dlt = data_link_info->dlt;
4097 link = (link_row *)g_malloc(sizeof(link_row));
4098 link->dlt = data_link_info->dlt;
4099 link->name = g_strdup(str);
4100 device.links = g_list_append(device.links, link);
4104 cap_settings.monitor_mode = FALSE;
4105 #if defined(HAVE_PCAP_CREATE)
4106 device.monitor_mode_enabled = FALSE;
4107 device.monitor_mode_supported = FALSE;
4109 device.active_dlt = -1;
4111 device.addresses = g_strdup(ip_str->str);
4112 device.no_addresses = ips;
4113 device.local = TRUE;
4114 device.if_info = *temp;
4115 device.last_packets = 0;
4116 device.pmode = capture_opts->default_options.promisc_mode;
4117 device.has_snaplen = capture_opts->default_options.has_snaplen;
4118 device.snaplen = capture_opts->default_options.snaplen;
4119 device.cfilter = g_strdup(capture_opts->default_options.cfilter);
4120 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
4124 if (capture_opts->ifaces->len > 0) {
4125 for (j = 0; j < capture_opts->ifaces->len; j++) {
4126 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
4127 if (strcmp(interface_opts.name, device.name) == 0) {
4128 #if defined(HAVE_PCAP_CREATE)
4129 device.buffer = interface_opts.buffer_size;
4130 device.monitor_mode_enabled = interface_opts.monitor_mode;
4132 device.pmode = interface_opts.promisc_mode;
4133 device.has_snaplen = interface_opts.has_snaplen;
4134 device.snaplen = interface_opts.snaplen;
4135 device.cfilter = g_strdup(interface_opts.cfilter);
4136 device.active_dlt = interface_opts.linktype;
4137 device.selected = TRUE;
4138 capture_opts->num_selected++;
4143 if (capture_opts->all_ifaces->len <= count) {
4144 g_array_append_val(capture_opts->all_ifaces, device);
4145 count = capture_opts->all_ifaces->len;
4147 g_array_insert_val(capture_opts->all_ifaces, count, device);
4150 free_if_capabilities(caps);
4153 g_string_free(ip_str, TRUE);
4156 free_interface_list(if_list);
4157 /* see whether there are additional interfaces in ifaces */
4158 for (j = 0; j < capture_opts->ifaces->len; j++) {
4159 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
4161 for (i = 0; i < (int)capture_opts->all_ifaces->len; i++) {
4162 device = g_array_index(capture_opts->all_ifaces, interface_t, i);
4163 if (strcmp(device.name, interface_opts.name) == 0) {
4168 if (!found) { /* new interface, maybe a pipe */
4169 device.name = g_strdup(interface_opts.name);
4170 device.display_name = g_strdup_printf("%s", device.name);
4171 device.hidden = FALSE;
4172 device.selected = TRUE;
4173 device.type = IF_PIPE;
4174 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
4175 device.buffer = interface_opts.buffer_size;
4177 #if defined(HAVE_PCAP_CREATE)
4178 device.monitor_mode_enabled = interface_opts.monitor_mode;
4179 device.monitor_mode_supported = FALSE;
4181 device.pmode = interface_opts.promisc_mode;
4182 device.has_snaplen = interface_opts.has_snaplen;
4183 device.snaplen = interface_opts.snaplen;
4184 device.cfilter = g_strdup(interface_opts.cfilter);
4185 device.active_dlt = interface_opts.linktype;
4186 device.addresses = NULL;
4187 device.no_addresses = 0;
4188 device.last_packets = 0;
4189 device.links = NULL;
4190 device.local = TRUE;
4191 device.locked = FALSE;
4193 g_array_append_val(capture_opts->all_ifaces, device);
4194 capture_opts->num_selected++;
4199 void hide_interface(gchar* new_hide)
4204 gboolean found = FALSE;
4205 GList *hidden_devices = NULL, *entry;
4206 if (new_hide != NULL) {
4207 for (tok = strtok (new_hide, ","); tok; tok = strtok(NULL, ",")) {
4208 hidden_devices = g_list_append(hidden_devices, tok);
4211 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
4212 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
4214 for (entry = hidden_devices; entry != NULL; entry = g_list_next(entry)) {
4215 if (strcmp(entry->data, device.name)==0) {
4216 device.hidden = TRUE;
4217 if (device.selected) {
4218 device.selected = FALSE;
4219 global_capture_opts.num_selected--;
4226 device.hidden = FALSE;
4228 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
4229 g_array_insert_val(global_capture_opts.all_ifaces, i, device);