3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0+
24 #ifndef HAVE_GETOPT_LONG
25 #include "wsutil/wsgetopt.h"
29 #include <wsutil/glib-compat.h>
32 #include <wsutil/clopts_common.h>
33 #include <wsutil/cmdarg_err.h>
34 #include <wsutil/crash_info.h>
35 #include <wsutil/filesystem.h>
36 #include <wsutil/privileges.h>
38 #include <wsutil/plugins.h>
40 #include <wsutil/report_message.h>
41 #include <wsutil/unicode-utils.h>
42 #include <version_info.h>
44 #include <epan/addr_resolv.h>
45 #include <epan/ex-opt.h>
47 #include <epan/stat_tap_ui.h>
48 #include <epan/column.h>
49 #include <epan/disabled_protos.h>
50 #include <epan/prefs.h>
53 #include <epan/packet.h>
54 #include <epan/asn1.h>
55 #include <epan/dissectors/packet-kerberos.h>
58 #include <codecs/codecs.h>
64 /* general (not Qt specific) */
66 #include "epan/color_filters.h"
69 #include "epan/rtd_table.h"
70 #include "epan/srt_table.h"
72 #include "ui/alert_box.h"
73 #include "ui/console.h"
74 #include "ui/iface_lists.h"
75 #include "ui/language.h"
76 #include "ui/persfilepath_opt.h"
77 #include "ui/recent.h"
78 #include "ui/simple_dialog.h"
80 #include "ui/dissect_opts.h"
81 #include "ui/commandline.h"
82 #include "ui/capture_ui_utils.h"
85 #include "ui/qt/conversation_dialog.h"
86 #include "ui/qt/utils/color_utils.h"
87 #include "ui/qt/coloring_rules_dialog.h"
88 #include "ui/qt/endpoint_dialog.h"
89 #include "ui/qt/main_window.h"
90 #include "ui/qt/response_time_delay_dialog.h"
91 #include "ui/qt/service_response_time_dialog.h"
92 #include "ui/qt/simple_dialog.h"
93 #include "ui/qt/simple_statistics_dialog.h"
94 #include "ui/qt/splash_overlay.h"
95 #include "ui/qt/wireshark_application.h"
97 #include "caputils/capture-pcap-util.h"
99 #include <QMessageBox>
102 # include "caputils/capture-wpcap.h"
103 # include "caputils/capture_wpcap_packet.h"
104 # include <tchar.h> /* Needed for Unicode */
105 # include <wsutil/file_util.h>
106 # include <wsutil/os_version_info.h>
110 # include <caputils/airpcap.h>
111 # include <caputils/airpcap_loader.h>
112 //# include "airpcap_dlg.h"
113 //# include "airpcap_gui_utils.h"
116 #include "epan/crypt/airpdcap_ws.h"
118 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
119 #include <QTextCodec>
122 #include <ui/qt/utils/qt_ui_utils.h>
124 #define INVALID_OPTION 1
125 #define INIT_FAILED 2
126 #define INVALID_CAPABILITY 2
127 #define INVALID_LINK_TYPE 2
129 //#define DEBUG_STARTUP_TIME 1
132 # Console log level (for debugging)
133 # A bitmask of log levels:
142 #define DEBUG_STARTUP_TIME_LOGLEVEL 252
144 /* update the main window */
145 void main_window_update(void)
147 WiresharkApplication::processEvents();
152 /* quit a nested main window */
153 void main_window_nested_quit(void)
155 // if (gtk_main_level() > 0)
159 /* quit the main window */
160 void main_window_quit(void)
165 #endif /* HAVE_LIBPCAP */
168 * Report an error in command-line arguments.
169 * Creates a console on Windows.
171 // xxx copied from ../gtk/main.c
173 wireshark_cmdarg_err(const char *fmt, va_list ap)
178 fprintf(stderr, "wireshark: ");
179 vfprintf(stderr, fmt, ap);
180 fprintf(stderr, "\n");
184 * Report additional information for an error in command-line arguments.
185 * Creates a console on Windows.
186 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
187 * terminal isn't the standard error?
189 // xxx copied from ../gtk/main.c
191 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
196 vfprintf(stderr, fmt, ap);
197 fprintf(stderr, "\n");
200 // xxx based from ../gtk/main.c:get_gtk_compiled_info
202 get_wireshark_qt_compiled_info(GString *str)
204 g_string_append(str, "with ");
205 g_string_append_printf(str,
207 "Qt %s", QT_VERSION_STR);
209 "Qt (version unknown)");
212 /* Capture libraries */
213 g_string_append(str, ", ");
214 get_compiled_caplibs_version(str);
217 // xxx copied from ../gtk/main.c
219 get_gui_compiled_info(GString *str)
221 epan_get_compiled_version_info(str);
223 g_string_append(str, ", ");
224 #ifdef QT_MULTIMEDIA_LIB
225 g_string_append(str, "with QtMultimedia");
227 g_string_append(str, "without QtMultimedia");
231 g_string_append(str, ", ");
233 get_compiled_airpcap_version(str);
235 g_string_append(str, "without AirPcap");
239 codec_get_compiled_version_info(str);
242 // xxx copied from ../gtk/main.c
244 get_wireshark_runtime_info(GString *str)
247 /* Capture libraries */
248 g_string_append(str, ", ");
249 get_runtime_caplibs_version(str);
252 /* stuff used by libwireshark */
253 epan_get_runtime_version_info(str);
256 g_string_append(str, ", ");
257 get_runtime_airpcap_version(str);
262 g_log_message_handler(QtMsgType type, const QMessageLogContext &, const QString &msg)
264 GLogLevelFlags log_level = G_LOG_LEVEL_DEBUG;
270 #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
272 log_level = G_LOG_LEVEL_INFO;
276 log_level = G_LOG_LEVEL_WARNING;
279 log_level = G_LOG_LEVEL_CRITICAL;
282 log_level = G_LOG_FLAG_FATAL;
285 g_log(LOG_DOMAIN_MAIN, log_level, "%s", qUtf8Printable(msg));
289 /* Check if there's something important to tell the user during startup.
290 * We want to do this *after* showing the main window so that any windows
291 * we pop up will be above the main window.
294 check_and_warn_user_startup(const QString &cf_name)
299 gchar *cur_user, *cur_group;
301 /* Tell the user not to run as root. */
302 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
303 cur_user = get_cur_username();
304 cur_group = get_cur_groupname();
305 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
306 "Running as user \"%s\" and group \"%s\".\n"
307 "This could be dangerous.\n\n"
308 "If you're running Wireshark this way in order to perform live capture, "
309 "you may want to be aware that there is a better way documented at\n"
310 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
316 /* Warn the user if npf.sys isn't loaded. */
317 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
318 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
319 "The NPF driver isn't running. You may have trouble\n"
320 "capturing or listing interfaces.");
328 // Try to avoid library search path collisions. QCoreApplication will
329 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
330 // the application directory. If
332 // - You have Qt version 5.x.y installed in the default location
333 // (C:\Qt\5.x) on your machine.
337 // - You install Wireshark that was built on a machine with Qt version
338 // 5.x.z installed in the default location.
340 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
341 // directory. This may not be compatible with qwindows.dll from that
342 // same path on the build machine. At any rate, loading DLLs from paths
343 // you don't control is ill-advised. We work around this by removing every
344 // path except our application directory.
347 reset_library_path(void)
349 QString app_path = QDir(get_progfile_dir()).path();
350 foreach (QString path, QCoreApplication::libraryPaths()) {
351 QCoreApplication::removeLibraryPath(path);
353 QCoreApplication::addLibraryPath(app_path);
357 /* And now our feature presentation... [ fade to music ] */
358 int main(int argc, char *qt_argv[])
365 int ret_val = EXIT_SUCCESS;
366 char **argv = qt_argv;
384 gchar *err_msg = NULL;
385 GString *comp_info_str = NULL;
386 GString *runtime_info_str = NULL;
388 QString dfilter, read_filter;
390 int caps_queries = 0;
392 /* Start time in microseconds*/
393 guint64 start_time = g_get_monotonic_time();
394 #ifdef DEBUG_STARTUP_TIME
395 /* At least on Windows there is a problem with the loging as the preferences is taken
396 * into account and the preferences are loaded pretty late in the startup process.
398 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
399 prefs.gui_console_open = console_open_always;
400 #endif /* DEBUG_STARTUP_TIME */
401 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
403 // In Qt 5, C strings are treated always as UTF-8 when converted to
404 // QStrings; in Qt 4, the codec must be set to make that happen
405 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
406 // Hopefully we won't have to use QString::fromUtf8() in as many places.
407 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
408 QTextCodec::setCodecForCStrings(utf8codec);
409 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
410 QTextCodec::setCodecForTr(utf8codec);
413 /* Set the C-language locale to the native environment. */
414 setlocale(LC_ALL, "");
417 // QCoreApplication clobbers argv. Let's have a local copy.
418 argv = (char **) g_malloc(sizeof(char *) * argc);
419 for (opt = 0; opt < argc; opt++) {
420 argv[opt] = qt_argv[opt];
422 arg_list_utf_16to8(argc, argv);
423 create_app_running_mutex();
427 * Get credential information for later use, and drop privileges
428 * before doing anything else.
429 * Let the user know if anything happened.
431 init_process_policies();
432 relinquish_special_privs_perm();
435 * Attempt to get the pathname of the directory containing the
438 /* init_progfile_dir_error = */ init_progfile_dir(argv[0],
439 (int (*)(int, char **)) get_gui_compiled_info);
440 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
443 ws_init_dll_search_path();
444 /* Load wpcap if possible. Do this before collecting the run-time version information */
447 /* ... and also load the packet.dll from wpcap */
451 /* Load the airpcap.dll. This must also be done before collecting
452 * run-time version information. */
455 airpcap_dll_ret_val = load_airpcap();
457 switch (airpcap_dll_ret_val) {
459 /* load the airpcap interfaces */
460 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
462 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
463 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
464 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
467 airpcap_if_active = NULL;
471 /* select the first ad default (THIS SHOULD BE CHANGED) */
472 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
476 * XXX - Maybe we need to warn the user if one of the following happens???
478 case AIRPCAP_DLL_OLD:
479 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
482 case AIRPCAP_DLL_ERROR:
483 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
486 case AIRPCAP_DLL_NOT_FOUND:
487 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
491 #endif /* HAVE_AIRPCAP */
494 /* Get the compile-time version information string */
495 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
496 get_gui_compiled_info);
498 /* Assemble the run-time version information string */
499 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
501 /* Create the user profiles directory */
502 if (create_profiles_dir(&rf_path) == -1) {
503 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
504 "Could not create profiles directory\n\"%s\"",
509 profile_store_persconffiles(TRUE);
512 /* Read the profile independent recent file. We have to do this here so we can */
513 /* set the profile before it can be set from the command line parameter */
514 if (!recent_read_static(&rf_path, &rf_open_errno)) {
515 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
516 "Could not open common recent file\n\"%s\": %s.",
517 rf_path, strerror(rf_open_errno));
521 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
524 reset_library_path();
527 // Handle DPI scaling on Windows. This causes problems in at least
528 // one case on X11 and we don't yet support Android.
529 // We do the equivalent on macOS by setting NSHighResolutionCapable
531 // http://doc.qt.io/qt-5/scalability.html
532 // http://doc.qt.io/qt-5/highdpi.html
533 // https://bugreports.qt.io/browse/QTBUG-53022 - The device pixel ratio is pretty much bogus on Windows.
534 // https://bugreports.qt.io/browse/QTBUG-55510 - Windows have wrong size
535 #if defined(Q_OS_WIN) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
536 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
539 /* Create The Wireshark app */
540 WiresharkApplication ws_app(argc, qt_argv);
542 /* initialize the funnel mini-api */
544 //initialize_funnel_ops();
546 AirPDcapInitContext(&airpdcap_ctx);
549 unsigned int in_file_type = WTAP_TYPE_AUTO;
551 /* Add it to the information to be reported on a crash. */
552 ws_add_crash_info("Wireshark %s\n"
557 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
558 g_string_free(comp_info_str, TRUE);
559 g_string_free(runtime_info_str, TRUE);
562 /* Start windows sockets */
563 result = WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
566 ret_val = INIT_FAILED;
571 /* Read the profile dependent (static part) of the recent file. */
572 /* Only the static part of it will be read, as we don't have the gui now to fill the */
573 /* recent lists which is done in the dynamic part. */
574 /* We have to do this already here, so command line parameters can overwrite these values. */
575 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
576 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
577 "Could not open recent file\n\"%s\": %s.",
578 rf_path, g_strerror(rf_open_errno));
581 wsApp->applyCustomColorsFromRecent();
583 // Initialize our language
584 read_language_prefs();
585 wsApp->loadLanguage(language);
587 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", language);
589 // Init the main window (and splash)
590 main_w = new(MainWindow);
592 // We may not need a queued connection here but it would seem to make sense
593 // to force the issue.
594 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
595 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
596 main_w->connect(&ws_app, SIGNAL(openCaptureOptions()),
597 main_w, SLOT(on_actionCaptureOptions_triggered()));
599 /* Init the "Open file" dialog directory */
600 /* (do this after the path settings are processed) */
601 if (recent.gui_fileopen_remembered_dir &&
602 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
603 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
605 wsApp->setLastOpenDir(get_persdatafile_dir());
609 // Replicates behavior in gtk_init();
610 signal(SIGPIPE, SIG_IGN);
613 set_console_log_handler();
614 qInstallMessageHandler(g_log_message_handler);
615 #ifdef DEBUG_STARTUP_TIME
616 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "set_console_log_handler, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
620 /* Set the initial values in the capture options. This might be overwritten
621 by preference settings and then again by the command line parameters. */
622 capture_opts_init(&global_capture_opts);
625 init_report_message(vfailure_alert_box, vwarning_alert_box,
626 open_failure_alert_box, read_failure_alert_box,
627 write_failure_alert_box);
631 splash_update(RA_DISSECTORS, NULL, NULL);
632 #ifdef DEBUG_STARTUP_TIME
633 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Calling epan init, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
635 /* Register all dissectors; we must do this before checking for the
636 "-G" flag, as the "-G" flag dumps information registered by the
637 dissectors, and we must do it before we read the preferences, in
638 case any dissectors register preferences. */
639 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
640 splash_update, NULL)) {
641 SimpleDialog::displayQueuedMessages(main_w);
642 ret_val = INIT_FAILED;
645 #ifdef DEBUG_STARTUP_TIME
646 /* epan_init resets the preferences */
647 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
648 prefs.gui_console_open = console_open_always;
649 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "epan done, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
652 /* Register all audio codecs. */
655 // Read the dynamic part of the recent file. This determines whether or
656 // not the recent list appears in the main window so the earlier we can
657 // call this the better.
658 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
659 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
660 "Could not open recent file\n\"%s\": %s.",
661 rf_path, g_strerror(rf_open_errno));
664 wsApp->refreshRecentCaptures();
666 splash_update(RA_LISTENERS, NULL, NULL);
667 #ifdef DEBUG_STARTUP_TIME
668 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Register all tap listeners, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
670 /* Register all tap listeners; we do this before we parse the arguments,
671 as the "-z" argument can specify a registered tap. */
673 /* we register the plugin taps before the other taps because
674 stats_tree taps plugins will be registered as tap listeners
675 by stats_tree_stat.c and need to registered before that */
677 register_all_plugin_tap_listeners();
680 /* Register all tap listeners. */
681 for (tap_reg_t *t = tap_reg_listener; t->cb_func != NULL; t++) {
684 conversation_table_set_gui_info(init_conversation_table);
685 hostlist_table_set_gui_info(init_endpoint_table);
686 srt_table_iterate_tables(register_service_response_tables, NULL);
687 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
688 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
690 if (ex_opt_count("read_format") > 0) {
691 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
695 #ifdef DEBUG_STARTUP_TIME
696 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Calling extcap_register_preferences, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
698 splash_update(RA_EXTCAP, NULL, NULL);
699 extcap_register_preferences();
701 splash_update(RA_PREFERENCES, NULL, NULL);
702 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Calling module preferences, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
704 global_commandline_info.prefs_p = ws_app.readConfigurationFiles(false);
706 /* Now get our args */
707 commandline_other_options(argc, argv, TRUE);
709 /* Convert some command-line parameters to QStrings */
710 if (global_commandline_info.cf_name != NULL)
711 cf_name = QString(global_commandline_info.cf_name);
712 if (global_commandline_info.rfilter != NULL)
713 read_filter = QString(global_commandline_info.rfilter);
714 if (global_commandline_info.dfilter != NULL)
715 dfilter = QString(global_commandline_info.dfilter);
717 /* Removed thread code:
718 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
721 timestamp_set_type(recent.gui_time_format);
722 timestamp_set_precision(recent.gui_time_precision);
723 timestamp_set_seconds_type (recent.gui_seconds_format);
726 #ifdef DEBUG_STARTUP_TIME
727 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Calling fill_in_local_interfaces, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
729 splash_update(RA_INTERFACES, NULL, NULL);
731 fill_in_local_interfaces(main_window_update);
733 if (global_commandline_info.list_link_layer_types)
734 caps_queries |= CAPS_QUERY_LINK_TYPES;
735 if (global_commandline_info.list_timestamp_types)
736 caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
738 if (global_commandline_info.start_capture || caps_queries) {
739 /* We're supposed to do a live capture or get a list of link-layer/timestamp
740 types for a live capture device; if the user didn't specify an
741 interface to use, pick a default. */
742 ret_val = capture_opts_default_iface_if_necessary(&global_capture_opts,
743 ((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);
750 /* Get the list of link-layer types for the capture devices. */
751 if_capabilities_t *caps;
754 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
755 int if_caps_queries = caps_queries;
756 device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
757 if (device->selected) {
758 #if defined(HAVE_PCAP_CREATE)
759 caps = capture_get_if_capabilities(device->name, device->monitor_mode_supported, NULL, &err_str, main_window_update);
761 caps = capture_get_if_capabilities(device->name, FALSE, NULL, &err_str,main_window_update);
764 cmdarg_err("%s", err_str);
766 ret_val = INVALID_CAPABILITY;
769 if (caps->data_link_types == NULL) {
770 cmdarg_err("The capture device \"%s\" has no data link types.", device->name);
771 ret_val = INVALID_LINK_TYPE;
777 #if defined(HAVE_PCAP_CREATE)
778 if (device->monitor_mode_supported)
779 if_caps_queries |= CAPS_MONITOR_MODE;
781 capture_opts_print_if_capabilities(caps, device->name, if_caps_queries);
785 free_if_capabilities(caps);
788 ret_val = EXIT_SUCCESS;
792 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
793 capture_opts_trim_ring_num_files(&global_capture_opts);
794 #endif /* HAVE_LIBPCAP */
797 /* Notify all registered modules that have had any of their preferences
798 changed either from one of the preferences file or from the command
799 line that their preferences have changed. */
800 #ifdef DEBUG_STARTUP_TIME
801 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Calling prefs_apply_all, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
804 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
807 if ((global_capture_opts.num_selected == 0) &&
808 (prefs.capture_device != NULL)) {
811 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
812 device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
813 if (!device->hidden && strcmp(device->display_name, prefs.capture_device) == 0) {
814 device->selected = TRUE;
815 global_capture_opts.num_selected++;
823 * Enabled and disabled protocols and heuristic dissectors as per
824 * command-line options.
826 if (!setup_enabled_and_disabled_protocols()) {
827 ret_val = INVALID_OPTION;
831 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
832 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
833 wsApp->emitAppSignal(WiresharkApplication::RecentPreferencesRead); // Must be emitted after PreferencesChanged.
835 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
837 /* For update of WindowTitle (When use gui.window_title preference) */
838 main_w->setWSWindowTitle();
841 packet_list_enable_color(recent.packet_list_colorize);
843 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
844 packet_list_enable_color(TRUE);
850 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
851 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
858 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
859 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
860 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
862 #else /* HAVE_LIBPCAP */
864 #endif /* HAVE_LIBPCAP */
866 wsApp->allSystemsGo();
867 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go, elapsed time %" G_GUINT64_FORMAT "us \n", g_get_monotonic_time() - start_time);
868 SimpleDialog::displayQueuedMessages(main_w);
870 /* User could specify filename, or display filter, or both */
871 if (!dfilter.isEmpty())
872 main_w->filterPackets(dfilter, false);
873 if (!cf_name.isEmpty()) {
874 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
876 /* Open stat windows; we do so after creating the main window,
877 to avoid Qt warnings, and after successfully opening the
878 capture file, so we know we have something to compute stats
879 on, and after registering all dissectors, so that MATE will
880 have registered its field array and we can have a tap filter
881 with one of MATE's late-registered fields as part of the
883 start_requested_stats();
885 if(global_commandline_info.go_to_packet != 0) {
886 /* Jump to the specified frame number, kept for backward
888 cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet);
889 } else if (global_commandline_info.jfilter != NULL) {
890 dfilter_t *jump_to_filter = NULL;
891 /* try to compile given filter */
892 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
893 // Similar code in MainWindow::mergeCaptureFile().
894 QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"),
895 QObject::tr("The filter expression %1 isn't a valid display filter. (%2).")
896 .arg(global_commandline_info.jfilter, err_msg),
900 /* Filter ok, jump to the first packet matching the filter
901 conditions. Default search direction is forward, but if
902 option d was given, search backwards */
903 cf_find_packet_dfilter(CaptureFile::globalCapFile(), jump_to_filter, global_commandline_info.jump_backwards);
910 if (global_commandline_info.start_capture) {
911 if (global_capture_opts.save_file != NULL) {
912 /* Save the directory name for future file dialogs. */
913 /* (get_dirname overwrites filename) */
914 gchar *s = g_strdup(global_capture_opts.save_file);
915 set_last_open_dir(get_dirname(s));
918 /* "-k" was specified; start a capture. */
919 // show_main_window(FALSE);
920 check_and_warn_user_startup(cf_name);
922 /* If no user interfaces were specified on the command line,
923 copy the list of selected interfaces to the set of interfaces
924 to use for this capture. */
925 if (global_capture_opts.ifaces->len == 0)
926 collect_ifaces(&global_capture_opts);
927 CaptureFile::globalCapFile()->window = main_w;
928 if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
929 /* The capture started. Open stat windows; we do so after creating
930 the main window, to avoid GTK warnings, and after successfully
931 opening the capture file, so we know we have something to compute
932 stats on, and after registering all dissectors, so that MATE will
933 have registered its field array and we can have a tap filter with
934 one of MATE's late-registered fields as part of the filter. */
935 start_requested_stats();
938 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
939 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
940 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
943 #endif /* HAVE_LIBPCAP */
945 // UAT files used in configuration profiles which are used in Qt dialogs
946 // are not registered during startup because they only get loaded when
947 // the dialog is shown. Register them here.
948 g_free(get_persconffile_path("io_graphs", TRUE));
950 profile_store_persconffiles(FALSE);
952 ret_val = wsApp->exec();
962 AirPDcapDestroyContext(&airpdcap_ctx);
965 /* Shutdown windows sockets */
968 /* For some unknown reason, the "atexit()" call in "create_console()"
969 doesn't arrange that "destroy_console()" be called when we exit,
970 so we call it here if a console was created. */
976 capture_opts_cleanup(&global_capture_opts);
978 col_cleanup(&CaptureFile::globalCapFile()->cinfo);
991 * indent-tabs-mode: nil
994 * ex: set shiftwidth=4 tabstop=8 expandtab:
995 * :indentSize=4:tabSize=8:noTabs=true: