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/addr_resolv.h>
47 #include <epan/packet.h>
48 #include <epan/proto.h>
49 #include <epan/prefs.h>
50 #include <epan/prefs-int.h>
51 #include <epan/timestamp.h>
52 #include <epan/stat_tap_ui.h>
54 #include "capture_opts.h"
55 #include "persfilepath_opt.h"
56 #include "preference_utils.h"
59 #include "decode_as_utils.h"
61 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
62 #include <epan/asn1.h>
63 #include <epan/dissectors/packet-kerberos.h>
68 #include "ui/commandline.h"
71 capture_options global_capture_opts;
75 commandline_print_usage(gboolean for_help_option) {
82 if (for_help_option) {
84 fprintf(output, "Wireshark %s\n"
85 "Interactively dump and analyze network traffic.\n"
86 "See https://www.wireshark.org for more information.\n",
87 get_ws_vcs_version_info());
91 fprintf(output, "\n");
92 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
93 fprintf(output, "\n");
96 fprintf(output, "Capture interface:\n");
97 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
98 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
99 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
100 fprintf(output, " -p don't capture in promiscuous mode\n");
101 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
102 fprintf(output, " -S update packet display when new packets are captured\n");
103 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
104 #ifdef HAVE_PCAP_CREATE
105 fprintf(output, " -I capture in monitor mode, if available\n");
107 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
108 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
110 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
111 fprintf(output, " -D print list of interfaces and exit\n");
112 fprintf(output, " -L print list of link-layer types of iface and exit\n");
113 fprintf(output, "\n");
114 fprintf(output, "Capture stop conditions:\n");
115 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
116 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
117 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
118 fprintf(output, " files:NUM - stop after NUM files\n");
119 /*fprintf(output, "\n");*/
120 fprintf(output, "Capture output:\n");
121 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
122 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
123 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
124 #endif /* HAVE_LIBPCAP */
125 #ifdef HAVE_PCAP_REMOTE
126 fprintf(output, "RPCAP options:\n");
127 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
129 /*fprintf(output, "\n");*/
130 fprintf(output, "Input file:\n");
131 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
133 fprintf(output, "\n");
134 fprintf(output, "Processing:\n");
135 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
136 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
137 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtd\"\n");
138 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
139 fprintf(output, " \"Decode As\", see the man page for details\n");
140 fprintf(output, " Example: tcp.port==8888,http\n");
141 fprintf(output, " --disable-protocol <proto_name>\n");
142 fprintf(output, " disable dissection of proto_name\n");
143 fprintf(output, " --enable-heuristic <short_name>\n");
144 fprintf(output, " enable dissection of heuristic protocol\n");
145 fprintf(output, " --disable-heuristic <short_name>\n");
146 fprintf(output, " disable dissection of heuristic protocol\n");
148 fprintf(output, "\n");
149 fprintf(output, "User interface:\n");
150 fprintf(output, " -C <config profile> start with specified configuration profile\n");
151 fprintf(output, " -Y <display filter> start with the given display filter\n");
152 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
153 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
154 fprintf(output, " filter\n");
155 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
156 fprintf(output, " -m <font> set the font name used for most text\n");
157 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
158 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
159 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
160 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
162 fprintf(output, "\n");
163 fprintf(output, "Output:\n");
164 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
166 fprintf(output, "\n");
167 fprintf(output, "Miscellaneous:\n");
168 fprintf(output, " -h display this help and exit\n");
169 fprintf(output, " -v display version info and exit\n");
170 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
171 fprintf(output, " persdata:path - personal data files\n");
172 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
173 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
175 fprintf(output, " --display=DISPLAY X display to use\n");
183 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:d:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
184 static const struct option long_options[] = {
185 {"help", no_argument, NULL, 'h'},
186 {"read-file", required_argument, NULL, 'r' },
187 {"read-filter", required_argument, NULL, 'R' },
188 {"display-filter", required_argument, NULL, 'Y' },
189 {"version", no_argument, NULL, 'v'},
190 LONGOPT_CAPTURE_COMMON
193 static const char optstring[] = OPTSTRING;
196 static void print_no_capture_support_error(void)
198 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
202 void commandline_early_options(int argc, char *argv[],
203 GString *comp_info_str, GString *runtime_info_str)
211 gboolean capture_option_specified;
215 * In order to have the -X opts assigned before the wslua machine starts
216 * we need to call getopt_long before epan_init() gets called.
218 * In addition, we process "console only" parameters (ones where we
219 * send output to the console and exit) here, so we don't start GUI
220 * if we're only showing command-line help or version information.
222 * XXX - this pre-scan is done before we start GUI, so we haven't
223 * run "GUI init function" on the arguments. That means that GUI-specific
224 * arguments have not been removed from the argument list; those arguments
225 * begin with "--", and will be treated as an error by getopt_long().
227 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
230 * XXX - should we, instead, first call gtk_parse_args(), without
231 * calling gtk_init(), and then call this?
233 * In order to handle, for example, -o options, we also need to call it
234 * *after* epan_init() gets called, so that the dissectors have had a
235 * chance to register their preferences, so we have another getopt_long()
238 * XXX - can we do this all with one getopt_long() call, saving the
239 * arguments we can't handle until after initializing libwireshark,
240 * and then process them after initializing libwireshark?
242 * Note that we don't want to initialize libwireshark until after the
243 * GUI is up, as that can take a while, and we want a window of some
244 * sort up to show progress while that's happening.
249 capture_option_specified = FALSE;
251 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
253 case 'C': /* Configuration Profile */
254 if (profile_exists (optarg, FALSE)) {
255 set_profile_name (optarg);
257 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
261 case 'D': /* Print a list of capture devices and exit */
263 if_list = capture_interface_list(&err, &err_str, NULL);
264 if (if_list == NULL) {
266 cmdarg_err("There are no interfaces on which a capture can be done");
268 cmdarg_err("%s", err_str);
276 capture_opts_print_interfaces(if_list);
277 free_interface_list(if_list);
282 #else /* HAVE_LIBPCAP */
283 capture_option_specified = TRUE;
284 #endif /* HAVE_LIBPCAP */
286 case 'h': /* Print help and exit */
287 commandline_print_usage(TRUE);
292 if (strcmp(optarg, "-") == 0)
293 set_stdin_capture(TRUE);
296 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
297 if (!persfilepath_opt(opt, optarg)) {
298 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
302 case 'v': /* Show version and exit */
306 show_version("Wireshark", comp_info_str, runtime_info_str);
314 * Extension command line options have to be processed before
315 * we call epan_init() as they are supposed to be used by dissectors
316 * or taps very early in the registration process.
320 case '?': /* Ignore errors - the "real" scan will catch them. */
326 if (capture_option_specified) {
327 print_no_capture_support_error();
328 commandline_print_usage(FALSE);
334 void commandline_other_options(int argc, char *argv[], commandline_param_info_t* param_info, gboolean opt_reset)
337 gboolean arg_error = FALSE;
341 gboolean capture_option_specified;
346 * To reset the options parser, set optreset to 1 on platforms that
347 * have optreset (documented in *BSD and OS X, apparently present but
348 * not documented in Solaris - the Illumos repository seems to
349 * suggest that the first Solaris getopt_long(), at least as of 2004,
350 * was based on the NetBSD one, it had optreset) and set optind to 1,
351 * and set optind to 0 otherwise (documented as working in the GNU
352 * getopt_long(). Setting optind to 0 didn't originally work in the
353 * NetBSD one, but that was added later - we don't want to depend on
354 * it if we have optreset).
356 * Also reset opterr to 1, so that error messages are printed by
359 * XXX - if we want to control all the command-line option errors, so
360 * that we can display them where we choose (e.g., in a window), we'd
361 * want to leave opterr as 0, and produce our own messages using optopt.
362 * We'd have to check the value of optopt to see if it's a valid option
363 * letter, in which case *presumably* the error is "this option requires
364 * an argument but none was specified", or not a valid option letter,
365 * in which case *presumably* the error is "this option isn't valid".
366 * Some versions of getopt() let you supply a option string beginning
367 * with ':', which means that getopt() will return ':' rather than '?'
368 * for "this option requires an argument but none was specified", but
369 * not all do. But we're now using getopt_long() - what does it do?
381 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
383 /*** capture option specific ***/
384 case 'a': /* autostop criteria */
385 case 'b': /* Ringbuffer option */
386 case 'c': /* Capture xxx packets */
387 case 'f': /* capture filter */
388 case 'k': /* Start capture immediately */
389 case 'H': /* Hide capture info dialog box */
390 case 'p': /* Don't capture in promiscuous mode */
391 case 'i': /* Use interface x */
392 #ifdef HAVE_PCAP_CREATE
393 case 'I': /* Capture in monitor mode, if available */
395 #ifdef HAVE_PCAP_REMOTE
396 case 'A': /* Authentication */
398 case 's': /* Set the snapshot (capture) length */
399 case 'S': /* "Sync" mode: used for following file ala tail -f */
400 case 'w': /* Write to capture file xxx */
401 case 'y': /* Set the pcap data link type */
402 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
403 case 'B': /* Buffer size */
406 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
407 ¶m_info->start_capture);
412 capture_option_specified = TRUE;
417 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
418 case 'K': /* Kerberos keytab file */
419 read_keytab_file(optarg);
423 /*** all non capture option specific ***/
425 /* Configuration profile settings were already processed just ignore them this time*/
427 case 'd': /* Decode as rule */
428 if (!decode_as_command_option(optarg))
431 case 'j': /* Search backwards for a matching packet from filter in option J */
432 param_info->jump_backwards = SD_BACKWARD;
434 case 'g': /* Go to packet with the given packet number */
435 param_info->go_to_packet = get_positive_int(optarg, "go to packet");
437 case 'J': /* Jump to the first packet which matches the filter criteria */
438 param_info->jfilter = optarg;
440 case 'l': /* Automatic scrolling in live capture mode */
442 auto_scroll_live = TRUE;
444 capture_option_specified = TRUE;
448 case 'L': /* Print list of link-layer types and exit */
450 param_info->list_link_layer_types = TRUE;
452 capture_option_specified = TRUE;
456 case 'm': /* Fixed-width font for the display */
457 g_free(param_info->prefs_p->gui_gtk2_font_name);
458 param_info->prefs_p->gui_gtk2_font_name = g_strdup(optarg);
460 case 'n': /* No name resolution */
461 disable_name_resolution();
463 case 'N': /* Select what types of addresses/port #s to resolve */
464 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
465 if (badopt != '\0') {
466 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
471 case 'o': /* Override preference from command line */
472 switch (prefs_set_pref(optarg)) {
475 case PREFS_SET_SYNTAX_ERR:
476 cmdarg_err("Invalid -o flag \"%s\"", optarg);
479 case PREFS_SET_NO_SUCH_PREF:
480 /* not a preference, might be a recent setting */
481 switch (recent_set_arg(optarg)) {
484 case PREFS_SET_SYNTAX_ERR:
485 /* shouldn't happen, checked already above */
486 cmdarg_err("Invalid -o flag \"%s\"", optarg);
489 case PREFS_SET_NO_SUCH_PREF:
490 case PREFS_SET_OBSOLETE:
491 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
496 g_assert_not_reached();
499 case PREFS_SET_OBSOLETE:
500 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
505 g_assert_not_reached();
509 /* Path settings were already processed just ignore them this time*/
511 case 'r': /* Read capture file xxx */
512 /* We may set "last_open_dir" to "cf_name", and if we change
513 "last_open_dir" later, we free the old value, so we have to
514 set "cf_name" to something that's been allocated. */
515 param_info->cf_name = g_strdup(optarg);
517 case 'R': /* Read file filter */
518 param_info->rfilter = optarg;
520 case 't': /* Time stamp type */
521 if (strcmp(optarg, "r") == 0)
522 timestamp_set_type(TS_RELATIVE);
523 else if (strcmp(optarg, "a") == 0)
524 timestamp_set_type(TS_ABSOLUTE);
525 else if (strcmp(optarg, "ad") == 0)
526 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
527 else if (strcmp(optarg, "adoy") == 0)
528 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
529 else if (strcmp(optarg, "d") == 0)
530 timestamp_set_type(TS_DELTA);
531 else if (strcmp(optarg, "dd") == 0)
532 timestamp_set_type(TS_DELTA_DIS);
533 else if (strcmp(optarg, "e") == 0)
534 timestamp_set_type(TS_EPOCH);
535 else if (strcmp(optarg, "u") == 0)
536 timestamp_set_type(TS_UTC);
537 else if (strcmp(optarg, "ud") == 0)
538 timestamp_set_type(TS_UTC_WITH_YMD);
539 else if (strcmp(optarg, "udoy") == 0)
540 timestamp_set_type(TS_UTC_WITH_YDOY);
542 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
543 cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
544 cmdarg_err_cont("\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
545 cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
546 cmdarg_err_cont("\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
547 cmdarg_err_cont("or \"udoy\" for absolute UTC with YYYY/DOY date.");
551 case 'u': /* Seconds type */
552 if (strcmp(optarg, "s") == 0)
553 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
554 else if (strcmp(optarg, "hms") == 0)
555 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
557 cmdarg_err("Invalid seconds type \"%s\"", optarg);
558 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
563 /* ext ops were already processed just ignore them this time*/
566 param_info->dfilter = optarg;
569 /* We won't call the init function for the stat this soon
570 as it would disallow MATE's fields (which are registered
571 by the preferences set callback) from being used as
572 part of a tap filter. Instead, we just add the argument
573 to a list of stat arguments. */
574 if (strcmp("help", optarg) == 0) {
575 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
576 list_stat_cmd_args();
579 if (!process_stat_cmd_arg(optarg)) {
580 cmdarg_err("Invalid -z argument.");
581 cmdarg_err_cont(" -z argument must be one of :");
582 list_stat_cmd_args();
586 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
587 param_info->disable_protocol_slist = g_slist_append(param_info->disable_protocol_slist, optarg);
589 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
590 param_info->enable_heur_slist = g_slist_append(param_info->enable_heur_slist, optarg);
592 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
593 param_info->disable_heur_slist = g_slist_append(param_info->disable_heur_slist, optarg);
596 case '?': /* Bad flag - print usage message */
606 if (param_info->cf_name != NULL) {
608 * Input file name specified with "-r" *and* specified as a regular
609 * command-line argument.
611 cmdarg_err("File name specified both with -r and regular argument");
615 * Input file name not specified with "-r", and a command-line argument
616 * was specified; treat it as the input file name.
618 * Yes, this is different from tshark, where non-flag command-line
619 * arguments are a filter, but this works better on GUI desktops
620 * where a command can be specified to be run to open a particular
621 * file - yes, you could have "-r" as the last part of the command,
622 * but that's a bit ugly.
624 #ifndef HAVE_GTKOSXAPPLICATION
626 * For GTK+ Mac Integration, file name passed as free argument passed
627 * through grag-and-drop and opened twice sometimes causing crashes.
628 * Subject to report to GTK+ MAC.
630 param_info->cf_name = g_strdup(argv[0]);
639 * Extra command line arguments were specified; complain.
641 cmdarg_err("Invalid argument: %s", argv[0]);
648 if (capture_option_specified) {
649 print_no_capture_support_error();
652 commandline_print_usage(FALSE);
657 if (param_info->start_capture && param_info->list_link_layer_types) {
658 /* Specifying *both* is bogus. */
659 cmdarg_err("You can't specify both -L and a live capture.");
663 if (param_info->list_link_layer_types) {
664 /* We're supposed to list the link-layer types for an interface;
665 did the user also specify a capture file to be read? */
666 if (param_info->cf_name) {
667 /* Yes - that's bogus. */
668 cmdarg_err("You can't specify -L and a capture file to be read.");
671 /* No - did they specify a ring buffer option? */
672 if (global_capture_opts.multi_files_on) {
673 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
677 /* We're supposed to do a live capture; did the user also specify
678 a capture file to be read? */
679 if (param_info->start_capture && param_info->cf_name) {
680 /* Yes - that's bogus. */
681 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
685 /* No - was the ring buffer option specified and, if so, does it make
687 if (global_capture_opts.multi_files_on) {
688 /* Ring buffer works only under certain conditions:
689 a) ring buffer does not work with temporary files;
690 b) real_time_mode and multi_files_on are mutually exclusive -
691 real_time_mode takes precedence;
692 c) it makes no sense to enable the ring buffer if the maximum
693 file size is set to "infinite". */
694 if (global_capture_opts.save_file == NULL) {
695 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
696 global_capture_opts.multi_files_on = FALSE;
698 if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
699 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
700 /* XXX - this must be redesigned as the conditions changed */
713 * indent-tabs-mode: nil
716 * ex: set shiftwidth=4 tabstop=8 expandtab:
717 * :indentSize=4:tabSize=8:noTabs=true: