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/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"
111 # include "caputils/capture-wpcap.h"
112 # include "caputils/capture_wpcap_packet.h"
113 # include <tchar.h> /* Needed for Unicode */
114 # include <wsutil/file_util.h>
115 # include <wsutil/os_version_info.h>
119 # include <caputils/airpcap.h>
120 # include <caputils/airpcap_loader.h>
121 //# include "airpcap_dlg.h"
122 //# include "airpcap_gui_utils.h"
125 #include "epan/crypt/airpdcap_ws.h"
127 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
128 #include <QTextCodec>
131 #define INVALID_OPTION 1
132 #define INIT_FAILED 2
133 #define INVALID_CAPABILITY 2
134 #define INVALID_LINK_TYPE 2
136 //#define DEBUG_STARTUP_TIME 1
139 # Console log level (for debugging)
140 # A bitmask of log levels:
149 #define DEBUG_STARTUP_TIME_LOGLEVEL 252
151 /* update the main window */
152 void main_window_update(void)
154 WiresharkApplication::processEvents();
159 /* quit a nested main window */
160 void main_window_nested_quit(void)
162 // if (gtk_main_level() > 0)
166 /* quit the main window */
167 void main_window_quit(void)
172 #endif /* HAVE_LIBPCAP */
175 * Report an error in command-line arguments.
176 * Creates a console on Windows.
178 // xxx copied from ../gtk/main.c
180 wireshark_cmdarg_err(const char *fmt, va_list ap)
185 fprintf(stderr, "wireshark: ");
186 vfprintf(stderr, fmt, ap);
187 fprintf(stderr, "\n");
191 * Report additional information for an error in command-line arguments.
192 * Creates a console on Windows.
193 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
194 * terminal isn't the standard error?
196 // xxx copied from ../gtk/main.c
198 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
203 vfprintf(stderr, fmt, ap);
204 fprintf(stderr, "\n");
207 // xxx based from ../gtk/main.c:get_gtk_compiled_info
209 get_wireshark_qt_compiled_info(GString *str)
211 g_string_append(str, "with ");
212 g_string_append_printf(str,
214 "Qt %s", QT_VERSION_STR);
216 "Qt (version unknown)");
219 /* Capture libraries */
220 g_string_append(str, ", ");
221 get_compiled_caplibs_version(str);
224 // xxx copied from ../gtk/main.c
226 get_gui_compiled_info(GString *str)
228 epan_get_compiled_version_info(str);
230 g_string_append(str, ", ");
231 #ifdef QT_MULTIMEDIA_LIB
232 g_string_append(str, "with QtMultimedia");
234 g_string_append(str, "without QtMultimedia");
237 g_string_append(str, ", ");
239 get_compiled_airpcap_version(str);
241 g_string_append(str, "without AirPcap");
244 codec_get_compiled_version_info(str);
247 // xxx copied from ../gtk/main.c
249 get_wireshark_runtime_info(GString *str)
252 /* Capture libraries */
253 g_string_append(str, ", ");
254 get_runtime_caplibs_version(str);
257 /* stuff used by libwireshark */
258 epan_get_runtime_version_info(str);
261 g_string_append(str, ", ");
262 get_runtime_airpcap_version(str);
267 /* Check if there's something important to tell the user during startup.
268 * We want to do this *after* showing the main window so that any windows
269 * we pop up will be above the main window.
272 check_and_warn_user_startup(const QString &cf_name)
277 gchar *cur_user, *cur_group;
279 /* Tell the user not to run as root. */
280 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
281 cur_user = get_cur_username();
282 cur_group = get_cur_groupname();
283 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
284 "Running as user \"%s\" and group \"%s\".\n"
285 "This could be dangerous.\n\n"
286 "If you're running Wireshark this way in order to perform live capture, "
287 "you may want to be aware that there is a better way documented at\n"
288 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
294 /* Warn the user if npf.sys isn't loaded. */
295 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
296 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
297 "The NPF driver isn't running. You may have trouble\n"
298 "capturing or listing interfaces.");
306 // Try to avoid library search path collisions. QCoreApplication will
307 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
308 // the application directory. If
310 // - You have Qt version 5.x.y installed in the default location
311 // (C:\Qt\5.x) on your machine.
315 // - You install Wireshark that was built on a machine with Qt version
316 // 5.x.z installed in the default location.
318 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
319 // directory. This may not be compatible with qwindows.dll from that
320 // same path on the build machine. At any rate, loading DLLs from paths
321 // you don't control is ill-advised. We work around this by removing every
322 // path except our application directory.
325 reset_library_path(void)
327 QString app_path = QDir(get_progfile_dir()).path();
328 foreach (QString path, QCoreApplication::libraryPaths()) {
329 QCoreApplication::removeLibraryPath(path);
331 QCoreApplication::addLibraryPath(app_path);
335 /* And now our feature presentation... [ fade to music ] */
336 int main(int argc, char *qt_argv[])
343 int ret_val = EXIT_SUCCESS;
344 char **argv = qt_argv;
362 gchar *err_msg = NULL;
363 GString *comp_info_str = NULL;
364 GString *runtime_info_str = NULL;
366 QString dfilter, read_filter;
367 /* Start time in microseconds*/
368 guint64 start_time = g_get_monotonic_time();
369 #ifdef DEBUG_STARTUP_TIME
370 /* At least on Windows there is a problem with the loging as the preferences is taken
371 * into account and the preferences are loaded pretty late in the startup process.
373 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
374 prefs.gui_console_open = console_open_always;
375 #endif /* DEBUG_STARTUP_TIME */
376 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
378 // In Qt 5, C strings are treated always as UTF-8 when converted to
379 // QStrings; in Qt 4, the codec must be set to make that happen
380 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
381 // Hopefully we won't have to use QString::fromUtf8() in as many places.
382 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
383 QTextCodec::setCodecForCStrings(utf8codec);
384 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
385 QTextCodec::setCodecForTr(utf8codec);
388 /* Set the C-language locale to the native environment. */
389 setlocale(LC_ALL, "");
392 // QCoreApplication clobbers argv. Let's have a local copy.
393 argv = (char **) g_malloc(sizeof(char *) * argc);
394 for (opt = 0; opt < argc; opt++) {
395 argv[opt] = qt_argv[opt];
397 arg_list_utf_16to8(argc, argv);
398 create_app_running_mutex();
402 * Get credential information for later use, and drop privileges
403 * before doing anything else.
404 * Let the user know if anything happened.
406 init_process_policies();
407 relinquish_special_privs_perm();
410 * Attempt to get the pathname of the directory containing the
413 /* init_progfile_dir_error = */ init_progfile_dir(argv[0],
414 (int (*)(int, char **)) get_gui_compiled_info);
415 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
418 ws_init_dll_search_path();
419 /* Load wpcap if possible. Do this before collecting the run-time version information */
422 /* ... and also load the packet.dll from wpcap */
426 /* Load the airpcap.dll. This must also be done before collecting
427 * run-time version information. */
430 airpcap_dll_ret_val = load_airpcap();
432 switch (airpcap_dll_ret_val) {
434 /* load the airpcap interfaces */
435 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
437 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
438 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
439 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
442 airpcap_if_active = NULL;
446 /* select the first ad default (THIS SHOULD BE CHANGED) */
447 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
451 * XXX - Maybe we need to warn the user if one of the following happens???
453 case AIRPCAP_DLL_OLD:
454 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
457 case AIRPCAP_DLL_ERROR:
458 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
461 case AIRPCAP_DLL_NOT_FOUND:
462 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
466 #endif /* HAVE_AIRPCAP */
469 /* Get the compile-time version information string */
470 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
471 get_gui_compiled_info);
473 /* Assemble the run-time version information string */
474 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
476 /* Create the user profiles directory */
477 if (create_profiles_dir(&rf_path) == -1) {
478 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
479 "Could not create profiles directory\n\"%s\"",
484 profile_store_persconffiles(TRUE);
486 /* Read the profile independent recent file. We have to do this here so we can */
487 /* set the profile before it can be set from the command line parameter */
488 if (!recent_read_static(&rf_path, &rf_open_errno)) {
489 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
490 "Could not open common recent file\n\"%s\": %s.",
491 rf_path, strerror(rf_open_errno));
495 commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
498 reset_library_path();
501 /* Create The Wireshark app */
502 WiresharkApplication ws_app(argc, qt_argv);
504 /* initialize the funnel mini-api */
506 //initialize_funnel_ops();
508 AirPDcapInitContext(&airpdcap_ctx);
511 unsigned int in_file_type = WTAP_TYPE_AUTO;
513 /* Add it to the information to be reported on a crash. */
514 ws_add_crash_info("Wireshark %s\n"
519 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
520 g_string_free(comp_info_str, TRUE);
521 g_string_free(runtime_info_str, TRUE);
524 /* Start windows sockets */
525 result = WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
528 ret_val = INIT_FAILED;
533 /* Read the profile dependent (static part) of the recent file. */
534 /* Only the static part of it will be read, as we don't have the gui now to fill the */
535 /* recent lists which is done in the dynamic part. */
536 /* We have to do this already here, so command line parameters can overwrite these values. */
537 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
538 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
539 "Could not open recent file\n\"%s\": %s.",
540 rf_path, g_strerror(rf_open_errno));
543 wsApp->applyCustomColorsFromRecent();
545 // Initialize our language
546 read_language_prefs();
547 wsApp->loadLanguage(language);
549 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", language);
551 // Init the main window (and splash)
552 main_w = new(MainWindow);
554 // We may not need a queued connection here but it would seem to make sense
555 // to force the issue.
556 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
557 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
558 main_w->connect(&ws_app, SIGNAL(openCaptureOptions()),
559 main_w, SLOT(on_actionCaptureOptions_triggered()));
561 /* Init the "Open file" dialog directory */
562 /* (do this after the path settings are processed) */
563 if (recent.gui_fileopen_remembered_dir &&
564 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
565 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
567 wsApp->setLastOpenDir(get_persdatafile_dir());
571 // Replicates behavior in gtk_init();
572 signal(SIGPIPE, SIG_IGN);
575 set_console_log_handler();
576 #ifdef DEBUG_STARTUP_TIME
577 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);
581 /* Set the initial values in the capture options. This might be overwritten
582 by preference settings and then again by the command line parameters. */
583 capture_opts_init(&global_capture_opts);
586 init_report_message(vfailure_alert_box, vwarning_alert_box,
587 open_failure_alert_box, read_failure_alert_box,
588 write_failure_alert_box);
593 /* Register all the plugin types we have. */
594 epan_register_plugin_types(); /* Types known to libwireshark */
595 codec_register_plugin_types(); /* Types known to libwscodecs */
597 /* Scan for plugins. This does *not* call their registration routines;
598 that's done later. */
599 scan_plugins(REPORT_LOAD_FAILURE);
601 /* Register all libwiretap plugin modules. */
602 register_all_wiretap_modules();
605 /* Register all audio codec plugins. */
606 register_all_codecs();
608 splash_update(RA_DISSECTORS, NULL, NULL);
609 #ifdef DEBUG_STARTUP_TIME
610 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);
612 /* Register all dissectors; we must do this before checking for the
613 "-G" flag, as the "-G" flag dumps information registered by the
614 dissectors, and we must do it before we read the preferences, in
615 case any dissectors register preferences. */
616 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
617 splash_update, NULL)) {
618 SimpleDialog::displayQueuedMessages(main_w);
619 ret_val = INIT_FAILED;
622 #ifdef DEBUG_STARTUP_TIME
623 /* epan_init resets the preferences */
624 prefs.console_log_level = DEBUG_STARTUP_TIME_LOGLEVEL;
625 prefs.gui_console_open = console_open_always;
626 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "epan done, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time);
629 // Read the dynamic part of the recent file. This determines whether or
630 // not the recent list appears in the main window so the earlier we can
631 // call this the better.
632 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
633 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
634 "Could not open recent file\n\"%s\": %s.",
635 rf_path, g_strerror(rf_open_errno));
639 splash_update(RA_LISTENERS, NULL, NULL);
640 #ifdef DEBUG_STARTUP_TIME
641 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);
643 /* Register all tap listeners; we do this before we parse the arguments,
644 as the "-z" argument can specify a registered tap. */
646 /* we register the plugin taps before the other taps because
647 stats_tree taps plugins will be registered as tap listeners
648 by stats_tree_stat.c and need to registered before that */
650 register_all_plugin_tap_listeners();
653 register_all_tap_listeners();
654 conversation_table_set_gui_info(init_conversation_table);
655 hostlist_table_set_gui_info(init_endpoint_table);
656 srt_table_iterate_tables(register_service_response_tables, NULL);
657 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
658 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
660 if (ex_opt_count("read_format") > 0) {
661 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
665 #ifdef DEBUG_STARTUP_TIME
666 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);
668 splash_update(RA_EXTCAP, NULL, NULL);
669 extcap_register_preferences();
671 splash_update(RA_PREFERENCES, NULL, NULL);
672 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);
674 global_commandline_info.prefs_p = ws_app.readConfigurationFiles(false);
676 /* Now get our args */
677 commandline_other_options(argc, argv, TRUE);
679 /* Convert some command-line parameters to QStrings */
680 if (global_commandline_info.cf_name != NULL)
681 cf_name = QString(global_commandline_info.cf_name);
682 if (global_commandline_info.rfilter != NULL)
683 read_filter = QString(global_commandline_info.rfilter);
684 if (global_commandline_info.dfilter != NULL)
685 dfilter = QString(global_commandline_info.dfilter);
687 /* Removed thread code:
688 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
691 timestamp_set_type(recent.gui_time_format);
692 timestamp_set_precision(recent.gui_time_precision);
693 timestamp_set_seconds_type (recent.gui_seconds_format);
696 #ifdef DEBUG_STARTUP_TIME
697 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);
699 splash_update(RA_INTERFACES, NULL, NULL);
701 fill_in_local_interfaces(main_window_update);
703 if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) {
704 /* We're supposed to do a live capture or get a list of link-layer
705 types for a live capture device; if the user didn't specify an
706 interface to use, pick a default. */
707 ret_val = capture_opts_default_iface_if_necessary(&global_capture_opts,
708 ((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);
714 if (global_commandline_info.list_link_layer_types) {
715 /* Get the list of link-layer types for the capture devices. */
716 if_capabilities_t *caps;
719 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
721 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
722 if (device.selected) {
723 #if defined(HAVE_PCAP_CREATE)
724 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
726 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
729 cmdarg_err("%s", err_str);
731 ret_val = INVALID_CAPABILITY;
734 if (caps->data_link_types == NULL) {
735 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
736 ret_val = INVALID_LINK_TYPE;
742 #if defined(HAVE_PCAP_CREATE)
743 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
745 capture_opts_print_if_capabilities(caps, device.name, FALSE);
750 free_if_capabilities(caps);
753 ret_val = EXIT_SUCCESS;
757 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
758 capture_opts_trim_ring_num_files(&global_capture_opts);
759 #endif /* HAVE_LIBPCAP */
762 /* Notify all registered modules that have had any of their preferences
763 changed either from one of the preferences file or from the command
764 line that their preferences have changed. */
765 #ifdef DEBUG_STARTUP_TIME
766 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);
769 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
772 if ((global_capture_opts.num_selected == 0) &&
773 (prefs.capture_device != NULL)) {
776 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
777 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
778 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
779 device.selected = TRUE;
780 global_capture_opts.num_selected++;
781 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
782 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
790 * Enabled and disabled protocols and heuristic dissectors as per
791 * command-line options.
793 if (!setup_enabled_and_disabled_protocols()) {
794 ret_val = INVALID_OPTION;
798 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
799 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
800 wsApp->emitAppSignal(WiresharkApplication::RecentPreferencesRead); // Must be emitted after PreferencesChanged.
802 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
804 /* For update of WindowTitle (When use gui.window_title preference) */
805 main_w->setWSWindowTitle();
808 packet_list_enable_color(recent.packet_list_colorize);
810 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
811 packet_list_enable_color(TRUE);
817 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
818 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
825 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
826 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
827 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
829 #else /* HAVE_LIBPCAP */
831 #endif /* HAVE_LIBPCAP */
833 wsApp->allSystemsGo();
834 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);
835 SimpleDialog::displayQueuedMessages(main_w);
837 /* User could specify filename, or display filter, or both */
838 if (!dfilter.isEmpty())
839 main_w->filterPackets(dfilter, false);
840 if (!cf_name.isEmpty()) {
841 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
843 /* Open stat windows; we do so after creating the main window,
844 to avoid Qt warnings, and after successfully opening the
845 capture file, so we know we have something to compute stats
846 on, and after registering all dissectors, so that MATE will
847 have registered its field array and we can have a tap filter
848 with one of MATE's late-registered fields as part of the
850 start_requested_stats();
852 if(global_commandline_info.go_to_packet != 0) {
853 /* Jump to the specified frame number, kept for backward
855 cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet);
856 } else if (global_commandline_info.jfilter != NULL) {
857 dfilter_t *jump_to_filter = NULL;
858 /* try to compile given filter */
859 if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
860 // Similar code in MainWindow::mergeCaptureFile().
861 QMessageBox::warning(main_w, QObject::tr("Invalid Display Filter"),
862 QObject::tr("The filter expression %1 isn't a valid display filter. (%2).")
863 .arg(global_commandline_info.jfilter, err_msg),
867 /* Filter ok, jump to the first packet matching the filter
868 conditions. Default search direction is forward, but if
869 option d was given, search backwards */
870 cf_find_packet_dfilter(CaptureFile::globalCapFile(), jump_to_filter, global_commandline_info.jump_backwards);
877 if (global_commandline_info.start_capture) {
878 if (global_capture_opts.save_file != NULL) {
879 /* Save the directory name for future file dialogs. */
880 /* (get_dirname overwrites filename) */
881 gchar *s = g_strdup(global_capture_opts.save_file);
882 set_last_open_dir(get_dirname(s));
885 /* "-k" was specified; start a capture. */
886 // show_main_window(FALSE);
887 check_and_warn_user_startup(cf_name);
889 /* If no user interfaces were specified on the command line,
890 copy the list of selected interfaces to the set of interfaces
891 to use for this capture. */
892 if (global_capture_opts.ifaces->len == 0)
893 collect_ifaces(&global_capture_opts);
894 CaptureFile::globalCapFile()->window = main_w;
895 if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
896 /* The capture started. Open stat windows; we do so after creating
897 the main window, to avoid GTK warnings, and after successfully
898 opening the capture file, so we know we have something to compute
899 stats on, and after registering all dissectors, so that MATE will
900 have registered its field array and we can have a tap filter with
901 one of MATE's late-registered fields as part of the filter. */
902 start_requested_stats();
905 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
906 if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
907 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
910 #endif /* HAVE_LIBPCAP */
912 // UAT files used in configuration profiles which are used in Qt dialogs
913 // are not registered during startup because they only get loaded when
914 // the dialog is shown. Register them here.
915 g_free(get_persconffile_path("io_graphs", TRUE));
917 profile_store_persconffiles(FALSE);
919 ret_val = wsApp->exec();
927 AirPDcapDestroyContext(&airpdcap_ctx);
930 /* Shutdown windows sockets */
933 /* For some unknown reason, the "atexit()" call in "create_console()"
934 doesn't arrange that "destroy_console()" be called when we exit,
935 so we call it here if a console was created. */
941 capture_opts_cleanup(&global_capture_opts);
943 col_cleanup(&CaptureFile::globalCapFile()->cinfo);
958 * indent-tabs-mode: nil
961 * ex: set shiftwidth=4 tabstop=8 expandtab:
962 * :indentSize=4:tabSize=8:noTabs=true: