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>
73 /* general (not Qt specific) */
76 #include "color_filters.h"
79 #include "epan/rtd_table.h"
80 #include "epan/srt_table.h"
82 #include "ui/alert_box.h"
83 #include "ui/console.h"
84 #include "ui/iface_lists.h"
85 #include "ui/language.h"
86 #include "ui/persfilepath_opt.h"
87 #include "ui/recent.h"
88 #include "ui/simple_dialog.h"
91 #include "ui/qt/conversation_dialog.h"
92 #include "ui/qt/endpoint_dialog.h"
93 #include "ui/qt/main_window.h"
94 #include "ui/qt/response_time_delay_dialog.h"
95 #include "ui/qt/service_response_time_dialog.h"
96 #include "ui/qt/simple_dialog.h"
97 #include "ui/qt/simple_statistics_dialog.h"
98 #include "ui/qt/splash_overlay.h"
99 #include "ui/qt/wireshark_application.h"
101 #include "caputils/capture-pcap-util.h"
104 # include "caputils/capture-wpcap.h"
105 # include "caputils/capture_wpcap_packet.h"
106 # include <tchar.h> /* Needed for Unicode */
107 # include <wsutil/file_util.h>
108 # include <wsutil/os_version_info.h>
112 # include <caputils/airpcap.h>
113 # include <caputils/airpcap_loader.h>
114 //# include "airpcap_dlg.h"
115 //# include "airpcap_gui_utils.h"
118 #include "epan/crypt/airpdcap_ws.h"
120 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
121 #include <QTextCodec>
124 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
125 capture_options global_capture_opts;
128 GString *comp_info_str, *runtime_info_str;
130 /* update the main window */
131 void main_window_update(void)
133 WiresharkApplication::processEvents();
138 /* quit a nested main window */
139 void main_window_nested_quit(void)
141 // if (gtk_main_level() > 0)
145 /* quit the main window */
146 void main_window_quit(void)
151 #endif /* HAVE_LIBPCAP */
154 // xxx copied from ../gtk/main.c
156 print_usage(gboolean for_help_option) {
163 if (for_help_option) {
165 fprintf(output, "Wireshark %s\n"
166 "Interactively dump and analyze network traffic.\n"
167 "See http://www.wireshark.org for more information.\n",
168 get_ws_vcs_version_info());
172 fprintf(output, "\n");
173 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
174 fprintf(output, "\n");
177 fprintf(output, "Capture interface:\n");
178 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
179 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
180 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
181 fprintf(output, " -p don't capture in promiscuous mode\n");
182 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
183 fprintf(output, " -S update packet display when new packets are captured\n");
184 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
185 #ifdef HAVE_PCAP_CREATE
186 fprintf(output, " -I capture in monitor mode, if available\n");
188 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
189 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
191 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
192 fprintf(output, " -D print list of interfaces and exit\n");
193 fprintf(output, " -L print list of link-layer types of iface and exit\n");
194 fprintf(output, "\n");
195 fprintf(output, "Capture stop conditions:\n");
196 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
197 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
198 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
199 fprintf(output, " files:NUM - stop after NUM files\n");
200 /*fprintf(output, "\n");*/
201 fprintf(output, "Capture output:\n");
202 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
203 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
204 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
205 #endif /* HAVE_LIBPCAP */
206 #ifdef HAVE_PCAP_REMOTE
207 fprintf(output, "RPCAP options:\n");
208 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
210 /*fprintf(output, "\n");*/
211 fprintf(output, "Input file:\n");
212 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
214 fprintf(output, "\n");
215 fprintf(output, "Processing:\n");
216 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
217 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
218 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtCd\"\n");
219 fprintf(output, " --disable-protocol <proto_name>\n");
220 fprintf(output, " disable dissection of proto_name\n");
221 fprintf(output, " --enable-heuristic <short_name>\n");
222 fprintf(output, " enable dissection of heuristic protocol\n");
223 fprintf(output, " --disable-heuristic <short_name>\n");
224 fprintf(output, " disable dissection of heuristic protocol\n");
226 fprintf(output, "\n");
227 fprintf(output, "User interface:\n");
228 fprintf(output, " -C <config profile> start with specified configuration profile\n");
229 fprintf(output, " -Y <display filter> start with the given display filter\n");
230 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
231 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
232 fprintf(output, " filter\n");
233 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
234 fprintf(output, " -m <font> set the font name used for most text\n");
235 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
236 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
237 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
238 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
240 fprintf(output, "\n");
241 fprintf(output, "Output:\n");
242 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
244 fprintf(output, "\n");
245 fprintf(output, "Miscellaneous:\n");
246 fprintf(output, " -h display this help and exit\n");
247 fprintf(output, " -v display version info and exit\n");
248 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
249 fprintf(output, " persdata:path - personal data files\n");
250 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
251 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
253 fprintf(output, " --display=DISPLAY X display to use\n");
255 fprintf(output, "\nNOTE: Not all options are implemented in the Qt port.\n");
263 * Report an error in command-line arguments.
264 * Creates a console on Windows.
266 // xxx copied from ../gtk/main.c
268 wireshark_cmdarg_err(const char *fmt, va_list ap)
273 fprintf(stderr, "wireshark: ");
274 vfprintf(stderr, fmt, ap);
275 fprintf(stderr, "\n");
279 * Report additional information for an error in command-line arguments.
280 * Creates a console on Windows.
281 * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
282 * terminal isn't the standard error?
284 // xxx copied from ../gtk/main.c
286 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
291 vfprintf(stderr, fmt, ap);
292 fprintf(stderr, "\n");
295 // xxx based from ../gtk/main.c:get_gtk_compiled_info
297 get_wireshark_qt_compiled_info(GString *str)
299 g_string_append(str, "with ");
300 g_string_append_printf(str,
302 "Qt %s", QT_VERSION_STR);
304 "Qt (version unknown)");
307 /* Capture libraries */
308 g_string_append(str, ", ");
309 get_compiled_caplibs_version(str);
312 g_string_append(str, ", ");
314 g_string_append(str, "with libz ");
316 g_string_append(str, ZLIB_VERSION);
317 #else /* ZLIB_VERSION */
318 g_string_append(str, "(version unknown)");
319 #endif /* ZLIB_VERSION */
320 #else /* HAVE_LIBZ */
321 g_string_append(str, "without libz");
322 #endif /* HAVE_LIBZ */
325 // xxx copied from ../gtk/main.c
327 get_gui_compiled_info(GString *str)
329 epan_get_compiled_version_info(str);
331 g_string_append(str, ", ");
332 #ifdef QT_MULTIMEDIA_LIB
333 g_string_append(str, "with QtMultimedia");
335 g_string_append(str, "without QtMultimedia");
338 g_string_append(str, ", ");
340 get_compiled_airpcap_version(str);
342 g_string_append(str, "without AirPcap");
346 // xxx copied from ../gtk/main.c
348 get_wireshark_runtime_info(GString *str)
351 /* Capture libraries */
352 g_string_append(str, ", ");
353 get_runtime_caplibs_version(str);
357 #if defined(HAVE_LIBZ) && !defined(_WIN32)
358 g_string_append_printf(str, ", with libz %s", zlibVersion());
361 /* stuff used by libwireshark */
362 epan_get_runtime_version_info(str);
365 g_string_append(str, ", ");
366 get_runtime_airpcap_version(str);
370 g_string_append(str, ", ");
371 u3_runtime_info(str);
376 /* Check if there's something important to tell the user during startup.
377 * We want to do this *after* showing the main window so that any windows
378 * we pop up will be above the main window.
381 check_and_warn_user_startup(const QString &cf_name)
386 gchar *cur_user, *cur_group;
388 /* Tell the user not to run as root. */
389 if (running_with_special_privs() && recent.privs_warn_if_elevated) {
390 cur_user = get_cur_username();
391 cur_group = get_cur_groupname();
392 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
393 "Running as user \"%s\" and group \"%s\".\n"
394 "This could be dangerous.\n\n"
395 "If you're running Wireshark this way in order to perform live capture, "
396 "you may want to be aware that there is a better way documented at\n"
397 "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
403 /* Warn the user if npf.sys isn't loaded. */
404 if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
405 simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
406 "The NPF driver isn't running. You may have trouble\n"
407 "capturing or listing interfaces.");
415 // Try to avoid library search path collisions. QCoreApplication will
416 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
417 // the application directory. If
419 // - You have Qt version 5.x.y installed in the default location
420 // (C:\Qt\5.x) on your machine.
424 // - You install Wireshark that was built on a machine with Qt version
425 // 5.x.z installed in the default location.
427 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
428 // directory. This may not be compatible with qwindows.dll from that
429 // same path on the build machine. At any rate, loading DLLs from paths
430 // you don't control is ill-advised. We work around this by removing every
431 // path except our application directory.
434 reset_library_path(void)
436 QString app_path = QDir(get_progfile_dir()).path();
437 foreach (QString path, QCoreApplication::libraryPaths()) {
438 QCoreApplication::removeLibraryPath(path);
440 QCoreApplication::addLibraryPath(app_path);
444 /* And now our feature presentation... [ fade to music ] */
445 int main(int argc, char *argv[])
450 gboolean arg_error = FALSE;
451 char **ws_argv = argv;
459 char *gdp_path, *dp_path;
462 gboolean start_capture = FALSE;
463 gboolean list_link_layer_types = FALSE;
468 gboolean capture_option_specified = FALSE;
477 guint go_to_packet = 0;
479 QString dfilter, read_filter;
480 GSList *disable_protocol_slist = NULL;
481 GSList *enable_heur_slist = NULL;
482 GSList *disable_heur_slist = NULL;
484 cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
486 // In Qt 5, C strings are treated always as UTF-8 when converted to
487 // QStrings; in Qt 4, the codec must be set to make that happen
488 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
489 // Hopefully we won't have to use QString::fromUtf8() in as many places.
490 QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
491 QTextCodec::setCodecForCStrings(utf8codec);
492 // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
493 QTextCodec::setCodecForTr(utf8codec);
496 /* Set the C-language locale to the native environment. */
497 // The GTK+ UI calls this. Should we as well?
498 //setlocale(LC_ALL, "");
500 // QCoreApplication clobbers argv. Let's have a local copy.
501 ws_argv = (char **) g_malloc(sizeof(char *) * argc);
502 for (opt = 0; opt < argc; opt++) {
503 ws_argv[opt] = argv[opt];
505 arg_list_utf_16to8(argc, ws_argv);
506 create_app_running_mutex();
510 * Get credential information for later use, and drop privileges
511 * before doing anything else.
512 * Let the user know if anything happened.
514 init_process_policies();
515 relinquish_special_privs_perm();
518 * Attempt to get the pathname of the executable file.
520 /* init_progfile_dir_error = */ init_progfile_dir(ws_argv[0],
521 (void *) get_gui_compiled_info);
522 g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
525 /* Load wpcap if possible. Do this before collecting the run-time version information */
528 /* ... and also load the packet.dll from wpcap */
532 /* Load the airpcap.dll. This must also be done before collecting
533 * run-time version information. */
536 airpcap_dll_ret_val = load_airpcap();
538 switch (airpcap_dll_ret_val) {
540 /* load the airpcap interfaces */
541 g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
543 if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
544 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
545 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
548 airpcap_if_active = NULL;
552 /* select the first ad default (THIS SHOULD BE CHANGED) */
553 airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
557 * XXX - Maybe we need to warn the user if one of the following happens???
559 case AIRPCAP_DLL_OLD:
560 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
563 case AIRPCAP_DLL_ERROR:
564 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
567 case AIRPCAP_DLL_NOT_FOUND:
568 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
572 #endif /* HAVE_AIRPCAP */
575 /* Get the compile-time version information string */
577 comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
578 get_gui_compiled_info);
580 /* Assemble the run-time version information string */
582 runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
585 * In order to have the -X opts assigned before the wslua machine starts
586 * we need to call getopt_long before epan_init() gets called.
588 * In addition, we process "console only" parameters (ones where we
589 * send output to the console and exit) here, so we don't start Qt
590 * if we're only showing command-line help or version information.
592 * XXX - this pre-scan is done before we start Qt, so we haven't
593 * run WiresharkApplication's constructor on the arguments. That
594 * means that Qt arguments have not been removed from the argument
595 * list; those arguments begin with "-", and may be treated as
596 * errors by getopt_long().
598 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
601 * XXX - is there some way to parse and remove Qt arguments without
602 * starting up the GUI, which we can call before calling this?
604 * In order to handle, for example, -o options, we also need to call it
605 * *after* epan_init() gets called, so that the dissectors have had a
606 * chance to register their preferences, so we have another getopt_long()
609 * XXX - can we do this all with one getopt_long() call, saving the
610 * arguments we can't handle until after initializing libwireshark,
611 * and then process them after initializing libwireshark?
613 * Note that we don't want to initialize libwireshark until after the
614 * GUI is up, as that can take a while, and we want a window of some
615 * sort up to show progress while that's happening.
617 // XXX Should the remaining code be in WiresharkApplcation::WiresharkApplication?
618 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
620 static const struct option long_options[] = {
621 {(char *)"help", no_argument, NULL, 'h'},
622 {(char *)"read-file", required_argument, NULL, 'r' },
623 {(char *)"read-filter", required_argument, NULL, 'R' },
624 {(char *)"display-filter", required_argument, NULL, 'Y' },
625 {(char *)"version", no_argument, NULL, 'v'},
626 LONGOPT_CAPTURE_COMMON
630 static const char optstring[] = OPTSTRING;
634 while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
636 case 'C': /* Configuration Profile */
637 if (profile_exists (optarg, FALSE)) {
638 set_profile_name (optarg);
640 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
644 case 'D': /* Print a list of capture devices and exit */
646 if_list = capture_interface_list(&err, &err_str, NULL);
647 if (if_list == NULL) {
649 cmdarg_err("There are no interfaces on which a capture can be done");
651 cmdarg_err("%s", err_str);
659 capture_opts_print_interfaces(if_list);
660 free_interface_list(if_list);
665 #else /* HAVE_LIBPCAP */
666 capture_option_specified = TRUE;
668 #endif /* HAVE_LIBPCAP */
670 case 'h': /* Print help and exit */
676 if (strcmp(optarg, "-") == 0)
677 set_stdin_capture(TRUE);
680 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
681 if (!persfilepath_opt(opt, optarg)) {
682 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
686 case 'v': /* Show version and exit */
690 show_version("Wireshark", comp_info_str, runtime_info_str);
698 * Extension command line options have to be processed before
699 * we call epan_init() as they are supposed to be used by dissectors
700 * or taps very early in the registration process.
704 case '?': /* Ignore errors - the "real" scan will catch them. */
710 reset_library_path();
713 /* Create The Wireshark app */
714 WiresharkApplication ws_app(argc, argv);
716 /* initialize the funnel mini-api */
718 //initialize_funnel_ops();
720 AirPDcapInitContext(&airpdcap_ctx);
724 unsigned int in_file_type = WTAP_TYPE_AUTO;
726 /* Add it to the information to be reported on a crash. */
727 ws_add_crash_info("Wireshark %s\n"
732 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
735 /* Start windows sockets */
736 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
739 profile_store_persconffiles(TRUE);
741 /* Read the profile independent recent file. We have to do this here so we can */
742 /* set the profile before it can be set from the command line parameter */
743 if (!recent_read_static(&rf_path, &rf_open_errno)) {
744 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
745 "Could not open common recent file\n\"%s\": %s.",
746 rf_path, strerror(rf_open_errno));
750 /* Init the "Open file" dialog directory */
751 /* (do this after the path settings are processed) */
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));
764 // Initialize our language
765 read_language_prefs();
766 locale = QString(language);
767 wsApp->loadLanguage(locale);
769 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", locale.toStdString().c_str());
771 // Init the main window (and splash)
772 main_w = new(MainWindow);
774 // We may not need a queued connection here but it would seem to make sense
775 // to force the issue.
776 main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
777 main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
779 /* Init the "Open file" dialog directory */
780 /* (do this after the path settings are processed) */
782 /* Read the profile dependent (static part) of the recent file. */
783 /* Only the static part of it will be read, as we don't have the gui now to fill the */
784 /* recent lists which is done in the dynamic part. */
785 /* We have to do this already here, so command line parameters can overwrite these values. */
786 if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
787 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
788 "Could not open recent file\n\"%s\": %s.",
789 rf_path, g_strerror(rf_open_errno));
793 if (recent.gui_fileopen_remembered_dir &&
794 test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
795 wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
797 wsApp->setLastOpenDir(get_persdatafile_dir());
801 // Replicates behavior in gtk_init();
802 signal(SIGPIPE, SIG_IGN);
805 set_console_log_handler();
808 /* Set the initial values in the capture options. This might be overwritten
809 by preference settings and then again by the command line parameters. */
810 capture_opts_init(&global_capture_opts);
813 init_report_err(failure_alert_box, open_failure_alert_box,
814 read_failure_alert_box, write_failure_alert_box);
816 init_open_routines();
819 /* Register all the plugin types we have. */
820 epan_register_plugin_types(); /* Types known to libwireshark */
821 wtap_register_plugin_types(); /* Types known to libwiretap */
822 codec_register_plugin_types(); /* Types known to libcodec */
824 /* Scan for plugins. This does *not* call their registration routines;
825 that's done later. */
828 /* Register all libwiretap plugin modules. */
829 register_all_wiretap_modules();
831 /* Register all audio codec plugins. */
832 register_all_codecs();
835 /* Register all dissectors; we must do this before checking for the
836 "-G" flag, as the "-G" flag dumps information registered by the
837 dissectors, and we must do it before we read the preferences, in
838 case any dissectors register preferences. */
839 epan_init(register_all_protocols,register_all_protocol_handoffs,
840 splash_update, NULL);
842 splash_update(RA_LISTENERS, NULL, NULL);
844 /* Register all tap listeners; we do this before we parse the arguments,
845 as the "-z" argument can specify a registered tap. */
847 /* we register the plugin taps before the other taps because
848 stats_tree taps plugins will be registered as tap listeners
849 by stats_tree_stat.c and need to registered before that */
851 register_all_plugin_tap_listeners();
854 register_all_tap_listeners();
855 conversation_table_set_gui_info(init_conversation_table);
856 hostlist_table_set_gui_info(init_endpoint_table);
857 srt_table_iterate_tables(register_service_response_tables, NULL);
858 rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
859 new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
861 if (ex_opt_count("read_format") > 0) {
862 in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
865 splash_update(RA_PREFERENCES, NULL, NULL);
867 prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path);
870 * To reset the options parser, set optreset to 1 on platforms that
871 * have optreset (documented in *BSD and OS X, apparently present but
872 * not documented in Solaris - the Illumos repository seems to
873 * suggest that the first Solaris getopt_long(), at least as of 2004,
874 * was based on the NetBSD one, it had optreset) and set optind to 1,
875 * and set optind to 0 otherwise (documented as working in the GNU
876 * getopt_long(). Setting optind to 0 didn't originally work in the
877 * NetBSD one, but that was added later - we don't want to depend on
878 * it if we have optreset).
880 * Also reset opterr to 1, so that error messages are printed by
883 * XXX - if we want to control all the command-line option errors, so
884 * that we can display them where we choose (e.g., in a window), we'd
885 * want to leave opterr as 0, and produce our own messages using optopt.
886 * We'd have to check the value of optopt to see if it's a valid option
887 * letter, in which case *presumably* the error is "this option requires
888 * an argument but none was specified", or not a valid option letter,
889 * in which case *presumably* the error is "this option isn't valid".
890 * Some versions of getopt() let you supply a option string beginning
891 * with ':', which means that getopt() will return ':' rather than '?'
892 * for "this option requires an argument but none was specified", but
893 * not all do. But we're now using getopt_long() - what does it do?
903 /* Now get our args */
904 while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
906 /*** capture option specific ***/
907 case 'a': /* autostop criteria */
908 case 'b': /* Ringbuffer option */
909 case 'c': /* Capture xxx packets */
910 case 'f': /* capture filter */
911 case 'k': /* Start capture immediately */
912 case 'H': /* Hide capture info dialog box */
913 case 'p': /* Don't capture in promiscuous mode */
914 case 'i': /* Use interface x */
915 #ifdef HAVE_PCAP_CREATE
916 case 'I': /* Capture in monitor mode, if available */
918 #ifdef HAVE_PCAP_REMOTE
919 case 'A': /* Authentication */
921 case 's': /* Set the snapshot (capture) length */
922 case 'S': /* "Sync" mode: used for following file ala tail -f */
923 case 'w': /* Write to capture file xxx */
924 case 'y': /* Set the pcap data link type */
925 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
926 case 'B': /* Buffer size */
929 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
935 capture_option_specified = TRUE;
940 case 'K': /* Kerberos keytab file */
941 read_keytab_file(optarg);
945 /*** all non capture option specific ***/
947 /* Configuration profile settings were already processed just ignore them this time*/
949 case 'j': /* Search backwards for a matching packet from filter in option J */
950 /* Not supported yet */
952 case 'g': /* Go to packet with the given packet number */
953 go_to_packet = get_positive_int(optarg, "go to packet");
955 case 'J': /* Jump to the first packet which matches the filter criteria */
956 /* Not supported yet */
958 case 'l': /* Automatic scrolling in live capture mode */
960 /* Not supported yet */
962 capture_option_specified = TRUE;
966 case 'L': /* Print list of link-layer types and exit */
968 list_link_layer_types = TRUE;
970 capture_option_specified = TRUE;
974 case 'm': /* Fixed-width font for the display */
975 /* Not supported yet */
977 case 'n': /* No name resolution */
978 disable_name_resolution();
980 case 'N': /* Select what types of addresses/port #s to resolve */
981 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
982 if (badopt != '\0') {
983 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
988 case 'o': /* Override preference from command line */
989 switch (prefs_set_pref(optarg)) {
992 case PREFS_SET_SYNTAX_ERR:
993 cmdarg_err("Invalid -o flag \"%s\"", optarg);
996 case PREFS_SET_NO_SUCH_PREF:
997 /* not a preference, might be a recent setting */
998 switch (recent_set_arg(optarg)) {
1001 case PREFS_SET_SYNTAX_ERR:
1002 /* shouldn't happen, checked already above */
1003 cmdarg_err("Invalid -o flag \"%s\"", optarg);
1006 case PREFS_SET_NO_SUCH_PREF:
1007 case PREFS_SET_OBSOLETE:
1008 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
1013 g_assert_not_reached();
1016 case PREFS_SET_OBSOLETE:
1017 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
1022 g_assert_not_reached();
1026 /* Path settings were already processed just ignore them this time*/
1031 case 'R': /* Read file filter */
1032 read_filter = QString(optarg);
1034 case 't': /* Time stamp type */
1035 if (strcmp(optarg, "r") == 0)
1036 timestamp_set_type(TS_RELATIVE);
1037 else if (strcmp(optarg, "a") == 0)
1038 timestamp_set_type(TS_ABSOLUTE);
1039 else if (strcmp(optarg, "ad") == 0)
1040 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
1041 else if (strcmp(optarg, "adoy") == 0)
1042 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
1043 else if (strcmp(optarg, "d") == 0)
1044 timestamp_set_type(TS_DELTA);
1045 else if (strcmp(optarg, "dd") == 0)
1046 timestamp_set_type(TS_DELTA_DIS);
1047 else if (strcmp(optarg, "e") == 0)
1048 timestamp_set_type(TS_EPOCH);
1049 else if (strcmp(optarg, "u") == 0)
1050 timestamp_set_type(TS_UTC);
1051 else if (strcmp(optarg, "ud") == 0)
1052 timestamp_set_type(TS_UTC_WITH_YMD);
1053 else if (strcmp(optarg, "udoy") == 0)
1054 timestamp_set_type(TS_UTC_WITH_YDOY);
1056 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
1058 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
1060 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
1062 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
1064 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
1066 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
1070 case 'u': /* Seconds type */
1071 if (strcmp(optarg, "s") == 0)
1072 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1073 else if (strcmp(optarg, "hms") == 0)
1074 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
1076 cmdarg_err("Invalid seconds type \"%s\"", optarg);
1078 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
1083 /* ext ops were already processed just ignore them this time*/
1086 dfilter = QString(optarg);
1089 /* We won't call the init function for the stat this soon
1090 as it would disallow MATE's fields (which are registered
1091 by the preferences set callback) from being used as
1092 part of a tap filter. Instead, we just add the argument
1093 to a list of stat arguments. */
1094 if (strcmp("help", optarg) == 0) {
1095 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
1096 list_stat_cmd_args();
1099 if (!process_stat_cmd_arg(optarg)) {
1100 cmdarg_err("Invalid -z argument.");
1101 cmdarg_err_cont(" -z argument must be one of :");
1102 list_stat_cmd_args();
1106 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1107 disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
1109 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1110 enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
1112 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1113 disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
1117 case '?': /* Bad flag - print usage message */
1128 if (!cf_name.isEmpty()) {
1130 * Input file name specified with "-r" *and* specified as a regular
1131 * command-line argument.
1133 cmdarg_err("File name specified both with -r and regular argument");
1137 * Input file name not specified with "-r", and a command-line argument
1138 * was specified; treat it as the input file name.
1140 * Yes, this is different from tshark, where non-flag command-line
1141 * arguments are a filter, but this works better on GUI desktops
1142 * where a command can be specified to be run to open a particular
1143 * file - yes, you could have "-r" as the last part of the command,
1144 * but that's a bit ugly.
1146 cf_name = ws_argv[0];
1155 * Extra command line arguments were specified; complain.
1157 cmdarg_err("Invalid argument: %s", ws_argv[0]);
1162 #ifndef HAVE_LIBPCAP
1163 if (capture_option_specified) {
1164 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
1171 /* Removed thread code:
1172 * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
1175 // XXX Is there a better place to set the timestamp format & precision?
1176 timestamp_set_type(recent.gui_time_format);
1177 timestamp_set_precision(recent.gui_time_precision);
1178 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1181 fill_in_local_interfaces(main_window_update);
1183 if (start_capture && list_link_layer_types) {
1184 /* Specifying *both* is bogus. */
1185 cmdarg_err("You can't specify both -L and a live capture.");
1189 if (list_link_layer_types) {
1190 /* We're supposed to list the link-layer types for an interface;
1191 did the user also specify a capture file to be read? */
1192 if (!cf_name.isEmpty()) {
1193 /* Yes - that's bogus. */
1194 cmdarg_err("You can't specify -L and a capture file to be read.");
1197 /* No - did they specify a ring buffer option? */
1198 if (global_capture_opts.multi_files_on) {
1199 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
1203 /* We're supposed to do a live capture; did the user also specify
1204 a capture file to be read? */
1205 if (start_capture && !cf_name.isEmpty()) {
1206 /* Yes - that's bogus. */
1207 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
1211 /* No - was the ring buffer option specified and, if so, does it make
1213 if (global_capture_opts.multi_files_on) {
1214 /* Ring buffer works only under certain conditions:
1215 a) ring buffer does not work with temporary files;
1216 b) real_time_mode and multi_files_on are mutually exclusive -
1217 real_time_mode takes precedence;
1218 c) it makes no sense to enable the ring buffer if the maximum
1219 file size is set to "infinite". */
1220 if (global_capture_opts.save_file == NULL) {
1221 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
1222 global_capture_opts.multi_files_on = FALSE;
1224 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
1225 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
1226 /* XXX - this must be redesigned as the conditions changed */
1231 if (start_capture || list_link_layer_types) {
1232 /* We're supposed to do a live capture or get a list of link-layer
1233 types for a live capture device; if the user didn't specify an
1234 interface to use, pick a default. */
1235 status = capture_opts_default_iface_if_necessary(&global_capture_opts,
1236 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
1242 if (list_link_layer_types) {
1243 /* Get the list of link-layer types for the capture devices. */
1244 if_capabilities_t *caps;
1247 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1249 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1250 if (device.selected) {
1251 #if defined(HAVE_PCAP_CREATE)
1252 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
1254 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
1257 cmdarg_err("%s", err_str);
1261 if (caps->data_link_types == NULL) {
1262 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
1268 #if defined(HAVE_PCAP_CREATE)
1269 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
1271 capture_opts_print_if_capabilities(caps, device.name, FALSE);
1276 free_if_capabilities(caps);
1282 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
1283 capture_opts_trim_ring_num_files(&global_capture_opts);
1284 #endif /* HAVE_LIBPCAP */
1286 /* Notify all registered modules that have had any of their preferences
1287 changed either from one of the preferences file or from the command
1288 line that their preferences have changed. */
1290 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
1293 if ((global_capture_opts.num_selected == 0) &&
1294 (prefs.capture_device != NULL)) {
1297 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1298 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1299 if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
1300 device.selected = TRUE;
1301 global_capture_opts.num_selected++;
1302 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
1303 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
1310 /* disabled protocols as per configuration file */
1311 if (gdp_path == NULL && dp_path == NULL) {
1312 set_disabled_protos_list();
1313 set_disabled_heur_dissector_list();
1316 if(disable_protocol_slist) {
1317 GSList *proto_disable;
1318 for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
1320 proto_disable_proto_by_name((char*)proto_disable->data);
1324 if(enable_heur_slist) {
1325 GSList *heur_enable;
1326 for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
1328 proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
1332 if(disable_heur_slist) {
1333 GSList *heur_disable;
1334 for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
1336 proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
1340 build_column_format_array(&CaptureFile::globalCapFile()->cinfo, prefs_p->num_cols, TRUE);
1341 wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
1342 wsApp->emitAppSignal(WiresharkApplication::RecentFilesRead); // Must be emitted after PreferencesChanged.
1344 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
1348 /* Read the dynamic part of the recent file, as we have the gui now ready for
1350 if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
1351 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1352 "Could not open recent file\n\"%s\": %s.",
1353 rf_path, g_strerror(rf_open_errno));
1357 color_filters_enable(recent.packet_list_colorize);
1359 g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
1360 color_filters_enable(TRUE);
1366 color_filters_init();
1371 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1372 if (!start_capture && !global_capture_opts.default_options.cfilter) {
1373 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1375 #else /* HAVE_LIBPCAP */
1377 #endif /* HAVE_LIBPCAP */
1379 wsApp->allSystemsGo();
1380 g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
1381 SimpleDialog::displayQueuedMessages(main_w);
1383 /* User could specify filename, or display filter, or both */
1384 if (!cf_name.isEmpty()) {
1385 if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
1386 if (!dfilter.isEmpty())
1387 main_w->filterPackets(dfilter, false);
1389 /* Open stat windows; we do so after creating the main window,
1390 to avoid Qt warnings, and after successfully opening the
1391 capture file, so we know we have something to compute stats
1392 on, and after registering all dissectors, so that MATE will
1393 have registered its field array and we can have a tap filter
1394 with one of MATE's late-registered fields as part of the
1396 start_requested_stats();
1398 if(go_to_packet != 0) {
1399 /* Jump to the specified frame number, kept for backward
1401 cf_goto_frame(CaptureFile::globalCapFile(), go_to_packet);
1407 if (start_capture) {
1408 if (global_capture_opts.save_file != NULL) {
1409 /* Save the directory name for future file dialogs. */
1410 /* (get_dirname overwrites filename) */
1411 gchar *s = get_dirname(g_strdup(global_capture_opts.save_file));
1412 set_last_open_dir(s);
1415 /* "-k" was specified; start a capture. */
1416 // show_main_window(FALSE);
1417 check_and_warn_user_startup(cf_name);
1419 /* If no user interfaces were specified on the command line,
1420 copy the list of selected interfaces to the set of interfaces
1421 to use for this capture. */
1422 if (global_capture_opts.ifaces->len == 0)
1423 collect_ifaces(&global_capture_opts);
1424 CaptureFile::globalCapFile()->window = main_w;
1425 if (capture_start(&global_capture_opts, main_w->captureSession(), main_window_update)) {
1426 /* The capture started. Open stat windows; we do so after creating
1427 the main window, to avoid GTK warnings, and after successfully
1428 opening the capture file, so we know we have something to compute
1429 stats on, and after registering all dissectors, so that MATE will
1430 have registered its field array and we can have a tap filter with
1431 one of MATE's late-registered fields as part of the filter. */
1432 start_requested_stats();
1435 /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1436 if (!start_capture && !global_capture_opts.default_options.cfilter) {
1437 global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1440 #endif /* HAVE_LIBPCAP */
1442 return wsApp->exec();
1451 * indent-tabs-mode: nil
1454 * ex: set shiftwidth=4 tabstop=8 expandtab:
1455 * :indentSize=4:tabSize=8:noTabs=true: