2 * Common command line handling between GUIs
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #ifndef HAVE_GETOPT_LONG
36 #include "wsutil/wsgetopt.h"
39 #include <ws_version_info.h>
41 #include <wsutil/clopts_common.h>
42 #include <wsutil/cmdarg_err.h>
43 #include <wsutil/filesystem.h>
45 #include <epan/ex-opt.h>
46 #include <epan/packet.h>
47 #include <epan/proto.h>
48 #include <epan/prefs.h>
49 #include <epan/prefs-int.h>
50 #include <epan/stat_tap_ui.h>
52 #include "capture_opts.h"
53 #include "persfilepath_opt.h"
54 #include "preference_utils.h"
57 #include "decode_as_utils.h"
61 #include "ui/dissect_opts.h"
63 #include "ui/commandline.h"
65 commandline_param_info_t global_commandline_info;
67 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
68 capture_options global_capture_opts;
72 commandline_print_usage(gboolean for_help_option) {
79 if (for_help_option) {
81 fprintf(output, "Wireshark %s\n"
82 "Interactively dump and analyze network traffic.\n"
83 "See https://www.wireshark.org for more information.\n",
84 get_ws_vcs_version_info());
88 fprintf(output, "\n");
89 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
90 fprintf(output, "\n");
93 fprintf(output, "Capture interface:\n");
94 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
95 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
96 #ifdef HAVE_PCAP_CREATE
97 fprintf(output, " -s <snaplen> packet snapshot length (def: appropriate maximum)\n");
99 fprintf(output, " -s <snaplen> packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
101 fprintf(output, " -p don't capture in promiscuous mode\n");
102 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
103 fprintf(output, " -S update packet display when new packets are captured\n");
104 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
105 #ifdef HAVE_PCAP_CREATE
106 fprintf(output, " -I capture in monitor mode, if available\n");
108 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
109 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
111 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
112 fprintf(output, " -D print list of interfaces and exit\n");
113 fprintf(output, " -L print list of link-layer types of iface and exit\n");
114 fprintf(output, "\n");
115 fprintf(output, "Capture stop conditions:\n");
116 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
117 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
118 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
119 fprintf(output, " files:NUM - stop after NUM files\n");
120 /*fprintf(output, "\n");*/
121 fprintf(output, "Capture output:\n");
122 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
123 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
124 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
125 #endif /* HAVE_LIBPCAP */
126 #ifdef HAVE_PCAP_REMOTE
127 fprintf(output, "RPCAP options:\n");
128 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
130 /*fprintf(output, "\n");*/
131 fprintf(output, "Input file:\n");
132 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
134 fprintf(output, "\n");
135 fprintf(output, "Processing:\n");
136 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
137 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
138 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtd\"\n");
139 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
140 fprintf(output, " \"Decode As\", see the man page for details\n");
141 fprintf(output, " Example: tcp.port==8888,http\n");
142 fprintf(output, " --enable-protocol <proto_name>\n");
143 fprintf(output, " enable dissection of proto_name\n");
144 fprintf(output, " --disable-protocol <proto_name>\n");
145 fprintf(output, " disable dissection of proto_name\n");
146 fprintf(output, " --enable-heuristic <short_name>\n");
147 fprintf(output, " enable dissection of heuristic protocol\n");
148 fprintf(output, " --disable-heuristic <short_name>\n");
149 fprintf(output, " disable dissection of heuristic protocol\n");
151 fprintf(output, "\n");
152 fprintf(output, "User interface:\n");
153 fprintf(output, " -C <config profile> start with specified configuration profile\n");
154 fprintf(output, " -Y <display filter> start with the given display filter\n");
155 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
156 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
157 fprintf(output, " filter\n");
158 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
159 fprintf(output, " -m <font> set the font name used for most text\n");
160 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
161 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
162 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
163 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
165 fprintf(output, "\n");
166 fprintf(output, "Output:\n");
167 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
169 fprintf(output, "\n");
170 fprintf(output, "Miscellaneous:\n");
171 fprintf(output, " -h display this help and exit\n");
172 fprintf(output, " -v display version info and exit\n");
173 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
174 fprintf(output, " persdata:path - personal data files\n");
175 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
176 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
178 fprintf(output, " --display=DISPLAY X display to use\n");
180 fprintf(output, " --fullscreen start Wireshark in full screen\n");
188 * For long options with no corresponding short options, we define values
189 * outside the range of ASCII graphic characters, make that the last
190 * component of the entry for the long option, and have a case for that
191 * option in the switch statement.
193 * We also pick values >= 65536, so as to leave values from 128 to 65535
194 * for capture and dissection options.
196 #define LONGOPT_FULL_SCREEN 65536
198 #define OPTSTRING OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "C:g:Hh" "jJ:klm:o:P:r:R:Svw:X:Y:z:"
199 static const struct option long_options[] = {
200 {"help", no_argument, NULL, 'h'},
201 {"read-file", required_argument, NULL, 'r' },
202 {"read-filter", required_argument, NULL, 'R' },
203 {"display-filter", required_argument, NULL, 'Y' },
204 {"version", no_argument, NULL, 'v'},
205 {"fullscreen", no_argument, NULL, LONGOPT_FULL_SCREEN },
206 LONGOPT_CAPTURE_COMMON
207 LONGOPT_DISSECT_COMMON
210 static const char optstring[] = OPTSTRING;
213 static void print_no_capture_support_error(void)
215 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
219 void commandline_early_options(int argc, char *argv[],
220 GString *comp_info_str, GString *runtime_info_str)
228 gboolean capture_option_specified;
232 * In order to have the -X opts assigned before the wslua machine starts
233 * we need to call getopt_long before epan_init() gets called.
235 * In addition, we process "console only" parameters (ones where we
236 * send output to the console and exit) here, so we don't start GUI
237 * if we're only showing command-line help or version information.
239 * XXX - this pre-scan is done before we start GUI, so we haven't
240 * run "GUI init function" on the arguments. That means that GUI-specific
241 * arguments have not been removed from the argument list; those arguments
242 * begin with "--", and will be treated as an error by getopt_long().
244 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
247 * XXX - should we, instead, first call gtk_parse_args(), without
248 * calling gtk_init(), and then call this?
250 * In order to handle, for example, -o options, we also need to call it
251 * *after* epan_init() gets called, so that the dissectors have had a
252 * chance to register their preferences, so we have another getopt_long()
255 * XXX - can we do this all with one getopt_long() call, saving the
256 * arguments we can't handle until after initializing libwireshark,
257 * and then process them after initializing libwireshark?
259 * Note that we don't want to initialize libwireshark until after the
260 * GUI is up, as that can take a while, and we want a window of some
261 * sort up to show progress while that's happening.
266 capture_option_specified = FALSE;
268 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
270 case 'C': /* Configuration Profile */
271 if (profile_exists (optarg, FALSE)) {
272 set_profile_name (optarg);
274 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
278 case 'D': /* Print a list of capture devices and exit */
280 if_list = capture_interface_list(&err, &err_str, NULL);
281 if (if_list == NULL) {
283 cmdarg_err("There are no interfaces on which a capture can be done");
285 cmdarg_err("%s", err_str);
293 capture_opts_print_interfaces(if_list);
294 free_interface_list(if_list);
299 #else /* HAVE_LIBPCAP */
300 capture_option_specified = TRUE;
301 #endif /* HAVE_LIBPCAP */
303 case 'h': /* Print help and exit */
304 commandline_print_usage(TRUE);
309 if (strcmp(optarg, "-") == 0)
310 set_stdin_capture(TRUE);
313 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
314 if (!persfilepath_opt(opt, optarg)) {
315 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
319 case 'v': /* Show version and exit */
323 show_version("Wireshark", comp_info_str, runtime_info_str);
331 * Extension command line options have to be processed before
332 * we call epan_init() as they are supposed to be used by dissectors
333 * or taps very early in the registration process.
337 case '?': /* Ignore errors - the "real" scan will catch them. */
343 if (capture_option_specified) {
344 print_no_capture_support_error();
345 commandline_print_usage(FALSE);
351 void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
354 gboolean arg_error = FALSE;
358 gboolean capture_option_specified;
362 * To reset the options parser, set optreset to 1 on platforms that
363 * have optreset (documented in *BSD and macOS, apparently present but
364 * not documented in Solaris - the Illumos repository seems to
365 * suggest that the first Solaris getopt_long(), at least as of 2004,
366 * was based on the NetBSD one, it had optreset) and set optind to 1,
367 * and set optind to 0 otherwise (documented as working in the GNU
368 * getopt_long(). Setting optind to 0 didn't originally work in the
369 * NetBSD one, but that was added later - we don't want to depend on
370 * it if we have optreset).
372 * Also reset opterr to 1, so that error messages are printed by
375 * XXX - if we want to control all the command-line option errors, so
376 * that we can display them where we choose (e.g., in a window), we'd
377 * want to leave opterr as 0, and produce our own messages using optopt.
378 * We'd have to check the value of optopt to see if it's a valid option
379 * letter, in which case *presumably* the error is "this option requires
380 * an argument but none was specified", or not a valid option letter,
381 * in which case *presumably* the error is "this option isn't valid".
382 * Some versions of getopt() let you supply a option string beginning
383 * with ':', which means that getopt() will return ':' rather than '?'
384 * for "this option requires an argument but none was specified", but
385 * not all do. But we're now using getopt_long() - what does it do?
397 /* Initialize with default values */
399 global_commandline_info.jump_backwards = SD_FORWARD;
400 global_commandline_info.go_to_packet = 0;
401 global_commandline_info.jfilter = NULL;
402 global_commandline_info.cf_name = NULL;
403 global_commandline_info.rfilter = NULL;
404 global_commandline_info.dfilter = NULL;
406 global_commandline_info.start_capture = FALSE;
407 global_commandline_info.list_link_layer_types = FALSE;
408 global_commandline_info.quit_after_cap = getenv("WIRESHARK_QUIT_AFTER_CAPTURE") ? TRUE : FALSE;
410 global_commandline_info.full_screen = FALSE;
412 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
414 /*** capture option specific ***/
415 case 'a': /* autostop criteria */
416 case 'b': /* Ringbuffer option */
417 case 'c': /* Capture xxx packets */
418 case 'f': /* capture filter */
419 case 'k': /* Start capture immediately */
420 case 'H': /* Hide capture info dialog box */
421 case 'p': /* Don't capture in promiscuous mode */
422 case 'i': /* Use interface x */
423 #ifdef HAVE_PCAP_CREATE
424 case 'I': /* Capture in monitor mode, if available */
426 #ifdef HAVE_PCAP_REMOTE
427 case 'A': /* Authentication */
429 case 's': /* Set the snapshot (capture) length */
430 case 'S': /* "Sync" mode: used for following file ala tail -f */
431 case 'w': /* Write to capture file xxx */
432 case 'y': /* Set the pcap data link type */
433 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
434 case 'B': /* Buffer size */
437 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
438 &global_commandline_info.start_capture);
443 capture_option_specified = TRUE;
448 /*** all non capture option specific ***/
450 /* Configuration profile settings were already processed just ignore them this time*/
452 case 'j': /* Search backwards for a matching packet from filter in option J */
453 global_commandline_info.jump_backwards = SD_BACKWARD;
455 case 'g': /* Go to packet with the given packet number */
456 global_commandline_info.go_to_packet = get_nonzero_guint32(optarg, "go to packet");
458 case 'J': /* Jump to the first packet which matches the filter criteria */
459 global_commandline_info.jfilter = optarg;
461 case 'l': /* Automatic scrolling in live capture mode */
463 auto_scroll_live = TRUE;
465 capture_option_specified = TRUE;
469 case 'L': /* Print list of link-layer types and exit */
471 global_commandline_info.list_link_layer_types = TRUE;
473 capture_option_specified = TRUE;
477 case 'o': /* Override preference from command line */
481 switch (prefs_set_pref(optarg, &errmsg)) {
484 case PREFS_SET_SYNTAX_ERR:
485 cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
486 errmsg ? ": " : "", errmsg ? errmsg : "");
490 case PREFS_SET_NO_SUCH_PREF:
491 /* not a preference, might be a recent setting */
492 switch (recent_set_arg(optarg)) {
495 case PREFS_SET_SYNTAX_ERR:
496 /* shouldn't happen, checked already above */
497 cmdarg_err("Invalid -o flag \"%s\"", optarg);
500 case PREFS_SET_NO_SUCH_PREF:
501 case PREFS_SET_OBSOLETE:
502 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
507 g_assert_not_reached();
510 case PREFS_SET_OBSOLETE:
511 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
516 g_assert_not_reached();
521 /* Path settings were already processed just ignore them this time*/
523 case 'r': /* Read capture file xxx */
524 /* We may set "last_open_dir" to "cf_name", and if we change
525 "last_open_dir" later, we free the old value, so we have to
526 set "cf_name" to something that's been allocated. */
527 global_commandline_info.cf_name = g_strdup(optarg);
529 case 'R': /* Read file filter */
530 global_commandline_info.rfilter = optarg;
533 /* ext ops were already processed just ignore them this time*/
536 global_commandline_info.dfilter = optarg;
539 /* We won't call the init function for the stat this soon
540 as it would disallow MATE's fields (which are registered
541 by the preferences set callback) from being used as
542 part of a tap filter. Instead, we just add the argument
543 to a list of stat arguments. */
544 if (strcmp("help", optarg) == 0) {
545 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
546 list_stat_cmd_args();
549 if (!process_stat_cmd_arg(optarg)) {
550 cmdarg_err("Invalid -z argument.");
551 cmdarg_err_cont(" -z argument must be one of :");
552 list_stat_cmd_args();
556 case 'd': /* Decode as rule */
557 case 'K': /* Kerberos keytab file */
558 case 'n': /* No name resolution */
559 case 'N': /* Select what types of addresses/port #s to resolve */
560 case 't': /* time stamp type */
561 case 'u': /* Seconds type */
562 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
563 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
564 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
565 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
566 if (!dissect_opts_handle_opt(opt, optarg))
569 case LONGOPT_FULL_SCREEN:
570 global_commandline_info.full_screen = TRUE;
573 case '?': /* Bad flag - print usage message */
583 if (global_commandline_info.cf_name != NULL) {
585 * Input file name specified with "-r" *and* specified as a regular
586 * command-line argument.
588 cmdarg_err("File name specified both with -r and regular argument");
592 * Input file name not specified with "-r", and a command-line argument
593 * was specified; treat it as the input file name.
595 * Yes, this is different from tshark, where non-flag command-line
596 * arguments are a filter, but this works better on GUI desktops
597 * where a command can be specified to be run to open a particular
598 * file - yes, you could have "-r" as the last part of the command,
599 * but that's a bit ugly.
601 #ifndef HAVE_GTKOSXAPPLICATION
603 * For GTK+ Mac Integration, file name passed as free argument passed
604 * through grag-and-drop and opened twice sometimes causing crashes.
605 * Subject to report to GTK+ MAC.
607 global_commandline_info.cf_name = g_strdup(argv[0]);
616 * Extra command line arguments were specified; complain.
618 cmdarg_err("Invalid argument: %s", argv[0]);
625 if (capture_option_specified) {
626 print_no_capture_support_error();
629 commandline_print_usage(FALSE);
634 if (global_commandline_info.start_capture && global_commandline_info.list_link_layer_types) {
635 /* Specifying *both* is bogus. */
636 cmdarg_err("You can't specify both -L and a live capture.");
640 if (global_commandline_info.list_link_layer_types) {
641 /* We're supposed to list the link-layer types for an interface;
642 did the user also specify a capture file to be read? */
643 if (global_commandline_info.cf_name) {
644 /* Yes - that's bogus. */
645 cmdarg_err("You can't specify -L and a capture file to be read.");
648 /* No - did they specify a ring buffer option? */
649 if (global_capture_opts.multi_files_on) {
650 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
654 /* We're supposed to do a live capture; did the user also specify
655 a capture file to be read? */
656 if (global_commandline_info.start_capture && global_commandline_info.cf_name) {
657 /* Yes - that's bogus. */
658 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
662 /* No - was the ring buffer option specified and, if so, does it make
664 if (global_capture_opts.multi_files_on) {
665 /* Ring buffer works only under certain conditions:
666 a) ring buffer does not work with temporary files;
667 b) real_time_mode and multi_files_on are mutually exclusive -
668 real_time_mode takes precedence;
669 c) it makes no sense to enable the ring buffer if the maximum
670 file size is set to "infinite". */
671 if (global_capture_opts.save_file == NULL) {
672 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
673 global_capture_opts.multi_files_on = FALSE;
675 if (!global_capture_opts.has_autostop_filesize &&
676 !global_capture_opts.has_file_duration &&
677 !global_capture_opts.has_file_interval) {
678 cmdarg_err("Ring buffer requested, but no maximum capture file size, duration or interval were specified.");
679 /* XXX - this must be redesigned as the conditions changed */
692 * indent-tabs-mode: nil
695 * ex: set shiftwidth=4 tabstop=8 expandtab:
696 * :indentSize=4:tabSize=8:noTabs=true: