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.
34 #ifndef HAVE_GETOPT_LONG
35 #include "wsutil/wsgetopt.h"
38 #include <wsutil/clopts_common.h>
39 #include <wsutil/cmdarg_err.h>
40 #include <wsutil/crash_info.h>
41 #include <wsutil/filesystem.h>
42 #include <wsutil/privileges.h>
44 #include <wsutil/plugins.h>
46 #include <wsutil/report_err.h>
47 #include <wsutil/unicode-utils.h>
48 #include <ws_version_info.h>
50 #include <epan/addr_resolv.h>
51 #include <epan/ex-opt.h>
53 #include <epan/stat_tap_ui.h>
54 #include <epan/column.h>
55 #include <epan/disabled_protos.h>
58 #include <epan/packet.h>
59 #include <epan/asn1.h>
60 #include <epan/dissectors/packet-kerberos.h>
64 #include <codecs/codecs.h>
71 /* general (not Qt specific) */
73 #include "epan/color_filters.h"
76 #include "epan/rtd_table.h"
77 #include "epan/srt_table.h"
79 #include "ui/alert_box.h"
80 #include "ui/console.h"
81 #include "ui/iface_lists.h"
82 #include "ui/language.h"
83 #include "ui/persfilepath_opt.h"
84 #include "ui/recent.h"
85 #include "ui/simple_dialog.h"
88 #include "ui/qt/conversation_dialog.h"
89 #include "ui/qt/color_utils.h"
90 #include "ui/qt/coloring_rules_dialog.h"
91 #include "ui/qt/endpoint_dialog.h"
92 #include "ui/qt/main_window.h"
93 #include "ui/qt/response_time_delay_dialog.h"
94 #include "ui/qt/service_response_time_dialog.h"
95 #include "ui/qt/simple_dialog.h"
96 #include "ui/qt/simple_statistics_dialog.h"
97 #include "ui/qt/splash_overlay.h"
98 #include "ui/qt/wireshark_application.h"
100 #include "caputils/capture-pcap-util.h"
103 # include "caputils/capture-wpcap.h"
104 # include "caputils/capture_wpcap_packet.h"
105 # include <tchar.h> /* Needed for Unicode */
106 # include <wsutil/file_util.h>
107 # include <wsutil/os_version_info.h>
111 # include <caputils/airpcap.h>
112 # include <caputils/airpcap_loader.h>
113 //# include "airpcap_dlg.h"
114 //# include "airpcap_gui_utils.h"
117 #include "epan/crypt/airpdcap_ws.h"
119 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
120 #include <QTextCodec>
123 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
124 capture_options global_capture_opts;
127 GString *comp_info_str, *runtime_info_str;
129 /* update the main window */
130 void main_window_update(void)
132 WiresharkApplication::processEvents();
137 /* quit a nested main window */
138 void main_window_nested_quit(void)
140 // if (gtk_main_level() > 0)
144 /* quit the main window */
145 void main_window_quit(void)
150 #endif /* HAVE_LIBPCAP */
153 // xxx copied from ../gtk/main.c
155 print_usage(gboolean for_help_option) {
162 if (for_help_option) {
164 fprintf(output, "Wireshark %s\n"
165 "Interactively dump and analyze network traffic.\n"
166 "See https://www.wireshark.org for more information.\n",
167 get_ws_vcs_version_info());
171 fprintf(output, "\n");
172 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
173 fprintf(output, "\n");
176 fprintf(output, "Capture interface:\n");
177 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
178 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
179 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
180 fprintf(output, " -p don't capture in promiscuous mode\n");
181 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
182 fprintf(output, " -S update packet display when new packets are captured\n");
183 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
184 #ifdef HAVE_PCAP_CREATE
185 fprintf(output, " -I capture in monitor mode, if available\n");
187 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
188 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
190 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
191 fprintf(output, " -D print list of interfaces and exit\n");
192 fprintf(output, " -L print list of link-layer types of iface and exit\n");
193 fprintf(output, "\n");
194 fprintf(output, "Capture stop conditions:\n");
195 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
196 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
197 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
198 fprintf(output, " files:NUM - stop after NUM files\n");
199 /*fprintf(output, "\n");*/
200 fprintf(output, "Capture output:\n");
201 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
202 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
203 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
204 #endif /* HAVE_LIBPCAP */
205 #ifdef HAVE_PCAP_REMOTE
206 fprintf(output, "RPCAP options:\n");
207 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
209 /*fprintf(output, "\n");*/
210 fprintf(output, "Input file:\n");
211 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
213 fprintf(output, "\n");
214 fprintf(output, "Processing:\n");
215 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
216 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
217 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtd\"\n");
218 fprintf(output, " --disable-protocol <proto_name>\n");
219 fprintf(output, " disable dissection of proto_name\n");
220 fprintf(output, " --enable-heuristic <short_name>\n");
221 fprintf(output, " enable dissection of heuristic protocol\n");
222 fprintf(output, " --disable-heuristic <short_name>\n");
223 fprintf(output, " disable dissection of heuristic protocol\n");
225 fprintf(output, "\n");
226 fprintf(output, "User interface:\n");
227 fprintf(output, " -C <config profile> start with specified configuration profile\n");
228 fprintf(output, " -Y <display filter> start with the given display filter\n");
229 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
230 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
231 fprintf(output, " filter\n");
232 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
233 fprintf(output, " -m <font> set the font name used for most text\n");
234 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
235 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
236 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
237 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
239 fprintf(output, "\n");
240 fprintf(output, "Output:\n");
241 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
243 fprintf(output, "\n");
244 fprintf(output, "Miscellaneous:\n");
245 fprintf(output, " -h display this help and exit\n");
246 fprintf(output, " -v display version info and exit\n");
247 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
248 fprintf(output, " persdata:path - personal data files\n");
249 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
250 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
252 fprintf(output, " --display=DISPLAY X display to use\n");
254 fprintf(output, "\nNOTE: Not all options are implemented in the Qt port.\n");
262 * Report an error in command-line arguments.
263 * Creates a console on Windows.
265 // xxx copied from ../gtk/main.c
267 wireshark_cmdarg_err(const char *fmt, va_list ap)
272 fprintf(stderr, "wireshark: ");
273 vfprintf(stderr, fmt, ap);
274 fprintf(stderr, "\n");
278 * Report additional information for an error in command-line arguments.
279 * Creates a console on Windows.
280 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
281 * terminal isn't the standard error?
283 // xxx copied from ../gtk/main.c
285 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
290 vfprintf(stderr, fmt, ap);
291 fprintf(stderr, "\n");
294 // xxx based from ../gtk/main.c:get_gtk_compiled_info
296 get_wireshark_qt_compiled_info(GString *str)
298 g_string_append(str, "with ");
299 g_string_append_printf(str,
301 "Qt %s", QT_VERSION_STR);
303 "Qt (version unknown)");
306 /* Capture libraries */
307 g_string_append(str, ", ");
308 get_compiled_caplibs_version(str);
311 // xxx copied from ../gtk/main.c
313 get_gui_compiled_info(GString *str)
315 epan_get_compiled_version_info(str);
317 g_string_append(str, ", ");
318 #ifdef QT_MULTIMEDIA_LIB
319 g_string_append(str, "with QtMultimedia");
321 g_string_append(str, "without QtMultimedia");
324 g_string_append(str, ", ");
326 get_compiled_airpcap_version(str);
328 g_string_append(str, "without AirPcap");
332 // xxx copied from ../gtk/main.c
334 get_wireshark_runtime_info(GString *str)
337 /* Capture libraries */
338 g_string_append(str, ", ");
339 get_runtime_caplibs_version(str);
342 /* stuff used by libwireshark */
343 epan_get_runtime_version_info(str);
346 g_string_append(str, ", ");
347 get_runtime_airpcap_version(str);
352 /* Check if there's something important to tell the user during startup.
353 * We want to do this *after* showing the main window so that any windows
354 * we pop up will be above the main window.
357 check_and_warn_user_startup(const QString &cf_name)
362 gchar *cur_user, *cur_group;
364 /* Tell the user not to run as root. */
365 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
366 cur_user = get_cur_username();
367 cur_group = get_cur_groupname();
368 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
369 "Running as user \"%s\" and group \"%s\".\n"
370 "This could be dangerous.\n\n"
371 "If you're running Wireshark this way in order to perform live capture, "
372 "you may want to be aware that there is a better way documented at\n"
373 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
379 /* Warn the user if npf.sys isn't loaded. */
380 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
381 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
382 "The NPF driver isn't running. You may have trouble\n"
383 "capturing or listing interfaces.");
391 // Try to avoid library search path collisions. QCoreApplication will
392 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
393 // the application directory. If
395 // - You have Qt version 5.x.y installed in the default location
396 // (C:\Qt\5.x) on your machine.
400 // - You install Wireshark that was built on a machine with Qt version
401 // 5.x.z installed in the default location.
403 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
404 // directory. This may not be compatible with qwindows.dll from that
405 // same path on the build machine. At any rate, loading DLLs from paths
406 // you don't control is ill-advised. We work around this by removing every
407 // path except our application directory.
410 reset_library_path(void)
412 QString app_path = QDir(get_progfile_dir()).path();
413 foreach (QString path, QCoreApplication::libraryPaths()) {
414 QCoreApplication::removeLibraryPath(path);
416 QCoreApplication::addLibraryPath(app_path);
420 /* And now our feature presentation... [ fade to music ] */
421 int main(int argc, char *argv[])
426 gboolean arg_error = FALSE;
427 char **ws_argv = argv;
435 char *gdp_path, *dp_path;
438 gboolean start_capture = FALSE;
439 gboolean list_link_layer_types = FALSE;
444 gboolean capture_option_specified = FALSE;
453 guint go_to_packet = 0;
455 QString dfilter, read_filter;
456 GSList *disable_protocol_slist = NULL;
457 GSList *enable_heur_slist = NULL;
458 GSList *disable_heur_slist = NULL;
460 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
462 // In Qt 5, C strings are treated always as UTF-8 when converted to
463 // QStrings; in Qt 4, the codec must be set to make that happen
464 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
465 // Hopefully we won't have to use QString::fromUtf8() in as many places.
466 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
467 QTextCodec::setCodecForCStrings(utf8codec);
468 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
469 QTextCodec::setCodecForTr(utf8codec);
472 /* Set the C-language locale to the native environment. */
473 // The GTK+ UI calls this. Should we as well?
474 //setlocale(LC_ALL, "");
476 // QCoreApplication clobbers argv. Let's have a local copy.
477 ws_argv = (char **) g_malloc(sizeof(char *) * argc);
478 for (opt = 0; opt < argc; opt++) {
479 ws_argv[opt] = argv[opt];
481 arg_list_utf_16to8(argc, ws_argv);
482 create_app_running_mutex();
486 * Get credential information for later use, and drop privileges
487 * before doing anything else.
488 * Let the user know if anything happened.
490 init_process_policies();
491 relinquish_special_privs_perm();
494 * Attempt to get the pathname of the executable file.
496 /* init_progfile_dir_error = */ init_progfile_dir(ws_argv[0],
497 (int (*)(int, char **)) get_gui_compiled_info);
498 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
501 /* Load wpcap if possible. Do this before collecting the run-time version information */
504 /* ... and also load the packet.dll from wpcap */
508 /* Load the airpcap.dll. This must also be done before collecting
509 * run-time version information. */
512 airpcap_dll_ret_val = load_airpcap();
514 switch (airpcap_dll_ret_val) {
516 /* load the airpcap interfaces */
517 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
519 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
520 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
521 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
524 airpcap_if_active = NULL;
528 /* select the first ad default (THIS SHOULD BE CHANGED) */
529 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
533 * XXX - Maybe we need to warn the user if one of the following happens???
535 case AIRPCAP_DLL_OLD:
536 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
539 case AIRPCAP_DLL_ERROR:
540 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
543 case AIRPCAP_DLL_NOT_FOUND:
544 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
548 #endif /* HAVE_AIRPCAP */
551 /* Get the compile-time version information string */
553 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
554 get_gui_compiled_info);
556 /* Assemble the run-time version information string */
558 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
561 * In order to have the -X opts assigned before the wslua machine starts
562 * we need to call getopt_long before epan_init() gets called.
564 * In addition, we process "console only" parameters (ones where we
565 * send output to the console and exit) here, so we don't start Qt
566 * if we're only showing command-line help or version information.
568 * XXX - this pre-scan is done before we start Qt, so we haven't
569 * run WiresharkApplication's constructor on the arguments. That
570 * means that Qt arguments have not been removed from the argument
571 * list; those arguments begin with "-", and may be treated as
572 * errors by getopt_long().
574 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
577 * XXX - is there some way to parse and remove Qt arguments without
578 * starting up the GUI, which we can call before calling this?
580 * In order to handle, for example, -o options, we also need to call it
581 * *after* epan_init() gets called, so that the dissectors have had a
582 * chance to register their preferences, so we have another getopt_long()
585 * XXX - can we do this all with one getopt_long() call, saving the
586 * arguments we can't handle until after initializing libwireshark,
587 * and then process them after initializing libwireshark?
589 * Note that we don't want to initialize libwireshark until after the
590 * GUI is up, as that can take a while, and we want a window of some
591 * sort up to show progress while that's happening.
593 // XXX Should the remaining code be in WiresharkApplcation::WiresharkApplication?
594 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
595 static const struct option long_options[] = {
596 {"help", no_argument, NULL, 'h'},
597 {"read-file", required_argument, NULL, 'r' },
598 {"read-filter", required_argument, NULL, 'R' },
599 {"display-filter", required_argument, NULL, 'Y' },
600 {"version", no_argument, NULL, 'v'},
601 LONGOPT_CAPTURE_COMMON
604 static const char optstring[] = OPTSTRING;
608 while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
610 case 'C': /* Configuration Profile */
611 if (profile_exists (optarg, FALSE)) {
612 set_profile_name (optarg);
614 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
618 case 'D': /* Print a list of capture devices and exit */
620 if_list = capture_interface_list(&err, &err_str, NULL);
621 if (if_list == NULL) {
623 cmdarg_err("There are no interfaces on which a capture can be done");
625 cmdarg_err("%s", err_str);
633 capture_opts_print_interfaces(if_list);
634 free_interface_list(if_list);
639 #else /* HAVE_LIBPCAP */
640 capture_option_specified = TRUE;
642 #endif /* HAVE_LIBPCAP */
644 case 'h': /* Print help and exit */
650 if (strcmp(optarg, "-") == 0)
651 set_stdin_capture(TRUE);
654 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
655 if (!persfilepath_opt(opt, optarg)) {
656 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
660 case 'v': /* Show version and exit */
664 show_version("Wireshark", comp_info_str, runtime_info_str);
672 * Extension command line options have to be processed before
673 * we call epan_init() as they are supposed to be used by dissectors
674 * or taps very early in the registration process.
678 case '?': /* Ignore errors - the "real" scan will catch them. */
684 reset_library_path();
687 /* Create The Wireshark app */
688 WiresharkApplication ws_app(argc, argv);
690 /* initialize the funnel mini-api */
692 //initialize_funnel_ops();
694 AirPDcapInitContext(&airpdcap_ctx);
698 unsigned int in_file_type = WTAP_TYPE_AUTO;
700 /* Add it to the information to be reported on a crash. */
701 ws_add_crash_info("Wireshark %s\n"
706 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
709 /* Start windows sockets */
710 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
713 profile_store_persconffiles(TRUE);
715 /* Read the profile independent recent file. We have to do this here so we can */
716 /* set the profile before it can be set from the command line parameter */
717 if (!recent_read_static(&rf_path, &rf_open_errno)) {
718 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
719 "Could not open common recent file\n\"%s\": %s.",
720 rf_path, strerror(rf_open_errno));
724 /* Read the profile dependent (static part) of the recent file. */
725 /* Only the static part of it will be read, as we don't have the gui now to fill the */
726 /* recent lists which is done in the dynamic part. */
727 /* We have to do this already here, so command line parameters can overwrite these values. */
728 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
729 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
730 "Could not open recent file\n\"%s\": %s.",
731 rf_path, g_strerror(rf_open_errno));
734 wsApp->applyCustomColorsFromRecent();
736 // Initialize our language
737 read_language_prefs();
738 locale = QString(language);
739 wsApp->loadLanguage(locale);
741 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", locale.toStdString().c_str());
743 // Init the main window (and splash)
744 main_w = new(MainWindow);
746 // We may not need a queued connection here but it would seem to make sense
747 // to force the issue.
748 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
749 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
751 /* Init the "Open file" dialog directory */
752 /* (do this after the path settings are processed) */
753 if (recent.gui_fileopen_remembered_dir &&
754 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
755 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
757 wsApp->setLastOpenDir(get_persdatafile_dir());
761 // Replicates behavior in gtk_init();
762 signal(SIGPIPE, SIG_IGN);
765 set_console_log_handler();
768 /* Set the initial values in the capture options. This might be overwritten
769 by preference settings and then again by the command line parameters. */
770 capture_opts_init(&global_capture_opts);
773 init_report_err(vfailure_alert_box, open_failure_alert_box,
774 read_failure_alert_box, write_failure_alert_box);
776 init_open_routines();
779 /* Register all the plugin types we have. */
780 epan_register_plugin_types(); /* Types known to libwireshark */
781 wtap_register_plugin_types(); /* Types known to libwiretap */
782 codec_register_plugin_types(); /* Types known to libwscodecs */
784 /* Scan for plugins. This does *not* call their registration routines;
785 that's done later. */
788 /* Register all libwiretap plugin modules. */
789 register_all_wiretap_modules();
791 /* Register all audio codec plugins. */
792 register_all_codecs();
795 /* Register all dissectors; we must do this before checking for the
796 "-G" flag, as the "-G" flag dumps information registered by the
797 dissectors, and we must do it before we read the preferences, in
798 case any dissectors register preferences. */
799 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
800 splash_update, NULL)) {
801 SimpleDialog::displayQueuedMessages(main_w);
805 splash_update(RA_LISTENERS, NULL, NULL);
807 /* Register all tap listeners; we do this before we parse the arguments,
808 as the "-z" argument can specify a registered tap. */
810 /* we register the plugin taps before the other taps because
811 stats_tree taps plugins will be registered as tap listeners
812 by stats_tree_stat.c and need to registered before that */
814 register_all_plugin_tap_listeners();
818 extcap_register_preferences();
821 register_all_tap_listeners();
822 conversation_table_set_gui_info(init_conversation_table);
823 hostlist_table_set_gui_info(init_endpoint_table);
824 srt_table_iterate_tables(register_service_response_tables, NULL);
825 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
826 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
828 if (ex_opt_count("read_format") > 0) {
829 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
832 splash_update(RA_PREFERENCES, NULL, NULL);
834 prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path, false);
837 * To reset the options parser, set optreset to 1 on platforms that
838 * have optreset (documented in *BSD and OS X, apparently present but
839 * not documented in Solaris - the Illumos repository seems to
840 * suggest that the first Solaris getopt_long(), at least as of 2004,
841 * was based on the NetBSD one, it had optreset) and set optind to 1,
842 * and set optind to 0 otherwise (documented as working in the GNU
843 * getopt_long(). Setting optind to 0 didn't originally work in the
844 * NetBSD one, but that was added later - we don't want to depend on
845 * it if we have optreset).
847 * Also reset opterr to 1, so that error messages are printed by
850 * XXX - if we want to control all the command-line option errors, so
851 * that we can display them where we choose (e.g., in a window), we'd
852 * want to leave opterr as 0, and produce our own messages using optopt.
853 * We'd have to check the value of optopt to see if it's a valid option
854 * letter, in which case *presumably* the error is "this option requires
855 * an argument but none was specified", or not a valid option letter,
856 * in which case *presumably* the error is "this option isn't valid".
857 * Some versions of getopt() let you supply a option string beginning
858 * with ':', which means that getopt() will return ':' rather than '?'
859 * for "this option requires an argument but none was specified", but
860 * not all do. But we're now using getopt_long() - what does it do?
870 /* Now get our args */
871 while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
873 /*** capture option specific ***/
874 case 'a': /* autostop criteria */
875 case 'b': /* Ringbuffer option */
876 case 'c': /* Capture xxx packets */
877 case 'f': /* capture filter */
878 case 'k': /* Start capture immediately */
879 case 'H': /* Hide capture info dialog box */
880 case 'p': /* Don't capture in promiscuous mode */
881 case 'i': /* Use interface x */
882 #ifdef HAVE_PCAP_CREATE
883 case 'I': /* Capture in monitor mode, if available */
885 #ifdef HAVE_PCAP_REMOTE
886 case 'A': /* Authentication */
888 case 's': /* Set the snapshot (capture) length */
889 case 'S': /* "Sync" mode: used for following file ala tail -f */
890 case 'w': /* Write to capture file xxx */
891 case 'y': /* Set the pcap data link type */
892 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
893 case 'B': /* Buffer size */
896 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
902 capture_option_specified = TRUE;
907 case 'K': /* Kerberos keytab file */
908 read_keytab_file(optarg);
912 /*** all non capture option specific ***/
914 /* Configuration profile settings were already processed just ignore them this time*/
916 case 'j': /* Search backwards for a matching packet from filter in option J */
917 /* Not supported yet */
919 case 'g': /* Go to packet with the given packet number */
920 go_to_packet = get_positive_int(optarg, "go to packet");
922 case 'J': /* Jump to the first packet which matches the filter criteria */
923 /* Not supported yet */
925 case 'l': /* Automatic scrolling in live capture mode */
927 /* Not supported yet */
929 capture_option_specified = TRUE;
933 case 'L': /* Print list of link-layer types and exit */
935 list_link_layer_types = TRUE;
937 capture_option_specified = TRUE;
941 case 'm': /* Fixed-width font for the display */
942 /* Not supported yet */
944 case 'n': /* No name resolution */
945 disable_name_resolution();
947 case 'N': /* Select what types of addresses/port #s to resolve */
948 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
949 if (badopt != '\0') {
950 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
955 case 'o': /* Override preference from command line */
956 switch (prefs_set_pref(optarg)) {
959 case PREFS_SET_SYNTAX_ERR:
960 cmdarg_err("Invalid -o flag \"%s\"", optarg);
963 case PREFS_SET_NO_SUCH_PREF:
964 /* not a preference, might be a recent setting */
965 switch (recent_set_arg(optarg)) {
968 case PREFS_SET_SYNTAX_ERR:
969 /* shouldn't happen, checked already above */
970 cmdarg_err("Invalid -o flag \"%s\"", optarg);
973 case PREFS_SET_NO_SUCH_PREF:
974 case PREFS_SET_OBSOLETE:
975 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
980 g_assert_not_reached();
983 case PREFS_SET_OBSOLETE:
984 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
989 g_assert_not_reached();
993 /* Path settings were already processed just ignore them this time*/
998 case 'R': /* Read file filter */
999 read_filter = QString(optarg);
1001 case 't': /* Time stamp type */
1002 if (strcmp(optarg, "r") == 0)
1003 timestamp_set_type(TS_RELATIVE);
1004 else if (strcmp(optarg, "a") == 0)
1005 timestamp_set_type(TS_ABSOLUTE);
1006 else if (strcmp(optarg, "ad") == 0)
1007 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
1008 else if (strcmp(optarg, "adoy") == 0)
1009 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
1010 else if (strcmp(optarg, "d") == 0)
1011 timestamp_set_type(TS_DELTA);
1012 else if (strcmp(optarg, "dd") == 0)
1013 timestamp_set_type(TS_DELTA_DIS);
1014 else if (strcmp(optarg, "e") == 0)
1015 timestamp_set_type(TS_EPOCH);
1016 else if (strcmp(optarg, "u") == 0)
1017 timestamp_set_type(TS_UTC);
1018 else if (strcmp(optarg, "ud") == 0)
1019 timestamp_set_type(TS_UTC_WITH_YMD);
1020 else if (strcmp(optarg, "udoy") == 0)
1021 timestamp_set_type(TS_UTC_WITH_YDOY);
1023 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
1025 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
1027 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
1029 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
1031 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
1033 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
1037 case 'u': /* Seconds type */
1038 if (strcmp(optarg, "s") == 0)
1039 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1040 else if (strcmp(optarg, "hms") == 0)
1041 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
1043 cmdarg_err("Invalid seconds type \"%s\"", optarg);
1045 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
1050 /* ext ops were already processed just ignore them this time*/
1053 dfilter = QString(optarg);
1056 /* We won't call the init function for the stat this soon
1057 as it would disallow MATE's fields (which are registered
1058 by the preferences set callback) from being used as
1059 part of a tap filter. Instead, we just add the argument
1060 to a list of stat arguments. */
1061 if (strcmp("help", optarg) == 0) {
1062 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
1063 list_stat_cmd_args();
1066 if (!process_stat_cmd_arg(optarg)) {
1067 cmdarg_err("Invalid -z argument.");
1068 cmdarg_err_cont(" -z argument must be one of :");
1069 list_stat_cmd_args();
1073 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1074 disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
1076 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1077 enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
1079 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1080 disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
1084 case '?': /* Bad flag - print usage message */
1095 if (!cf_name.isEmpty()) {
1097 * Input file name specified with "-r" *and* specified as a regular
1098 * command-line argument.
1100 cmdarg_err("File name specified both with -r and regular argument");
1104 * Input file name not specified with "-r", and a command-line argument
1105 * was specified; treat it as the input file name.
1107 * Yes, this is different from tshark, where non-flag command-line
1108 * arguments are a filter, but this works better on GUI desktops
1109 * where a command can be specified to be run to open a particular
1110 * file - yes, you could have "-r" as the last part of the command,
1111 * but that's a bit ugly.
1113 cf_name = ws_argv[0];
1122 * Extra command line arguments were specified; complain.
1124 cmdarg_err("Invalid argument: %s", ws_argv[0]);
1129 #ifndef HAVE_LIBPCAP
1130 if (capture_option_specified) {
1131 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
1138 /* Removed thread code:
1139 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
1142 // XXX Is there a better place to set the timestamp format & precision?
1143 timestamp_set_type(recent.gui_time_format);
1144 timestamp_set_precision(recent.gui_time_precision);
1145 timestamp_set_seconds_type (recent.gui_seconds_format);
1148 fill_in_local_interfaces(main_window_update);
1150 if (start_capture && list_link_layer_types) {
1151 /* Specifying *both* is bogus. */
1152 cmdarg_err("You can't specify both -L and a live capture.");
1156 if (list_link_layer_types) {
1157 /* We're supposed to list the link-layer types for an interface;
1158 did the user also specify a capture file to be read? */
1159 if (!cf_name.isEmpty()) {
1160 /* Yes - that's bogus. */
1161 cmdarg_err("You can't specify -L and a capture file to be read.");
1164 /* No - did they specify a ring buffer option? */
1165 if (global_capture_opts.multi_files_on) {
1166 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
1170 /* We're supposed to do a live capture; did the user also specify
1171 a capture file to be read? */
1172 if (start_capture && !cf_name.isEmpty()) {
1173 /* Yes - that's bogus. */
1174 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
1178 /* No - was the ring buffer option specified and, if so, does it make
1180 if (global_capture_opts.multi_files_on) {
1181 /* Ring buffer works only under certain conditions:
1182 a) ring buffer does not work with temporary files;
1183 b) real_time_mode and multi_files_on are mutually exclusive -
1184 real_time_mode takes precedence;
1185 c) it makes no sense to enable the ring buffer if the maximum
1186 file size is set to "infinite". */
1187 if (global_capture_opts.save_file == NULL) {
1188 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
1189 global_capture_opts.multi_files_on = FALSE;
1191 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
1192 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
1193 /* XXX - this must be redesigned as the conditions changed */
1198 if (start_capture || list_link_layer_types) {
1199 /* We're supposed to do a live capture or get a list of link-layer
1200 types for a live capture device; if the user didn't specify an
1201 interface to use, pick a default. */
1202 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
1203 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
1209 if (list_link_layer_types) {
1210 /* Get the list of link-layer types for the capture devices. */
1211 if_capabilities_t *caps;
1214 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1216 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1217 if (device.selected) {
1218 #if defined(HAVE_PCAP_CREATE)
1219 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
1221 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
1224 cmdarg_err("%s", err_str);
1228 if (caps->data_link_types == NULL) {
1229 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
1235 #if defined(HAVE_PCAP_CREATE)
1236 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
1238 capture_opts_print_if_capabilities(caps, device.name, FALSE);
1243 free_if_capabilities(caps);
1249 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
1250 capture_opts_trim_ring_num_files(&global_capture_opts);
1251 #endif /* HAVE_LIBPCAP */
1253 /* Notify all registered modules that have had any of their preferences
1254 changed either from one of the preferences file or from the command
1255 line that their preferences have changed. */
1257 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
1260 if ((global_capture_opts.num_selected == 0) &&
1261 (prefs.capture_device != NULL)) {
1264 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1265 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1266 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
1267 device.selected = TRUE;
1268 global_capture_opts.num_selected++;
1269 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
1270 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
1277 /* disabled protocols as per configuration file */
1278 if (gdp_path == NULL && dp_path == NULL) {
1279 set_disabled_protos_list();
1280 set_disabled_heur_dissector_list();
1283 if(disable_protocol_slist) {
1284 GSList *proto_disable;
1285 for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
1287 proto_disable_proto_by_name((char*)proto_disable->data);
1291 if(enable_heur_slist) {
1292 GSList *heur_enable;
1293 for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
1295 proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
1299 if(disable_heur_slist) {
1300 GSList *heur_disable;
1301 for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
1303 proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
1307 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, prefs_p->num_cols, TRUE);
1308 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
1309 wsApp->emitAppSignal(WiresharkApplication::RecentFilesRead); // Must be emitted after PreferencesChanged.
1311 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
1313 /* For update of WindowTitle (When use gui.window_title preference) */
1314 main_w->setWSWindowTitle();
1317 /* Read the dynamic part of the recent file, as we have the gui now ready for
1319 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
1320 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1321 "Could not open recent file\n\"%s\": %s.",
1322 rf_path, g_strerror(rf_open_errno));
1326 packet_list_enable_color(recent.packet_list_colorize);
1328 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
1329 packet_list_enable_color(TRUE);
1335 gchar* err_msg = NULL;
1336 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
1337 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
1344 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1345 if (!start_capture && !global_capture_opts.default_options.cfilter) {
1346 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1348 #else /* HAVE_LIBPCAP */
1350 #endif /* HAVE_LIBPCAP */
1352 wsApp->allSystemsGo();
1353 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
1354 SimpleDialog::displayQueuedMessages(main_w);
1356 /* User could specify filename, or display filter, or both */
1357 if (!dfilter.isEmpty())
1358 main_w->filterPackets(dfilter, false);
1359 if (!cf_name.isEmpty()) {
1360 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
1362 /* Open stat windows; we do so after creating the main window,
1363 to avoid Qt warnings, and after successfully opening the
1364 capture file, so we know we have something to compute stats
1365 on, and after registering all dissectors, so that MATE will
1366 have registered its field array and we can have a tap filter
1367 with one of MATE's late-registered fields as part of the
1369 start_requested_stats();
1371 if(go_to_packet != 0) {
1372 /* Jump to the specified frame number, kept for backward
1374 cf_goto_frame(CaptureFile::globalCapFile(), go_to_packet);
1380 if (start_capture) {
1381 if (global_capture_opts.save_file != NULL) {
1382 /* Save the directory name for future file dialogs. */
1383 /* (get_dirname overwrites filename) */
1384 gchar *s = g_strdup(global_capture_opts.save_file);
1385 set_last_open_dir(get_dirname(s));
1388 /* "-k" was specified; start a capture. */
1389 // show_main_window(FALSE);
1390 check_and_warn_user_startup(cf_name);
1392 /* If no user interfaces were specified on the command line,
1393 copy the list of selected interfaces to the set of interfaces
1394 to use for this capture. */
1395 if (global_capture_opts.ifaces->len == 0)
1396 collect_ifaces(&global_capture_opts);
1397 CaptureFile::globalCapFile()->window = main_w;
1398 if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
1399 /* The capture started. Open stat windows; we do so after creating
1400 the main window, to avoid GTK warnings, and after successfully
1401 opening the capture file, so we know we have something to compute
1402 stats on, and after registering all dissectors, so that MATE will
1403 have registered its field array and we can have a tap filter with
1404 one of MATE's late-registered fields as part of the filter. */
1405 start_requested_stats();
1408 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1409 if (!start_capture && !global_capture_opts.default_options.cfilter) {
1410 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1413 #endif /* HAVE_LIBPCAP */
1415 return wsApp->exec();
1424 * indent-tabs-mode: nil
1427 * ex: set shiftwidth=4 tabstop=8 expandtab:
1428 * :indentSize=4:tabSize=8:noTabs=true: