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.
31 #include <zlib.h> /* to get the libz version number */
38 #ifndef HAVE_GETOPT_LONG
39 #include "wsutil/wsgetopt.h"
42 #include <wsutil/clopts_common.h>
43 #include <wsutil/cmdarg_err.h>
44 #include <wsutil/crash_info.h>
45 #include <wsutil/filesystem.h>
46 #include <wsutil/privileges.h>
48 #include <wsutil/plugins.h>
50 #include <wsutil/report_err.h>
51 #include <wsutil/u3.h>
52 #include <wsutil/unicode-utils.h>
53 #include <wsutil/ws_diag_control.h>
54 #include <wsutil/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>
64 #include <epan/packet.h>
65 #include <epan/asn1.h>
66 #include <epan/dissectors/packet-kerberos.h>
70 #include <codecs/codecs.h>
77 /* general (not Qt specific) */
79 #include "epan/color_filters.h"
82 #include "epan/rtd_table.h"
83 #include "epan/srt_table.h"
85 #include "ui/alert_box.h"
86 #include "ui/console.h"
87 #include "ui/iface_lists.h"
88 #include "ui/language.h"
89 #include "ui/persfilepath_opt.h"
90 #include "ui/recent.h"
91 #include "ui/simple_dialog.h"
94 #include "ui/qt/conversation_dialog.h"
95 #include "ui/qt/color_utils.h"
96 #include "ui/qt/coloring_rules_dialog.h"
97 #include "ui/qt/endpoint_dialog.h"
98 #include "ui/qt/main_window.h"
99 #include "ui/qt/response_time_delay_dialog.h"
100 #include "ui/qt/service_response_time_dialog.h"
101 #include "ui/qt/simple_dialog.h"
102 #include "ui/qt/simple_statistics_dialog.h"
103 #include "ui/qt/splash_overlay.h"
104 #include "ui/qt/wireshark_application.h"
106 #include "caputils/capture-pcap-util.h"
109 # include "caputils/capture-wpcap.h"
110 # include "caputils/capture_wpcap_packet.h"
111 # include <tchar.h> /* Needed for Unicode */
112 # include <wsutil/file_util.h>
113 # include <wsutil/os_version_info.h>
117 # include <caputils/airpcap.h>
118 # include <caputils/airpcap_loader.h>
119 //# include "airpcap_dlg.h"
120 //# include "airpcap_gui_utils.h"
123 #include "epan/crypt/airpdcap_ws.h"
125 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
126 #include <QTextCodec>
129 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
130 capture_options global_capture_opts;
133 GString *comp_info_str, *runtime_info_str;
135 /* update the main window */
136 void main_window_update(void)
138 WiresharkApplication::processEvents();
143 /* quit a nested main window */
144 void main_window_nested_quit(void)
146 // if (gtk_main_level() > 0)
150 /* quit the main window */
151 void main_window_quit(void)
156 #endif /* HAVE_LIBPCAP */
159 // xxx copied from ../gtk/main.c
161 print_usage(gboolean for_help_option) {
168 if (for_help_option) {
170 fprintf(output, "Wireshark %s\n"
171 "Interactively dump and analyze network traffic.\n"
172 "See https://www.wireshark.org for more information.\n",
173 get_ws_vcs_version_info());
177 fprintf(output, "\n");
178 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
179 fprintf(output, "\n");
182 fprintf(output, "Capture interface:\n");
183 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
184 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
185 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
186 fprintf(output, " -p don't capture in promiscuous mode\n");
187 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
188 fprintf(output, " -S update packet display when new packets are captured\n");
189 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
190 #ifdef HAVE_PCAP_CREATE
191 fprintf(output, " -I capture in monitor mode, if available\n");
193 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
194 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
196 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
197 fprintf(output, " -D print list of interfaces and exit\n");
198 fprintf(output, " -L print list of link-layer types of iface and exit\n");
199 fprintf(output, "\n");
200 fprintf(output, "Capture stop conditions:\n");
201 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
202 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
203 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
204 fprintf(output, " files:NUM - stop after NUM files\n");
205 /*fprintf(output, "\n");*/
206 fprintf(output, "Capture output:\n");
207 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
208 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
209 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
210 #endif /* HAVE_LIBPCAP */
211 #ifdef HAVE_PCAP_REMOTE
212 fprintf(output, "RPCAP options:\n");
213 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
215 /*fprintf(output, "\n");*/
216 fprintf(output, "Input file:\n");
217 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
219 fprintf(output, "\n");
220 fprintf(output, "Processing:\n");
221 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
222 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
223 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtCd\"\n");
224 fprintf(output, " --disable-protocol <proto_name>\n");
225 fprintf(output, " disable dissection of proto_name\n");
226 fprintf(output, " --enable-heuristic <short_name>\n");
227 fprintf(output, " enable dissection of heuristic protocol\n");
228 fprintf(output, " --disable-heuristic <short_name>\n");
229 fprintf(output, " disable dissection of heuristic protocol\n");
231 fprintf(output, "\n");
232 fprintf(output, "User interface:\n");
233 fprintf(output, " -C <config profile> start with specified configuration profile\n");
234 fprintf(output, " -Y <display filter> start with the given display filter\n");
235 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
236 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
237 fprintf(output, " filter\n");
238 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
239 fprintf(output, " -m <font> set the font name used for most text\n");
240 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
241 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
242 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
243 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
245 fprintf(output, "\n");
246 fprintf(output, "Output:\n");
247 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
249 fprintf(output, "\n");
250 fprintf(output, "Miscellaneous:\n");
251 fprintf(output, " -h display this help and exit\n");
252 fprintf(output, " -v display version info and exit\n");
253 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
254 fprintf(output, " persdata:path - personal data files\n");
255 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
256 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
258 fprintf(output, " --display=DISPLAY X display to use\n");
260 fprintf(output, "\nNOTE: Not all options are implemented in the Qt port.\n");
268 * Report an error in command-line arguments.
269 * Creates a console on Windows.
271 // xxx copied from ../gtk/main.c
273 wireshark_cmdarg_err(const char *fmt, va_list ap)
278 fprintf(stderr, "wireshark: ");
279 vfprintf(stderr, fmt, ap);
280 fprintf(stderr, "\n");
284 * Report additional information for an error in command-line arguments.
285 * Creates a console on Windows.
286 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
287 * terminal isn't the standard error?
289 // xxx copied from ../gtk/main.c
291 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
296 vfprintf(stderr, fmt, ap);
297 fprintf(stderr, "\n");
300 // xxx based from ../gtk/main.c:get_gtk_compiled_info
302 get_wireshark_qt_compiled_info(GString *str)
304 g_string_append(str, "with ");
305 g_string_append_printf(str,
307 "Qt %s", QT_VERSION_STR);
309 "Qt (version unknown)");
312 /* Capture libraries */
313 g_string_append(str, ", ");
314 get_compiled_caplibs_version(str);
317 g_string_append(str, ", ");
319 g_string_append(str, "with libz ");
321 g_string_append(str, ZLIB_VERSION);
322 #else /* ZLIB_VERSION */
323 g_string_append(str, "(version unknown)");
324 #endif /* ZLIB_VERSION */
325 #else /* HAVE_LIBZ */
326 g_string_append(str, "without libz");
327 #endif /* HAVE_LIBZ */
330 // xxx copied from ../gtk/main.c
332 get_gui_compiled_info(GString *str)
334 epan_get_compiled_version_info(str);
336 g_string_append(str, ", ");
337 #ifdef QT_MULTIMEDIA_LIB
338 g_string_append(str, "with QtMultimedia");
340 g_string_append(str, "without QtMultimedia");
343 g_string_append(str, ", ");
345 get_compiled_airpcap_version(str);
347 g_string_append(str, "without AirPcap");
351 // xxx copied from ../gtk/main.c
353 get_wireshark_runtime_info(GString *str)
356 /* Capture libraries */
357 g_string_append(str, ", ");
358 get_runtime_caplibs_version(str);
362 #if defined(HAVE_LIBZ) && !defined(_WIN32)
363 g_string_append_printf(str, ", with libz %s", zlibVersion());
366 /* stuff used by libwireshark */
367 epan_get_runtime_version_info(str);
370 g_string_append(str, ", ");
371 get_runtime_airpcap_version(str);
375 g_string_append(str, ", ");
376 u3_runtime_info(str);
381 /* Check if there's something important to tell the user during startup.
382 * We want to do this *after* showing the main window so that any windows
383 * we pop up will be above the main window.
386 check_and_warn_user_startup(const QString &cf_name)
391 gchar *cur_user, *cur_group;
393 /* Tell the user not to run as root. */
394 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
395 cur_user = get_cur_username();
396 cur_group = get_cur_groupname();
397 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
398 "Running as user \"%s\" and group \"%s\".\n"
399 "This could be dangerous.\n\n"
400 "If you're running Wireshark this way in order to perform live capture, "
401 "you may want to be aware that there is a better way documented at\n"
402 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
408 /* Warn the user if npf.sys isn't loaded. */
409 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
410 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
411 "The NPF driver isn't running. You may have trouble\n"
412 "capturing or listing interfaces.");
420 // Try to avoid library search path collisions. QCoreApplication will
421 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
422 // the application directory. If
424 // - You have Qt version 5.x.y installed in the default location
425 // (C:\Qt\5.x) on your machine.
429 // - You install Wireshark that was built on a machine with Qt version
430 // 5.x.z installed in the default location.
432 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
433 // directory. This may not be compatible with qwindows.dll from that
434 // same path on the build machine. At any rate, loading DLLs from paths
435 // you don't control is ill-advised. We work around this by removing every
436 // path except our application directory.
439 reset_library_path(void)
441 QString app_path = QDir(get_progfile_dir()).path();
442 foreach (QString path, QCoreApplication::libraryPaths()) {
443 QCoreApplication::removeLibraryPath(path);
445 QCoreApplication::addLibraryPath(app_path);
449 /* And now our feature presentation... [ fade to music ] */
450 int main(int argc, char *argv[])
455 gboolean arg_error = FALSE;
456 char **ws_argv = argv;
464 char *gdp_path, *dp_path;
467 gboolean start_capture = FALSE;
468 gboolean list_link_layer_types = FALSE;
473 gboolean capture_option_specified = FALSE;
482 guint go_to_packet = 0;
484 QString dfilter, read_filter;
485 GSList *disable_protocol_slist = NULL;
486 GSList *enable_heur_slist = NULL;
487 GSList *disable_heur_slist = NULL;
489 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
491 // In Qt 5, C strings are treated always as UTF-8 when converted to
492 // QStrings; in Qt 4, the codec must be set to make that happen
493 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
494 // Hopefully we won't have to use QString::fromUtf8() in as many places.
495 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
496 QTextCodec::setCodecForCStrings(utf8codec);
497 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
498 QTextCodec::setCodecForTr(utf8codec);
501 /* Set the C-language locale to the native environment. */
502 // The GTK+ UI calls this. Should we as well?
503 //setlocale(LC_ALL, "");
505 // QCoreApplication clobbers argv. Let's have a local copy.
506 ws_argv = (char **) g_malloc(sizeof(char *) * argc);
507 for (opt = 0; opt < argc; opt++) {
508 ws_argv[opt] = argv[opt];
510 arg_list_utf_16to8(argc, ws_argv);
511 create_app_running_mutex();
515 * Get credential information for later use, and drop privileges
516 * before doing anything else.
517 * Let the user know if anything happened.
519 init_process_policies();
520 relinquish_special_privs_perm();
523 * Attempt to get the pathname of the executable file.
525 /* init_progfile_dir_error = */ init_progfile_dir(ws_argv[0],
526 (int (*)(int, char **)) get_gui_compiled_info);
527 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
530 /* Load wpcap if possible. Do this before collecting the run-time version information */
533 /* ... and also load the packet.dll from wpcap */
537 /* Load the airpcap.dll. This must also be done before collecting
538 * run-time version information. */
541 airpcap_dll_ret_val = load_airpcap();
543 switch (airpcap_dll_ret_val) {
545 /* load the airpcap interfaces */
546 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
548 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
549 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
550 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
553 airpcap_if_active = NULL;
557 /* select the first ad default (THIS SHOULD BE CHANGED) */
558 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
562 * XXX - Maybe we need to warn the user if one of the following happens???
564 case AIRPCAP_DLL_OLD:
565 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
568 case AIRPCAP_DLL_ERROR:
569 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
572 case AIRPCAP_DLL_NOT_FOUND:
573 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
577 #endif /* HAVE_AIRPCAP */
580 /* Get the compile-time version information string */
582 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
583 get_gui_compiled_info);
585 /* Assemble the run-time version information string */
587 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
590 * In order to have the -X opts assigned before the wslua machine starts
591 * we need to call getopt_long before epan_init() gets called.
593 * In addition, we process "console only" parameters (ones where we
594 * send output to the console and exit) here, so we don't start Qt
595 * if we're only showing command-line help or version information.
597 * XXX - this pre-scan is done before we start Qt, so we haven't
598 * run WiresharkApplication's constructor on the arguments. That
599 * means that Qt arguments have not been removed from the argument
600 * list; those arguments begin with "-", and may be treated as
601 * errors by getopt_long().
603 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
606 * XXX - is there some way to parse and remove Qt arguments without
607 * starting up the GUI, which we can call before calling this?
609 * In order to handle, for example, -o options, we also need to call it
610 * *after* epan_init() gets called, so that the dissectors have had a
611 * chance to register their preferences, so we have another getopt_long()
614 * XXX - can we do this all with one getopt_long() call, saving the
615 * arguments we can't handle until after initializing libwireshark,
616 * and then process them after initializing libwireshark?
618 * Note that we don't want to initialize libwireshark until after the
619 * GUI is up, as that can take a while, and we want a window of some
620 * sort up to show progress while that's happening.
622 // XXX Should the remaining code be in WiresharkApplcation::WiresharkApplication?
623 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
624 static const struct option long_options[] = {
625 {"help", no_argument, NULL, 'h'},
626 {"read-file", required_argument, NULL, 'r' },
627 {"read-filter", required_argument, NULL, 'R' },
628 {"display-filter", required_argument, NULL, 'Y' },
629 {"version", no_argument, NULL, 'v'},
630 LONGOPT_CAPTURE_COMMON
633 static const char optstring[] = OPTSTRING;
637 while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
639 case 'C': /* Configuration Profile */
640 if (profile_exists (optarg, FALSE)) {
641 set_profile_name (optarg);
643 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
647 case 'D': /* Print a list of capture devices and exit */
649 if_list = capture_interface_list(&err, &err_str, NULL);
650 if (if_list == NULL) {
652 cmdarg_err("There are no interfaces on which a capture can be done");
654 cmdarg_err("%s", err_str);
662 capture_opts_print_interfaces(if_list);
663 free_interface_list(if_list);
668 #else /* HAVE_LIBPCAP */
669 capture_option_specified = TRUE;
671 #endif /* HAVE_LIBPCAP */
673 case 'h': /* Print help and exit */
679 if (strcmp(optarg, "-") == 0)
680 set_stdin_capture(TRUE);
683 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
684 if (!persfilepath_opt(opt, optarg)) {
685 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
689 case 'v': /* Show version and exit */
693 show_version("Wireshark", comp_info_str, runtime_info_str);
701 * Extension command line options have to be processed before
702 * we call epan_init() as they are supposed to be used by dissectors
703 * or taps very early in the registration process.
707 case '?': /* Ignore errors - the "real" scan will catch them. */
713 reset_library_path();
716 /* Create The Wireshark app */
717 WiresharkApplication ws_app(argc, argv);
719 /* initialize the funnel mini-api */
721 //initialize_funnel_ops();
723 AirPDcapInitContext(&airpdcap_ctx);
727 unsigned int in_file_type = WTAP_TYPE_AUTO;
729 /* Add it to the information to be reported on a crash. */
730 ws_add_crash_info("Wireshark %s\n"
735 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
738 /* Start windows sockets */
739 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
742 profile_store_persconffiles(TRUE);
744 /* Read the profile independent recent file. We have to do this here so we can */
745 /* set the profile before it can be set from the command line parameter */
746 if (!recent_read_static(&rf_path, &rf_open_errno)) {
747 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
748 "Could not open common recent file\n\"%s\": %s.",
749 rf_path, strerror(rf_open_errno));
753 /* Read the profile dependent (static part) of the recent file. */
754 /* Only the static part of it will be read, as we don't have the gui now to fill the */
755 /* recent lists which is done in the dynamic part. */
756 /* We have to do this already here, so command line parameters can overwrite these values. */
757 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
758 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
759 "Could not open recent file\n\"%s\": %s.",
760 rf_path, g_strerror(rf_open_errno));
763 wsApp->applyCustomColorsFromRecent();
765 // Initialize our language
766 read_language_prefs();
767 locale = QString(language);
768 wsApp->loadLanguage(locale);
770 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", locale.toStdString().c_str());
772 // Init the main window (and splash)
773 main_w = new(MainWindow);
775 // We may not need a queued connection here but it would seem to make sense
776 // to force the issue.
777 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
778 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
780 /* Init the "Open file" dialog directory */
781 /* (do this after the path settings are processed) */
782 if (recent.gui_fileopen_remembered_dir &&
783 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
784 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
786 wsApp->setLastOpenDir(get_persdatafile_dir());
790 // Replicates behavior in gtk_init();
791 signal(SIGPIPE, SIG_IGN);
794 set_console_log_handler();
797 /* Set the initial values in the capture options. This might be overwritten
798 by preference settings and then again by the command line parameters. */
799 capture_opts_init(&global_capture_opts);
802 init_report_err(failure_alert_box, open_failure_alert_box,
803 read_failure_alert_box, write_failure_alert_box);
805 init_open_routines();
808 /* Register all the plugin types we have. */
809 epan_register_plugin_types(); /* Types known to libwireshark */
810 wtap_register_plugin_types(); /* Types known to libwiretap */
811 codec_register_plugin_types(); /* Types known to libwscodecs */
813 /* Scan for plugins. This does *not* call their registration routines;
814 that's done later. */
817 /* Register all libwiretap plugin modules. */
818 register_all_wiretap_modules();
820 /* Register all audio codec plugins. */
821 register_all_codecs();
824 /* Register all dissectors; we must do this before checking for the
825 "-G" flag, as the "-G" flag dumps information registered by the
826 dissectors, and we must do it before we read the preferences, in
827 case any dissectors register preferences. */
828 if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
829 splash_update, NULL)) {
830 SimpleDialog::displayQueuedMessages(main_w);
834 splash_update(RA_LISTENERS, NULL, NULL);
836 /* Register all tap listeners; we do this before we parse the arguments,
837 as the "-z" argument can specify a registered tap. */
839 /* we register the plugin taps before the other taps because
840 stats_tree taps plugins will be registered as tap listeners
841 by stats_tree_stat.c and need to registered before that */
843 register_all_plugin_tap_listeners();
847 extcap_register_preferences();
850 register_all_tap_listeners();
851 conversation_table_set_gui_info(init_conversation_table);
852 hostlist_table_set_gui_info(init_endpoint_table);
853 srt_table_iterate_tables(register_service_response_tables, NULL);
854 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
855 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
857 if (ex_opt_count("read_format") > 0) {
858 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
861 splash_update(RA_PREFERENCES, NULL, NULL);
863 prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path, false);
866 * To reset the options parser, set optreset to 1 on platforms that
867 * have optreset (documented in *BSD and OS X, apparently present but
868 * not documented in Solaris - the Illumos repository seems to
869 * suggest that the first Solaris getopt_long(), at least as of 2004,
870 * was based on the NetBSD one, it had optreset) and set optind to 1,
871 * and set optind to 0 otherwise (documented as working in the GNU
872 * getopt_long(). Setting optind to 0 didn't originally work in the
873 * NetBSD one, but that was added later - we don't want to depend on
874 * it if we have optreset).
876 * Also reset opterr to 1, so that error messages are printed by
879 * XXX - if we want to control all the command-line option errors, so
880 * that we can display them where we choose (e.g., in a window), we'd
881 * want to leave opterr as 0, and produce our own messages using optopt.
882 * We'd have to check the value of optopt to see if it's a valid option
883 * letter, in which case *presumably* the error is "this option requires
884 * an argument but none was specified", or not a valid option letter,
885 * in which case *presumably* the error is "this option isn't valid".
886 * Some versions of getopt() let you supply a option string beginning
887 * with ':', which means that getopt() will return ':' rather than '?'
888 * for "this option requires an argument but none was specified", but
889 * not all do. But we're now using getopt_long() - what does it do?
899 /* Now get our args */
900 while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
902 /*** capture option specific ***/
903 case 'a': /* autostop criteria */
904 case 'b': /* Ringbuffer option */
905 case 'c': /* Capture xxx packets */
906 case 'f': /* capture filter */
907 case 'k': /* Start capture immediately */
908 case 'H': /* Hide capture info dialog box */
909 case 'p': /* Don't capture in promiscuous mode */
910 case 'i': /* Use interface x */
911 #ifdef HAVE_PCAP_CREATE
912 case 'I': /* Capture in monitor mode, if available */
914 #ifdef HAVE_PCAP_REMOTE
915 case 'A': /* Authentication */
917 case 's': /* Set the snapshot (capture) length */
918 case 'S': /* "Sync" mode: used for following file ala tail -f */
919 case 'w': /* Write to capture file xxx */
920 case 'y': /* Set the pcap data link type */
921 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
922 case 'B': /* Buffer size */
925 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
931 capture_option_specified = TRUE;
936 case 'K': /* Kerberos keytab file */
937 read_keytab_file(optarg);
941 /*** all non capture option specific ***/
943 /* Configuration profile settings were already processed just ignore them this time*/
945 case 'j': /* Search backwards for a matching packet from filter in option J */
946 /* Not supported yet */
948 case 'g': /* Go to packet with the given packet number */
949 go_to_packet = get_positive_int(optarg, "go to packet");
951 case 'J': /* Jump to the first packet which matches the filter criteria */
952 /* Not supported yet */
954 case 'l': /* Automatic scrolling in live capture mode */
956 /* Not supported yet */
958 capture_option_specified = TRUE;
962 case 'L': /* Print list of link-layer types and exit */
964 list_link_layer_types = TRUE;
966 capture_option_specified = TRUE;
970 case 'm': /* Fixed-width font for the display */
971 /* Not supported yet */
973 case 'n': /* No name resolution */
974 disable_name_resolution();
976 case 'N': /* Select what types of addresses/port #s to resolve */
977 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
978 if (badopt != '\0') {
979 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
984 case 'o': /* Override preference from command line */
985 switch (prefs_set_pref(optarg)) {
988 case PREFS_SET_SYNTAX_ERR:
989 cmdarg_err("Invalid -o flag \"%s\"", optarg);
992 case PREFS_SET_NO_SUCH_PREF:
993 /* not a preference, might be a recent setting */
994 switch (recent_set_arg(optarg)) {
997 case PREFS_SET_SYNTAX_ERR:
998 /* shouldn't happen, checked already above */
999 cmdarg_err("Invalid -o flag \"%s\"", optarg);
1002 case PREFS_SET_NO_SUCH_PREF:
1003 case PREFS_SET_OBSOLETE:
1004 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
1009 g_assert_not_reached();
1012 case PREFS_SET_OBSOLETE:
1013 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
1018 g_assert_not_reached();
1022 /* Path settings were already processed just ignore them this time*/
1027 case 'R': /* Read file filter */
1028 read_filter = QString(optarg);
1030 case 't': /* Time stamp type */
1031 if (strcmp(optarg, "r") == 0)
1032 timestamp_set_type(TS_RELATIVE);
1033 else if (strcmp(optarg, "a") == 0)
1034 timestamp_set_type(TS_ABSOLUTE);
1035 else if (strcmp(optarg, "ad") == 0)
1036 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
1037 else if (strcmp(optarg, "adoy") == 0)
1038 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
1039 else if (strcmp(optarg, "d") == 0)
1040 timestamp_set_type(TS_DELTA);
1041 else if (strcmp(optarg, "dd") == 0)
1042 timestamp_set_type(TS_DELTA_DIS);
1043 else if (strcmp(optarg, "e") == 0)
1044 timestamp_set_type(TS_EPOCH);
1045 else if (strcmp(optarg, "u") == 0)
1046 timestamp_set_type(TS_UTC);
1047 else if (strcmp(optarg, "ud") == 0)
1048 timestamp_set_type(TS_UTC_WITH_YMD);
1049 else if (strcmp(optarg, "udoy") == 0)
1050 timestamp_set_type(TS_UTC_WITH_YDOY);
1052 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
1054 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
1056 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
1058 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
1060 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
1062 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
1066 case 'u': /* Seconds type */
1067 if (strcmp(optarg, "s") == 0)
1068 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1069 else if (strcmp(optarg, "hms") == 0)
1070 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
1072 cmdarg_err("Invalid seconds type \"%s\"", optarg);
1074 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
1079 /* ext ops were already processed just ignore them this time*/
1082 dfilter = QString(optarg);
1085 /* We won't call the init function for the stat this soon
1086 as it would disallow MATE's fields (which are registered
1087 by the preferences set callback) from being used as
1088 part of a tap filter. Instead, we just add the argument
1089 to a list of stat arguments. */
1090 if (strcmp("help", optarg) == 0) {
1091 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
1092 list_stat_cmd_args();
1095 if (!process_stat_cmd_arg(optarg)) {
1096 cmdarg_err("Invalid -z argument.");
1097 cmdarg_err_cont(" -z argument must be one of :");
1098 list_stat_cmd_args();
1102 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1103 disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
1105 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1106 enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
1108 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1109 disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
1113 case '?': /* Bad flag - print usage message */
1124 if (!cf_name.isEmpty()) {
1126 * Input file name specified with "-r" *and* specified as a regular
1127 * command-line argument.
1129 cmdarg_err("File name specified both with -r and regular argument");
1133 * Input file name not specified with "-r", and a command-line argument
1134 * was specified; treat it as the input file name.
1136 * Yes, this is different from tshark, where non-flag command-line
1137 * arguments are a filter, but this works better on GUI desktops
1138 * where a command can be specified to be run to open a particular
1139 * file - yes, you could have "-r" as the last part of the command,
1140 * but that's a bit ugly.
1142 cf_name = ws_argv[0];
1151 * Extra command line arguments were specified; complain.
1153 cmdarg_err("Invalid argument: %s", ws_argv[0]);
1158 #ifndef HAVE_LIBPCAP
1159 if (capture_option_specified) {
1160 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
1167 /* Removed thread code:
1168 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
1171 // XXX Is there a better place to set the timestamp format & precision?
1172 timestamp_set_type(recent.gui_time_format);
1173 timestamp_set_precision(recent.gui_time_precision);
1174 timestamp_set_seconds_type (recent.gui_seconds_format);
1177 fill_in_local_interfaces(main_window_update);
1179 if (start_capture && list_link_layer_types) {
1180 /* Specifying *both* is bogus. */
1181 cmdarg_err("You can't specify both -L and a live capture.");
1185 if (list_link_layer_types) {
1186 /* We're supposed to list the link-layer types for an interface;
1187 did the user also specify a capture file to be read? */
1188 if (!cf_name.isEmpty()) {
1189 /* Yes - that's bogus. */
1190 cmdarg_err("You can't specify -L and a capture file to be read.");
1193 /* No - did they specify a ring buffer option? */
1194 if (global_capture_opts.multi_files_on) {
1195 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
1199 /* We're supposed to do a live capture; did the user also specify
1200 a capture file to be read? */
1201 if (start_capture && !cf_name.isEmpty()) {
1202 /* Yes - that's bogus. */
1203 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
1207 /* No - was the ring buffer option specified and, if so, does it make
1209 if (global_capture_opts.multi_files_on) {
1210 /* Ring buffer works only under certain conditions:
1211 a) ring buffer does not work with temporary files;
1212 b) real_time_mode and multi_files_on are mutually exclusive -
1213 real_time_mode takes precedence;
1214 c) it makes no sense to enable the ring buffer if the maximum
1215 file size is set to "infinite". */
1216 if (global_capture_opts.save_file == NULL) {
1217 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
1218 global_capture_opts.multi_files_on = FALSE;
1220 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
1221 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
1222 /* XXX - this must be redesigned as the conditions changed */
1227 if (start_capture || list_link_layer_types) {
1228 /* We're supposed to do a live capture or get a list of link-layer
1229 types for a live capture device; if the user didn't specify an
1230 interface to use, pick a default. */
1231 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
1232 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
1238 if (list_link_layer_types) {
1239 /* Get the list of link-layer types for the capture devices. */
1240 if_capabilities_t *caps;
1243 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1245 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1246 if (device.selected) {
1247 #if defined(HAVE_PCAP_CREATE)
1248 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
1250 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
1253 cmdarg_err("%s", err_str);
1257 if (caps->data_link_types == NULL) {
1258 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
1264 #if defined(HAVE_PCAP_CREATE)
1265 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
1267 capture_opts_print_if_capabilities(caps, device.name, FALSE);
1272 free_if_capabilities(caps);
1278 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
1279 capture_opts_trim_ring_num_files(&global_capture_opts);
1280 #endif /* HAVE_LIBPCAP */
1282 /* Notify all registered modules that have had any of their preferences
1283 changed either from one of the preferences file or from the command
1284 line that their preferences have changed. */
1286 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
1289 if ((global_capture_opts.num_selected == 0) &&
1290 (prefs.capture_device != NULL)) {
1293 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1294 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1295 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
1296 device.selected = TRUE;
1297 global_capture_opts.num_selected++;
1298 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
1299 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
1306 /* disabled protocols as per configuration file */
1307 if (gdp_path == NULL && dp_path == NULL) {
1308 set_disabled_protos_list();
1309 set_disabled_heur_dissector_list();
1312 if(disable_protocol_slist) {
1313 GSList *proto_disable;
1314 for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
1316 proto_disable_proto_by_name((char*)proto_disable->data);
1320 if(enable_heur_slist) {
1321 GSList *heur_enable;
1322 for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
1324 proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
1328 if(disable_heur_slist) {
1329 GSList *heur_disable;
1330 for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
1332 proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
1336 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, prefs_p->num_cols, TRUE);
1337 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
1338 wsApp->emitAppSignal(WiresharkApplication::RecentFilesRead); // Must be emitted after PreferencesChanged.
1340 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
1342 /* For update of WindowTitle (When use gui.window_title preference) */
1343 main_w->setWSWindowTitle();
1346 /* Read the dynamic part of the recent file, as we have the gui now ready for
1348 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
1349 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1350 "Could not open recent file\n\"%s\": %s.",
1351 rf_path, g_strerror(rf_open_errno));
1355 packet_list_enable_color(recent.packet_list_colorize);
1357 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
1358 packet_list_enable_color(TRUE);
1364 gchar* err_msg = NULL;
1365 if (!color_filters_init(&err_msg, color_filter_add_cb)) {
1366 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
1373 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1374 if (!start_capture && !global_capture_opts.default_options.cfilter) {
1375 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1377 #else /* HAVE_LIBPCAP */
1379 #endif /* HAVE_LIBPCAP */
1381 wsApp->allSystemsGo();
1382 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
1383 SimpleDialog::displayQueuedMessages(main_w);
1385 /* User could specify filename, or display filter, or both */
1386 if (!dfilter.isEmpty())
1387 main_w->filterPackets(dfilter, false);
1388 if (!cf_name.isEmpty()) {
1389 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
1391 /* Open stat windows; we do so after creating the main window,
1392 to avoid Qt warnings, and after successfully opening the
1393 capture file, so we know we have something to compute stats
1394 on, and after registering all dissectors, so that MATE will
1395 have registered its field array and we can have a tap filter
1396 with one of MATE's late-registered fields as part of the
1398 start_requested_stats();
1400 if(go_to_packet != 0) {
1401 /* Jump to the specified frame number, kept for backward
1403 cf_goto_frame(CaptureFile::globalCapFile(), go_to_packet);
1409 if (start_capture) {
1410 if (global_capture_opts.save_file != NULL) {
1411 /* Save the directory name for future file dialogs. */
1412 /* (get_dirname overwrites filename) */
1413 gchar *s = g_strdup(global_capture_opts.save_file);
1414 set_last_open_dir(get_dirname(s));
1417 /* "-k" was specified; start a capture. */
1418 // show_main_window(FALSE);
1419 check_and_warn_user_startup(cf_name);
1421 /* If no user interfaces were specified on the command line,
1422 copy the list of selected interfaces to the set of interfaces
1423 to use for this capture. */
1424 if (global_capture_opts.ifaces->len == 0)
1425 collect_ifaces(&global_capture_opts);
1426 CaptureFile::globalCapFile()->window = main_w;
1427 if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
1428 /* The capture started. Open stat windows; we do so after creating
1429 the main window, to avoid GTK warnings, and after successfully
1430 opening the capture file, so we know we have something to compute
1431 stats on, and after registering all dissectors, so that MATE will
1432 have registered its field array and we can have a tap filter with
1433 one of MATE's late-registered fields as part of the filter. */
1434 start_requested_stats();
1437 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1438 if (!start_capture && !global_capture_opts.default_options.cfilter) {
1439 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1442 #endif /* HAVE_LIBPCAP */
1444 return wsApp->exec();
1453 * indent-tabs-mode: nil
1456 * ex: set shiftwidth=4 tabstop=8 expandtab:
1457 * :indentSize=4:tabSize=8:noTabs=true: