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 <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");
240 g_string_append(str, ", ");
242 get_compiled_airpcap_version(str);
244 g_string_append(str, "without AirPcap");
248 codec_get_compiled_version_info(str);
251 // xxx copied from ../gtk/main.c
253 get_wireshark_runtime_info(GString *str)
256 /* Capture libraries */
257 g_string_append(str, ", ");
258 get_runtime_caplibs_version(str);
261 /* stuff used by libwireshark */
262 epan_get_runtime_version_info(str);
265 g_string_append(str, ", ");
266 get_runtime_airpcap_version(str);
271 /* Check if there's something important to tell the user during startup.
272 * We want to do this *after* showing the main window so that any windows
273 * we pop up will be above the main window.
276 check_and_warn_user_startup(const QString &cf_name)
281 gchar *cur_user, *cur_group;
283 /* Tell the user not to run as root. */
284 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
285 cur_user = get_cur_username();
286 cur_group = get_cur_groupname();
287 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
288 "Running as user \"%s\" and group \"%s\".\n"
289 "This could be dangerous.\n\n"
290 "If you're running Wireshark this way in order to perform live capture, "
291 "you may want to be aware that there is a better way documented at\n"
292 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
298 /* Warn the user if npf.sys isn't loaded. */
299 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
300 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
301 "The NPF driver isn't running. You may have trouble\n"
302 "capturing or listing interfaces.");
310 // Try to avoid library search path collisions. QCoreApplication will
311 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
312 // the application directory. If
314 // - You have Qt version 5.x.y installed in the default location
315 // (C:\Qt\5.x) on your machine.
319 // - You install Wireshark that was built on a machine with Qt version
320 // 5.x.z installed in the default location.
322 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
323 // directory. This may not be compatible with qwindows.dll from that
324 // same path on the build machine. At any rate, loading DLLs from paths
325 // you don't control is ill-advised. We work around this by removing every
326 // path except our application directory.
329 reset_library_path(void)
331 QString app_path = QDir(get_progfile_dir()).path();
332 foreach (QString path, QCoreApplication::libraryPaths()) {
333 QCoreApplication::removeLibraryPath(path);
335 QCoreApplication::addLibraryPath(app_path);
339 /* And now our feature presentation... [ fade to music ] */
340 int main(int argc, char *qt_argv[])
347 int ret_val = EXIT_SUCCESS;
348 char **argv = qt_argv;
366 gchar *err_msg = NULL;
367 GString *comp_info_str = NULL;
368 GString *runtime_info_str = NULL;
370 QString dfilter, read_filter;
372 int caps_queries = 0;
374 /* Start time in microseconds*/
375 guint64 start_time = g_get_monotonic_time();
376 #ifdef DEBUG_STARTUP_TIME
377 /* At least on Windows there is a problem with the loging as the preferences is taken
378 * into account and the preferences are loaded pretty late in the startup process.
380 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
381 prefs.gui_console_open = console_open_always;
382 #endif /* DEBUG_STARTUP_TIME */
383 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
385 // In Qt 5, C strings are treated always as UTF-8 when converted to
386 // QStrings; in Qt 4, the codec must be set to make that happen
387 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
388 // Hopefully we won't have to use QString::fromUtf8() in as many places.
389 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
390 QTextCodec::setCodecForCStrings(utf8codec);
391 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
392 QTextCodec::setCodecForTr(utf8codec);
395 /* Set the C-language locale to the native environment. */
396 setlocale(LC_ALL, "");
399 // QCoreApplication clobbers argv. Let's have a local copy.
400 argv = (char **) g_malloc(sizeof(char *) * argc);
401 for (opt = 0; opt < argc; opt++) {
402 argv[opt] = qt_argv[opt];
404 arg_list_utf_16to8(argc, argv);
405 create_app_running_mutex();
409 * Get credential information for later use, and drop privileges
410 * before doing anything else.
411 * Let the user know if anything happened.
413 init_process_policies();
414 relinquish_special_privs_perm();
417 * Attempt to get the pathname of the directory containing the
420 /* init_progfile_dir_error = */ init_progfile_dir(argv[0],
421 (int (*)(int, char **)) get_gui_compiled_info);
422 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
425 ws_init_dll_search_path();
426 /* Load wpcap if possible. Do this before collecting the run-time version information */
429 /* ... and also load the packet.dll from wpcap */
433 /* Load the airpcap.dll. This must also be done before collecting
434 * run-time version information. */
437 airpcap_dll_ret_val = load_airpcap();
439 switch (airpcap_dll_ret_val) {
441 /* load the airpcap interfaces */
442 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
444 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
445 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
446 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
449 airpcap_if_active = NULL;
453 /* select the first ad default (THIS SHOULD BE CHANGED) */
454 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
458 * XXX - Maybe we need to warn the user if one of the following happens???
460 case AIRPCAP_DLL_OLD:
461 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
464 case AIRPCAP_DLL_ERROR:
465 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
468 case AIRPCAP_DLL_NOT_FOUND:
469 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
473 #endif /* HAVE_AIRPCAP */
476 /* Get the compile-time version information string */
477 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
478 get_gui_compiled_info);
480 /* Assemble the run-time version information string */
481 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
483 /* Create the user profiles directory */
484 if (create_profiles_dir(&rf_path) == -1) {
485 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
486 "Could not create profiles directory\n\"%s\"",
491 profile_store_persconffiles(TRUE);
494 /* Read the profile independent recent file. We have to do this here so we can */
495 /* set the profile before it can be set from the command line parameter */
496 if (!recent_read_static(&rf_path, &rf_open_errno)) {
497 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
498 "Could not open common recent file\n\"%s\": %s.",
499 rf_path, strerror(rf_open_errno));
503 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
506 reset_library_path();
509 // Handle DPI scaling on Windows. This causes problems in at least
510 // one case on X11 and we don't yet support Android.
511 // We do the equivalent on macOS by setting NSHighResolutionCapable
513 // http://doc.qt.io/qt-5/scalability.html
514 // http://doc.qt.io/qt-5/highdpi.html
515 // https://bugreports.qt.io/browse/QTBUG-53022 - The device pixel ratio is pretty much bogus on Windows.
516 // https://bugreports.qt.io/browse/QTBUG-55510 - Windows have wrong size
517 #if defined(Q_OS_WIN) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
518 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
521 /* Create The Wireshark app */
522 WiresharkApplication ws_app(argc, qt_argv);
524 /* initialize the funnel mini-api */
526 //initialize_funnel_ops();
528 AirPDcapInitContext(&airpdcap_ctx);
531 unsigned int in_file_type = WTAP_TYPE_AUTO;
533 /* Add it to the information to be reported on a crash. */
534 ws_add_crash_info("Wireshark %s\n"
539 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
540 g_string_free(comp_info_str, TRUE);
541 g_string_free(runtime_info_str, TRUE);
544 /* Start windows sockets */
545 result = WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
548 ret_val = INIT_FAILED;
553 /* Read the profile dependent (static part) of the recent file. */
554 /* Only the static part of it will be read, as we don't have the gui now to fill the */
555 /* recent lists which is done in the dynamic part. */
556 /* We have to do this already here, so command line parameters can overwrite these values. */
557 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
558 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
559 "Could not open recent file\n\"%s\": %s.",
560 rf_path, g_strerror(rf_open_errno));
563 wsApp->applyCustomColorsFromRecent();
565 // Initialize our language
566 read_language_prefs();
567 wsApp->loadLanguage(language);
569 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", language);
571 // Init the main window (and splash)
572 main_w = new(MainWindow);
574 // We may not need a queued connection here but it would seem to make sense
575 // to force the issue.
576 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
577 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
578 main_w->connect(&ws_app, SIGNAL(openCaptureOptions()),
579 main_w, SLOT(on_actionCaptureOptions_triggered()));
581 /* Init the "Open file" dialog directory */
582 /* (do this after the path settings are processed) */
583 if (recent.gui_fileopen_remembered_dir &&
584 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
585 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
587 wsApp->setLastOpenDir(get_persdatafile_dir());
591 // Replicates behavior in gtk_init();
592 signal(SIGPIPE, SIG_IGN);
595 set_console_log_handler();
596 #ifdef DEBUG_STARTUP_TIME
597 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);
601 /* Set the initial values in the capture options. This might be overwritten
602 by preference settings and then again by the command line parameters. */
603 capture_opts_init(&global_capture_opts);
606 init_report_message(vfailure_alert_box, vwarning_alert_box,
607 open_failure_alert_box, read_failure_alert_box,
608 write_failure_alert_box);
613 /* Register all the plugin types we have. */
614 epan_register_plugin_types(); /* Types known to libwireshark */
615 codec_register_plugin_types(); /* Types known to libwscodecs */
617 /* Scan for plugins. This does *not* call their registration routines;
618 that's done later. */
619 scan_plugins(REPORT_LOAD_FAILURE);
621 /* Register all libwiretap plugin modules. */
622 register_all_wiretap_modules();
625 /* Register all audio codec plugins. */
626 register_all_codecs();
628 splash_update(RA_DISSECTORS, NULL, NULL);
629 #ifdef DEBUG_STARTUP_TIME
630 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);
632 /* Register all dissectors; we must do this before checking for the
633 "-G" flag, as the "-G" flag dumps information registered by the
634 dissectors, and we must do it before we read the preferences, in
635 case any dissectors register preferences. */
636 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
637 splash_update, NULL)) {
638 SimpleDialog::displayQueuedMessages(main_w);
639 ret_val = INIT_FAILED;
642 #ifdef DEBUG_STARTUP_TIME
643 /* epan_init resets the preferences */
644 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
645 prefs.gui_console_open = console_open_always;
646 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "epan done, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
649 // Read the dynamic part of the recent file. This determines whether or
650 // not the recent list appears in the main window so the earlier we can
651 // call this the better.
652 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
653 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
654 "Could not open recent file\n\"%s\": %s.",
655 rf_path, g_strerror(rf_open_errno));
659 splash_update(RA_LISTENERS, NULL, NULL);
660 #ifdef DEBUG_STARTUP_TIME
661 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);
663 /* Register all tap listeners; we do this before we parse the arguments,
664 as the "-z" argument can specify a registered tap. */
666 /* we register the plugin taps before the other taps because
667 stats_tree taps plugins will be registered as tap listeners
668 by stats_tree_stat.c and need to registered before that */
670 register_all_plugin_tap_listeners();
673 register_all_tap_listeners();
674 conversation_table_set_gui_info(init_conversation_table);
675 hostlist_table_set_gui_info(init_endpoint_table);
676 srt_table_iterate_tables(register_service_response_tables, NULL);
677 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
678 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
680 if (ex_opt_count("read_format") > 0) {
681 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
685 #ifdef DEBUG_STARTUP_TIME
686 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);
688 splash_update(RA_EXTCAP, NULL, NULL);
689 extcap_register_preferences();
691 splash_update(RA_PREFERENCES, NULL, NULL);
692 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);
694 global_commandline_info.prefs_p = ws_app.readConfigurationFiles(false);
696 /* Now get our args */
697 commandline_other_options(argc, argv, TRUE);
699 /* Convert some command-line parameters to QStrings */
700 if (global_commandline_info.cf_name != NULL)
701 cf_name = QString(global_commandline_info.cf_name);
702 if (global_commandline_info.rfilter != NULL)
703 read_filter = QString(global_commandline_info.rfilter);
704 if (global_commandline_info.dfilter != NULL)
705 dfilter = QString(global_commandline_info.dfilter);
707 /* Removed thread code:
708 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
711 timestamp_set_type(recent.gui_time_format);
712 timestamp_set_precision(recent.gui_time_precision);
713 timestamp_set_seconds_type (recent.gui_seconds_format);
716 #ifdef DEBUG_STARTUP_TIME
717 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);
719 splash_update(RA_INTERFACES, NULL, NULL);
721 fill_in_local_interfaces(main_window_update);
723 if (global_commandline_info.list_link_layer_types)
724 caps_queries |= CAPS_QUERY_LINK_TYPES;
725 if (global_commandline_info.list_timestamp_types)
726 caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
728 if (global_commandline_info.start_capture || caps_queries) {
729 /* We're supposed to do a live capture or get a list of link-layer/timestamp
730 types for a live capture device; if the user didn't specify an
731 interface to use, pick a default. */
732 ret_val = capture_opts_default_iface_if_necessary(&global_capture_opts,
733 ((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);
740 /* Get the list of link-layer types for the capture devices. */
741 if_capabilities_t *caps;
744 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
745 int if_caps_queries = caps_queries;
746 device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
747 if (device->selected) {
748 #if defined(HAVE_PCAP_CREATE)
749 caps = capture_get_if_capabilities(device->name, device->monitor_mode_supported, NULL, &err_str, main_window_update);
751 caps = capture_get_if_capabilities(device->name, FALSE, NULL, &err_str,main_window_update);
754 cmdarg_err("%s", err_str);
756 ret_val = INVALID_CAPABILITY;
759 if (caps->data_link_types == NULL) {
760 cmdarg_err("The capture device \"%s\" has no data link types.", device->name);
761 ret_val = INVALID_LINK_TYPE;
767 #if defined(HAVE_PCAP_CREATE)
768 if (device->monitor_mode_supported)
769 if_caps_queries |= CAPS_MONITOR_MODE;
771 capture_opts_print_if_capabilities(caps, device->name, if_caps_queries);
775 free_if_capabilities(caps);
778 ret_val = EXIT_SUCCESS;
782 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
783 capture_opts_trim_ring_num_files(&global_capture_opts);
784 #endif /* HAVE_LIBPCAP */
787 /* Notify all registered modules that have had any of their preferences
788 changed either from one of the preferences file or from the command
789 line that their preferences have changed. */
790 #ifdef DEBUG_STARTUP_TIME
791 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);
794 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
797 if ((global_capture_opts.num_selected == 0) &&
798 (prefs.capture_device != NULL)) {
801 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
802 device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
803 if (!device->hidden && strcmp(device->display_name, prefs.capture_device) == 0) {
804 device->selected = TRUE;
805 global_capture_opts.num_selected++;
813 * Enabled and disabled protocols and heuristic dissectors as per
814 * command-line options.
816 if (!setup_enabled_and_disabled_protocols()) {
817 ret_val = INVALID_OPTION;
821 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
822 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
823 wsApp->emitAppSignal(WiresharkApplication::RecentPreferencesRead); // Must be emitted after PreferencesChanged.
825 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
827 /* For update of WindowTitle (When use gui.window_title preference) */
828 main_w->setWSWindowTitle();
831 packet_list_enable_color(recent.packet_list_colorize);
833 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
834 packet_list_enable_color(TRUE);
840 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
841 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
848 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
849 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
850 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
852 #else /* HAVE_LIBPCAP */
854 #endif /* HAVE_LIBPCAP */
856 wsApp->allSystemsGo();
857 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);
858 SimpleDialog::displayQueuedMessages(main_w);
860 /* User could specify filename, or display filter, or both */
861 if (!dfilter.isEmpty())
862 main_w->filterPackets(dfilter, false);
863 if (!cf_name.isEmpty()) {
864 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
866 /* Open stat windows; we do so after creating the main window,
867 to avoid Qt warnings, and after successfully opening the
868 capture file, so we know we have something to compute stats
869 on, and after registering all dissectors, so that MATE will
870 have registered its field array and we can have a tap filter
871 with one of MATE's late-registered fields as part of the
873 start_requested_stats();
875 if(global_commandline_info.go_to_packet != 0) {
876 /* Jump to the specified frame number, kept for backward
878 cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet);
879 } else if (global_commandline_info.jfilter != NULL) {
880 dfilter_t *jump_to_filter = NULL;
881 /* try to compile given filter */
882 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
883 // Similar code in MainWindow::mergeCaptureFile().
884 QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"),
885 QObject::tr("The filter expression %1 isn't a valid display filter. (%2).")
886 .arg(global_commandline_info.jfilter, err_msg),
890 /* Filter ok, jump to the first packet matching the filter
891 conditions. Default search direction is forward, but if
892 option d was given, search backwards */
893 cf_find_packet_dfilter(CaptureFile::globalCapFile(), jump_to_filter, global_commandline_info.jump_backwards);
900 if (global_commandline_info.start_capture) {
901 if (global_capture_opts.save_file != NULL) {
902 /* Save the directory name for future file dialogs. */
903 /* (get_dirname overwrites filename) */
904 gchar *s = g_strdup(global_capture_opts.save_file);
905 set_last_open_dir(get_dirname(s));
908 /* "-k" was specified; start a capture. */
909 // show_main_window(FALSE);
910 check_and_warn_user_startup(cf_name);
912 /* If no user interfaces were specified on the command line,
913 copy the list of selected interfaces to the set of interfaces
914 to use for this capture. */
915 if (global_capture_opts.ifaces->len == 0)
916 collect_ifaces(&global_capture_opts);
917 CaptureFile::globalCapFile()->window = main_w;
918 if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
919 /* The capture started. Open stat windows; we do so after creating
920 the main window, to avoid GTK warnings, and after successfully
921 opening the capture file, so we know we have something to compute
922 stats on, and after registering all dissectors, so that MATE will
923 have registered its field array and we can have a tap filter with
924 one of MATE's late-registered fields as part of the filter. */
925 start_requested_stats();
928 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
929 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
930 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
933 #endif /* HAVE_LIBPCAP */
935 // UAT files used in configuration profiles which are used in Qt dialogs
936 // are not registered during startup because they only get loaded when
937 // the dialog is shown. Register them here.
938 g_free(get_persconffile_path("io_graphs", TRUE));
940 profile_store_persconffiles(FALSE);
942 ret_val = wsApp->exec();
952 AirPDcapDestroyContext(&airpdcap_ctx);
955 /* Shutdown windows sockets */
958 /* For some unknown reason, the "atexit()" call in "create_console()"
959 doesn't arrange that "destroy_console()" be called when we exit,
960 so we call it here if a console was created. */
966 capture_opts_cleanup(&global_capture_opts);
968 col_cleanup(&CaptureFile::globalCapFile()->cinfo);
983 * indent-tabs-mode: nil
986 * ex: set shiftwidth=4 tabstop=8 expandtab:
987 * :indentSize=4:tabSize=8:noTabs=true: