Allow "capture info data" to not be a singleton.
[metze/wireshark/wip.git] / ui / gtk / main.c
1 /* main.c
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * Richard Sharpe, 13-Feb-1999, added support for initializing structures
8  *                              needed by dissect routines
9  * Jeff Foster,    2001/03/12,  added support tabbed hex display windowss
10  *
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26
27 #include "config.h"
28
29 #include <gtk/gtk.h>
30 #include <gdk/gdkkeysyms.h>
31 #if GTK_CHECK_VERSION(3,0,0)
32 # include <gdk/gdkkeysyms-compat.h>
33 #endif
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <locale.h>
38
39 #ifdef HAVE_GETOPT_H
40 #include <getopt.h>
41 #endif
42
43 #ifndef HAVE_GETOPT_LONG
44 #include "wsutil/wsgetopt.h"
45 #endif
46
47 #ifdef HAVE_LIBZ
48 #include <zlib.h>      /* to get the libz version number */
49 #endif
50
51 #ifdef HAVE_LIBPORTAUDIO
52 #include <portaudio.h>
53 #endif /* HAVE_LIBPORTAUDIO */
54
55 #include <wsutil/clopts_common.h>
56 #include <wsutil/copyright_info.h>
57 #include <wsutil/crash_info.h>
58 #include <wsutil/filesystem.h>
59 #include <wsutil/file_util.h>
60 #include <wsutil/privileges.h>
61 #include <wsutil/report_err.h>
62 #include <wsutil/u3.h>
63 #include <wsutil/ws_diag_control.h>
64 #include <wsutil/ws_version_info.h>
65
66 #include <wiretap/merge.h>
67
68 #include <epan/addr_resolv.h>
69 #include <epan/column.h>
70 #include <epan/disabled_protos.h>
71 #include <epan/epan.h>
72 #include <epan/proto.h>
73 #include <epan/epan_dissect.h>
74 #include <epan/dfilter/dfilter.h>
75 #include <epan/strutil.h>
76 #include <epan/ex-opt.h>
77 #include <epan/funnel.h>
78 #include <epan/expert.h>
79 #include <epan/prefs.h>
80 #include <epan/prefs-int.h>
81 #include <epan/tap.h>
82 #include <epan/stat_tap_ui.h>
83 #include <epan/uat.h>
84 #include <epan/print.h>
85 #include <epan/timestamp.h>
86 #include <epan/conversation_table.h>
87
88 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
89 #include <epan/asn1.h>
90 #include <epan/dissectors/packet-kerberos.h>
91 #endif
92
93 #include <wsutil/cmdarg_err.h>
94 #include <wsutil/plugins.h>
95
96 /* general (not GTK specific) */
97 #include "../file.h"
98 #include "../frame_tvbuff.h"
99 #include "../summary.h"
100 #include "../color.h"
101 #include "../color_filters.h"
102 #include "../register.h"
103 #include "../ringbuffer.h"
104 #include "../log.h"
105
106 #include "gtk_iface_monitor.h"
107
108 #include "ui/alert_box.h"
109 #include "ui/console.h"
110 #include "ui/decode_as_utils.h"
111 #include "ui/filters.h"
112 #include "ui/main_statusbar.h"
113 #include "ui/persfilepath_opt.h"
114 #include "ui/preference_utils.h"
115 #include "ui/recent.h"
116 #include "ui/recent_utils.h"
117 #include "ui/software_update.h"
118 #include "ui/ui_util.h"
119 #include "ui/util.h"
120
121 #ifdef HAVE_LIBPCAP
122 #include "ui/capture_ui_utils.h"
123 #include "ui/capture_globals.h"
124 #include "ui/iface_lists.h"
125 #endif
126
127 #include "codecs/codecs.h"
128
129 #include "caputils/capture-pcap-util.h"
130
131 #ifdef HAVE_LIBPCAP
132 #include "caputils/capture_ifinfo.h"
133 #include "ui/capture.h"
134 #include <capchild/capture_sync.h>
135 #endif
136
137 #ifdef _WIN32
138 #include "caputils/capture-wpcap.h"
139 #include "caputils/capture_wpcap_packet.h"
140 #include <tchar.h> /* Needed for Unicode */
141 #include <wsutil/os_version_info.h>
142 #include <wsutil/unicode-utils.h>
143 #include <commctrl.h>
144 #include <shellapi.h>
145 #endif /* _WIN32 */
146
147 /* GTK related */
148 #include "ui/gtk/file_dlg.h"
149 #include "ui/gtk/gtkglobals.h"
150 #include "ui/gtk/color_utils.h"
151 #include "ui/gtk/gui_utils.h"
152 #include "ui/gtk/color_dlg.h"
153 #include "ui/gtk/filter_dlg.h"
154 #include "ui/gtk/fileset_dlg.h"
155 #include "ui/gtk/uat_gui.h"
156 #include "ui/gtk/main.h"
157 #include "ui/gtk/main_80211_toolbar.h"
158 #include "ui/gtk/main_airpcap_toolbar.h"
159 #include "ui/gtk/main_filter_toolbar.h"
160 #include "ui/gtk/main_titlebar.h"
161 #include "ui/gtk/menus.h"
162 #include "ui/gtk/main_menubar_private.h"
163 #include "ui/gtk/macros_dlg.h"
164 #include "ui/gtk/main_statusbar_private.h"
165 #include "ui/gtk/main_toolbar.h"
166 #include "ui/gtk/main_toolbar_private.h"
167 #include "ui/gtk/main_welcome.h"
168 #include "ui/gtk/main_welcome_private.h"
169 #include "ui/gtk/drag_and_drop.h"
170 #include "ui/gtk/capture_file_dlg.h"
171 #include "ui/gtk/packet_panes.h"
172 #include "ui/gtk/keys.h"
173 #include "ui/gtk/packet_win.h"
174 #include "ui/gtk/stock_icons.h"
175 #include "ui/gtk/find_dlg.h"
176 #include "ui/gtk/follow_tcp.h"
177 #include "ui/gtk/font_utils.h"
178 #include "ui/gtk/about_dlg.h"
179 #include "ui/gtk/help_dlg.h"
180 #include "ui/gtk/decode_as_dlg.h"
181 #include "ui/gtk/webbrowser.h"
182 #include "ui/gtk/capture_dlg.h"
183 #include "ui/gtk/capture_if_dlg.h"
184 #include "ui/gtk/tap_param_dlg.h"
185 #include "ui/gtk/prefs_column.h"
186 #include "ui/gtk/prefs_dlg.h"
187 #include "ui/gtk/proto_help.h"
188 #include "ui/gtk/packet_list.h"
189 #include "ui/gtk/filter_expression_save_dlg.h"
190 #include "ui/gtk/conversations_table.h"
191 #include "ui/gtk/hostlist_table.h"
192 #include "ui/gtk/service_response_time_table.h"
193 #include "ui/gtk/response_time_delay_table.h"
194 #include "ui/gtk/simple_stattable.h"
195 #include "simple_dialog.h"
196 #ifdef HAVE_GRESOURCE
197 #include "wireshark-gresources.h"
198 #else
199 #include "ui/gtk/pixbuf-csource.h"
200 #endif
201
202 #include "ui/gtk/old-gtk-compat.h"
203
204 #ifdef HAVE_AIRPCAP
205 #include <caputils/airpcap.h>
206 #include <caputils/airpcap_loader.h>
207 #include "airpcap_dlg.h"
208 #include "airpcap_gui_utils.h"
209 #endif
210
211 #include <epan/crypt/airpdcap_ws.h>
212
213
214 #ifdef HAVE_GTKOSXAPPLICATION
215 #include <gtkmacintegration/gtkosxapplication.h>
216 #endif
217
218 /*
219  * Files under personal and global preferences directories in which
220  * GTK settings for Wireshark are stored.
221  */
222 #define RC_FILE "gtkrc"
223
224 #ifdef HAVE_LIBPCAP
225 capture_options global_capture_opts;
226 capture_session global_capture_session;
227 info_data_t global_info_data;
228 #endif
229
230 capture_file cfile;
231
232 static gboolean capture_stopping;
233
234 /* "exported" main widgets */
235 GtkWidget   *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
236
237 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
238 static GtkWidget   *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
239 static GtkWidget   *main_first_pane, *main_second_pane;
240
241 /* internally used widgets */
242 static GtkWidget   *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
243
244 GtkWidget *wireless_tb;
245 #ifdef HAVE_AIRPCAP
246 int    airpcap_dll_ret_val = -1;
247 #endif
248
249 GString *comp_info_str, *runtime_info_str;
250
251 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
252
253 static guint  tap_update_timer_id;
254
255 static void create_main_window(gint, gint, gint, e_prefs*);
256 static void show_main_window(gboolean);
257 static void main_save_window_geometry(GtkWidget *widget);
258
259
260 /* Match selected byte pattern */
261 static void
262 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
263 {
264     char       *cur_filter, *new_filter;
265
266     if ((!text) || (0 == strlen(text))) {
267         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
268         return;
269     }
270
271     g_assert(filter_te);
272
273     cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
274
275     switch (action&MATCH_SELECTED_MASK) {
276
277     case MATCH_SELECTED_REPLACE:
278         new_filter = g_strdup(text);
279         break;
280
281     case MATCH_SELECTED_AND:
282         if ((!cur_filter) || (0 == strlen(cur_filter)))
283             new_filter = g_strdup(text);
284         else
285             new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
286         break;
287
288     case MATCH_SELECTED_OR:
289         if ((!cur_filter) || (0 == strlen(cur_filter)))
290             new_filter = g_strdup(text);
291         else
292             new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
293         break;
294
295     case MATCH_SELECTED_NOT:
296         new_filter = g_strconcat("!(", text, ")", NULL);
297         break;
298
299     case MATCH_SELECTED_AND_NOT:
300         if ((!cur_filter) || (0 == strlen(cur_filter)))
301             new_filter = g_strconcat("!(", text, ")", NULL);
302         else
303             new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
304         break;
305
306     case MATCH_SELECTED_OR_NOT:
307         if ((!cur_filter) || (0 == strlen(cur_filter)))
308             new_filter = g_strconcat("!(", text, ")", NULL);
309         else
310             new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
311         break;
312
313     default:
314         g_assert_not_reached();
315         new_filter = NULL;
316         break;
317     }
318
319     /* Free up the copy we got of the old filter text. */
320     g_free(cur_filter);
321
322     /* Don't change the current display filter if we only want to copy the filter */
323     if (action&MATCH_SELECTED_COPY_ONLY) {
324         GString *gtk_text_str = g_string_new("");
325         g_string_append(gtk_text_str, new_filter);
326         copy_to_clipboard(gtk_text_str);
327         g_string_free(gtk_text_str, TRUE);
328     } else {
329         /* create a new one and set the display filter entry accordingly */
330         gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
331
332         /* Run the display filter so it goes in effect. */
333         if (action&MATCH_SELECTED_APPLY_NOW)
334             main_filter_packets(&cfile, new_filter, FALSE);
335     }
336
337     /* Free up the new filter text. */
338     g_free(new_filter);
339 }
340
341 void
342 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
343 {
344     char *filter = NULL;
345
346     if (cfile.finfo_selected) {
347         filter = proto_construct_match_selected_string(cfile.finfo_selected,
348                                                        cfile.edt);
349         match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
350         wmem_free(NULL, filter);
351     }
352 }
353
354 void
355 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
356 {
357     char *filter = NULL;
358
359     if (cfile.finfo_selected) {
360         filter = proto_construct_match_selected_string(cfile.finfo_selected,
361                                                        cfile.edt);
362         if ((!filter) || (0 == strlen(filter))) {
363             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
364                 "Could not acquire information to build a filter!\n"
365                 "Try expanding or choosing another item.");
366             return;
367         }
368
369         if (filt_nr==0) {
370             color_display_with_filter(filter);
371         } else {
372             if (filt_nr==255) {
373                 color_filters_reset_tmp();
374             } else {
375                 color_filters_set_tmp(filt_nr,filter, FALSE);
376             }
377             packet_list_colorize_packets();
378         }
379         wmem_free(NULL, filter);
380     }
381 }
382
383
384 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
385 {
386     gchar *selected_proto_url;
387     gchar *proto_abbrev = (gchar *)data;
388
389
390     switch(btn) {
391     case(ESD_BTN_OK):
392         if (cfile.finfo_selected) {
393             /* open wiki page using the protocol abbreviation */
394             selected_proto_url = g_strdup_printf("https://wiki.wireshark.org/Protocols/%s", proto_abbrev);
395             browser_open_url(selected_proto_url);
396             g_free(selected_proto_url);
397         }
398         break;
399     case(ESD_BTN_CANCEL):
400         break;
401     default:
402         g_assert_not_reached();
403     }
404 }
405
406
407 void
408 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
409 {
410     int field_id;
411     const gchar *proto_abbrev;
412     gpointer  dialog;
413
414
415     if (cfile.finfo_selected) {
416         /* convert selected field to protocol abbreviation */
417         /* XXX - could this conversion be simplified? */
418         field_id = cfile.finfo_selected->hfinfo->id;
419         /* if the selected field isn't a protocol, get its parent */
420         if(!proto_registrar_is_protocol(field_id)) {
421             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
422         }
423
424         proto_abbrev = proto_registrar_get_abbrev(field_id);
425
426         /* ask the user if the wiki page really should be opened */
427         dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
428                 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
429                 "\n"
430                 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
431                 "\n"
432                 "The Wireshark Wiki is a collaborative approach to provide information "
433                 "about Wireshark in several ways (not limited to protocol specifics).\n"
434                 "\n"
435                 "This Wiki is new, so the page of the selected protocol "
436                 "may not exist and/or may not contain valuable information.\n"
437                 "\n"
438                 "As everyone can edit the Wiki and add new content (or extend existing), "
439                 "you are encouraged to add information if you can.\n"
440                 "\n"
441                 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
442                 "\n"
443                 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
444                 "which will save you a lot of editing and will give a consistent look over the pages.",
445                 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
446         simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
447     }
448 }
449
450 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
451 {
452     gchar *selected_proto_url;
453     gchar *proto_abbrev = (gchar *)data;
454
455     switch(btn) {
456     case(ESD_BTN_OK):
457         if (cfile.finfo_selected) {
458             /* open reference page using the protocol abbreviation */
459             selected_proto_url = g_strdup_printf("https://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
460             browser_open_url(selected_proto_url);
461             g_free(selected_proto_url);
462         }
463         break;
464     case(ESD_BTN_CANCEL):
465         break;
466     default:
467         g_assert_not_reached();
468     }
469 }
470
471 void
472 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
473 {
474     int field_id;
475     const gchar *proto_abbrev;
476     gpointer  dialog;
477
478
479     if (cfile.finfo_selected) {
480         /* convert selected field to protocol abbreviation */
481         /* XXX - could this conversion be simplified? */
482         field_id = cfile.finfo_selected->hfinfo->id;
483         /* if the selected field isn't a protocol, get its parent */
484         if(!proto_registrar_is_protocol(field_id)) {
485             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
486         }
487
488         proto_abbrev = proto_registrar_get_abbrev(field_id);
489
490         /* ask the user if the wiki page really should be opened */
491         dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
492                 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
493                 "\n"
494                 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
495                 "\n",
496                 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
497         simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
498     }
499 }
500
501 static gboolean
502 is_address_column (gint column)
503 {
504     if (((cfile.cinfo.columns[column].col_fmt == COL_DEF_SRC) ||
505          (cfile.cinfo.columns[column].col_fmt == COL_RES_SRC) ||
506          (cfile.cinfo.columns[column].col_fmt == COL_DEF_DST) ||
507          (cfile.cinfo.columns[column].col_fmt == COL_RES_DST)) &&
508         strlen(cfile.cinfo.col_expr.col_expr_val[column]))
509     {
510         return TRUE;
511     }
512
513     return FALSE;
514 }
515
516 GList *
517 get_ip_address_list_from_packet_list_row(gpointer data)
518 {
519     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
520     gint    column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
521     gint    col;
522     frame_data *fdata;
523     GList      *addr_list = NULL;
524
525     fdata = (frame_data *) packet_list_get_row_data(row);
526
527     if (fdata != NULL) {
528         epan_dissect_t edt;
529
530         if (!cf_read_record(&cfile, fdata))
531             return NULL; /* error reading the frame */
532
533         epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
534         col_custom_prime_edt(&edt, &cfile.cinfo);
535
536         epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
537             frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
538         epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
539
540         /* First check selected column */
541         if (is_address_column (column)) {
542             addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
543         }
544
545         for (col = 0; col < cfile.cinfo.num_cols; col++) {
546             /* Then check all columns except the selected */
547             if ((col != column) && (is_address_column (col))) {
548                 addr_list = g_list_append (addr_list, g_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
549             }
550         }
551
552         epan_dissect_cleanup(&edt);
553     }
554
555     return addr_list;
556 }
557
558 static gchar *
559 get_filter_from_packet_list_row_and_column(gpointer data)
560 {
561     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
562     gint    column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
563     frame_data *fdata;
564     gchar      *buf=NULL;
565
566     fdata = (frame_data *) packet_list_get_row_data(row);
567
568     if (fdata != NULL) {
569         epan_dissect_t edt;
570
571         if (!cf_read_record(&cfile, fdata))
572             return NULL; /* error reading the record */
573         /* proto tree, visible. We need a proto tree if there's custom columns */
574         epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
575         col_custom_prime_edt(&edt, &cfile.cinfo);
576
577         epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
578                          frame_tvbuff_new_buffer(fdata, &cfile.buf),
579                          fdata, &cfile.cinfo);
580         epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
581
582         if ((cfile.cinfo.columns[column].col_custom_occurrence) ||
583             (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
584         {
585             /* Only construct the filter when a single occurrence is displayed
586              * otherwise we might end up with a filter like "ip.proto==1,6".
587              *
588              * Or do we want to be able to filter on multiple occurrences so that
589              * the filter might be calculated as "ip.proto==1 && ip.proto==6"
590              * instead?
591              */
592             if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
593                 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
594                 /* leak a little; is there a safe wmem_ scope here? */
595                 if (cfile.cinfo.columns[column].col_fmt == COL_CUSTOM) {
596                     header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.columns[column].col_custom_field);
597                     if (hfi && hfi->parent == -1) {
598                         /* Protocol only */
599                         buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
600                     } else if (hfi && IS_FT_STRING(hfi->type)) {
601                         /* Custom string, add quotes */
602                         buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
603                                                cfile.cinfo.col_expr.col_expr_val[column]);
604                     }
605                 }
606                 if (buf == NULL) {
607                     buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
608                                            cfile.cinfo.col_expr.col_expr_val[column]);
609                 }
610             }
611         }
612
613         epan_dissect_cleanup(&edt);
614     }
615
616     return buf;
617 }
618
619 void
620 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
621 {
622     char *filter;
623
624     filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
625
626     match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
627         action, filter);
628
629     g_free(filter);
630 }
631
632 /* This function allows users to right click in the details window and copy the text
633  * information to the operating systems clipboard.
634  *
635  * We first check to see if a string representation is setup in the tree and then
636  * read the string. If not available then we try to grab the value. If all else
637  * fails we display a message to the user to indicate the copy could not be completed.
638  */
639 void
640 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
641 {
642     GString *gtk_text_str = g_string_new("");
643     char labelstring[ITEM_LABEL_LENGTH];
644     char *stringpointer = labelstring;
645
646     switch(action)
647     {
648     case COPY_SELECTED_DESCRIPTION:
649         if (cfile.finfo_selected->rep &&
650             strlen(cfile.finfo_selected->rep->representation) > 0) {
651             g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
652         }
653         break;
654     case COPY_SELECTED_FIELDNAME:
655         if (cfile.finfo_selected->hfinfo->abbrev != 0) {
656             g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
657         }
658         break;
659     case COPY_SELECTED_VALUE:
660         if (cfile.edt !=0 ) {
661             gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
662             g_string_append(gtk_text_str, field_str);
663             g_free(field_str);
664         }
665         break;
666     default:
667         break;
668     }
669
670     if (gtk_text_str->len == 0) {
671         /* If no representation then... Try to read the value */
672         proto_item_fill_label(cfile.finfo_selected, stringpointer);
673         g_string_append(gtk_text_str, stringpointer);
674     }
675
676     if (gtk_text_str->len == 0) {
677         /* Could not get item so display error msg */
678         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
679     } else {
680         /* Copy string to clipboard */
681         copy_to_clipboard(gtk_text_str);
682     }
683     g_string_free(gtk_text_str, TRUE);                       /* Free the memory */
684 }
685
686
687 /* mark as reference time frame */
688 void
689 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
690     if (row == -1)
691         return;
692     if (set) {
693         frame->flags.ref_time=1;
694         cfile.ref_time_count++;
695     } else {
696         frame->flags.ref_time=0;
697         cfile.ref_time_count--;
698     }
699     cf_reftime_packets(&cfile);
700     if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
701         packet_list_freeze();
702         cfile.displayed_count--;
703         packet_list_recreate_visible_rows();
704         packet_list_thaw();
705     }
706     packet_list_queue_draw();
707 }
708
709
710 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
711 {
712     switch(btn) {
713     case(ESD_BTN_YES):
714         timestamp_set_type(TS_RELATIVE);
715         recent.gui_time_format  = TS_RELATIVE;
716         cf_timestamp_auto_precision(&cfile);
717         packet_list_queue_draw();
718         break;
719     case(ESD_BTN_NO):
720         break;
721     default:
722         g_assert_not_reached();
723     }
724
725     if (cfile.current_frame) {
726       set_frame_reftime(!cfile.current_frame->flags.ref_time,
727       cfile.current_frame, cfile.current_row);
728     }
729 }
730
731
732 void
733 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
734 {
735     static GtkWidget *reftime_dialog = NULL;
736
737     switch(action){
738     case REFTIME_TOGGLE:
739         if (cfile.current_frame) {
740             if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
741                 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
742                     "%sSwitch to the appropriate Time Display Format?%s\n\n"
743                     "Time References don't work well with the currently selected Time Display Format.\n\n"
744                     "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
745                     simple_dialog_primary_start(), simple_dialog_primary_end());
746                 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
747             } else {
748                 set_frame_reftime(!cfile.current_frame->flags.ref_time,
749                                   cfile.current_frame, cfile.current_row);
750             }
751         }
752         break;
753     case REFTIME_FIND_NEXT:
754         cf_find_packet_time_reference(&cfile, SD_FORWARD);
755         break;
756     case REFTIME_FIND_PREV:
757         cf_find_packet_time_reference(&cfile, SD_BACKWARD);
758         break;
759     }
760 }
761
762 void
763 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
764 {
765     cf_find_packet_marked(&cfile, SD_FORWARD);
766 }
767
768 void
769 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
770 {
771     cf_find_packet_marked(&cfile, SD_BACKWARD);
772 }
773
774 static void
775 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
776 {
777     field_info   *finfo;
778     gchar         len_str[2+10+1+5+1]; /* ", {N} bytes\0",
779                                           N < 4294967296 */
780     gboolean      has_blurb = FALSE;
781     guint         length = 0, byte_len;
782     GtkWidget    *byte_view;
783     const guint8 *byte_data;
784     gint          finfo_length;
785     GtkTreeModel *model;
786     GtkTreeIter   iter;
787
788     /* if nothing is selected */
789     if (!gtk_tree_selection_get_selected(sel, &model, &iter))
790     {
791         /*
792          * Which byte view is displaying the current protocol tree
793          * row's data?
794          */
795         byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
796         if (byte_view == NULL)
797             return; /* none */
798
799         byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
800         if (byte_data == NULL)
801             return; /* none */
802
803         cf_unselect_field(&cfile);
804         packet_hex_print(byte_view, byte_data,
805                          cfile.current_frame, NULL, byte_len);
806         proto_help_menu_modify(sel, &cfile);
807         return;
808     }
809     gtk_tree_model_get(model, &iter, 1, &finfo, -1);
810     if (!finfo) return;
811
812     set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
813
814     byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
815     byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
816     g_assert(byte_data != NULL);
817
818     cfile.finfo_selected = finfo;
819     set_menus_for_selected_tree_row(&cfile);
820
821     if (finfo->hfinfo) {
822         if (finfo->hfinfo->blurb != NULL &&
823             finfo->hfinfo->blurb[0] != '\0') {
824             has_blurb = TRUE;
825             length = (guint) strlen(finfo->hfinfo->blurb);
826         } else {
827             length = (guint) strlen(finfo->hfinfo->name);
828         }
829         finfo_length = finfo->length + finfo->appendix_length;
830
831         if (finfo_length == 0) {
832             len_str[0] = '\0';
833         } else if (finfo_length == 1) {
834             g_strlcpy (len_str, ", 1 byte", sizeof len_str);
835         } else {
836             g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
837         }
838         statusbar_pop_field_msg(); /* get rid of current help msg */
839         if (length) {
840             statusbar_push_field_msg(" %s (%s)%s",
841                     (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
842                     finfo->hfinfo->abbrev, len_str);
843         } else {
844             /*
845              * Don't show anything if the field name is zero-length;
846              * the pseudo-field for text-only items is such
847              * a field, and we don't want "Text (text)" showing up
848              * on the status line if you've selected such a field.
849              *
850              * XXX - there are zero-length fields for which we *do*
851              * want to show the field name.
852              *
853              * XXX - perhaps the name and abbrev field should be null
854              * pointers rather than null strings for that pseudo-field,
855              * but we'd have to add checks for null pointers in some
856              * places if we did that.
857              *
858              * Or perhaps text-only items should have -1 as the field
859              * index, with no pseudo-field being used, but that might
860              * also require special checks for -1 to be added.
861              */
862             statusbar_push_field_msg("%s", "");
863         }
864     }
865     packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
866                      byte_len);
867     proto_help_menu_modify(sel, &cfile);
868 }
869
870 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
871 {
872     if (cfile.edt->tree)
873         collapse_all_tree(cfile.edt->tree, tree_view_gbl);
874 }
875
876 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
877 {
878     if (cfile.edt->tree)
879         expand_all_tree(cfile.edt->tree, tree_view_gbl);
880 }
881
882 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
883 {
884     if (cfile.finfo_selected) {
885         column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
886                                 cfile.finfo_selected->hfinfo->abbrev,0);
887         /* Recreate the packet list according to new preferences */
888         packet_list_recreate ();
889         if (!prefs.gui_use_pref_save) {
890             prefs_main_write();
891         }
892         cfile.columns_changed = FALSE; /* Reset value */
893     }
894 }
895
896 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
897 {
898     GtkTreePath  *path;
899
900     path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
901     if(path) {
902         /* the mouse position is at an entry, expand that one */
903         gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
904         gtk_tree_path_free(path);
905     }
906 }
907
908 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
909 {
910     GtkTreePath  *path;
911
912     path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
913     if(path) {
914         /* the mouse position is at an entry, expand that one */
915
916         tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
917         gtk_tree_path_free(path);
918     }
919 }
920
921 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
922 {
923     static const e_addr_resolve resolv_flags = {
924         TRUE,   /* mac_name */
925         TRUE,   /* network_name */
926         TRUE,   /* transport_name */
927         TRUE,   /* concurrent_dns */
928         TRUE,   /* dns_pkt_addr_resolution */
929         TRUE,   /* use_external_net_name_resolver */
930         FALSE   /* load_hosts_file_from_profile_only */
931     };
932
933     if (cfile.edt->tree) {
934         proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
935     }
936 }
937
938 /* Update main window items based on whether there's a capture in progress. */
939 static void
940 main_set_for_capture_in_progress(gboolean capture_in_progress)
941 {
942     set_menus_for_capture_in_progress(capture_in_progress);
943
944 #ifdef HAVE_LIBPCAP
945     set_toolbar_for_capture_in_progress(capture_in_progress);
946
947     set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
948 #endif
949 }
950
951 /* Update main window items based on whether we have a capture file. */
952 static void
953 main_set_for_capture_file(gboolean have_capture_file_in)
954 {
955     have_capture_file = have_capture_file_in;
956
957     main_widgets_show_or_hide();
958 }
959
960 /* Update main window items based on whether we have captured packets. */
961 static void
962 main_set_for_captured_packets(gboolean have_captured_packets)
963 {
964     set_menus_for_captured_packets(have_captured_packets);
965     set_toolbar_for_captured_packets(have_captured_packets);
966 }
967
968 /* Update main window items based on whether we have a packet history. */
969 void
970 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
971 {
972     set_menus_for_packet_history(back_history, forward_history);
973     set_toolbar_for_packet_history(back_history, forward_history);
974 }
975
976 gboolean
977 main_do_quit(void)
978 {
979     /* get the current geometry, before writing it to disk */
980     main_save_window_geometry(top_level);
981
982     /* write user's recent file to disk
983      * It is no problem to write this file, even if we do not quit */
984     write_profile_recent();
985     write_recent();
986
987     /* XXX - should we check whether the capture file is an
988        unsaved temporary file for a live capture and, if so,
989        pop up a "do you want to exit without saving the capture
990        file?" dialog, and then just return, leaving said dialog
991        box to forcibly quit if the user clicks "OK"?
992
993        If so, note that this should be done in a subroutine that
994        returns TRUE if we do so, and FALSE otherwise, and if it
995        returns TRUE we should return TRUE without nuking anything.
996
997        Note that, if we do that, we might also want to check if
998        an "Update list of packets in real time" capture is in
999        progress and, if so, ask whether they want to terminate
1000        the capture and discard it, and return TRUE, before nuking
1001        any child capture, if they say they don't want to do so. */
1002
1003 #ifdef HAVE_LIBPCAP
1004     /* Nuke any child capture in progress. */
1005     capture_kill_child(&global_capture_session);
1006 #endif
1007
1008     /* Are we in the middle of reading a capture? */
1009     if (cfile.state == FILE_READ_IN_PROGRESS) {
1010         /* Yes, so we can't just close the file and quit, as
1011            that may yank the rug out from under the read in
1012            progress; instead, just set the state to
1013            "FILE_READ_ABORTED" and return - the code doing the read
1014            will check for that and, if it sees that, will clean
1015            up and quit. */
1016         cfile.state = FILE_READ_ABORTED;
1017
1018         /* Say that the window should *not* be deleted;
1019            that'll be done by the code that cleans up. */
1020         return TRUE;
1021     } else {
1022         /* Close any capture file we have open; on some OSes, you
1023            can't unlink a temporary capture file if you have it
1024            open.
1025            "cf_close()" will unlink it after closing it if
1026            it's a temporary file.
1027
1028            We do this here, rather than after the main loop returns,
1029            as, after the main loop returns, the main window may have
1030            been destroyed (if this is called due to a "destroy"
1031            even on the main window rather than due to the user
1032            selecting a menu item), and there may be a crash
1033            or other problem when "cf_close()" tries to
1034            clean up stuff in the main window.
1035
1036            XXX - is there a better place to put this?
1037            Or should we have a routine that *just* closes the
1038            capture file, and doesn't do anything with the UI,
1039            which we'd call here, and another routine that
1040            calls that routine and also cleans up the UI, which
1041            we'd call elsewhere? */
1042         cf_close(&cfile);
1043
1044         /* Exit by leaving the main loop, so that any quit functions
1045            we registered get called. */
1046         gtk_main_quit();
1047
1048         /* Say that the window should be deleted. */
1049         return FALSE;
1050     }
1051 }
1052
1053 static gboolean
1054 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1055 {
1056     /* If we're in the middle of stopping a capture, don't do anything;
1057        the user can try deleting the window after the capture stops. */
1058     if (capture_stopping)
1059         return TRUE;
1060
1061     /* If there's unsaved data, let the user save it first.
1062        If they cancel out of it, don't quit. */
1063     if (do_file_close(&cfile, TRUE, " before quitting"))
1064         return main_do_quit();
1065     else
1066         return TRUE; /* will this keep the window from being deleted? */
1067 }
1068
1069
1070 static void
1071 main_pane_load_window_geometry(void)
1072 {
1073     if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1074         gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1075     if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1076         gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1077     }
1078 }
1079
1080
1081 static void
1082 main_load_window_geometry(GtkWidget *widget)
1083 {
1084     window_geometry_t geom;
1085
1086     geom.set_pos        = prefs.gui_geometry_save_position;
1087     geom.x              = recent.gui_geometry_main_x;
1088     geom.y              = recent.gui_geometry_main_y;
1089     geom.set_size       = prefs.gui_geometry_save_size;
1090     if (recent.gui_geometry_main_width > 0 &&
1091         recent.gui_geometry_main_height > 0) {
1092         geom.width          = recent.gui_geometry_main_width;
1093         geom.height         = recent.gui_geometry_main_height;
1094         geom.set_maximized  = prefs.gui_geometry_save_maximized;
1095     } else {
1096         /* We assume this means the width and height weren't set in
1097            the "recent" file (or that there is no "recent" file),
1098            and weren't set to a default value, so we don't set the
1099            size.  (The "recent" file code rejects non-positive width
1100            and height values.) */
1101        geom.set_size = FALSE;
1102     }
1103     geom.maximized      = recent.gui_geometry_main_maximized;
1104
1105     window_set_geometry(widget, &geom);
1106
1107     main_pane_load_window_geometry();
1108     statusbar_load_window_geometry();
1109 }
1110
1111
1112 static void
1113 main_save_window_geometry(GtkWidget *widget)
1114 {
1115     window_geometry_t geom;
1116
1117     window_get_geometry(widget, &geom);
1118
1119     if (prefs.gui_geometry_save_position) {
1120         recent.gui_geometry_main_x = geom.x;
1121         recent.gui_geometry_main_y = geom.y;
1122     }
1123
1124     if (prefs.gui_geometry_save_size) {
1125         recent.gui_geometry_main_width  = geom.width;
1126         recent.gui_geometry_main_height = geom.height;
1127     }
1128
1129     if(prefs.gui_geometry_save_maximized) {
1130         recent.gui_geometry_main_maximized = geom.maximized;
1131     }
1132
1133     recent.gui_geometry_main_upper_pane     = gtk_paned_get_position(GTK_PANED(main_first_pane));
1134     recent.gui_geometry_main_lower_pane     = gtk_paned_get_position(GTK_PANED(main_second_pane));
1135     statusbar_save_window_geometry();
1136 }
1137
1138 void
1139 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1140 {
1141     /* If there's unsaved data, let the user save it first. */
1142     if (do_file_close(&cfile, TRUE, " before quitting"))
1143         main_do_quit();
1144 }
1145
1146 static void
1147 print_usage(gboolean for_help_option) {
1148
1149     FILE *output;
1150
1151 #ifdef _WIN32
1152     create_console();
1153 #endif
1154
1155     if (for_help_option) {
1156         output = stdout;
1157         fprintf(output, "Wireshark %s\n"
1158             "Interactively dump and analyze network traffic.\n"
1159             "See https://www.wireshark.org for more information.\n",
1160             get_ws_vcs_version_info());
1161     } else {
1162         output = stderr;
1163     }
1164     fprintf(output, "\n");
1165     fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1166     fprintf(output, "\n");
1167
1168 #ifdef HAVE_LIBPCAP
1169     fprintf(output, "Capture interface:\n");
1170     fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
1171     fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
1172     fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
1173     fprintf(output, "  -p                       don't capture in promiscuous mode\n");
1174     fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
1175     fprintf(output, "  -S                       update packet display when new packets are captured\n");
1176     fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
1177 #ifdef HAVE_PCAP_CREATE
1178     fprintf(output, "  -I                       capture in monitor mode, if available\n");
1179 #endif
1180 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
1181     fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1182 #endif
1183     fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
1184     fprintf(output, "  -D                       print list of interfaces and exit\n");
1185     fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
1186     fprintf(output, "\n");
1187     fprintf(output, "Capture stop conditions:\n");
1188     fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
1189     fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
1190     fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
1191     fprintf(output, "                              files:NUM - stop after NUM files\n");
1192     /*fprintf(output, "\n");*/
1193     fprintf(output, "Capture output:\n");
1194     fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1195     fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
1196     fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
1197 #endif  /* HAVE_LIBPCAP */
1198 #ifdef HAVE_PCAP_REMOTE
1199     fprintf(output, "RPCAP options:\n");
1200     fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
1201 #endif
1202     /*fprintf(output, "\n");*/
1203     fprintf(output, "Input file:\n");
1204     fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
1205
1206     fprintf(output, "\n");
1207     fprintf(output, "Processing:\n");
1208     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
1209     fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
1210     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtCd\"\n");
1211     fprintf(output, "  --disable-protocol <proto_name>\n");
1212     fprintf(output, "                           disable dissection of proto_name\n");
1213     fprintf(output, "  --enable-heuristic <short_name>\n");
1214     fprintf(output, "                           enable dissection of heuristic protocol\n");
1215     fprintf(output, "  --disable-heuristic <short_name>\n");
1216     fprintf(output, "                           disable dissection of heuristic protocol\n");
1217
1218     fprintf(output, "\n");
1219     fprintf(output, "User interface:\n");
1220     fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
1221     fprintf(output, "  -Y <display filter>      start with the given display filter\n");
1222     fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
1223     fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
1224     fprintf(output, "                           filter\n");
1225     fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
1226     fprintf(output, "  -m <font>                set the font name used for most text\n");
1227     fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
1228     fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
1229     fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
1230     fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
1231
1232     fprintf(output, "\n");
1233     fprintf(output, "Output:\n");
1234     fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
1235
1236     fprintf(output, "\n");
1237     fprintf(output, "Miscellaneous:\n");
1238     fprintf(output, "  -h                       display this help and exit\n");
1239     fprintf(output, "  -v                       display version info and exit\n");
1240     fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
1241     fprintf(output, "                           persdata:path - personal data files\n");
1242     fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
1243     fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
1244 #ifndef _WIN32
1245     fprintf(output, "  --display=DISPLAY        X display to use\n");
1246 #endif
1247
1248 #ifdef _WIN32
1249     destroy_console();
1250 #endif
1251 }
1252
1253 /*
1254  * Report an error in command-line arguments.
1255  * Creates a console on Windows.
1256  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1257  * terminal isn't the standard error?
1258  */
1259 static void
1260 wireshark_cmdarg_err(const char *fmt, va_list ap)
1261 {
1262 #ifdef _WIN32
1263     create_console();
1264 #endif
1265     fprintf(stderr, "wireshark: ");
1266     vfprintf(stderr, fmt, ap);
1267     fprintf(stderr, "\n");
1268 }
1269
1270 /*
1271  * Report additional information for an error in command-line arguments.
1272  * Creates a console on Windows.
1273  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1274  * terminal isn't the standard error?
1275  */
1276 static void
1277 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1278 {
1279 #ifdef _WIN32
1280     create_console();
1281 #endif
1282     vfprintf(stderr, fmt, ap);
1283     fprintf(stderr, "\n");
1284 }
1285
1286 /*
1287    Once every 3 seconds we get a callback here which we use to update
1288    the tap extensions.
1289  */
1290 static gboolean
1291 tap_update_cb(gpointer data _U_)
1292 {
1293     draw_tap_listeners(FALSE);
1294     return TRUE;
1295 }
1296
1297 /*
1298  * Periodically process outstanding hostname lookups. If we have new items,
1299  * redraw the packet list and tree view.
1300  */
1301
1302 static gboolean
1303 resolv_update_cb(gpointer data _U_)
1304 {
1305     /* Anything new show up? */
1306     if (host_name_lookup_process()) {
1307         if (gtk_widget_get_window(pkt_scrollw))
1308             gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1309         if (gtk_widget_get_window(tv_scrollw))
1310             gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1311     }
1312
1313     /* Always check. Even if we don't do async lookups we could still get
1314         passive updates, e.g. from DNS packets. */
1315     return TRUE;
1316 }
1317
1318
1319 /* Update various parts of the main window for a capture file "unsaved
1320    changes" change - update the title to reflect whether there are
1321    unsaved changes or not, and update the menus and toolbar to
1322    enable or disable the "Save" operation. */
1323 void
1324 main_update_for_unsaved_changes(capture_file *cf)
1325 {
1326     set_titlebar_for_capture_file(cf);
1327     set_menus_for_capture_file(cf);
1328     set_toolbar_for_capture_file(cf);
1329 }
1330
1331 #ifdef HAVE_LIBPCAP
1332 void
1333 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1334 {
1335     /* Update menubar and toolbar */
1336     menu_auto_scroll_live_changed(auto_scroll_live_in);
1337     toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1338
1339     /* change auto scroll state */
1340     auto_scroll_live  = auto_scroll_live_in;
1341 }
1342 #endif
1343
1344 void
1345 main_colorize_changed(gboolean packet_list_colorize)
1346 {
1347     /* Update menubar and toolbar */
1348     menu_colorize_changed(packet_list_colorize);
1349     toolbar_colorize_changed(packet_list_colorize);
1350
1351     /* change colorization */
1352     if(packet_list_colorize != recent.packet_list_colorize) {
1353         recent.packet_list_colorize = packet_list_colorize;
1354         color_filters_enable(packet_list_colorize);
1355         packet_list_colorize_packets();
1356     }
1357 }
1358
1359 static GtkWidget           *close_dlg = NULL;
1360
1361 static void
1362 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1363 {
1364     recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1365 }
1366
1367 #ifdef _WIN32
1368 static void
1369 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1370 {
1371     recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1372 }
1373 #endif
1374
1375 static void
1376 main_cf_cb_file_closing(capture_file *cf)
1377 {
1378     /* if we have more than 10000 packets, show a splash screen while closing */
1379     /* XXX - don't know a better way to decide whether to show or not,
1380      * as most of the time is spend in various calls that destroy various
1381      * data structures, so it wouldn't be easy to use a progress bar,
1382      * rather than, say, a progress spinner, here! */
1383     if(cf->count > 10000) {
1384         close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1385                                   "%sClosing file!%s\n\nPlease wait ...",
1386                                   simple_dialog_primary_start(),
1387                                   simple_dialog_primary_end());
1388         gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1389     }
1390     /* Clear maunally resolved addresses */
1391     manually_resolve_cleanup();
1392     /* Destroy all windows that refer to the
1393        capture file we're closing. */
1394     destroy_packet_wins();
1395
1396     /* Update the titlebar to reflect the lack of a capture file. */
1397     set_titlebar_for_capture_file(NULL);
1398
1399     /* Disable all menu and toolbar items that make sense only if
1400        you have a capture. */
1401     set_menus_for_capture_file(NULL);
1402     set_toolbar_for_capture_file(NULL);
1403     main_set_for_captured_packets(FALSE);
1404     set_menus_for_selected_packet(cf);
1405     main_set_for_capture_in_progress(FALSE);
1406     set_capture_if_dialog_for_capture_in_progress(FALSE);
1407     set_menus_for_selected_tree_row(cf);
1408
1409     /* Set up main window for no capture file. */
1410     main_set_for_capture_file(FALSE);
1411
1412     main_window_update();
1413
1414 }
1415
1416 static void
1417 main_cf_cb_file_closed(capture_file *cf _U_)
1418 {
1419     if(close_dlg != NULL) {
1420         splash_destroy(close_dlg);
1421         close_dlg = NULL;
1422     }
1423 }
1424
1425
1426 static void
1427 main_cf_cb_file_read_started(capture_file *cf _U_)
1428 {
1429     tap_param_dlg_update();
1430
1431     /* Set up main window for a capture file. */
1432     main_set_for_capture_file(TRUE);
1433 }
1434
1435 static void
1436 main_cf_cb_file_read_finished(capture_file *cf)
1437 {
1438     gchar *dir_path;
1439
1440     if (!cf->is_tempfile && cf->filename) {
1441         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1442         add_menu_recent_capture_file(cf->filename);
1443
1444         /* Remember folder for next Open dialog and save it in recent */
1445         dir_path = get_dirname(g_strdup(cf->filename));
1446         set_last_open_dir(dir_path);
1447         g_free(dir_path);
1448     }
1449
1450     /* Update the appropriate parts of the main window. */
1451     main_update_for_unsaved_changes(cf);
1452
1453     /* Enable menu items that make sense if you have some captured packets. */
1454     main_set_for_captured_packets(TRUE);
1455 }
1456
1457 static void
1458 main_cf_cb_file_rescan_finished(capture_file *cf)
1459 {
1460     gchar *dir_path;
1461
1462     if (!cf->is_tempfile && cf->filename) {
1463         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1464         add_menu_recent_capture_file(cf->filename);
1465
1466         /* Remember folder for next Open dialog and save it in recent */
1467         dir_path = get_dirname(g_strdup(cf->filename));
1468         set_last_open_dir(dir_path);
1469         g_free(dir_path);
1470     }
1471
1472     /* Update the appropriate parts of the main window. */
1473     main_update_for_unsaved_changes(cf);
1474 }
1475
1476 #ifdef HAVE_LIBPCAP
1477 static GList *icon_list_create(
1478 #ifdef HAVE_GRESOURCE
1479     const gchar *icon16_path,
1480     const gchar *icon32_path,
1481     const gchar *icon48_path,
1482     const gchar *icon64_path)
1483 #else
1484     const guint8 *icon16_pb,
1485     const guint8 *icon32_pb,
1486     const guint8 *icon48_pb,
1487     const guint8 *icon64_pb)
1488 #endif
1489 {
1490     GList *icon_list = NULL;
1491     GdkPixbuf *pixbuf16 = NULL;
1492     GdkPixbuf *pixbuf32 = NULL;
1493     GdkPixbuf *pixbuf48 = NULL;
1494     GdkPixbuf *pixbuf64 = NULL;
1495
1496 #ifdef HAVE_GRESOURCE
1497     if (icon16_path != NULL)
1498         pixbuf16 = ws_gdk_pixbuf_new_from_resource(icon16_path);
1499     if (icon32_path != NULL)
1500         pixbuf32 = ws_gdk_pixbuf_new_from_resource(icon32_path);
1501     if (icon48_path != NULL)
1502         pixbuf48 = ws_gdk_pixbuf_new_from_resource(icon48_path);
1503     if (icon64_path != NULL)
1504         pixbuf64 = ws_gdk_pixbuf_new_from_resource(icon64_path);
1505 #else
1506     if (icon16_pb != NULL)
1507         pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1508     if (icon32_pb != NULL)
1509         pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1510     if (icon48_pb != NULL)
1511         pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1512     if (icon64_pb != NULL)
1513         pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1514 #endif
1515
1516     if (pixbuf16 != NULL)
1517         icon_list = g_list_append(icon_list, pixbuf16);
1518     if (pixbuf32 != NULL)
1519         icon_list = g_list_append(icon_list, pixbuf32);
1520     if (pixbuf48 != NULL)
1521         icon_list = g_list_append(icon_list, pixbuf48);
1522     if (pixbuf64 != NULL)
1523         icon_list = g_list_append(icon_list, pixbuf64);
1524
1525     return icon_list;
1526 }
1527
1528 static void
1529 main_capture_cb_capture_prepared(capture_session *cap_session)
1530 {
1531     static GList *icon_list = NULL;
1532
1533     set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1534
1535     if(icon_list == NULL) {
1536 #ifdef HAVE_GRESOURCE
1537         icon_list = icon_list_create("/org/wireshark/image/wsiconcap16.png",
1538                                         "/org/wireshark/image/wsiconcap32.png",
1539                                         "/org/wireshark/image/wsiconcap48.png",
1540                                         "/org/wireshark/image/wsiconcap64.png");
1541 #else
1542         icon_list = icon_list_create(wsiconcap_16_pb_data,
1543                                         wsiconcap_32_pb_data,
1544                                         wsiconcap_48_pb_data,
1545                                         wsiconcap_64_pb_data);
1546 #endif
1547     }
1548     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1549
1550     /* Disable menu items that make no sense if you're currently running
1551        a capture. */
1552     main_set_for_capture_in_progress(TRUE);
1553     set_capture_if_dialog_for_capture_in_progress(TRUE);
1554
1555     /* Don't set up main window for a capture file. */
1556     main_set_for_capture_file(FALSE);
1557 }
1558
1559 static void
1560 main_capture_cb_capture_update_started(capture_session *cap_session)
1561 {
1562     /* We've done this in "prepared" above, but it will be cleared while
1563        switching to the next multiple file. */
1564     set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1565
1566     main_set_for_capture_in_progress(TRUE);
1567     set_capture_if_dialog_for_capture_in_progress(TRUE);
1568
1569     /* Enable menu items that make sense if you have some captured
1570        packets (yes, I know, we don't have any *yet*). */
1571     main_set_for_captured_packets(TRUE);
1572
1573     /* Set up main window for a capture file. */
1574     main_set_for_capture_file(TRUE);
1575 }
1576
1577 static void
1578 main_capture_cb_capture_update_finished(capture_session *cap_session)
1579 {
1580     capture_file *cf = (capture_file *)cap_session->cf;
1581     static GList *icon_list = NULL;
1582
1583     /* The capture isn't stopping any more - it's stopped. */
1584     capture_stopping = FALSE;
1585
1586     if (!cf->is_tempfile && cf->filename) {
1587         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1588         add_menu_recent_capture_file(cf->filename);
1589     }
1590
1591     /* Enable menu items that make sense if you're not currently running
1592      a capture. */
1593     main_set_for_capture_in_progress(FALSE);
1594     set_capture_if_dialog_for_capture_in_progress(FALSE);
1595
1596     /* Update the main window as appropriate. This has to occur AFTER
1597      * main_set_for_capture_in_progress() or else some of the menus are
1598      * incorrectly disabled (see bug
1599      * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1600     main_update_for_unsaved_changes(cf);
1601
1602     /* Set up main window for a capture file. */
1603     main_set_for_capture_file(TRUE);
1604
1605     if(icon_list == NULL) {
1606 #ifdef HAVE_GRESOURCE
1607         icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1608                                         "/org/wireshark/image/wsicon32.png",
1609                                         "/org/wireshark/image/wsicon48.png",
1610                                         "/org/wireshark/image/wsicon64.png");
1611 #else
1612         icon_list = icon_list_create(wsicon_16_pb_data,
1613                                         wsicon_32_pb_data,
1614                                         wsicon_48_pb_data,
1615                                         wsicon_64_pb_data);
1616 #endif
1617     }
1618     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1619
1620     if(global_capture_opts.quit_after_cap) {
1621         /* command line asked us to quit after the capture */
1622         /* don't pop up a dialog to ask for unsaved files etc. */
1623         main_do_quit();
1624     }
1625 }
1626
1627 static void
1628 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1629 {
1630     /* Don't set up main window for a capture file. */
1631     main_set_for_capture_file(FALSE);
1632 }
1633
1634 static void
1635 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1636 {
1637 #if 0
1638     capture_file *cf = (capture_file *)cap_session->cf;
1639 #endif
1640     static GList *icon_list = NULL;
1641
1642     /* The capture isn't stopping any more - it's stopped. */
1643     capture_stopping = FALSE;
1644
1645     /*set_titlebar_for_capture_file(cf);*/
1646
1647     /* Enable menu items that make sense if you're not currently running
1648      a capture. */
1649     main_set_for_capture_in_progress(FALSE);
1650     set_capture_if_dialog_for_capture_in_progress(FALSE);
1651
1652     /* Restore the standard title bar message */
1653     /* (just in case we have trouble opening the capture file). */
1654     set_titlebar_for_capture_file(NULL);
1655
1656     if(icon_list == NULL) {
1657 #ifdef HAVE_GRESOURCE
1658         icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1659                                         "/org/wireshark/image/wsicon32.png",
1660                                         "/org/wireshark/image/wsicon48.png",
1661                                         "/org/wireshark/image/wsicon64.png");
1662 #else
1663         icon_list = icon_list_create(wsicon_16_pb_data,
1664                                         wsicon_32_pb_data,
1665                                         wsicon_48_pb_data,
1666                                         wsicon_64_pb_data);
1667 #endif
1668     }
1669     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1670
1671     /* We don't have loaded the capture file, this will be done later.
1672      * For now we still have simply a blank screen. */
1673
1674     if(global_capture_opts.quit_after_cap) {
1675         /* command line asked us to quit after the capture */
1676         /* don't pop up a dialog to ask for unsaved files etc. */
1677         main_do_quit();
1678     }
1679 }
1680
1681 static void
1682 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1683 {
1684     capture_stopping = TRUE;
1685     set_menus_for_capture_stopping();
1686 #ifdef HAVE_LIBPCAP
1687     set_toolbar_for_capture_stopping();
1688
1689     set_capture_if_dialog_for_capture_stopping();
1690 #endif
1691 }
1692
1693 static void
1694 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1695 {
1696     static GList *icon_list = NULL;
1697
1698     /* Capture isn't stopping any more. */
1699     capture_stopping = FALSE;
1700
1701     /* the capture failed before the first packet was captured
1702        reset title, menus and icon */
1703     set_titlebar_for_capture_file(NULL);
1704
1705     main_set_for_capture_in_progress(FALSE);
1706     set_capture_if_dialog_for_capture_in_progress(FALSE);
1707
1708     main_set_for_capture_file(FALSE);
1709
1710     if(icon_list == NULL) {
1711 #ifdef HAVE_GRESOURCE
1712         icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1713                                         "/org/wireshark/image/wsicon32.png",
1714                                         "/org/wireshark/image/wsicon48.png",
1715                                         "/org/wireshark/image/wsicon64.png");
1716 #else
1717         icon_list = icon_list_create(wsicon_16_pb_data,
1718                                         wsicon_32_pb_data,
1719                                         wsicon_48_pb_data,
1720                                         wsicon_64_pb_data);
1721 #endif
1722     }
1723     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1724
1725
1726     if(global_capture_opts.quit_after_cap) {
1727         /* command line asked us to quit after the capture */
1728         /* don't pop up a dialog to ask for unsaved files etc. */
1729         main_do_quit();
1730     }
1731 }
1732 #endif  /* HAVE_LIBPCAP */
1733
1734 static void
1735 main_cf_cb_packet_selected(gpointer data)
1736 {
1737     capture_file *cf = (capture_file *)data;
1738
1739     /* Display the GUI protocol tree and packet bytes.
1740       XXX - why do we dump core if we call "proto_tree_draw()"
1741       before calling "add_byte_views()"? */
1742     add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1743     proto_tree_draw(cf->edt->tree, tree_view_gbl);
1744
1745     /* Note: Both string and hex value searches in the packet data produce a non-zero
1746        search_pos if successful */
1747     if(cf->search_in_progress &&
1748       (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1749         highlight_field(cf->edt->tvb, cf->search_pos,
1750                         (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1751     }
1752
1753     /* A packet is selected. */
1754     set_menus_for_selected_packet(cf);
1755 }
1756
1757 static void
1758 main_cf_cb_packet_unselected(capture_file *cf)
1759 {
1760     /* No packet is being displayed; clear the hex dump pane by getting
1761        rid of all the byte views. */
1762     while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1763         gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1764
1765     /* Add a placeholder byte view so that there's at least something
1766        displayed in the byte view notebook. */
1767     add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1768
1769     /* And clear the protocol tree display as well. */
1770     proto_tree_draw(NULL, tree_view_gbl);
1771
1772     /* No packet is selected. */
1773     set_menus_for_selected_packet(cf);
1774 }
1775
1776 static void
1777 main_cf_cb_field_unselected(capture_file *cf)
1778 {
1779     set_menus_for_selected_tree_row(cf);
1780 }
1781
1782 static void
1783 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1784 {
1785     capture_file *cf = (capture_file *)data;
1786     switch(event) {
1787     case(cf_cb_file_opened):
1788         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1789         fileset_file_opened(cf);
1790         break;
1791     case(cf_cb_file_closing):
1792         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1793         main_cf_cb_file_closing(cf);
1794         break;
1795     case(cf_cb_file_closed):
1796         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1797         main_cf_cb_file_closed(cf);
1798         fileset_file_closed();
1799         break;
1800     case(cf_cb_file_read_started):
1801         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1802         main_cf_cb_file_read_started(cf);
1803         break;
1804     case(cf_cb_file_read_finished):
1805         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1806         main_cf_cb_file_read_finished(cf);
1807         break;
1808     case(cf_cb_file_reload_started):
1809         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1810         main_cf_cb_file_read_started(cf);
1811         break;
1812     case(cf_cb_file_reload_finished):
1813         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1814         main_cf_cb_file_read_finished(cf);
1815         break;
1816     case(cf_cb_file_rescan_started):
1817         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1818         break;
1819     case(cf_cb_file_rescan_finished):
1820         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1821         main_cf_cb_file_rescan_finished(cf);
1822         break;
1823     case(cf_cb_file_retap_started):
1824         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap started");
1825         break;
1826     case(cf_cb_file_retap_finished):
1827         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap finished");
1828         break;
1829     case(cf_cb_file_fast_save_finished):
1830         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1831         main_cf_cb_file_rescan_finished(cf);
1832         break;
1833     case(cf_cb_packet_selected):
1834         main_cf_cb_packet_selected(cf);
1835         break;
1836     case(cf_cb_packet_unselected):
1837         main_cf_cb_packet_unselected(cf);
1838         break;
1839     case(cf_cb_field_unselected):
1840         main_cf_cb_field_unselected(cf);
1841         break;
1842     case(cf_cb_file_save_started):
1843         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1844         break;
1845     case(cf_cb_file_save_finished):
1846         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1847         break;
1848     case(cf_cb_file_save_failed):
1849         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1850         break;
1851     case(cf_cb_file_save_stopped):
1852         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1853         break;
1854     case(cf_cb_file_export_specified_packets_started):
1855         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1856         break;
1857     case(cf_cb_file_export_specified_packets_finished):
1858         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1859         break;
1860     case(cf_cb_file_export_specified_packets_failed):
1861         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1862         break;
1863     case(cf_cb_file_export_specified_packets_stopped):
1864         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1865         break;
1866     default:
1867         g_warning("main_cf_callback: event %u unknown", event);
1868         g_assert_not_reached();
1869     }
1870 }
1871
1872 #ifdef HAVE_LIBPCAP
1873 static void
1874 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1875 {
1876 #ifdef HAVE_GTKOSXAPPLICATION
1877     GtkosxApplication *theApp;
1878 #endif
1879     switch(event) {
1880     case(capture_cb_capture_prepared):
1881         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1882         main_capture_cb_capture_prepared(cap_session);
1883         break;
1884     case(capture_cb_capture_update_started):
1885         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1886         main_capture_cb_capture_update_started(cap_session);
1887 #ifdef HAVE_GTKOSXAPPLICATION
1888         theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1889 #ifdef HAVE_GRESOURCE
1890         gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon48.png"));
1891 #else
1892         gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_48_pb_data, FALSE, NULL));
1893 #endif
1894 #endif
1895         break;
1896     case(capture_cb_capture_update_continue):
1897         /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1898         break;
1899     case(capture_cb_capture_update_finished):
1900         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1901         main_capture_cb_capture_update_finished(cap_session);
1902         break;
1903     case(capture_cb_capture_fixed_started):
1904         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1905         main_capture_cb_capture_fixed_started(cap_session);
1906         break;
1907     case(capture_cb_capture_fixed_continue):
1908         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1909         break;
1910     case(capture_cb_capture_fixed_finished):
1911         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1912         main_capture_cb_capture_fixed_finished(cap_session);
1913         break;
1914     case(capture_cb_capture_stopping):
1915         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1916         /* Beware: this state won't be called, if the capture child
1917          * closes the capturing on its own! */
1918 #ifdef HAVE_GTKOSXAPPLICATION
1919         theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1920 #ifdef HAVE_GRESOURCE
1921         gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
1922 #else
1923         gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1924 #endif
1925 #endif
1926         main_capture_cb_capture_stopping(cap_session);
1927         break;
1928     case(capture_cb_capture_failed):
1929         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1930         main_capture_cb_capture_failed(cap_session);
1931         break;
1932     default:
1933         g_warning("main_capture_callback: event %u unknown", event);
1934         g_assert_not_reached();
1935     }
1936 }
1937 #endif
1938
1939 static void
1940 get_wireshark_gtk_compiled_info(GString *str)
1941 {
1942     g_string_append(str, "with ");
1943     g_string_append_printf(str,
1944 #ifdef GTK_MAJOR_VERSION
1945                            "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1946                            GTK_MICRO_VERSION);
1947 #else
1948                            "GTK+ (version unknown)");
1949 #endif
1950
1951     /* Cairo */
1952     g_string_append(str, ", with Cairo ");
1953     g_string_append(str, CAIRO_VERSION_STRING);
1954
1955     /* Pango */
1956     g_string_append(str, ", with Pango ");
1957     g_string_append(str, PANGO_VERSION_STRING);
1958
1959     /* Capture libraries */
1960     g_string_append(str, ", ");
1961     get_compiled_caplibs_version(str);
1962
1963     /* LIBZ */
1964     g_string_append(str, ", ");
1965 #ifdef HAVE_LIBZ
1966     g_string_append(str, "with libz ");
1967 #ifdef ZLIB_VERSION
1968     g_string_append(str, ZLIB_VERSION);
1969 #else /* ZLIB_VERSION */
1970     g_string_append(str, "(version unknown)");
1971 #endif /* ZLIB_VERSION */
1972 #else /* HAVE_LIBZ */
1973     g_string_append(str, "without libz");
1974 #endif /* HAVE_LIBZ */
1975 }
1976
1977 static void
1978 get_gui_compiled_info(GString *str)
1979 {
1980     epan_get_compiled_version_info(str);
1981
1982     g_string_append(str, ", ");
1983 #ifdef HAVE_LIBPORTAUDIO
1984 #ifdef PORTAUDIO_API_1
1985     g_string_append(str, "with PortAudio <= V18");
1986 #else /* PORTAUDIO_API_1 */
1987     g_string_append(str, "with ");
1988     g_string_append(str, Pa_GetVersionText());
1989 #endif /* PORTAUDIO_API_1 */
1990 #else /* HAVE_LIBPORTAUDIO */
1991     g_string_append(str, "without PortAudio");
1992 #endif /* HAVE_LIBPORTAUDIO */
1993
1994     g_string_append(str, ", ");
1995 #ifdef HAVE_AIRPCAP
1996     get_compiled_airpcap_version(str);
1997 #else
1998     g_string_append(str, "without AirPcap");
1999 #endif
2000 }
2001
2002 static void
2003 get_wireshark_runtime_info(GString *str)
2004 {
2005 #ifdef HAVE_LIBPCAP
2006     /* Capture libraries */
2007     g_string_append(str, ", ");
2008     get_runtime_caplibs_version(str);
2009 #endif
2010
2011     /* zlib */
2012 #if defined(HAVE_LIBZ) && !defined(_WIN32)
2013     g_string_append_printf(str, ", with libz %s", zlibVersion());
2014 #endif
2015
2016     /* stuff used by libwireshark */
2017     epan_get_runtime_version_info(str);
2018
2019 #ifdef HAVE_AIRPCAP
2020     g_string_append(str, ", ");
2021     get_runtime_airpcap_version(str);
2022 #endif
2023
2024     if(u3_active()) {
2025         g_string_append(str, ", ");
2026         u3_runtime_info(str);
2027     }
2028 }
2029
2030 static e_prefs *
2031 read_configuration_files(char **gdp_path, char **dp_path)
2032 {
2033     int                  gpf_open_errno, gpf_read_errno;
2034     int                  cf_open_errno, df_open_errno;
2035     int                  gdp_open_errno, gdp_read_errno;
2036     int                  dp_open_errno, dp_read_errno;
2037     char                *gpf_path, *pf_path;
2038     char                *cf_path, *df_path;
2039     int                  pf_open_errno, pf_read_errno;
2040     e_prefs             *prefs_p;
2041
2042     /* load the decode as entries of this profile */
2043     load_decode_as_entries();
2044
2045     /* Read the preference files. */
2046     prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2047                          &pf_open_errno, &pf_read_errno, &pf_path);
2048
2049     if (gpf_path != NULL) {
2050         if (gpf_open_errno != 0) {
2051             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2052                           "Could not open global preferences file\n\"%s\": %s.",
2053                           gpf_path, g_strerror(gpf_open_errno));
2054         }
2055         if (gpf_read_errno != 0) {
2056             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2057                           "I/O error reading global preferences file\n\"%s\": %s.",
2058                           gpf_path, g_strerror(gpf_read_errno));
2059         }
2060     }
2061     if (pf_path != NULL) {
2062         if (pf_open_errno != 0) {
2063             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2064                           "Could not open your preferences file\n\"%s\": %s.",
2065                           pf_path, g_strerror(pf_open_errno));
2066         }
2067         if (pf_read_errno != 0) {
2068             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2069                           "I/O error reading your preferences file\n\"%s\": %s.",
2070                           pf_path, g_strerror(pf_read_errno));
2071         }
2072         g_free(pf_path);
2073         pf_path = NULL;
2074     }
2075
2076 #ifdef _WIN32
2077     /* if the user wants a console to be always there, well, we should open one for him */
2078     if (prefs_p->gui_console_open == console_open_always) {
2079         create_console();
2080     }
2081 #endif
2082
2083     /* Read the capture filter file. */
2084     read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2085     if (cf_path != NULL) {
2086         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2087                       "Could not open your capture filter file\n\"%s\": %s.",
2088                       cf_path, g_strerror(cf_open_errno));
2089         g_free(cf_path);
2090     }
2091
2092     /* Read the display filter file. */
2093     read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2094     if (df_path != NULL) {
2095         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2096                       "Could not open your display filter file\n\"%s\": %s.",
2097                       df_path, g_strerror(df_open_errno));
2098         g_free(df_path);
2099     }
2100
2101     /* Read the disabled protocols file. */
2102     read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2103                               dp_path, &dp_open_errno, &dp_read_errno);
2104     read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2105                               dp_path, &dp_open_errno, &dp_read_errno);
2106     if (*gdp_path != NULL) {
2107         if (gdp_open_errno != 0) {
2108             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2109                           "Could not open global disabled protocols file\n\"%s\": %s.",
2110                           *gdp_path, g_strerror(gdp_open_errno));
2111         }
2112         if (gdp_read_errno != 0) {
2113             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2114                           "I/O error reading global disabled protocols file\n\"%s\": %s.",
2115                           *gdp_path, g_strerror(gdp_read_errno));
2116         }
2117         g_free(*gdp_path);
2118         *gdp_path = NULL;
2119     }
2120     if (*dp_path != NULL) {
2121         if (dp_open_errno != 0) {
2122             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2123                           "Could not open your disabled protocols file\n\"%s\": %s.",
2124                           *dp_path, g_strerror(dp_open_errno));
2125         }
2126         if (dp_read_errno != 0) {
2127             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2128                           "I/O error reading your disabled protocols file\n\"%s\": %s.",
2129                           *dp_path, g_strerror(dp_read_errno));
2130         }
2131         g_free(*dp_path);
2132         *dp_path = NULL;
2133     }
2134
2135     return prefs_p;
2136 }
2137
2138 /*  Check if there's something important to tell the user during startup.
2139  *  We want to do this *after* showing the main window so that any windows
2140  *  we pop up will be above the main window.
2141  */
2142 static void
2143 #ifdef _WIN32
2144 check_and_warn_user_startup(gchar *cf_name)
2145 #else
2146 check_and_warn_user_startup(gchar *cf_name _U_)
2147 #endif
2148 {
2149     gchar               *cur_user, *cur_group;
2150     gpointer             priv_warning_dialog;
2151
2152     /* Tell the user not to run as root. */
2153     if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2154         cur_user = get_cur_username();
2155         cur_group = get_cur_groupname();
2156         priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2157         "Running as user \"%s\" and group \"%s\".\n"
2158         "This could be dangerous.\n\n"
2159         "If you're running Wireshark this way in order to perform live capture, "
2160         "you may want to be aware that there is a better way documented at\n"
2161         "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2162         g_free(cur_user);
2163         g_free(cur_group);
2164         simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2165         simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2166     }
2167
2168 #ifdef _WIN32
2169     /* Warn the user if npf.sys isn't loaded. */
2170     if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2171         priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2172         "The NPF driver isn't running.  You may have trouble\n"
2173         "capturing or listing interfaces.");
2174         simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2175         simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2176     }
2177 #endif
2178
2179 }
2180
2181 /* And now our feature presentation... [ fade to music ] */
2182 int
2183 main(int argc, char *argv[])
2184 {
2185     char                *init_progfile_dir_error;
2186     char                *s;
2187     int                  opt;
2188     gboolean             arg_error = FALSE;
2189
2190     extern int           info_update_freq;  /* Found in about_dlg.c. */
2191     const gchar         *filter;
2192
2193 #ifdef _WIN32
2194     WSADATA              wsaData;
2195 #endif  /* _WIN32 */
2196
2197     char                *rf_path;
2198     int                  rf_open_errno;
2199     char                *gdp_path, *dp_path;
2200     int                  err;
2201 #ifdef HAVE_LIBPCAP
2202     gboolean             start_capture = FALSE;
2203     gboolean             list_link_layer_types = FALSE;
2204     GList               *if_list;
2205     gchar               *err_str;
2206     int                  status;
2207 #else
2208     gboolean             capture_option_specified = FALSE;
2209 #ifdef _WIN32
2210 #ifdef HAVE_AIRPCAP
2211     gchar               *err_str;
2212 #endif
2213 #endif
2214 #endif
2215     gint                 pl_size = 280, tv_size = 95, bv_size = 75;
2216     gchar               *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2217     dfilter_t           *rfcode = NULL;
2218     gchar               *err_msg;
2219     gboolean             rfilter_parse_failed = FALSE;
2220     e_prefs             *prefs_p;
2221     char                 badopt;
2222     GtkWidget           *splash_win = NULL;
2223     guint                go_to_packet = 0;
2224     search_direction     jump_backwards = SD_FORWARD;
2225     dfilter_t           *jump_to_filter = NULL;
2226     unsigned int         in_file_type = WTAP_TYPE_AUTO;
2227 #ifdef HAVE_GTKOSXAPPLICATION
2228     GtkosxApplication   *theApp;
2229 #endif
2230     GSList              *disable_protocol_slist = NULL;
2231     GSList              *enable_heur_slist = NULL;
2232     GSList              *disable_heur_slist = NULL;
2233
2234 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
2235     static const struct option long_options[] = {
2236         {"help", no_argument, NULL, 'h'},
2237         {"read-file", required_argument, NULL, 'r' },
2238         {"read-filter", required_argument, NULL, 'R' },
2239         {"display-filter", required_argument, NULL, 'Y' },
2240         {"version", no_argument, NULL, 'v'},
2241         LONGOPT_CAPTURE_COMMON
2242         {0, 0, 0, 0 }
2243     };
2244     static const char optstring[] = OPTSTRING;
2245
2246 #ifdef HAVE_GRESOURCE
2247     main_register_resource();
2248 #endif
2249
2250     cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2251
2252     /* Set the C-language locale to the native environment. */
2253     setlocale(LC_ALL, "");
2254 #ifdef _WIN32
2255     arg_list_utf_16to8(argc, argv);
2256     create_app_running_mutex();
2257 #endif /* _WIN32 */
2258
2259     /*
2260      * Get credential information for later use, and drop privileges
2261      * before doing anything else.
2262      * Let the user know if anything happened.
2263      */
2264     init_process_policies();
2265     relinquish_special_privs_perm();
2266
2267     /*
2268      * Attempt to get the pathname of the executable file.
2269      */
2270     init_progfile_dir_error = init_progfile_dir(argv[0], main);
2271
2272     /* initialize the funnel mini-api */
2273     initialize_funnel_ops();
2274
2275     AirPDcapInitContext(&airpdcap_ctx);
2276
2277 #ifdef _WIN32
2278     /* Load wpcap if possible. Do this before collecting the run-time version information */
2279     load_wpcap();
2280
2281     /* ... and also load the packet.dll from wpcap */
2282     wpcap_packet_load();
2283
2284 #ifdef HAVE_AIRPCAP
2285     /* Load the airpcap.dll.  This must also be done before collecting
2286      * run-time version information. */
2287     airpcap_dll_ret_val = load_airpcap();
2288
2289     switch (airpcap_dll_ret_val) {
2290         case AIRPCAP_DLL_OK:
2291             /* load the airpcap interfaces */
2292             g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2293
2294             if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
2295                 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2296                     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2297                     g_free(err_str);
2298                 }
2299             airpcap_if_active = NULL;
2300
2301             } else {
2302
2303                 /* select the first ad default (THIS SHOULD BE CHANGED) */
2304                 airpcap_if_active = airpcap_get_default_if(g_airpcap_if_list);
2305             }
2306         break;
2307 #if 0
2308         /*
2309          * XXX - Maybe we need to warn the user if one of the following happens???
2310          */
2311         case AIRPCAP_DLL_OLD:
2312             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2313         break;
2314
2315         case AIRPCAP_DLL_ERROR:
2316             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2317         break;
2318
2319         case AIRPCAP_DLL_NOT_FOUND:
2320             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2321         break;
2322 #endif
2323     }
2324 #endif /* HAVE_AIRPCAP */
2325 #endif  /* _WIN32 */
2326
2327     /* Get the compile-time version information string */
2328     comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
2329                                               get_gui_compiled_info);
2330
2331     /* Get the run-time version information string */
2332     runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
2333
2334     /* Add it to the information to be reported on a crash. */
2335     ws_add_crash_info("Wireshark %s\n"
2336         "\n"
2337         "%s"
2338         "\n"
2339         "%s",
2340         get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2341
2342 #ifdef _WIN32
2343     /* Start windows sockets */
2344     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2345 #endif  /* _WIN32 */
2346
2347     profile_store_persconffiles (TRUE);
2348
2349     /* Read the profile independent recent file.  We have to do this here so we can */
2350     /* set the profile before it can be set from the command line parameter */
2351     recent_read_static(&rf_path, &rf_open_errno);
2352     if (rf_path != NULL && rf_open_errno != 0) {
2353         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2354                       "Could not open common recent file\n\"%s\": %s.",
2355                       rf_path, g_strerror(rf_open_errno));
2356     }
2357
2358     /*
2359      * In order to have the -X opts assigned before the wslua machine starts
2360      * we need to call getopt_long before epan_init() gets called.
2361      *
2362      * In addition, we process "console only" parameters (ones where we
2363      * send output to the console and exit) here, so we don't start GTK+
2364      * if we're only showing command-line help or version information.
2365      *
2366      * XXX - this pre-scan is done before we start GTK+, so we haven't
2367      * run gtk_init() on the arguments.  That means that GTK+ arguments
2368      * have not been removed from the argument list; those arguments
2369      * begin with "--", and will be treated as an error by getopt_long().
2370      *
2371      * We thus ignore errors - *and* set "opterr" to 0 to suppress the
2372      * error messages.
2373      *
2374      * XXX - should we, instead, first call gtk_parse_args(), without
2375      * calling gtk_init(), and then call this?
2376      *
2377      * In order to handle, for example, -o options, we also need to call it
2378      * *after* epan_init() gets called, so that the dissectors have had a
2379      * chance to register their preferences, so we have another getopt_long()
2380      * call later.
2381      *
2382      * XXX - can we do this all with one getopt_long() call, saving the
2383      * arguments we can't handle until after initializing libwireshark,
2384      * and then process them after initializing libwireshark?
2385      *
2386      * Note that we don't want to initialize libwireshark until after the
2387      * GUI is up, as that can take a while, and we want a window of some
2388      * sort up to show progress while that's happening.
2389      */
2390     opterr = 0;
2391
2392     while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
2393         switch (opt) {
2394             case 'C':        /* Configuration Profile */
2395                 if (profile_exists (optarg, FALSE)) {
2396                     set_profile_name (optarg);
2397                 } else {
2398                     cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2399                     exit(1);
2400                 }
2401                 break;
2402             case 'D':        /* Print a list of capture devices and exit */
2403 #ifdef HAVE_LIBPCAP
2404                 if_list = capture_interface_list(&err, &err_str, NULL);
2405                 if (if_list == NULL) {
2406                     if (err == 0)
2407                         cmdarg_err("There are no interfaces on which a capture can be done");
2408                     else {
2409                         cmdarg_err("%s", err_str);
2410                         g_free(err_str);
2411                     }
2412                     exit(2);
2413                 }
2414 #ifdef _WIN32
2415                 create_console();
2416 #endif /* _WIN32 */
2417                 capture_opts_print_interfaces(if_list);
2418                 free_interface_list(if_list);
2419 #ifdef _WIN32
2420                 destroy_console();
2421 #endif /* _WIN32 */
2422                 exit(0);
2423 #else /* HAVE_LIBPCAP */
2424                 capture_option_specified = TRUE;
2425                 arg_error = TRUE;
2426 #endif /* HAVE_LIBPCAP */
2427                 break;
2428             case 'h':        /* Print help and exit */
2429                 print_usage(TRUE);
2430                 exit(0);
2431                 break;
2432 #ifdef _WIN32
2433             case 'i':
2434                 if (strcmp(optarg, "-") == 0)
2435                     set_stdin_capture(TRUE);
2436                 break;
2437 #endif
2438             case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
2439                 if (!persfilepath_opt(opt, optarg)) {
2440                     cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2441                     exit(2);
2442                 }
2443                 break;
2444             case 'v':        /* Show version and exit */
2445 #ifdef _WIN32
2446                 create_console();
2447 #endif
2448                 show_version("Wireshark", comp_info_str, runtime_info_str);
2449 #ifdef _WIN32
2450                 destroy_console();
2451 #endif
2452                 exit(0);
2453                 break;
2454             case 'X':
2455                 /*
2456                  *  Extension command line options have to be processed before
2457                  *  we call epan_init() as they are supposed to be used by dissectors
2458                  *  or taps very early in the registration process.
2459                  */
2460                 ex_opt_add(optarg);
2461                 break;
2462             case '?':        /* Ignore errors - the "real" scan will catch them. */
2463                 break;
2464         }
2465     }
2466
2467     /* Init the "Open file" dialog directory */
2468     /* (do this after the path settings are processed) */
2469
2470     /* Read the profile dependent (static part) of the recent file. */
2471     /* Only the static part of it will be read, as we don't have the gui now to fill the */
2472     /* recent lists which is done in the dynamic part. */
2473     /* We have to do this already here, so command line parameters can overwrite these values. */
2474     if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
2475         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2476                       "Could not open recent file\n\"%s\": %s.",
2477                       rf_path, g_strerror(rf_open_errno));
2478         g_free(rf_path);
2479     }
2480
2481     if (recent.gui_fileopen_remembered_dir &&
2482         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2483         set_last_open_dir(recent.gui_fileopen_remembered_dir);
2484     } else {
2485         set_last_open_dir(get_persdatafile_dir());
2486     }
2487
2488 #if !GLIB_CHECK_VERSION(2,31,0)
2489     g_thread_init(NULL);
2490 #endif
2491
2492     /* Set the current locale according to the program environment.
2493      * We haven't localized anything, but some GTK widgets are localized
2494      * (the file selection dialogue, for example).
2495      * This also sets the C-language locale to the native environment. */
2496     setlocale (LC_ALL, "");
2497
2498     /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2499     gtk_init (&argc, &argv);
2500
2501     cf_callback_add(main_cf_callback, NULL);
2502 #ifdef HAVE_LIBPCAP
2503     capture_callback_add(main_capture_callback, NULL);
2504 #endif
2505
2506     cf_callback_add(statusbar_cf_callback, NULL);
2507 #ifdef HAVE_LIBPCAP
2508     capture_callback_add(statusbar_capture_callback, NULL);
2509 #endif
2510
2511     cf_callback_add(welcome_cf_callback, NULL);
2512 #ifdef HAVE_LIBPCAP
2513     capture_callback_add(welcome_capture_callback, NULL);
2514 #endif
2515
2516     set_console_log_handler();
2517
2518 #ifdef HAVE_LIBPCAP
2519     /* Set the initial values in the capture options. This might be overwritten
2520        by preference settings and then again by the command line parameters. */
2521     capture_opts_init(&global_capture_opts);
2522
2523     capture_session_init(&global_capture_session, &cfile);
2524 #endif
2525
2526     init_report_err(failure_alert_box, open_failure_alert_box,
2527                     read_failure_alert_box, write_failure_alert_box);
2528
2529     /* Initialize whatever we need to allocate colors for GTK+ */
2530     colors_init();
2531
2532     /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2533     filter = get_conn_cfilter();
2534     if ( *filter != '\0' ) {
2535         info_update_freq = 1000;  /* Milliseconds */
2536     }
2537
2538     /* We won't come till here, if we had a "console only" command line parameter. */
2539     splash_win = splash_new("Loading Wireshark ...");
2540     if (init_progfile_dir_error != NULL) {
2541         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2542                       "Can't get pathname of Wireshark: %s.\n"
2543                       "It won't be possible to capture traffic.\n"
2544                       "Report this to the Wireshark developers.",
2545                       init_progfile_dir_error);
2546         g_free(init_progfile_dir_error);
2547     }
2548
2549     init_open_routines();
2550
2551 #ifdef HAVE_PLUGINS
2552     /* Register all the plugin types we have. */
2553     epan_register_plugin_types(); /* Types known to libwireshark */
2554     wtap_register_plugin_types(); /* Types known to libwiretap */
2555     codec_register_plugin_types(); /* Types known to libwscodecs */
2556
2557     /* Scan for plugins.  This does *not* call their registration routines;
2558        that's done later. */
2559     scan_plugins();
2560
2561     /* Register all libwiretap plugin modules. */
2562     register_all_wiretap_modules();
2563
2564     /* Register all audio codec plugins. */
2565     register_all_codecs();
2566 #endif
2567
2568     splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2569
2570     /* Register all dissectors; we must do this before checking for the
2571        "-G" flag, as the "-G" flag dumps information registered by the
2572        dissectors, and we must do it before we read the preferences, in
2573        case any dissectors register preferences. */
2574     if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
2575                    splash_update, (gpointer) splash_win))
2576       return 2;
2577
2578     splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2579
2580     /* Register all tap listeners; we do this before we parse the arguments,
2581        as the "-z" argument can specify a registered tap. */
2582
2583     /* we register the plugin taps before the other taps because
2584        stats_tree taps plugins will be registered as tap listeners
2585        by stats_tree_stat.c and need to registered before that */
2586
2587 #ifdef HAVE_PLUGINS
2588     register_all_plugin_tap_listeners();
2589 #endif
2590
2591     register_all_tap_listeners();
2592     conversation_table_set_gui_info(init_conversation_table);
2593     hostlist_table_set_gui_info(init_hostlist_table);
2594     srt_table_iterate_tables(register_service_response_tables, NULL);
2595     rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2596     new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2597
2598     splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2599
2600     prefs_p = read_configuration_files (&gdp_path, &dp_path);
2601     /* Removed thread code:
2602      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2603      */
2604
2605     /* this is to keep tap extensions updating once every 3 seconds */
2606     tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2607
2608     splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2609     proto_help_init();
2610     cap_file_init(&cfile);
2611
2612     /* Fill in capture options with values from the preferences */
2613     prefs_to_capture_opts();
2614
2615 /*#ifdef HAVE_LIBPCAP
2616     fill_in_local_interfaces();
2617 #endif*/
2618     /*
2619      * To reset the options parser, set optreset to 1 on platforms that
2620      * have optreset (documented in *BSD and OS X, apparently present but
2621      * not documented in Solaris - the Illumos repository seems to
2622      * suggest that the first Solaris getopt_long(), at least as of 2004,
2623      * was based on the NetBSD one, it had optreset) and set optind to 1,
2624      * and set optind to 0 otherwise (documented as working in the GNU
2625      * getopt_long().  Setting optind to 0 didn't originally work in the
2626      * NetBSD one, but that was added later - we don't want to depend on
2627      * it if we have optreset).
2628      *
2629      * Also reset opterr to 1, so that error messages are printed by
2630      * getopt_long().
2631      *
2632      * XXX - if we want to control all the command-line option errors, so
2633      * that we can display them where we choose (e.g., in a window), we'd
2634      * want to leave opterr as 0, and produce our own messages using optopt.
2635      * We'd have to check the value of optopt to see if it's a valid option
2636      * letter, in which case *presumably* the error is "this option requires
2637      * an argument but none was specified", or not a valid option letter,
2638      * in which case *presumably* the error is "this option isn't valid".
2639      * Some versions of getopt() let you supply a option string beginning
2640      * with ':', which means that getopt() will return ':' rather than '?'
2641      * for "this option requires an argument but none was specified", but
2642      * not all do.  But we're now using getopt_long() - what does it do?
2643      */
2644 #ifdef HAVE_OPTRESET
2645     optreset = 1;
2646     optind = 1;
2647 #else
2648     optind = 0;
2649 #endif
2650     opterr = 1;
2651
2652     /* Now get our args */
2653     while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
2654         switch (opt) {
2655             /*** capture option specific ***/
2656             case 'a':        /* autostop criteria */
2657             case 'b':        /* Ringbuffer option */
2658             case 'c':        /* Capture xxx packets */
2659             case 'f':        /* capture filter */
2660             case 'k':        /* Start capture immediately */
2661             case 'H':        /* Hide capture info dialog box */
2662             case 'p':        /* Don't capture in promiscuous mode */
2663             case 'i':        /* Use interface x */
2664 #ifdef HAVE_PCAP_CREATE
2665             case 'I':        /* Capture in monitor mode, if available */
2666 #endif
2667 #ifdef HAVE_PCAP_REMOTE
2668             case 'A':        /* Authentication */
2669 #endif
2670             case 's':        /* Set the snapshot (capture) length */
2671             case 'S':        /* "Sync" mode: used for following file ala tail -f */
2672             case 'w':        /* Write to capture file xxx */
2673             case 'y':        /* Set the pcap data link type */
2674 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
2675             case 'B':        /* Buffer size */
2676 #endif
2677 #ifdef HAVE_LIBPCAP
2678                 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2679                                               &start_capture);
2680                 if(status != 0) {
2681                     exit(status);
2682                 }
2683 #else
2684                 capture_option_specified = TRUE;
2685                 arg_error = TRUE;
2686 #endif
2687                 break;
2688
2689 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2690             case 'K':        /* Kerberos keytab file */
2691                     read_keytab_file(optarg);
2692                 break;
2693 #endif
2694
2695             /*** all non capture option specific ***/
2696             case 'C':
2697                 /* Configuration profile settings were already processed just ignore them this time*/
2698                 break;
2699             case 'j':        /* Search backwards for a matching packet from filter in option J */
2700                 jump_backwards = SD_BACKWARD;
2701                 break;
2702             case 'g':        /* Go to packet with the given packet number */
2703                 go_to_packet = get_positive_int(optarg, "go to packet");
2704                 break;
2705             case 'J':        /* Jump to the first packet which matches the filter criteria */
2706                 jfilter = optarg;
2707                 break;
2708             case 'l':        /* Automatic scrolling in live capture mode */
2709 #ifdef HAVE_LIBPCAP
2710                 auto_scroll_live = TRUE;
2711 #else
2712                 capture_option_specified = TRUE;
2713                 arg_error = TRUE;
2714 #endif
2715                 break;
2716             case 'L':        /* Print list of link-layer types and exit */
2717 #ifdef HAVE_LIBPCAP
2718                 list_link_layer_types = TRUE;
2719 #else
2720                 capture_option_specified = TRUE;
2721                 arg_error = TRUE;
2722 #endif
2723                 break;
2724             case 'm':        /* Fixed-width font for the display */
2725                 g_free(prefs_p->gui_gtk2_font_name);
2726                 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2727                 break;
2728             case 'n':        /* No name resolution */
2729                 disable_name_resolution();
2730                 break;
2731             case 'N':        /* Select what types of addresses/port #s to resolve */
2732                 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2733                 if (badopt != '\0') {
2734                     cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
2735                                badopt);
2736                     exit(1);
2737                 }
2738                 break;
2739             case 'o':        /* Override preference from command line */
2740                 switch (prefs_set_pref(optarg)) {
2741                     case PREFS_SET_OK:
2742                         break;
2743                     case PREFS_SET_SYNTAX_ERR:
2744                         cmdarg_err("Invalid -o flag \"%s\"", optarg);
2745                         exit(1);
2746                         break;
2747                     case PREFS_SET_NO_SUCH_PREF:
2748                     /* not a preference, might be a recent setting */
2749                         switch (recent_set_arg(optarg)) {
2750                             case PREFS_SET_OK:
2751                                 break;
2752                             case PREFS_SET_SYNTAX_ERR:
2753                                 /* shouldn't happen, checked already above */
2754                                 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2755                                 exit(1);
2756                                 break;
2757                             case PREFS_SET_NO_SUCH_PREF:
2758                             case PREFS_SET_OBSOLETE:
2759                                 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2760                                            optarg);
2761                                 exit(1);
2762                                 break;
2763                             default:
2764                                 g_assert_not_reached();
2765                         }
2766                         break;
2767                     case PREFS_SET_OBSOLETE:
2768                         cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2769                                    optarg);
2770                         exit(1);
2771                         break;
2772                     default:
2773                         g_assert_not_reached();
2774                 }
2775                 break;
2776             case 'P':
2777                 /* Path settings were already processed just ignore them this time*/
2778                 break;
2779             case 'r':        /* Read capture file xxx */
2780                 /* We may set "last_open_dir" to "cf_name", and if we change
2781                  "last_open_dir" later, we free the old value, so we have to
2782                  set "cf_name" to something that's been allocated. */
2783                 cf_name = g_strdup(optarg);
2784                 break;
2785             case 'R':        /* Read file filter */
2786                 rfilter = optarg;
2787                 break;
2788             case 't':        /* Time stamp type */
2789                 if (strcmp(optarg, "r") == 0)
2790                     timestamp_set_type(TS_RELATIVE);
2791                 else if (strcmp(optarg, "a") == 0)
2792                     timestamp_set_type(TS_ABSOLUTE);
2793                 else if (strcmp(optarg, "ad") == 0)
2794                     timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2795                 else if (strcmp(optarg, "adoy") == 0)
2796                     timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
2797                 else if (strcmp(optarg, "d") == 0)
2798                     timestamp_set_type(TS_DELTA);
2799                 else if (strcmp(optarg, "dd") == 0)
2800                     timestamp_set_type(TS_DELTA_DIS);
2801                 else if (strcmp(optarg, "e") == 0)
2802                     timestamp_set_type(TS_EPOCH);
2803                 else if (strcmp(optarg, "u") == 0)
2804                     timestamp_set_type(TS_UTC);
2805                 else if (strcmp(optarg, "ud") == 0)
2806                     timestamp_set_type(TS_UTC_WITH_YMD);
2807                 else if (strcmp(optarg, "udoy") == 0)
2808                     timestamp_set_type(TS_UTC_WITH_YDOY);
2809                 else {
2810                     cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2811                     cmdarg_err_cont(
2812 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2813                     cmdarg_err_cont(
2814 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2815                     cmdarg_err_cont(
2816 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2817                     cmdarg_err_cont(
2818 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2819                     cmdarg_err_cont(
2820 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2821                     exit(1);
2822                 }
2823                 break;
2824             case 'u':        /* Seconds type */
2825                 if (strcmp(optarg, "s") == 0)
2826                     timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2827                 else if (strcmp(optarg, "hms") == 0)
2828                     timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2829                 else {
2830                     cmdarg_err("Invalid seconds type \"%s\"", optarg);
2831                     cmdarg_err_cont(
2832 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2833                     exit(1);
2834                 }
2835                 break;
2836             case 'X':
2837                 /* ext ops were already processed just ignore them this time*/
2838                 break;
2839             case 'Y':
2840                 dfilter = optarg;
2841                 break;
2842             case 'z':
2843                 /* We won't call the init function for the stat this soon
2844                  as it would disallow MATE's fields (which are registered
2845                  by the preferences set callback) from being used as
2846                  part of a tap filter.  Instead, we just add the argument
2847                  to a list of stat arguments. */
2848                 if (strcmp("help", optarg) == 0) {
2849                   fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
2850                   list_stat_cmd_args();
2851                   exit(0);
2852                 }
2853                 if (!process_stat_cmd_arg(optarg)) {
2854                     cmdarg_err("Invalid -z argument.");
2855                     cmdarg_err_cont("  -z argument must be one of :");
2856                     list_stat_cmd_args();
2857                     exit(1);
2858                 }
2859                 break;
2860             case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
2861                 disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
2862                 break;
2863             case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
2864                 enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
2865                 break;
2866             case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
2867                 disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
2868                 break;
2869             default:
2870             case '?':        /* Bad flag - print usage message */
2871                 arg_error = TRUE;
2872                 break;
2873             }
2874     }
2875     if (!arg_error) {
2876         argc -= optind;
2877         argv += optind;
2878         if (argc >= 1) {
2879             if (cf_name != NULL) {
2880                 /*
2881                  * Input file name specified with "-r" *and* specified as a regular
2882                  * command-line argument.
2883                  */
2884                 cmdarg_err("File name specified both with -r and regular argument");
2885                 arg_error = TRUE;
2886             } else {
2887                 /*
2888                  * Input file name not specified with "-r", and a command-line argument
2889                  * was specified; treat it as the input file name.
2890                  *
2891                  * Yes, this is different from tshark, where non-flag command-line
2892                  * arguments are a filter, but this works better on GUI desktops
2893                  * where a command can be specified to be run to open a particular
2894                  * file - yes, you could have "-r" as the last part of the command,
2895                  * but that's a bit ugly.
2896                  */
2897 #ifndef HAVE_GTKOSXAPPLICATION
2898                 /*
2899                  * For GTK+ Mac Integration, file name passed as free argument passed
2900                  * through grag-and-drop and opened twice sometimes causing crashes.
2901                  * Subject to report to GTK+ MAC.
2902                  */
2903                 cf_name = g_strdup(argv[0]);
2904 #endif
2905             }
2906             argc--;
2907             argv++;
2908         }
2909
2910         if (argc != 0) {
2911             /*
2912              * Extra command line arguments were specified; complain.
2913              */
2914             cmdarg_err("Invalid argument: %s", argv[0]);
2915             arg_error = TRUE;
2916         }
2917     }
2918
2919     if (arg_error) {
2920 #ifndef HAVE_LIBPCAP
2921         if (capture_option_specified) {
2922             cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2923         }
2924 #endif
2925         print_usage(FALSE);
2926         exit(1);
2927     }
2928
2929 #ifdef HAVE_LIBPCAP
2930     fill_in_local_interfaces(main_window_update);
2931     if (start_capture && list_link_layer_types) {
2932         /* Specifying *both* is bogus. */
2933         cmdarg_err("You can't specify both -L and a live capture.");
2934         exit(1);
2935     }
2936
2937     if (list_link_layer_types) {
2938         /* We're supposed to list the link-layer types for an interface;
2939            did the user also specify a capture file to be read? */
2940         if (cf_name) {
2941             /* Yes - that's bogus. */
2942             cmdarg_err("You can't specify -L and a capture file to be read.");
2943         exit(1);
2944         }
2945         /* No - did they specify a ring buffer option? */
2946         if (global_capture_opts.multi_files_on) {
2947             cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2948             exit(1);
2949         }
2950     } else {
2951         /* We're supposed to do a live capture; did the user also specify
2952            a capture file to be read? */
2953         if (start_capture && cf_name) {
2954             /* Yes - that's bogus. */
2955             cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2956             exit(1);
2957         }
2958
2959         /* No - was the ring buffer option specified and, if so, does it make
2960            sense? */
2961         if (global_capture_opts.multi_files_on) {
2962             /* Ring buffer works only under certain conditions:
2963              a) ring buffer does not work with temporary files;
2964              b) real_time_mode and multi_files_on are mutually exclusive -
2965              real_time_mode takes precedence;
2966              c) it makes no sense to enable the ring buffer if the maximum
2967              file size is set to "infinite". */
2968             if (global_capture_opts.save_file == NULL) {
2969                 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2970                 global_capture_opts.multi_files_on = FALSE;
2971             }
2972             if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2973                 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2974                 /* XXX - this must be redesigned as the conditions changed */
2975             }
2976         }
2977     }
2978
2979     if (start_capture || list_link_layer_types) {
2980         /* We're supposed to do a live capture or get a list of link-layer
2981            types for a live capture device; if the user didn't specify an
2982            interface to use, pick a default. */
2983         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2984         ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2985         if (status != 0) {
2986             exit(status);
2987         }
2988     }
2989
2990     if (list_link_layer_types) {
2991         /* Get the list of link-layer types for the capture devices. */
2992         if_capabilities_t *caps;
2993         guint i;
2994         interface_t device;
2995         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2996
2997             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2998             if (device.selected) {
2999                 gchar* auth_str = NULL;
3000 #ifdef HAVE_PCAP_REMOTE
3001                 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
3002                     auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
3003                                                device.remote_opts.remote_host_opts.auth_password);
3004                 }
3005 #endif
3006 #if defined(HAVE_PCAP_CREATE)
3007                 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
3008 #else
3009                 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
3010 #endif
3011                 g_free(auth_str);
3012                 if (caps == NULL) {
3013                     cmdarg_err("%s", err_str);
3014                     g_free(err_str);
3015                     exit(2);
3016                 }
3017             if (caps->data_link_types == NULL) {
3018                 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
3019                 exit(2);
3020             }
3021 #ifdef _WIN32
3022             create_console();
3023 #endif /* _WIN32 */
3024 #if defined(HAVE_PCAP_CREATE)
3025             capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
3026 #else
3027             capture_opts_print_if_capabilities(caps, device.name, FALSE);
3028 #endif
3029 #ifdef _WIN32
3030             destroy_console();
3031 #endif /* _WIN32 */
3032             free_if_capabilities(caps);
3033             }
3034         }
3035         exit(0);
3036     }
3037   capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
3038   capture_opts_trim_ring_num_files(&global_capture_opts);
3039 #endif /* HAVE_LIBPCAP */
3040
3041     /* Notify all registered modules that have had any of their preferences
3042        changed either from one of the preferences file or from the command
3043        line that their preferences have changed. */
3044     prefs_apply_all();
3045
3046 #ifdef HAVE_LIBPCAP
3047     if ((global_capture_opts.num_selected == 0) &&
3048         ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
3049         guint i;
3050         interface_t device;
3051         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
3052             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
3053             if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
3054                 device.selected = TRUE;
3055                 global_capture_opts.num_selected++;
3056                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
3057                 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
3058                 break;
3059             }
3060         }
3061     }
3062     if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
3063         interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
3064         device.selected = TRUE;
3065         global_capture_opts.num_selected++;
3066         global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
3067         g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
3068     }
3069 #endif
3070
3071     /* disabled protocols as per configuration file */
3072     if (gdp_path == NULL && dp_path == NULL) {
3073         set_disabled_protos_list();
3074         set_disabled_heur_dissector_list();
3075     }
3076
3077     if(disable_protocol_slist) {
3078         GSList *proto_disable;
3079         for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
3080         {
3081             proto_disable_proto_by_name((char*)proto_disable->data);
3082         }
3083     }
3084
3085     if(enable_heur_slist) {
3086         GSList *heur_enable;
3087         for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
3088         {
3089             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
3090         }
3091     }
3092
3093     if(disable_heur_slist) {
3094         GSList *heur_disable;
3095         for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
3096         {
3097             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
3098         }
3099     }
3100
3101     build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
3102
3103     /* read in rc file from global and personal configuration paths. */
3104     rc_file = get_datafile_path(RC_FILE);
3105 #if GTK_CHECK_VERSION(3,0,0)
3106     /* XXX resolve later */
3107 #else
3108     gtk_rc_parse(rc_file);
3109     g_free(rc_file);
3110     rc_file = get_persconffile_path(RC_FILE, FALSE);
3111     gtk_rc_parse(rc_file);
3112 #endif
3113     g_free(rc_file);
3114
3115     font_init();
3116
3117     macros_init();
3118
3119     stock_icons_init();
3120
3121     /* close the splash screen, as we are going to open the main window now */
3122     splash_destroy(splash_win);
3123
3124     /************************************************************************/
3125     /* Everything is prepared now, preferences and command line was read in */
3126
3127     /* Pop up the main window. */
3128     create_main_window(pl_size, tv_size, bv_size, prefs_p);
3129
3130     /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3131     if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
3132         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3133                       "Could not open recent file\n\"%s\": %s.",
3134                       rf_path, g_strerror(rf_open_errno));
3135         g_free(rf_path);
3136     }
3137
3138     color_filters_enable(recent.packet_list_colorize);
3139
3140     /* rearrange all the widgets as we now have all recent settings ready for this */
3141     main_widgets_rearrange();
3142
3143     /* Fill in column titles.  This must be done after the top level window
3144      is displayed.
3145
3146      XXX - is that still true, with fixed-width columns? */
3147
3148     menu_recent_read_finished();
3149 #ifdef HAVE_LIBPCAP
3150     main_auto_scroll_live_changed(auto_scroll_live);
3151 #endif
3152
3153     switch (user_font_apply()) {
3154         case FA_SUCCESS:
3155             break;
3156         case FA_ZOOMED_TOO_FAR:
3157             /* The zoom level is too big for this font; turn off zooming. */
3158             recent.gui_zoom_level = 0;
3159             break;
3160         case FA_FONT_NOT_AVAILABLE:
3161             /* XXX - did we successfully load the un-zoomed version earlier?
3162              If so, this *probably* means the font is available, but not at
3163              this particular zoom level, but perhaps some other failure
3164              occurred; I'm not sure you can determine which is the case,
3165              however. */
3166             /* turn off zooming - zoom level is unavailable */
3167         default:
3168             /* in any other case than FA_SUCCESS, turn off zooming */
3169             recent.gui_zoom_level = 0;
3170             /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3171             break;
3172     }
3173
3174     dnd_init(top_level);
3175
3176     color_filters_init();
3177 #ifdef HAVE_LIBPCAP
3178     capture_filter_init();
3179 #endif
3180
3181     /* the window can be sized only, if it's not already shown, so do it now! */
3182     main_load_window_geometry(top_level);
3183
3184     g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3185
3186     /* If we were given the name of a capture file, read it in now;
3187      we defer it until now, so that, if we can't open it, and pop
3188      up an alert box, the alert box is more likely to come up on
3189      top of the main window - but before the preference-file-error
3190      alert box, so, if we get one of those, it's more likely to come
3191      up on top of us. */
3192     if (cf_name) {
3193         show_main_window(TRUE);
3194         check_and_warn_user_startup(cf_name);
3195         if (rfilter != NULL) {
3196             if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
3197                 bad_dfilter_alert_box(top_level, rfilter, err_msg);
3198                 g_free(err_msg);
3199                 rfilter_parse_failed = TRUE;
3200             }
3201         }
3202         if (ex_opt_count("read_format") > 0) {
3203             in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
3204         }
3205         if (!rfilter_parse_failed) {
3206             if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
3207                 /* "cf_open()" succeeded, so it closed the previous
3208                  capture file, and thus destroyed any previous read filter
3209                  attached to "cf". */
3210
3211                 cfile.rfcode = rfcode;
3212                 /* Open stat windows; we do so after creating the main window,
3213                    to avoid GTK warnings, and after successfully opening the
3214                    capture file, so we know we have something to compute stats
3215                    on, and after registering all dissectors, so that MATE will
3216                    have registered its field array and we can have a tap filter
3217                    with one of MATE's late-registered fields as part of the
3218                    filter. */
3219                 start_requested_stats();
3220
3221                 /* Read the capture file. */
3222                 switch (cf_read(&cfile, FALSE)) {
3223
3224                     case CF_READ_OK:
3225                     case CF_READ_ERROR:
3226                         /* Just because we got an error, that doesn't mean we were unable
3227                            to read any of the file; we handle what we could get from the
3228                            file. */
3229                         /* if the user told us to jump to a specific packet, do it now */
3230                         if(go_to_packet != 0) {
3231                             /* Jump to the specified frame number, kept for backward
3232                                compatibility. */
3233                             cf_goto_frame(&cfile, go_to_packet);
3234                         } else if (jfilter != NULL) {
3235                             /* try to compile given filter */
3236                             if (!dfilter_compile(jfilter, &jump_to_filter, &err_msg)) {
3237                                 bad_dfilter_alert_box(top_level, jfilter, err_msg);
3238                                 g_free(err_msg);
3239                             } else {
3240                             /* Filter ok, jump to the first packet matching the filter
3241                                conditions. Default search direction is forward, but if
3242                                option d was given, search backwards */
3243                             cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3244                             }
3245                         }
3246                         break;
3247
3248                     case CF_READ_ABORTED:
3249                         /* Exit now. */
3250                         exit(0);
3251                         break;
3252                 }
3253
3254                 /* If the filename is not the absolute path, prepend the current dir. This happens
3255                    when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3256                 if (!g_path_is_absolute(cf_name)) {
3257                     char *old_cf_name = cf_name;
3258                     char *pwd = g_get_current_dir();
3259                     cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3260                     g_free(old_cf_name);
3261                     g_free(pwd);
3262                 }
3263
3264                 /* Save the name of the containing directory specified in the
3265                    path name, if any; we can write over cf_name, which is a
3266                    good thing, given that "get_dirname()" does write over its
3267                    argument. */
3268                 s = get_dirname(cf_name);
3269                 set_last_open_dir(s);
3270                 g_free(cf_name);
3271                 cf_name = NULL;
3272             } else {
3273                 if (rfcode != NULL)
3274                     dfilter_free(rfcode);
3275                 cfile.rfcode = NULL;
3276                 show_main_window(FALSE);
3277                 /* Don't call check_and_warn_user_startup(): we did it above */
3278                 main_set_for_capture_in_progress(FALSE);
3279                 set_capture_if_dialog_for_capture_in_progress(FALSE);
3280             }
3281         }
3282     } else {
3283 #ifdef HAVE_LIBPCAP
3284         if (start_capture) {
3285             if (global_capture_opts.save_file != NULL) {
3286                 /* Save the directory name for future file dialogs. */
3287                 /* (get_dirname overwrites filename) */
3288                 s = get_dirname(g_strdup(global_capture_opts.save_file));
3289                 set_last_open_dir(s);
3290                 g_free(s);
3291             }
3292             /* "-k" was specified; start a capture. */
3293             show_main_window(FALSE);
3294             check_and_warn_user_startup(cf_name);
3295
3296             /* If no user interfaces were specified on the command line,
3297                copy the list of selected interfaces to the set of interfaces
3298                to use for this capture. */
3299             if (global_capture_opts.ifaces->len == 0)
3300                 collect_ifaces(&global_capture_opts);
3301             if (capture_start(&global_capture_opts, &global_capture_session, &global_info_data,main_window_update)) {
3302                 /* The capture started.  Open stat windows; we do so after creating
3303                    the main window, to avoid GTK warnings, and after successfully
3304                    opening the capture file, so we know we have something to compute
3305                    stats on, and after registering all dissectors, so that MATE will
3306                    have registered its field array and we can have a tap filter with
3307                    one of MATE's late-registered fields as part of the filter. */
3308                 start_requested_stats();
3309             }
3310         } else {
3311             show_main_window(FALSE);
3312             check_and_warn_user_startup(cf_name);
3313             main_set_for_capture_in_progress(FALSE);
3314             set_capture_if_dialog_for_capture_in_progress(FALSE);
3315         }
3316     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3317         if (!start_capture && !global_capture_opts.default_options.cfilter) {
3318             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3319         }
3320 #else /* HAVE_LIBPCAP */
3321         show_main_window(FALSE);
3322         check_and_warn_user_startup(cf_name);
3323         main_set_for_capture_in_progress(FALSE);
3324         set_capture_if_dialog_for_capture_in_progress(FALSE);
3325 #endif /* HAVE_LIBPCAP */
3326     }
3327
3328     if (dfilter) {
3329         GtkWidget *filter_te;
3330         filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3331         gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3332
3333         /* Run the display filter so it goes in effect. */
3334         main_filter_packets(&cfile, dfilter, FALSE);
3335     }
3336
3337
3338     /* register our pid if we are being run from a U3 device */
3339     u3_register_pid();
3340
3341     profile_store_persconffiles (FALSE);
3342
3343 #ifdef HAVE_GTKOSXAPPLICATION
3344     theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3345 #ifdef HAVE_GRESOURCE
3346     gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
3347 #else
3348     gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3349 #endif
3350     gtkosx_application_ready(theApp);
3351 #endif
3352
3353     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3354
3355 #ifdef HAVE_LIBPCAP
3356     gtk_iface_mon_start();
3357 #endif
3358
3359     software_update_init();
3360
3361     /* we'll enter the GTK loop now and hand the control over to GTK ... */
3362     gtk_main();
3363     /* ... back from GTK, we're going down now! */
3364
3365 #ifdef HAVE_LIBPCAP
3366     gtk_iface_mon_stop();
3367 #endif
3368
3369     /* deregister our pid */
3370     u3_deregister_pid();
3371
3372     epan_cleanup();
3373
3374     AirPDcapDestroyContext(&airpdcap_ctx);
3375
3376 #ifdef HAVE_GTKOSXAPPLICATION
3377     g_object_unref(theApp);
3378 #endif
3379
3380 #ifdef _WIN32
3381     /* hide the (unresponsive) main window, while asking the user to close the console window */
3382     if (G_IS_OBJECT(top_level))
3383         gtk_widget_hide(top_level);
3384
3385     software_update_cleanup();
3386
3387     /* Shutdown windows sockets */
3388     WSACleanup();
3389
3390     /* For some unknown reason, the "atexit()" call in "create_console()"
3391        doesn't arrange that "destroy_console()" be called when we exit,
3392        so we call it here if a console was created. */
3393     destroy_console();
3394 #endif
3395
3396 #ifdef HAVE_GRESOURCE
3397     main_unregister_resource();
3398 #endif
3399
3400     exit(0);
3401 }
3402
3403 #ifdef _WIN32
3404
3405 /* We build this as a GUI subsystem application on Win32, so
3406    "WinMain()", not "main()", gets called.
3407
3408    Hack shamelessly stolen from the Win32 port of the GIMP. */
3409 #ifdef __GNUC__
3410 #define _stdcall  __attribute__((stdcall))
3411 #endif
3412
3413 int _stdcall
3414 WinMain (struct HINSTANCE__ *hInstance,
3415          struct HINSTANCE__ *hPrevInstance,
3416          char               *lpszCmdLine,
3417          int                 nCmdShow)
3418 {
3419     INITCOMMONCONTROLSEX comm_ctrl;
3420
3421     /*
3422      * Initialize our DLL search path. MUST be called before LoadLibrary
3423      * or g_module_open.
3424      */
3425     ws_init_dll_search_path();
3426
3427     /* Initialize our controls. Required for native Windows file dialogs. */
3428     memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3429     comm_ctrl.dwSize = sizeof(comm_ctrl);
3430     /* Includes the animate, header, hot key, list view, progress bar,
3431      * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3432      * up-down controls
3433      */
3434     comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3435     InitCommonControlsEx(&comm_ctrl);
3436
3437     /* RichEd20.DLL is needed for filter entries. */
3438     ws_load_library("riched20.dll");
3439
3440     set_has_console(FALSE);
3441     set_console_wait(FALSE);
3442     return main (__argc, __argv);
3443 }
3444
3445 #endif /* _WIN32 */
3446
3447
3448
3449
3450 /*
3451  * Helper for main_widgets_rearrange()
3452  */
3453 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3454     gtk_container_remove(GTK_CONTAINER(data), widget);
3455 }
3456
3457 static GtkWidget *main_widget_layout(gint layout_content)
3458 {
3459     switch(layout_content) {
3460     case(layout_pane_content_none):
3461         return NULL;
3462     case(layout_pane_content_plist):
3463         return pkt_scrollw;
3464     case(layout_pane_content_pdetails):
3465         return tv_scrollw;
3466     case(layout_pane_content_pbytes):
3467         return byte_nb_ptr_gbl;
3468     default:
3469         g_assert_not_reached();
3470         return NULL;
3471     }
3472 }
3473
3474 /*
3475  * Rearrange the main window widgets
3476  */
3477 void main_widgets_rearrange(void) {
3478     GtkWidget *first_pane_widget1, *first_pane_widget2;
3479     GtkWidget *second_pane_widget1, *second_pane_widget2;
3480     gboolean split_top_left = FALSE;
3481
3482     /* be a bit faster */
3483     gtk_widget_hide(main_vbox);
3484
3485     /* be sure we don't lose a widget while rearranging */
3486     g_object_ref(G_OBJECT(menubar));
3487     g_object_ref(G_OBJECT(main_tb));
3488     g_object_ref(G_OBJECT(filter_tb));
3489     g_object_ref(G_OBJECT(wireless_tb));
3490     g_object_ref(G_OBJECT(pkt_scrollw));
3491     g_object_ref(G_OBJECT(tv_scrollw));
3492     g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3493     g_object_ref(G_OBJECT(statusbar));
3494     g_object_ref(G_OBJECT(main_pane_v1));
3495     g_object_ref(G_OBJECT(main_pane_v2));
3496     g_object_ref(G_OBJECT(main_pane_h1));
3497     g_object_ref(G_OBJECT(main_pane_h2));
3498     g_object_ref(G_OBJECT(welcome_pane));
3499
3500     /* empty all containers participating */
3501     gtk_container_foreach(GTK_CONTAINER(main_vbox),     foreach_remove_a_child, main_vbox);
3502     gtk_container_foreach(GTK_CONTAINER(main_pane_v1),  foreach_remove_a_child, main_pane_v1);
3503     gtk_container_foreach(GTK_CONTAINER(main_pane_v2),  foreach_remove_a_child, main_pane_v2);
3504     gtk_container_foreach(GTK_CONTAINER(main_pane_h1),  foreach_remove_a_child, main_pane_h1);
3505     gtk_container_foreach(GTK_CONTAINER(main_pane_h2),  foreach_remove_a_child, main_pane_h2);
3506
3507     statusbar_widgets_emptying(statusbar);
3508
3509     /* add the menubar always at the top */
3510     gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3511
3512     /* main toolbar */
3513     gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3514
3515     /* filter toolbar in toolbar area */
3516     if (!prefs.filter_toolbar_show_in_statusbar) {
3517         gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3518     }
3519
3520     /* airpcap toolbar */
3521     gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3522