Add enabled protocol list for dissectors who are disabled by default
[metze/wireshark/wip.git] / wireshark-qt.cpp
1 /* wireshark-qt.cpp
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <config.h>
23
24 #include <glib.h>
25
26 #ifdef Q_OS_UNIX
27 #include <signal.h>
28 #endif
29
30 #include <locale.h>
31
32 #ifdef HAVE_GETOPT_H
33 #include <getopt.h>
34 #endif
35
36 #ifndef HAVE_GETOPT_LONG
37 #include "wsutil/wsgetopt.h"
38 #endif
39
40 #include <wsutil/clopts_common.h>
41 #include <wsutil/cmdarg_err.h>
42 #include <wsutil/crash_info.h>
43 #include <wsutil/filesystem.h>
44 #include <wsutil/privileges.h>
45 #ifdef HAVE_PLUGINS
46 #include <wsutil/plugins.h>
47 #endif
48 #include <wsutil/report_err.h>
49 #include <wsutil/unicode-utils.h>
50 #include <ws_version_info.h>
51
52 #include <epan/addr_resolv.h>
53 #include <epan/ex-opt.h>
54 #include <epan/tap.h>
55 #include <epan/stat_tap_ui.h>
56 #include <epan/column.h>
57 #include <epan/disabled_protos.h>
58 #include <epan/prefs.h>
59
60 #ifdef HAVE_KERBEROS
61 #include <epan/packet.h>
62 #include <epan/asn1.h>
63 #include <epan/dissectors/packet-kerberos.h>
64 #endif
65
66 #include <codecs/codecs.h>
67
68 #ifdef HAVE_EXTCAP
69 #include <extcap.h>
70 #endif
71
72 /* general (not Qt specific) */
73 #include "file.h"
74 #include "epan/color_filters.h"
75 #include "log.h"
76
77 #include "epan/rtd_table.h"
78 #include "epan/srt_table.h"
79
80 #include "ui/alert_box.h"
81 #include "ui/console.h"
82 #include "ui/iface_lists.h"
83 #include "ui/language.h"
84 #include "ui/persfilepath_opt.h"
85 #include "ui/recent.h"
86 #include "ui/simple_dialog.h"
87 #include "ui/util.h"
88 #include "ui/dissect_opts.h"
89 #include "ui/commandline.h"
90 #include "ui/capture_ui_utils.h"
91
92 #include "ui/qt/conversation_dialog.h"
93 #include "ui/qt/color_utils.h"
94 #include "ui/qt/coloring_rules_dialog.h"
95 #include "ui/qt/endpoint_dialog.h"
96 #include "ui/qt/main_window.h"
97 #include "ui/qt/response_time_delay_dialog.h"
98 #include "ui/qt/service_response_time_dialog.h"
99 #include "ui/qt/simple_dialog.h"
100 #include "ui/qt/simple_statistics_dialog.h"
101 #include "ui/qt/splash_overlay.h"
102 #include "ui/qt/wireshark_application.h"
103
104 #include "caputils/capture-pcap-util.h"
105
106 #ifdef _WIN32
107 #  include "caputils/capture-wpcap.h"
108 #  include "caputils/capture_wpcap_packet.h"
109 #  include <tchar.h> /* Needed for Unicode */
110 #  include <wsutil/file_util.h>
111 #  include <wsutil/os_version_info.h>
112 #endif /* _WIN32 */
113
114 #ifdef HAVE_AIRPCAP
115 #  include <caputils/airpcap.h>
116 #  include <caputils/airpcap_loader.h>
117 //#  include "airpcap_dlg.h"
118 //#  include "airpcap_gui_utils.h"
119 #endif
120
121 #include "epan/crypt/airpdcap_ws.h"
122
123 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
124 #include <QTextCodec>
125 #endif
126
127 /* update the main window */
128 void main_window_update(void)
129 {
130     WiresharkApplication::processEvents();
131 }
132
133 #ifdef HAVE_LIBPCAP
134
135 /* quit a nested main window */
136 void main_window_nested_quit(void)
137 {
138 //    if (gtk_main_level() > 0)
139     wsApp->quit();
140 }
141
142 /* quit the main window */
143 void main_window_quit(void)
144 {
145     wsApp->quit();
146 }
147
148 #endif /* HAVE_LIBPCAP */
149
150 /*
151  * Report an error in command-line arguments.
152  * Creates a console on Windows.
153  */
154 // xxx copied from ../gtk/main.c
155 static void
156 wireshark_cmdarg_err(const char *fmt, va_list ap)
157 {
158 #ifdef _WIN32
159     create_console();
160 #endif
161     fprintf(stderr, "wireshark: ");
162     vfprintf(stderr, fmt, ap);
163     fprintf(stderr, "\n");
164 }
165
166 /*
167  * Report additional information for an error in command-line arguments.
168  * Creates a console on Windows.
169  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
170  * terminal isn't the standard error?
171  */
172 // xxx copied from ../gtk/main.c
173 static void
174 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
175 {
176 #ifdef _WIN32
177     create_console();
178 #endif
179     vfprintf(stderr, fmt, ap);
180     fprintf(stderr, "\n");
181 }
182
183 // xxx based from ../gtk/main.c:get_gtk_compiled_info
184 void
185 get_wireshark_qt_compiled_info(GString *str)
186 {
187     g_string_append(str, "with ");
188     g_string_append_printf(str,
189 #ifdef QT_VERSION
190                     "Qt %s", QT_VERSION_STR);
191 #else
192                     "Qt (version unknown)");
193 #endif
194
195     /* Capture libraries */
196     g_string_append(str, ", ");
197     get_compiled_caplibs_version(str);
198 }
199
200 // xxx copied from ../gtk/main.c
201 void
202 get_gui_compiled_info(GString *str)
203 {
204     epan_get_compiled_version_info(str);
205
206     g_string_append(str, ", ");
207 #ifdef QT_MULTIMEDIA_LIB
208     g_string_append(str, "with QtMultimedia");
209 #else
210     g_string_append(str, "without QtMultimedia");
211 #endif
212
213     g_string_append(str, ", ");
214 #ifdef HAVE_AIRPCAP
215     get_compiled_airpcap_version(str);
216 #else
217     g_string_append(str, "without AirPcap");
218 #endif
219
220     codec_get_compiled_version_info(str);
221 }
222
223 // xxx copied from ../gtk/main.c
224 void
225 get_wireshark_runtime_info(GString *str)
226 {
227 #ifdef HAVE_LIBPCAP
228     /* Capture libraries */
229     g_string_append(str, ", ");
230     get_runtime_caplibs_version(str);
231 #endif
232
233     /* stuff used by libwireshark */
234     epan_get_runtime_version_info(str);
235
236 #ifdef HAVE_AIRPCAP
237     g_string_append(str, ", ");
238     get_runtime_airpcap_version(str);
239 #endif
240 }
241
242 #ifdef HAVE_LIBPCAP
243 /*  Check if there's something important to tell the user during startup.
244  *  We want to do this *after* showing the main window so that any windows
245  *  we pop up will be above the main window.
246  */
247 static void
248 check_and_warn_user_startup(const QString &cf_name)
249 {
250 #ifndef _WIN32
251     Q_UNUSED(cf_name)
252 #endif
253     gchar               *cur_user, *cur_group;
254
255     /* Tell the user not to run as root. */
256     if (running_with_special_privs() && recent.privs_warn_if_elevated) {
257         cur_user = get_cur_username();
258         cur_group = get_cur_groupname();
259         simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
260         "Running as user \"%s\" and group \"%s\".\n"
261         "This could be dangerous.\n\n"
262         "If you're running Wireshark this way in order to perform live capture, "
263         "you may want to be aware that there is a better way documented at\n"
264         "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
265         g_free(cur_user);
266         g_free(cur_group);
267     }
268
269 #ifdef _WIN32
270     /* Warn the user if npf.sys isn't loaded. */
271     if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
272         simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
273         "The NPF driver isn't running. You may have trouble\n"
274         "capturing or listing interfaces.");
275     }
276 #endif
277
278 }
279 #endif
280
281 #ifdef _WIN32
282 // Try to avoid library search path collisions. QCoreApplication will
283 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
284 // the application directory. If
285 //
286 // - You have Qt version 5.x.y installed in the default location
287 //   (C:\Qt\5.x) on your machine.
288 //
289 // and
290 //
291 // - You install Wireshark that was built on a machine with Qt version
292 //   5.x.z installed in the default location.
293 //
294 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
295 // directory. This may not be compatible with qwindows.dll from that
296 // same path on the build machine. At any rate, loading DLLs from paths
297 // you don't control is ill-advised. We work around this by removing every
298 // path except our application directory.
299
300 static inline void
301 reset_library_path(void)
302 {
303     QString app_path = QDir(get_progfile_dir()).path();
304     foreach (QString path, QCoreApplication::libraryPaths()) {
305         QCoreApplication::removeLibraryPath(path);
306     }
307     QCoreApplication::addLibraryPath(app_path);
308 }
309 #endif
310
311 /* And now our feature presentation... [ fade to music ] */
312 int main(int argc, char *qt_argv[])
313 {
314     MainWindow *main_w;
315
316 #ifdef _WIN32
317     int                  opt;
318 #endif
319     int                  ret_val;
320     char               **argv = qt_argv;
321
322 #ifdef _WIN32
323     WSADATA              wsaData;
324 #endif  /* _WIN32 */
325
326     char                *rf_path;
327     int                  rf_open_errno;
328     char                *gdp_path, *dp_path;
329 #ifdef HAVE_LIBPCAP
330     gchar               *err_str;
331     int                  status;
332 #else
333 #ifdef _WIN32
334 #ifdef HAVE_AIRPCAP
335     gchar               *err_str;
336 #endif
337 #endif
338 #endif
339     GString             *comp_info_str = NULL;
340     GString             *runtime_info_str = NULL;
341
342     QString              dfilter, read_filter;
343
344     cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
345
346     // In Qt 5, C strings are treated always as UTF-8 when converted to
347     // QStrings; in Qt 4, the codec must be set to make that happen
348 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
349     // Hopefully we won't have to use QString::fromUtf8() in as many places.
350     QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
351     QTextCodec::setCodecForCStrings(utf8codec);
352     // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
353     QTextCodec::setCodecForTr(utf8codec);
354 #endif
355
356     /* Set the C-language locale to the native environment. */
357     setlocale(LC_ALL, "");
358
359 #ifdef _WIN32
360     // QCoreApplication clobbers argv. Let's have a local copy.
361     argv = (char **) g_malloc(sizeof(char *) * argc);
362     for (opt = 0; opt < argc; opt++) {
363         argv[opt] = qt_argv[opt];
364     }
365     arg_list_utf_16to8(argc, argv);
366     create_app_running_mutex();
367 #endif /* _WIN32 */
368
369     /*
370      * Get credential information for later use, and drop privileges
371      * before doing anything else.
372      * Let the user know if anything happened.
373      */
374     init_process_policies();
375     relinquish_special_privs_perm();
376
377     /*
378      * Attempt to get the pathname of the directory containing the
379      * executable file.
380      */
381     /* init_progfile_dir_error = */ init_progfile_dir(argv[0],
382         (int (*)(int, char **)) get_gui_compiled_info);
383     g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
384
385 #ifdef _WIN32
386     ws_init_dll_search_path();
387     /* Load wpcap if possible. Do this before collecting the run-time version information */
388     load_wpcap();
389
390     /* ... and also load the packet.dll from wpcap */
391     wpcap_packet_load();
392
393 #ifdef HAVE_AIRPCAP
394     /* Load the airpcap.dll.  This must also be done before collecting
395      * run-time version information. */
396     load_airpcap();
397 #if 0
398     airpcap_dll_ret_val = load_airpcap();
399
400     switch (airpcap_dll_ret_val) {
401     case AIRPCAP_DLL_OK:
402         /* load the airpcap interfaces */
403         g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
404
405         if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
406             if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
407                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
408                 g_free(err_str);
409             }
410             airpcap_if_active = NULL;
411
412         } else {
413
414             /* select the first ad default (THIS SHOULD BE CHANGED) */
415             airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
416         }
417         break;
418     /*
419      * XXX - Maybe we need to warn the user if one of the following happens???
420      */
421     case AIRPCAP_DLL_OLD:
422         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
423         break;
424
425     case AIRPCAP_DLL_ERROR:
426         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
427         break;
428
429     case AIRPCAP_DLL_NOT_FOUND:
430         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
431         break;
432     }
433 #endif
434 #endif /* HAVE_AIRPCAP */
435 #endif /* _WIN32 */
436
437     /* Get the compile-time version information string */
438     comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
439                                               get_gui_compiled_info);
440
441     /* Assemble the run-time version information string */
442     runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
443
444     profile_store_persconffiles(TRUE);
445
446     /* Read the profile independent recent file.  We have to do this here so we can */
447     /* set the profile before it can be set from the command line parameter */
448     if (!recent_read_static(&rf_path, &rf_open_errno)) {
449         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
450                       "Could not open common recent file\n\"%s\": %s.",
451                       rf_path, strerror(rf_open_errno));
452         g_free(rf_path);
453     }
454
455     commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
456
457 #ifdef _WIN32
458     reset_library_path();
459 #endif
460
461     /* Create The Wireshark app */
462     WiresharkApplication ws_app(argc, qt_argv);
463
464     /* initialize the funnel mini-api */
465     // xxx qtshark
466     //initialize_funnel_ops();
467
468     AirPDcapInitContext(&airpdcap_ctx);
469
470     QString cf_name;
471     unsigned int in_file_type = WTAP_TYPE_AUTO;
472
473     /* Add it to the information to be reported on a crash. */
474     ws_add_crash_info("Wireshark %s\n"
475            "\n"
476            "%s"
477            "\n"
478            "%s",
479         get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
480     g_string_free(comp_info_str, TRUE);
481     g_string_free(runtime_info_str, TRUE);
482
483 #ifdef _WIN32
484     /* Start windows sockets */
485     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
486 #endif  /* _WIN32 */
487
488     /* Read the profile dependent (static part) of the recent file. */
489     /* Only the static part of it will be read, as we don't have the gui now to fill the */
490     /* recent lists which is done in the dynamic part. */
491     /* We have to do this already here, so command line parameters can overwrite these values. */
492     if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
493         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
494                       "Could not open recent file\n\"%s\": %s.",
495                       rf_path, g_strerror(rf_open_errno));
496         g_free(rf_path);
497     }
498     wsApp->applyCustomColorsFromRecent();
499
500     // Initialize our language
501     read_language_prefs();
502     wsApp->loadLanguage(language);
503
504     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", language);
505
506     // Init the main window (and splash)
507     main_w = new(MainWindow);
508     main_w->show();
509     // We may not need a queued connection here but it would seem to make sense
510     // to force the issue.
511     main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
512             main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
513     main_w->connect(&ws_app, SIGNAL(openCaptureOptions()),
514             main_w, SLOT(on_actionCaptureOptions_triggered()));
515
516     /* Init the "Open file" dialog directory */
517     /* (do this after the path settings are processed) */
518     if (recent.gui_fileopen_remembered_dir &&
519         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
520       wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
521     } else {
522       wsApp->setLastOpenDir(get_persdatafile_dir());
523     }
524
525 #ifdef Q_OS_UNIX
526     // Replicates behavior in gtk_init();
527     signal(SIGPIPE, SIG_IGN);
528 #endif
529
530     set_console_log_handler();
531
532 #ifdef HAVE_LIBPCAP
533     /* Set the initial values in the capture options. This might be overwritten
534        by preference settings and then again by the command line parameters. */
535     capture_opts_init(&global_capture_opts);
536 #endif
537
538     init_report_err(vfailure_alert_box, open_failure_alert_box,
539                     read_failure_alert_box, write_failure_alert_box);
540
541     wtap_init();
542
543 #ifdef HAVE_PLUGINS
544     /* Register all the plugin types we have. */
545     epan_register_plugin_types(); /* Types known to libwireshark */
546     codec_register_plugin_types(); /* Types known to libwscodecs */
547
548     /* Scan for plugins.  This does *not* call their registration routines;
549        that's done later. */
550     scan_plugins(REPORT_LOAD_FAILURE);
551
552     /* Register all libwiretap plugin modules. */
553     register_all_wiretap_modules();
554 #endif
555
556     /* Register all audio codec plugins. */
557     register_all_codecs();
558
559     /* Register all dissectors; we must do this before checking for the
560        "-G" flag, as the "-G" flag dumps information registered by the
561        dissectors, and we must do it before we read the preferences, in
562        case any dissectors register preferences. */
563     if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
564                    splash_update, NULL)) {
565         SimpleDialog::displayQueuedMessages(main_w);
566         return 2;
567     }
568
569     // Read the dynamic part of the recent file. This determines whether or
570     // not the recent list appears in the main window so the earlier we can
571     // call this the better.
572     if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
573         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
574                       "Could not open recent file\n\"%s\": %s.",
575                       rf_path, g_strerror(rf_open_errno));
576         g_free(rf_path);
577     }
578
579     splash_update(RA_LISTENERS, NULL, NULL);
580
581     /* Register all tap listeners; we do this before we parse the arguments,
582        as the "-z" argument can specify a registered tap. */
583
584     /* we register the plugin taps before the other taps because
585             stats_tree taps plugins will be registered as tap listeners
586             by stats_tree_stat.c and need to registered before that */
587 #ifdef HAVE_PLUGINS
588     register_all_plugin_tap_listeners();
589 #endif
590
591 #ifdef HAVE_EXTCAP
592     extcap_register_preferences();
593 #endif
594
595     register_all_tap_listeners();
596     conversation_table_set_gui_info(init_conversation_table);
597     hostlist_table_set_gui_info(init_endpoint_table);
598     srt_table_iterate_tables(register_service_response_tables, NULL);
599     rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
600     new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
601
602     if (ex_opt_count("read_format") > 0) {
603         in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
604     }
605
606     splash_update(RA_PREFERENCES, NULL, NULL);
607
608     global_commandline_info.prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path, false);
609
610     /* Now get our args */
611     commandline_other_options(argc, argv, TRUE);
612
613     /* Convert some command-line parameters to QStrings */
614     if (global_commandline_info.cf_name != NULL)
615         cf_name = QString(global_commandline_info.cf_name);
616     if (global_commandline_info.rfilter != NULL)
617         read_filter = QString(global_commandline_info.rfilter);
618     if (global_commandline_info.dfilter != NULL)
619         dfilter = QString(global_commandline_info.dfilter);
620
621     /* Removed thread code:
622      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
623      */
624
625     timestamp_set_type(recent.gui_time_format);
626     timestamp_set_precision(recent.gui_time_precision);
627     timestamp_set_seconds_type (recent.gui_seconds_format);
628
629 #ifdef HAVE_LIBPCAP
630     splash_update(RA_INTERFACES, NULL, NULL);
631
632     fill_in_local_interfaces(main_window_update);
633
634     if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) {
635         /* We're supposed to do a live capture or get a list of link-layer
636            types for a live capture device; if the user didn't specify an
637            interface to use, pick a default. */
638         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
639         ((global_commandline_info.prefs_p->capture_device) && (*global_commandline_info.prefs_p->capture_device != '\0')) ? get_if_name(global_commandline_info.prefs_p->capture_device) : NULL);
640         if (status != 0) {
641             exit(status);
642         }
643     }
644
645     if (global_commandline_info.list_link_layer_types) {
646         /* Get the list of link-layer types for the capture devices. */
647         if_capabilities_t *caps;
648         guint i;
649         interface_t device;
650         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
651
652             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
653             if (device.selected) {
654 #if defined(HAVE_PCAP_CREATE)
655                 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
656 #else
657                 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
658 #endif
659                 if (caps == NULL) {
660                     cmdarg_err("%s", err_str);
661                     g_free(err_str);
662                     exit(2);
663                 }
664             if (caps->data_link_types == NULL) {
665                 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
666                 exit(2);
667             }
668 #ifdef _WIN32
669             create_console();
670 #endif /* _WIN32 */
671 #if defined(HAVE_PCAP_CREATE)
672             capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
673 #else
674             capture_opts_print_if_capabilities(caps, device.name, FALSE);
675 #endif
676 #ifdef _WIN32
677             destroy_console();
678 #endif /* _WIN32 */
679             free_if_capabilities(caps);
680             }
681         }
682         exit(0);
683     }
684
685     capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
686     capture_opts_trim_ring_num_files(&global_capture_opts);
687 #endif /* HAVE_LIBPCAP */
688
689     /* Notify all registered modules that have had any of their preferences
690        changed either from one of the preferences file or from the command
691        line that their preferences have changed. */
692     prefs_apply_all();
693     wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
694
695 #ifdef HAVE_LIBPCAP
696     if ((global_capture_opts.num_selected == 0) &&
697             (prefs.capture_device != NULL)) {
698         guint i;
699         interface_t device;
700         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
701             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
702             if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
703                 device.selected = TRUE;
704                 global_capture_opts.num_selected++;
705                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
706                 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
707                 break;
708             }
709         }
710     }
711 #endif
712
713     /* disabled protocols as per configuration file */
714     if (gdp_path == NULL && dp_path == NULL) {
715         set_disabled_protos_list();
716         set_enabled_protos_list();
717         set_disabled_heur_dissector_list();
718     }
719
720     if(global_dissect_options.disable_protocol_slist) {
721         GSList *proto_disable;
722         for (proto_disable = global_dissect_options.disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
723         {
724             proto_disable_proto_by_name((char*)proto_disable->data);
725         }
726     }
727
728     if(global_dissect_options.enable_protocol_slist) {
729         GSList *proto_enable;
730         for (proto_enable = global_dissect_options.enable_protocol_slist; proto_enable != NULL; proto_enable = g_slist_next(proto_enable))
731         {
732             proto_enable_proto_by_name((char*)proto_enable->data);
733         }
734     }
735
736     if(global_dissect_options.enable_heur_slist) {
737         GSList *heur_enable;
738         for (heur_enable = global_dissect_options.enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
739         {
740             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
741         }
742     }
743
744     if(global_dissect_options.disable_heur_slist) {
745         GSList *heur_disable;
746         for (heur_disable = global_dissect_options.disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
747         {
748             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
749         }
750     }
751
752     build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
753     wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
754     wsApp->emitAppSignal(WiresharkApplication::RecentPreferencesRead); // Must be emitted after PreferencesChanged.
755
756     wsApp->setMonospaceFont(prefs.gui_qt_font_name);
757
758     /* For update of WindowTitle (When use gui.window_title preference) */
759     main_w->setWSWindowTitle();
760 ////////
761
762     packet_list_enable_color(recent.packet_list_colorize);
763
764     g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
765     packet_list_enable_color(TRUE);
766
767 ////////
768
769
770 ////////
771     gchar* err_msg = NULL;
772     if (!color_filters_init(&err_msg, color_filter_add_cb)) {
773         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
774         g_free(err_msg);
775     }
776
777 ////////
778
779 #ifdef HAVE_LIBPCAP
780     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
781     if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
782         global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
783     }
784 #else /* HAVE_LIBPCAP */
785     ////////
786 #endif /* HAVE_LIBPCAP */
787
788     wsApp->allSystemsGo();
789     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
790     SimpleDialog::displayQueuedMessages(main_w);
791
792     /* User could specify filename, or display filter, or both */
793     if (!dfilter.isEmpty())
794         main_w->filterPackets(dfilter, false);
795     if (!cf_name.isEmpty()) {
796         if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
797
798             /* Open stat windows; we do so after creating the main window,
799                to avoid Qt warnings, and after successfully opening the
800                capture file, so we know we have something to compute stats
801                on, and after registering all dissectors, so that MATE will
802                have registered its field array and we can have a tap filter
803                with one of MATE's late-registered fields as part of the
804                filter. */
805             start_requested_stats();
806
807             if(global_commandline_info.go_to_packet != 0) {
808                 /* Jump to the specified frame number, kept for backward
809                    compatibility. */
810                 cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet);
811             } else if (global_commandline_info.jfilter != NULL) {
812                 dfilter_t *jump_to_filter = NULL;
813                 /* try to compile given filter */
814                 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
815                     // Similar code in MainWindow::mergeCaptureFile().
816                     QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"),
817                                          QObject::tr("The filter expression %1 isn't a valid display filter. (%2).")
818                                                  .arg(global_commandline_info.jfilter, err_msg),
819                                          QMessageBox::Ok);
820                     g_free(err_msg);
821                 } else {
822                     /* Filter ok, jump to the first packet matching the filter
823                        conditions. Default search direction is forward, but if
824                        option d was given, search backwards */
825                     cf_find_packet_dfilter(CaptureFile::globalCapFile(), jump_to_filter, global_commandline_info.jump_backwards);
826                 }
827             }
828         }
829     }
830 #ifdef HAVE_LIBPCAP
831     else {
832         if (global_commandline_info.start_capture) {
833             if (global_capture_opts.save_file != NULL) {
834                 /* Save the directory name for future file dialogs. */
835                 /* (get_dirname overwrites filename) */
836                 gchar *s = g_strdup(global_capture_opts.save_file);
837                 set_last_open_dir(get_dirname(s));
838                 g_free(s);
839             }
840             /* "-k" was specified; start a capture. */
841 //            show_main_window(FALSE);
842             check_and_warn_user_startup(cf_name);
843
844             /* If no user interfaces were specified on the command line,
845                copy the list of selected interfaces to the set of interfaces
846                to use for this capture. */
847             if (global_capture_opts.ifaces->len == 0)
848                 collect_ifaces(&global_capture_opts);
849             CaptureFile::globalCapFile()->window = main_w;
850             if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
851                 /* The capture started.  Open stat windows; we do so after creating
852                    the main window, to avoid GTK warnings, and after successfully
853                    opening the capture file, so we know we have something to compute
854                    stats on, and after registering all dissectors, so that MATE will
855                    have registered its field array and we can have a tap filter with
856                    one of MATE's late-registered fields as part of the filter. */
857                 start_requested_stats();
858             }
859         }
860     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
861         if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
862             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
863         }
864     }
865 #endif /* HAVE_LIBPCAP */
866
867     profile_store_persconffiles(FALSE);
868
869     ret_val = wsApp->exec();
870
871     epan_cleanup();
872
873 #ifdef HAVE_EXTCAP
874     extcap_cleanup();
875 #endif
876
877     AirPDcapDestroyContext(&airpdcap_ctx);
878
879 #ifdef _WIN32
880     /* Shutdown windows sockets */
881     WSACleanup();
882
883     /* For some unknown reason, the "atexit()" call in "create_console()"
884        doesn't arrange that "destroy_console()" be called when we exit,
885        so we call it here if a console was created. */
886     destroy_console();
887 #endif /* _WIN32 */
888
889     return ret_val;
890 }
891
892 /*
893  * Editor modelines
894  *
895  * Local Variables:
896  * c-basic-offset: 4
897  * tab-width: 8
898  * indent-tabs-mode: nil
899  * End:
900  *
901  * ex: set shiftwidth=4 tabstop=8 expandtab:
902  * :indentSize=4:tabSize=8:noTabs=true:
903  */