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>
62 /* general (not Qt specific) */
64 #include "epan/color_filters.h"
67 #include "epan/rtd_table.h"
68 #include "epan/srt_table.h"
70 #include "ui/alert_box.h"
71 #include "ui/console.h"
72 #include "ui/iface_lists.h"
73 #include "ui/language.h"
74 #include "ui/persfilepath_opt.h"
75 #include "ui/recent.h"
76 #include "ui/simple_dialog.h"
78 #include "ui/dissect_opts.h"
79 #include "ui/commandline.h"
80 #include "ui/capture_ui_utils.h"
81 #include "ui/preference_utils.h"
84 #include "ui/qt/conversation_dialog.h"
85 #include "ui/qt/utils/color_utils.h"
86 #include "ui/qt/coloring_rules_dialog.h"
87 #include "ui/qt/endpoint_dialog.h"
88 #include "ui/qt/main_window.h"
89 #include "ui/qt/response_time_delay_dialog.h"
90 #include "ui/qt/service_response_time_dialog.h"
91 #include "ui/qt/simple_dialog.h"
92 #include "ui/qt/simple_statistics_dialog.h"
93 #include "ui/qt/splash_overlay.h"
94 #include "ui/qt/wireshark_application.h"
96 #include "caputils/capture-pcap-util.h"
98 #include <QMessageBox>
101 # include "caputils/capture-wpcap.h"
102 # include "caputils/capture_wpcap_packet.h"
103 # include <tchar.h> /* Needed for Unicode */
104 # include <wsutil/file_util.h>
105 # include <wsutil/os_version_info.h>
109 # include <caputils/airpcap.h>
110 # include <caputils/airpcap_loader.h>
111 //# include "airpcap_dlg.h"
112 //# include "airpcap_gui_utils.h"
115 #include "epan/crypt/airpdcap_ws.h"
117 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
118 #include <QTextCodec>
121 #include <ui/qt/utils/qt_ui_utils.h>
123 #define INVALID_OPTION 1
124 #define INIT_FAILED 2
125 #define INVALID_CAPABILITY 2
126 #define INVALID_LINK_TYPE 2
128 //#define DEBUG_STARTUP_TIME 1
131 # Console log level (for debugging)
132 # A bitmask of log levels:
141 #define DEBUG_STARTUP_TIME_LOGLEVEL 252
143 /* update the main window */
144 void main_window_update(void)
146 WiresharkApplication::processEvents();
151 /* quit a nested main window */
152 void main_window_nested_quit(void)
154 // if (gtk_main_level() > 0)
158 /* quit the main window */
159 void main_window_quit(void)
164 #endif /* HAVE_LIBPCAP */
167 * Report an error in command-line arguments.
168 * Creates a console on Windows.
170 // xxx copied from ../gtk/main.c
172 wireshark_cmdarg_err(const char *fmt, va_list ap)
177 fprintf(stderr, "wireshark: ");
178 vfprintf(stderr, fmt, ap);
179 fprintf(stderr, "\n");
183 * Report additional information for an error in command-line arguments.
184 * Creates a console on Windows.
185 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
186 * terminal isn't the standard error?
188 // xxx copied from ../gtk/main.c
190 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
195 vfprintf(stderr, fmt, ap);
196 fprintf(stderr, "\n");
199 // xxx based from ../gtk/main.c:get_gtk_compiled_info
201 get_wireshark_qt_compiled_info(GString *str)
203 g_string_append(str, "with ");
204 g_string_append_printf(str,
206 "Qt %s", QT_VERSION_STR);
208 "Qt (version unknown)");
211 /* Capture libraries */
212 g_string_append(str, ", ");
213 get_compiled_caplibs_version(str);
216 // xxx copied from ../gtk/main.c
218 get_gui_compiled_info(GString *str)
220 epan_get_compiled_version_info(str);
222 g_string_append(str, ", ");
223 #ifdef QT_MULTIMEDIA_LIB
224 g_string_append(str, "with QtMultimedia");
226 g_string_append(str, "without QtMultimedia");
230 g_string_append(str, ", ");
232 get_compiled_airpcap_version(str);
234 g_string_append(str, "without AirPcap");
238 codec_get_compiled_version_info(str);
241 // xxx copied from ../gtk/main.c
243 get_wireshark_runtime_info(GString *str)
246 /* Capture libraries */
247 g_string_append(str, ", ");
248 get_runtime_caplibs_version(str);
251 /* stuff used by libwireshark */
252 epan_get_runtime_version_info(str);
255 g_string_append(str, ", ");
256 get_runtime_airpcap_version(str);
261 g_log_message_handler(QtMsgType type, const QMessageLogContext &, const QString &msg)
263 GLogLevelFlags log_level = G_LOG_LEVEL_DEBUG;
269 #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
271 log_level = G_LOG_LEVEL_INFO;
275 log_level = G_LOG_LEVEL_WARNING;
278 log_level = G_LOG_LEVEL_CRITICAL;
281 log_level = G_LOG_FLAG_FATAL;
284 g_log(LOG_DOMAIN_MAIN, log_level, "%s", qUtf8Printable(msg));
288 /* Check if there's something important to tell the user during startup.
289 * We want to do this *after* showing the main window so that any windows
290 * we pop up will be above the main window.
293 check_and_warn_user_startup(const QString &cf_name)
298 gchar *cur_user, *cur_group;
300 /* Tell the user not to run as root. */
301 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
302 cur_user = get_cur_username();
303 cur_group = get_cur_groupname();
304 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
305 "Running as user \"%s\" and group \"%s\".\n"
306 "This could be dangerous.\n\n"
307 "If you're running Wireshark this way in order to perform live capture, "
308 "you may want to be aware that there is a better way documented at\n"
309 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
315 /* Warn the user if npf.sys isn't loaded. */
316 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
317 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
318 "The NPF driver isn't running. You may have trouble\n"
319 "capturing or listing interfaces.");
327 // Try to avoid library search path collisions. QCoreApplication will
328 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
329 // the application directory. If
331 // - You have Qt version 5.x.y installed in the default location
332 // (C:\Qt\5.x) on your machine.
336 // - You install Wireshark that was built on a machine with Qt version
337 // 5.x.z installed in the default location.
339 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
340 // directory. This may not be compatible with qwindows.dll from that
341 // same path on the build machine. At any rate, loading DLLs from paths
342 // you don't control is ill-advised. We work around this by removing every
343 // path except our application directory.
346 reset_library_path(void)
348 QString app_path = QDir(get_progfile_dir()).path();
349 foreach (QString path, QCoreApplication::libraryPaths()) {
350 QCoreApplication::removeLibraryPath(path);
352 QCoreApplication::addLibraryPath(app_path);
356 /* And now our feature presentation... [ fade to music ] */
357 int main(int argc, char *qt_argv[])
364 int ret_val = EXIT_SUCCESS;
365 char **argv = qt_argv;
383 gchar *err_msg = NULL;
384 GString *comp_info_str = NULL;
385 GString *runtime_info_str = NULL;
387 QString dfilter, read_filter;
389 int caps_queries = 0;
391 /* Start time in microseconds*/
392 guint64 start_time = g_get_monotonic_time();
393 #ifdef DEBUG_STARTUP_TIME
394 /* At least on Windows there is a problem with the loging as the preferences is taken
395 * into account and the preferences are loaded pretty late in the startup process.
397 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
398 prefs.gui_console_open = console_open_always;
399 #endif /* DEBUG_STARTUP_TIME */
400 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
402 // In Qt 5, C strings are treated always as UTF-8 when converted to
403 // QStrings; in Qt 4, the codec must be set to make that happen
404 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
405 // Hopefully we won't have to use QString::fromUtf8() in as many places.
406 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
407 QTextCodec::setCodecForCStrings(utf8codec);
408 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
409 QTextCodec::setCodecForTr(utf8codec);
412 /* Set the C-language locale to the native environment. */
413 setlocale(LC_ALL, "");
416 // QCoreApplication clobbers argv. Let's have a local copy.
417 argv = (char **) g_malloc(sizeof(char *) * argc);
418 for (opt = 0; opt < argc; opt++) {
419 argv[opt] = qt_argv[opt];
421 arg_list_utf_16to8(argc, argv);
422 create_app_running_mutex();
426 * Get credential information for later use, and drop privileges
427 * before doing anything else.
428 * Let the user know if anything happened.
430 init_process_policies();
431 relinquish_special_privs_perm();
434 * Attempt to get the pathname of the directory containing the
437 /* init_progfile_dir_error = */ init_progfile_dir(argv[0],
438 (int (*)(int, char **)) get_gui_compiled_info);
439 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
442 ws_init_dll_search_path();
443 /* Load wpcap if possible. Do this before collecting the run-time version information */
446 /* ... and also load the packet.dll from wpcap */
450 /* Load the airpcap.dll. This must also be done before collecting
451 * run-time version information. */
454 airpcap_dll_ret_val = load_airpcap();
456 switch (airpcap_dll_ret_val) {
458 /* load the airpcap interfaces */
459 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
461 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
462 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
463 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
466 airpcap_if_active = NULL;
470 /* select the first ad default (THIS SHOULD BE CHANGED) */
471 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
475 * XXX - Maybe we need to warn the user if one of the following happens???
477 case AIRPCAP_DLL_OLD:
478 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
481 case AIRPCAP_DLL_ERROR:
482 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
485 case AIRPCAP_DLL_NOT_FOUND:
486 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
490 #endif /* HAVE_AIRPCAP */
493 /* Get the compile-time version information string */
494 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
495 get_gui_compiled_info);
497 /* Assemble the run-time version information string */
498 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
500 /* Create the user profiles directory */
501 if (create_profiles_dir(&rf_path) == -1) {
502 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
503 "Could not create profiles directory\n\"%s\"",
508 profile_store_persconffiles(TRUE);
511 /* Read the profile independent recent file. We have to do this here so we can */
512 /* set the profile before it can be set from the command line parameter */
513 if (!recent_read_static(&rf_path, &rf_open_errno)) {
514 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
515 "Could not open common recent file\n\"%s\": %s.",
516 rf_path, strerror(rf_open_errno));
520 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
523 reset_library_path();
526 // Handle DPI scaling on Windows. This causes problems in at least
527 // one case on X11 and we don't yet support Android.
528 // We do the equivalent on macOS by setting NSHighResolutionCapable
530 // http://doc.qt.io/qt-5/scalability.html
531 // http://doc.qt.io/qt-5/highdpi.html
532 // https://bugreports.qt.io/browse/QTBUG-53022 - The device pixel ratio is pretty much bogus on Windows.
533 // https://bugreports.qt.io/browse/QTBUG-55510 - Windows have wrong size
534 #if defined(Q_OS_WIN) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
535 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
538 /* Create The Wireshark app */
539 WiresharkApplication ws_app(argc, qt_argv);
541 /* initialize the funnel mini-api */
543 //initialize_funnel_ops();
545 AirPDcapInitContext(&airpdcap_ctx);
548 unsigned int in_file_type = WTAP_TYPE_AUTO;
550 /* Add it to the information to be reported on a crash. */
551 ws_add_crash_info("Wireshark %s\n"
556 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
557 g_string_free(comp_info_str, TRUE);
558 g_string_free(runtime_info_str, TRUE);
561 /* Start windows sockets */
562 result = WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
565 ret_val = INIT_FAILED;
570 /* Read the profile dependent (static part) of the recent file. */
571 /* Only the static part of it will be read, as we don't have the gui now to fill the */
572 /* recent lists which is done in the dynamic part. */
573 /* We have to do this already here, so command line parameters can overwrite these values. */
574 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
575 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
576 "Could not open recent file\n\"%s\": %s.",
577 rf_path, g_strerror(rf_open_errno));
580 wsApp->applyCustomColorsFromRecent();
582 // Initialize our language
583 read_language_prefs();
584 wsApp->loadLanguage(language);
586 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", language);
588 // Init the main window (and splash)
589 main_w = new(MainWindow);
591 // We may not need a queued connection here but it would seem to make sense
592 // to force the issue.
593 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
594 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
595 main_w->connect(&ws_app, SIGNAL(openCaptureOptions()),
596 main_w, SLOT(on_actionCaptureOptions_triggered()));
598 /* Init the "Open file" dialog directory */
599 /* (do this after the path settings are processed) */
600 if (recent.gui_fileopen_remembered_dir &&
601 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
602 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
604 wsApp->setLastOpenDir(get_persdatafile_dir());
608 // Replicates behavior in gtk_init();
609 signal(SIGPIPE, SIG_IGN);
612 set_console_log_handler();
613 qInstallMessageHandler(g_log_message_handler);
614 #ifdef DEBUG_STARTUP_TIME
615 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);
619 /* Set the initial values in the capture options. This might be overwritten
620 by preference settings and then again by the command line parameters. */
621 capture_opts_init(&global_capture_opts);
624 init_report_message(vfailure_alert_box, vwarning_alert_box,
625 open_failure_alert_box, read_failure_alert_box,
626 write_failure_alert_box);
630 splash_update(RA_DISSECTORS, NULL, NULL);
631 #ifdef DEBUG_STARTUP_TIME
632 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);
634 /* Register all dissectors; we must do this before checking for the
635 "-G" flag, as the "-G" flag dumps information registered by the
636 dissectors, and we must do it before we read the preferences, in
637 case any dissectors register preferences. */
638 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
639 splash_update, NULL)) {
640 SimpleDialog::displayQueuedMessages(main_w);
641 ret_val = INIT_FAILED;
644 #ifdef DEBUG_STARTUP_TIME
645 /* epan_init resets the preferences */
646 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
647 prefs.gui_console_open = console_open_always;
648 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "epan done, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
651 /* Register all audio codecs. */
654 // Read the dynamic part of the recent file. This determines whether or
655 // not the recent list appears in the main window so the earlier we can
656 // call this the better.
657 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
658 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
659 "Could not open recent file\n\"%s\": %s.",
660 rf_path, g_strerror(rf_open_errno));
663 wsApp->refreshRecentCaptures();
665 splash_update(RA_LISTENERS, NULL, NULL);
666 #ifdef DEBUG_STARTUP_TIME
667 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);
669 /* Register all tap listeners; we do this before we parse the arguments,
670 as the "-z" argument can specify a registered tap. */
672 /* we register the plugin taps before the other taps because
673 stats_tree taps plugins will be registered as tap listeners
674 by stats_tree_stat.c and need to registered before that */
676 register_all_plugin_tap_listeners();
679 /* Register all tap listeners. */
680 for (tap_reg_t *t = tap_reg_listener; t->cb_func != NULL; t++) {
683 conversation_table_set_gui_info(init_conversation_table);
684 hostlist_table_set_gui_info(init_endpoint_table);
685 srt_table_iterate_tables(register_service_response_tables, NULL);
686 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
687 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
689 if (ex_opt_count("read_format") > 0) {
690 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
693 #ifdef DEBUG_STARTUP_TIME
694 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);
696 splash_update(RA_EXTCAP, NULL, NULL);
697 extcap_register_preferences();
698 splash_update(RA_PREFERENCES, NULL, NULL);
699 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);
701 global_commandline_info.prefs_p = ws_app.readConfigurationFiles(false);
703 /* Now get our args */
704 commandline_other_options(argc, argv, TRUE);
706 /* Convert some command-line parameters to QStrings */
707 if (global_commandline_info.cf_name != NULL)
708 cf_name = QString(global_commandline_info.cf_name);
709 if (global_commandline_info.rfilter != NULL)
710 read_filter = QString(global_commandline_info.rfilter);
711 if (global_commandline_info.dfilter != NULL)
712 dfilter = QString(global_commandline_info.dfilter);
714 /* Removed thread code:
715 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
718 timestamp_set_type(recent.gui_time_format);
719 timestamp_set_precision(recent.gui_time_precision);
720 timestamp_set_seconds_type (recent.gui_seconds_format);
723 #ifdef DEBUG_STARTUP_TIME
724 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);
726 splash_update(RA_INTERFACES, NULL, NULL);
728 fill_in_local_interfaces(main_window_update);
730 if (global_commandline_info.list_link_layer_types)
731 caps_queries |= CAPS_QUERY_LINK_TYPES;
732 if (global_commandline_info.list_timestamp_types)
733 caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
735 if (global_commandline_info.start_capture || caps_queries) {
736 /* We're supposed to do a live capture or get a list of link-layer/timestamp
737 types for a live capture device; if the user didn't specify an
738 interface to use, pick a default. */
739 ret_val = capture_opts_default_iface_if_necessary(&global_capture_opts,
740 ((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);
747 /* Get the list of link-layer types for the capture devices. */
748 if_capabilities_t *caps;
751 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
752 int if_caps_queries = caps_queries;
753 device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
754 if (device->selected) {
755 #if defined(HAVE_PCAP_CREATE)
756 caps = capture_get_if_capabilities(device->name, device->monitor_mode_supported, NULL, &err_str, main_window_update);
758 caps = capture_get_if_capabilities(device->name, FALSE, NULL, &err_str,main_window_update);
761 cmdarg_err("%s", err_str);
763 ret_val = INVALID_CAPABILITY;
766 if (caps->data_link_types == NULL) {
767 cmdarg_err("The capture device \"%s\" has no data link types.", device->name);
768 ret_val = INVALID_LINK_TYPE;
774 #if defined(HAVE_PCAP_CREATE)
775 if (device->monitor_mode_supported)
776 if_caps_queries |= CAPS_MONITOR_MODE;
778 capture_opts_print_if_capabilities(caps, device->name, if_caps_queries);
782 free_if_capabilities(caps);
785 ret_val = EXIT_SUCCESS;
789 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
790 capture_opts_trim_ring_num_files(&global_capture_opts);
791 #endif /* HAVE_LIBPCAP */
793 /* Notify all registered modules that have had any of their preferences
794 changed either from one of the preferences file or from the command
795 line that their preferences have changed. */
796 #ifdef DEBUG_STARTUP_TIME
797 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);
800 prefs_to_capture_opts();
801 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
804 if ((global_capture_opts.num_selected == 0) &&
805 (prefs.capture_device != NULL)) {
808 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
809 device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
810 if (!device->hidden && strcmp(device->display_name, prefs.capture_device) == 0) {
811 device->selected = TRUE;
812 global_capture_opts.num_selected++;
820 * Enabled and disabled protocols and heuristic dissectors as per
821 * command-line options.
823 if (!setup_enabled_and_disabled_protocols()) {
824 ret_val = INVALID_OPTION;
828 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
829 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
830 wsApp->emitAppSignal(WiresharkApplication::RecentPreferencesRead); // Must be emitted after PreferencesChanged.
832 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
834 /* For update of WindowTitle (When use gui.window_title preference) */
835 main_w->setWSWindowTitle();
838 packet_list_enable_color(recent.packet_list_colorize);
840 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
841 packet_list_enable_color(TRUE);
847 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
848 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
855 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
856 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
857 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
859 #else /* HAVE_LIBPCAP */
861 #endif /* HAVE_LIBPCAP */
863 wsApp->allSystemsGo();
864 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);
865 SimpleDialog::displayQueuedMessages(main_w);
867 /* User could specify filename, or display filter, or both */
868 if (!dfilter.isEmpty())
869 main_w->filterPackets(dfilter, false);
870 if (!cf_name.isEmpty()) {
871 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
873 /* Open stat windows; we do so after creating the main window,
874 to avoid Qt warnings, and after successfully opening the
875 capture file, so we know we have something to compute stats
876 on, and after registering all dissectors, so that MATE will
877 have registered its field array and we can have a tap filter
878 with one of MATE's late-registered fields as part of the
880 start_requested_stats();
882 if(global_commandline_info.go_to_packet != 0) {
883 /* Jump to the specified frame number, kept for backward
885 cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet);
886 } else if (global_commandline_info.jfilter != NULL) {
887 dfilter_t *jump_to_filter = NULL;
888 /* try to compile given filter */
889 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
890 // Similar code in MainWindow::mergeCaptureFile().
891 QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"),
892 QObject::tr("The filter expression %1 isn't a valid display filter. (%2).")
893 .arg(global_commandline_info.jfilter, err_msg),
897 /* Filter ok, jump to the first packet matching the filter
898 conditions. Default search direction is forward, but if
899 option d was given, search backwards */
900 cf_find_packet_dfilter(CaptureFile::globalCapFile(), jump_to_filter, global_commandline_info.jump_backwards);
907 if (global_commandline_info.start_capture) {
908 if (global_capture_opts.save_file != NULL) {
909 /* Save the directory name for future file dialogs. */
910 /* (get_dirname overwrites filename) */
911 gchar *s = g_strdup(global_capture_opts.save_file);
912 set_last_open_dir(get_dirname(s));
915 /* "-k" was specified; start a capture. */
916 // show_main_window(FALSE);
917 check_and_warn_user_startup(cf_name);
919 /* If no user interfaces were specified on the command line,
920 copy the list of selected interfaces to the set of interfaces
921 to use for this capture. */
922 if (global_capture_opts.ifaces->len == 0)
923 collect_ifaces(&global_capture_opts);
924 CaptureFile::globalCapFile()->window = main_w;
925 if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
926 /* The capture started. Open stat windows; we do so after creating
927 the main window, to avoid GTK warnings, and after successfully
928 opening the capture file, so we know we have something to compute
929 stats on, and after registering all dissectors, so that MATE will
930 have registered its field array and we can have a tap filter with
931 one of MATE's late-registered fields as part of the filter. */
932 start_requested_stats();
935 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
936 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
937 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
940 #endif /* HAVE_LIBPCAP */
942 // UAT files used in configuration profiles which are used in Qt dialogs
943 // are not registered during startup because they only get loaded when
944 // the dialog is shown. Register them here.
945 g_free(get_persconffile_path("io_graphs", TRUE));
947 profile_store_persconffiles(FALSE);
949 ret_val = wsApp->exec();
957 AirPDcapDestroyContext(&airpdcap_ctx);
960 /* Shutdown windows sockets */
963 /* For some unknown reason, the "atexit()" call in "create_console()"
964 doesn't arrange that "destroy_console()" be called when we exit,
965 so we call it here if a console was created. */
971 capture_opts_cleanup(&global_capture_opts);
973 col_cleanup(&CaptureFile::globalCapFile()->cinfo);
986 * indent-tabs-mode: nil
989 * ex: set shiftwidth=4 tabstop=8 expandtab:
990 * :indentSize=4:tabSize=8:noTabs=true: