3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
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.
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.
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.
36 #ifndef HAVE_GETOPT_LONG
37 #include "wsutil/wsgetopt.h"
41 #include <wsutil/glib-compat.h>
44 #include <wsutil/clopts_common.h>
45 #include <wsutil/cmdarg_err.h>
46 #include <wsutil/crash_info.h>
47 #include <wsutil/filesystem.h>
48 #include <wsutil/privileges.h>
50 #include <wsutil/plugins.h>
52 #include <wsutil/report_message.h>
53 #include <wsutil/unicode-utils.h>
54 #include <ws_version_info.h>
56 #include <epan/addr_resolv.h>
57 #include <epan/ex-opt.h>
59 #include <epan/stat_tap_ui.h>
60 #include <epan/column.h>
61 #include <epan/disabled_protos.h>
62 #include <epan/prefs.h>
65 #include <epan/packet.h>
66 #include <epan/asn1.h>
67 #include <epan/dissectors/packet-kerberos.h>
70 #include <codecs/codecs.h>
76 /* general (not Qt specific) */
78 #include "epan/color_filters.h"
81 #include "epan/rtd_table.h"
82 #include "epan/srt_table.h"
84 #include "ui/alert_box.h"
85 #include "ui/console.h"
86 #include "ui/iface_lists.h"
87 #include "ui/language.h"
88 #include "ui/persfilepath_opt.h"
89 #include "ui/recent.h"
90 #include "ui/simple_dialog.h"
92 #include "ui/dissect_opts.h"
93 #include "ui/commandline.h"
94 #include "ui/capture_ui_utils.h"
96 #include "ui/qt/conversation_dialog.h"
97 #include "ui/qt/utils/color_utils.h"
98 #include "ui/qt/coloring_rules_dialog.h"
99 #include "ui/qt/endpoint_dialog.h"
100 #include "ui/qt/main_window.h"
101 #include "ui/qt/response_time_delay_dialog.h"
102 #include "ui/qt/service_response_time_dialog.h"
103 #include "ui/qt/simple_dialog.h"
104 #include "ui/qt/simple_statistics_dialog.h"
105 #include "ui/qt/splash_overlay.h"
106 #include "ui/qt/wireshark_application.h"
108 #include "caputils/capture-pcap-util.h"
110 #include <QMessageBox>
113 # include "caputils/capture-wpcap.h"
114 # include "caputils/capture_wpcap_packet.h"
115 # include <tchar.h> /* Needed for Unicode */
116 # include <wsutil/file_util.h>
117 # include <wsutil/os_version_info.h>
121 # include <caputils/airpcap.h>
122 # include <caputils/airpcap_loader.h>
123 //# include "airpcap_dlg.h"
124 //# include "airpcap_gui_utils.h"
127 #include "epan/crypt/airpdcap_ws.h"
129 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
130 #include <QTextCodec>
133 #define INVALID_OPTION 1
134 #define INIT_FAILED 2
135 #define INVALID_CAPABILITY 2
136 #define INVALID_LINK_TYPE 2
138 //#define DEBUG_STARTUP_TIME 1
141 # Console log level (for debugging)
142 # A bitmask of log levels:
151 #define DEBUG_STARTUP_TIME_LOGLEVEL 252
153 /* update the main window */
154 void main_window_update(void)
156 WiresharkApplication::processEvents();
161 /* quit a nested main window */
162 void main_window_nested_quit(void)
164 // if (gtk_main_level() > 0)
168 /* quit the main window */
169 void main_window_quit(void)
174 #endif /* HAVE_LIBPCAP */
177 * Report an error in command-line arguments.
178 * Creates a console on Windows.
180 // xxx copied from ../gtk/main.c
182 wireshark_cmdarg_err(const char *fmt, va_list ap)
187 fprintf(stderr, "wireshark: ");
188 vfprintf(stderr, fmt, ap);
189 fprintf(stderr, "\n");
193 * Report additional information for an error in command-line arguments.
194 * Creates a console on Windows.
195 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
196 * terminal isn't the standard error?
198 // xxx copied from ../gtk/main.c
200 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
205 vfprintf(stderr, fmt, ap);
206 fprintf(stderr, "\n");
209 // xxx based from ../gtk/main.c:get_gtk_compiled_info
211 get_wireshark_qt_compiled_info(GString *str)
213 g_string_append(str, "with ");
214 g_string_append_printf(str,
216 "Qt %s", QT_VERSION_STR);
218 "Qt (version unknown)");
221 /* Capture libraries */
222 g_string_append(str, ", ");
223 get_compiled_caplibs_version(str);
226 // xxx copied from ../gtk/main.c
228 get_gui_compiled_info(GString *str)
230 epan_get_compiled_version_info(str);
232 g_string_append(str, ", ");
233 #ifdef QT_MULTIMEDIA_LIB
234 g_string_append(str, "with QtMultimedia");
236 g_string_append(str, "without QtMultimedia");
239 g_string_append(str, ", ");
241 get_compiled_airpcap_version(str);
243 g_string_append(str, "without AirPcap");
246 codec_get_compiled_version_info(str);
249 // xxx copied from ../gtk/main.c
251 get_wireshark_runtime_info(GString *str)
254 /* Capture libraries */
255 g_string_append(str, ", ");
256 get_runtime_caplibs_version(str);
259 /* stuff used by libwireshark */
260 epan_get_runtime_version_info(str);
263 g_string_append(str, ", ");
264 get_runtime_airpcap_version(str);
269 /* Check if there's something important to tell the user during startup.
270 * We want to do this *after* showing the main window so that any windows
271 * we pop up will be above the main window.
274 check_and_warn_user_startup(const QString &cf_name)
279 gchar *cur_user, *cur_group;
281 /* Tell the user not to run as root. */
282 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
283 cur_user = get_cur_username();
284 cur_group = get_cur_groupname();
285 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
286 "Running as user \"%s\" and group \"%s\".\n"
287 "This could be dangerous.\n\n"
288 "If you're running Wireshark this way in order to perform live capture, "
289 "you may want to be aware that there is a better way documented at\n"
290 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
296 /* Warn the user if npf.sys isn't loaded. */
297 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
298 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
299 "The NPF driver isn't running. You may have trouble\n"
300 "capturing or listing interfaces.");
308 // Try to avoid library search path collisions. QCoreApplication will
309 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
310 // the application directory. If
312 // - You have Qt version 5.x.y installed in the default location
313 // (C:\Qt\5.x) on your machine.
317 // - You install Wireshark that was built on a machine with Qt version
318 // 5.x.z installed in the default location.
320 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
321 // directory. This may not be compatible with qwindows.dll from that
322 // same path on the build machine. At any rate, loading DLLs from paths
323 // you don't control is ill-advised. We work around this by removing every
324 // path except our application directory.
327 reset_library_path(void)
329 QString app_path = QDir(get_progfile_dir()).path();
330 foreach (QString path, QCoreApplication::libraryPaths()) {
331 QCoreApplication::removeLibraryPath(path);
333 QCoreApplication::addLibraryPath(app_path);
337 /* And now our feature presentation... [ fade to music ] */
338 int main(int argc, char *qt_argv[])
345 int ret_val = EXIT_SUCCESS;
346 char **argv = qt_argv;
364 gchar *err_msg = NULL;
365 GString *comp_info_str = NULL;
366 GString *runtime_info_str = NULL;
368 QString dfilter, read_filter;
369 /* Start time in microseconds*/
370 guint64 start_time = g_get_monotonic_time();
371 #ifdef DEBUG_STARTUP_TIME
372 /* At least on Windows there is a problem with the loging as the preferences is taken
373 * into account and the preferences are loaded pretty late in the startup process.
375 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
376 prefs.gui_console_open = console_open_always;
377 #endif /* DEBUG_STARTUP_TIME */
378 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
380 // In Qt 5, C strings are treated always as UTF-8 when converted to
381 // QStrings; in Qt 4, the codec must be set to make that happen
382 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
383 // Hopefully we won't have to use QString::fromUtf8() in as many places.
384 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
385 QTextCodec::setCodecForCStrings(utf8codec);
386 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
387 QTextCodec::setCodecForTr(utf8codec);
390 /* Set the C-language locale to the native environment. */
391 setlocale(LC_ALL, "");
394 // QCoreApplication clobbers argv. Let's have a local copy.
395 argv = (char **) g_malloc(sizeof(char *) * argc);
396 for (opt = 0; opt < argc; opt++) {
397 argv[opt] = qt_argv[opt];
399 arg_list_utf_16to8(argc, argv);
400 create_app_running_mutex();
404 * Get credential information for later use, and drop privileges
405 * before doing anything else.
406 * Let the user know if anything happened.
408 init_process_policies();
409 relinquish_special_privs_perm();
412 * Attempt to get the pathname of the directory containing the
415 /* init_progfile_dir_error = */ init_progfile_dir(argv[0],
416 (int (*)(int, char **)) get_gui_compiled_info);
417 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
420 ws_init_dll_search_path();
421 /* Load wpcap if possible. Do this before collecting the run-time version information */
424 /* ... and also load the packet.dll from wpcap */
428 /* Load the airpcap.dll. This must also be done before collecting
429 * run-time version information. */
432 airpcap_dll_ret_val = load_airpcap();
434 switch (airpcap_dll_ret_val) {
436 /* load the airpcap interfaces */
437 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
439 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
440 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
441 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
444 airpcap_if_active = NULL;
448 /* select the first ad default (THIS SHOULD BE CHANGED) */
449 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
453 * XXX - Maybe we need to warn the user if one of the following happens???
455 case AIRPCAP_DLL_OLD:
456 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
459 case AIRPCAP_DLL_ERROR:
460 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
463 case AIRPCAP_DLL_NOT_FOUND:
464 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
468 #endif /* HAVE_AIRPCAP */
471 /* Get the compile-time version information string */
472 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
473 get_gui_compiled_info);
475 /* Assemble the run-time version information string */
476 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
478 /* Create the user profiles directory */
479 if (create_profiles_dir(&rf_path) == -1) {
480 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
481 "Could not create profiles directory\n\"%s\"",
486 profile_store_persconffiles(TRUE);
488 /* Read the profile independent recent file. We have to do this here so we can */
489 /* set the profile before it can be set from the command line parameter */
490 if (!recent_read_static(&rf_path, &rf_open_errno)) {
491 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
492 "Could not open common recent file\n\"%s\": %s.",
493 rf_path, strerror(rf_open_errno));
497 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
500 reset_library_path();
503 // Handle DPI scaling on Windows. This causes problems in at least
504 // one case on X11 and we don't yet support Android.
505 // We do the equivalent on macOS by setting NSHighResolutionCapable
507 // http://doc.qt.io/qt-5/scalability.html
508 // http://doc.qt.io/qt-5/highdpi.html
509 // https://bugreports.qt.io/browse/QTBUG-53022 - The device pixel ratio is pretty much bogus on Windows.
510 // https://bugreports.qt.io/browse/QTBUG-55510 - Windows have wrong size
511 #if defined(Q_OS_WIN) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
512 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
515 /* Create The Wireshark app */
516 WiresharkApplication ws_app(argc, qt_argv);
518 /* initialize the funnel mini-api */
520 //initialize_funnel_ops();
522 AirPDcapInitContext(&airpdcap_ctx);
525 unsigned int in_file_type = WTAP_TYPE_AUTO;
527 /* Add it to the information to be reported on a crash. */
528 ws_add_crash_info("Wireshark %s\n"
533 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
534 g_string_free(comp_info_str, TRUE);
535 g_string_free(runtime_info_str, TRUE);
538 /* Start windows sockets */
539 result = WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
542 ret_val = INIT_FAILED;
547 /* Read the profile dependent (static part) of the recent file. */
548 /* Only the static part of it will be read, as we don't have the gui now to fill the */
549 /* recent lists which is done in the dynamic part. */
550 /* We have to do this already here, so command line parameters can overwrite these values. */
551 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
552 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
553 "Could not open recent file\n\"%s\": %s.",
554 rf_path, g_strerror(rf_open_errno));
557 wsApp->applyCustomColorsFromRecent();
559 // Initialize our language
560 read_language_prefs();
561 wsApp->loadLanguage(language);
563 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", language);
565 // Init the main window (and splash)
566 main_w = new(MainWindow);
568 // We may not need a queued connection here but it would seem to make sense
569 // to force the issue.
570 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
571 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
572 main_w->connect(&ws_app, SIGNAL(openCaptureOptions()),
573 main_w, SLOT(on_actionCaptureOptions_triggered()));
575 /* Init the "Open file" dialog directory */
576 /* (do this after the path settings are processed) */
577 if (recent.gui_fileopen_remembered_dir &&
578 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
579 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
581 wsApp->setLastOpenDir(get_persdatafile_dir());
585 // Replicates behavior in gtk_init();
586 signal(SIGPIPE, SIG_IGN);
589 set_console_log_handler();
590 #ifdef DEBUG_STARTUP_TIME
591 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);
595 /* Set the initial values in the capture options. This might be overwritten
596 by preference settings and then again by the command line parameters. */
597 capture_opts_init(&global_capture_opts);
600 init_report_message(vfailure_alert_box, vwarning_alert_box,
601 open_failure_alert_box, read_failure_alert_box,
602 write_failure_alert_box);
607 /* Register all the plugin types we have. */
608 epan_register_plugin_types(); /* Types known to libwireshark */
609 codec_register_plugin_types(); /* Types known to libwscodecs */
611 /* Scan for plugins. This does *not* call their registration routines;
612 that's done later. */
613 scan_plugins(REPORT_LOAD_FAILURE);
615 /* Register all libwiretap plugin modules. */
616 register_all_wiretap_modules();
619 /* Register all audio codec plugins. */
620 register_all_codecs();
622 splash_update(RA_DISSECTORS, NULL, NULL);
623 #ifdef DEBUG_STARTUP_TIME
624 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);
626 /* Register all dissectors; we must do this before checking for the
627 "-G" flag, as the "-G" flag dumps information registered by the
628 dissectors, and we must do it before we read the preferences, in
629 case any dissectors register preferences. */
630 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
631 splash_update, NULL)) {
632 SimpleDialog::displayQueuedMessages(main_w);
633 ret_val = INIT_FAILED;
636 #ifdef DEBUG_STARTUP_TIME
637 /* epan_init resets the preferences */
638 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
639 prefs.gui_console_open = console_open_always;
640 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "epan done, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
643 // Read the dynamic part of the recent file. This determines whether or
644 // not the recent list appears in the main window so the earlier we can
645 // call this the better.
646 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
647 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
648 "Could not open recent file\n\"%s\": %s.",
649 rf_path, g_strerror(rf_open_errno));
653 splash_update(RA_LISTENERS, NULL, NULL);
654 #ifdef DEBUG_STARTUP_TIME
655 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);
657 /* Register all tap listeners; we do this before we parse the arguments,
658 as the "-z" argument can specify a registered tap. */
660 /* we register the plugin taps before the other taps because
661 stats_tree taps plugins will be registered as tap listeners
662 by stats_tree_stat.c and need to registered before that */
664 register_all_plugin_tap_listeners();
667 register_all_tap_listeners();
668 conversation_table_set_gui_info(init_conversation_table);
669 hostlist_table_set_gui_info(init_endpoint_table);
670 srt_table_iterate_tables(register_service_response_tables, NULL);
671 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
672 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
674 if (ex_opt_count("read_format") > 0) {
675 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
679 #ifdef DEBUG_STARTUP_TIME
680 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);
682 splash_update(RA_EXTCAP, NULL, NULL);
683 extcap_register_preferences();
685 splash_update(RA_PREFERENCES, NULL, NULL);
686 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);
688 global_commandline_info.prefs_p = ws_app.readConfigurationFiles(false);
690 /* Now get our args */
691 commandline_other_options(argc, argv, TRUE);
693 /* Convert some command-line parameters to QStrings */
694 if (global_commandline_info.cf_name != NULL)
695 cf_name = QString(global_commandline_info.cf_name);
696 if (global_commandline_info.rfilter != NULL)
697 read_filter = QString(global_commandline_info.rfilter);
698 if (global_commandline_info.dfilter != NULL)
699 dfilter = QString(global_commandline_info.dfilter);
701 /* Removed thread code:
702 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
705 timestamp_set_type(recent.gui_time_format);
706 timestamp_set_precision(recent.gui_time_precision);
707 timestamp_set_seconds_type (recent.gui_seconds_format);
710 #ifdef DEBUG_STARTUP_TIME
711 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);
713 splash_update(RA_INTERFACES, NULL, NULL);
715 fill_in_local_interfaces(main_window_update);
717 if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) {
718 /* We're supposed to do a live capture or get a list of link-layer
719 types for a live capture device; if the user didn't specify an
720 interface to use, pick a default. */
721 ret_val = capture_opts_default_iface_if_necessary(&global_capture_opts,
722 ((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);
728 if (global_commandline_info.list_link_layer_types) {
729 /* Get the list of link-layer types for the capture devices. */
730 if_capabilities_t *caps;
733 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
735 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
736 if (device.selected) {
737 #if defined(HAVE_PCAP_CREATE)
738 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
740 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
743 cmdarg_err("%s", err_str);
745 ret_val = INVALID_CAPABILITY;
748 if (caps->data_link_types == NULL) {
749 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
750 ret_val = INVALID_LINK_TYPE;
756 #if defined(HAVE_PCAP_CREATE)
757 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
759 capture_opts_print_if_capabilities(caps, device.name, FALSE);
764 free_if_capabilities(caps);
767 ret_val = EXIT_SUCCESS;
771 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
772 capture_opts_trim_ring_num_files(&global_capture_opts);
773 #endif /* HAVE_LIBPCAP */
776 /* Notify all registered modules that have had any of their preferences
777 changed either from one of the preferences file or from the command
778 line that their preferences have changed. */
779 #ifdef DEBUG_STARTUP_TIME
780 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);
783 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
786 if ((global_capture_opts.num_selected == 0) &&
787 (prefs.capture_device != NULL)) {
790 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
791 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
792 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
793 device.selected = TRUE;
794 global_capture_opts.num_selected++;
795 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
796 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
804 * Enabled and disabled protocols and heuristic dissectors as per
805 * command-line options.
807 if (!setup_enabled_and_disabled_protocols()) {
808 ret_val = INVALID_OPTION;
812 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
813 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
814 wsApp->emitAppSignal(WiresharkApplication::RecentPreferencesRead); // Must be emitted after PreferencesChanged.
816 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
818 /* For update of WindowTitle (When use gui.window_title preference) */
819 main_w->setWSWindowTitle();
822 packet_list_enable_color(recent.packet_list_colorize);
824 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
825 packet_list_enable_color(TRUE);
831 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
832 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
839 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
840 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
841 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
843 #else /* HAVE_LIBPCAP */
845 #endif /* HAVE_LIBPCAP */
847 wsApp->allSystemsGo();
848 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);
849 SimpleDialog::displayQueuedMessages(main_w);
851 /* User could specify filename, or display filter, or both */
852 if (!dfilter.isEmpty())
853 main_w->filterPackets(dfilter, false);
854 if (!cf_name.isEmpty()) {
855 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
857 /* Open stat windows; we do so after creating the main window,
858 to avoid Qt warnings, and after successfully opening the
859 capture file, so we know we have something to compute stats
860 on, and after registering all dissectors, so that MATE will
861 have registered its field array and we can have a tap filter
862 with one of MATE's late-registered fields as part of the
864 start_requested_stats();
866 if(global_commandline_info.go_to_packet != 0) {
867 /* Jump to the specified frame number, kept for backward
869 cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet);
870 } else if (global_commandline_info.jfilter != NULL) {
871 dfilter_t *jump_to_filter = NULL;
872 /* try to compile given filter */
873 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
874 // Similar code in MainWindow::mergeCaptureFile().
875 QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"),
876 QObject::tr("The filter expression %1 isn't a valid display filter. (%2).")
877 .arg(global_commandline_info.jfilter, err_msg),
881 /* Filter ok, jump to the first packet matching the filter
882 conditions. Default search direction is forward, but if
883 option d was given, search backwards */
884 cf_find_packet_dfilter(CaptureFile::globalCapFile(), jump_to_filter, global_commandline_info.jump_backwards);
891 if (global_commandline_info.start_capture) {
892 if (global_capture_opts.save_file != NULL) {
893 /* Save the directory name for future file dialogs. */
894 /* (get_dirname overwrites filename) */
895 gchar *s = g_strdup(global_capture_opts.save_file);
896 set_last_open_dir(get_dirname(s));
899 /* "-k" was specified; start a capture. */
900 // show_main_window(FALSE);
901 check_and_warn_user_startup(cf_name);
903 /* If no user interfaces were specified on the command line,
904 copy the list of selected interfaces to the set of interfaces
905 to use for this capture. */
906 if (global_capture_opts.ifaces->len == 0)
907 collect_ifaces(&global_capture_opts);
908 CaptureFile::globalCapFile()->window = main_w;
909 if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
910 /* The capture started. Open stat windows; we do so after creating
911 the main window, to avoid GTK warnings, and after successfully
912 opening the capture file, so we know we have something to compute
913 stats on, and after registering all dissectors, so that MATE will
914 have registered its field array and we can have a tap filter with
915 one of MATE's late-registered fields as part of the filter. */
916 start_requested_stats();
919 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
920 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
921 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
924 #endif /* HAVE_LIBPCAP */
926 // UAT files used in configuration profiles which are used in Qt dialogs
927 // are not registered during startup because they only get loaded when
928 // the dialog is shown. Register them here.
929 g_free(get_persconffile_path("io_graphs", TRUE));
931 profile_store_persconffiles(FALSE);
933 ret_val = wsApp->exec();
941 AirPDcapDestroyContext(&airpdcap_ctx);
944 /* Shutdown windows sockets */
947 /* For some unknown reason, the "atexit()" call in "create_console()"
948 doesn't arrange that "destroy_console()" be called when we exit,
949 so we call it here if a console was created. */
955 capture_opts_cleanup(&global_capture_opts);
957 col_cleanup(&CaptureFile::globalCapFile()->cinfo);
972 * indent-tabs-mode: nil
975 * ex: set shiftwidth=4 tabstop=8 expandtab:
976 * :indentSize=4:tabSize=8:noTabs=true: