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"
60 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
61 #include <epan/asn1.h>
62 #include <epan/dissectors/packet-kerberos.h>
67 #include "ui/commandline.h"
70 capture_options global_capture_opts;
74 commandline_print_usage(gboolean for_help_option) {
81 if (for_help_option) {
83 fprintf(output, "Wireshark %s\n"
84 "Interactively dump and analyze network traffic.\n"
85 "See https://www.wireshark.org for more information.\n",
86 get_ws_vcs_version_info());
90 fprintf(output, "\n");
91 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
92 fprintf(output, "\n");
95 fprintf(output, "Capture interface:\n");
96 fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
97 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
98 fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
99 fprintf(output, " -p don't capture in promiscuous mode\n");
100 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
101 fprintf(output, " -S update packet display when new packets are captured\n");
102 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
103 #ifdef HAVE_PCAP_CREATE
104 fprintf(output, " -I capture in monitor mode, if available\n");
106 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
107 fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
109 fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
110 fprintf(output, " -D print list of interfaces and exit\n");
111 fprintf(output, " -L print list of link-layer types of iface and exit\n");
112 fprintf(output, "\n");
113 fprintf(output, "Capture stop conditions:\n");
114 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
115 fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
116 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
117 fprintf(output, " files:NUM - stop after NUM files\n");
118 /*fprintf(output, "\n");*/
119 fprintf(output, "Capture output:\n");
120 fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
121 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
122 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
123 #endif /* HAVE_LIBPCAP */
124 #ifdef HAVE_PCAP_REMOTE
125 fprintf(output, "RPCAP options:\n");
126 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
128 /*fprintf(output, "\n");*/
129 fprintf(output, "Input file:\n");
130 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
132 fprintf(output, "\n");
133 fprintf(output, "Processing:\n");
134 fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
135 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
136 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtd\"\n");
137 fprintf(output, " --disable-protocol <proto_name>\n");
138 fprintf(output, " disable dissection of proto_name\n");
139 fprintf(output, " --enable-heuristic <short_name>\n");
140 fprintf(output, " enable dissection of heuristic protocol\n");
141 fprintf(output, " --disable-heuristic <short_name>\n");
142 fprintf(output, " disable dissection of heuristic protocol\n");
144 fprintf(output, "\n");
145 fprintf(output, "User interface:\n");
146 fprintf(output, " -C <config profile> start with specified configuration profile\n");
147 fprintf(output, " -Y <display filter> start with the given display filter\n");
148 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
149 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
150 fprintf(output, " filter\n");
151 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
152 fprintf(output, " -m <font> set the font name used for most text\n");
153 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
154 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
155 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
156 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
158 fprintf(output, "\n");
159 fprintf(output, "Output:\n");
160 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
162 fprintf(output, "\n");
163 fprintf(output, "Miscellaneous:\n");
164 fprintf(output, " -h display this help and exit\n");
165 fprintf(output, " -v display version info and exit\n");
166 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
167 fprintf(output, " persdata:path - personal data files\n");
168 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
169 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
171 fprintf(output, " --display=DISPLAY X display to use\n");
179 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
180 static const struct option long_options[] = {
181 {"help", no_argument, NULL, 'h'},
182 {"read-file", required_argument, NULL, 'r' },
183 {"read-filter", required_argument, NULL, 'R' },
184 {"display-filter", required_argument, NULL, 'Y' },
185 {"version", no_argument, NULL, 'v'},
186 LONGOPT_CAPTURE_COMMON
189 static const char optstring[] = OPTSTRING;
191 void commandline_capture_options(int argc, char *argv[], commandline_capture_param_info_t* param_info)
201 * In order to have the -X opts assigned before the wslua machine starts
202 * we need to call getopt_long before epan_init() gets called.
204 * In addition, we process "console only" parameters (ones where we
205 * send output to the console and exit) here, so we don't start GUI
206 * if we're only showing command-line help or version information.
208 * XXX - this pre-scan is done before we start GUI, so we haven't
209 * run "GUI init function" on the arguments. That means that GUI-specific
210 * arguments have not been removed from the argument list; those arguments
211 * begin with "--", and will be treated as an error by getopt_long().
213 * We thus ignore errors - *and* set "opterr" to 0 to suppress the
216 * XXX - should we, instead, first call gtk_parse_args(), without
217 * calling gtk_init(), and then call this?
219 * In order to handle, for example, -o options, we also need to call it
220 * *after* epan_init() gets called, so that the dissectors have had a
221 * chance to register their preferences, so we have another getopt_long()
224 * XXX - can we do this all with one getopt_long() call, saving the
225 * arguments we can't handle until after initializing libwireshark,
226 * and then process them after initializing libwireshark?
228 * Note that we don't want to initialize libwireshark until after the
229 * GUI is up, as that can take a while, and we want a window of some
230 * sort up to show progress while that's happening.
234 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
236 case 'C': /* Configuration Profile */
237 if (profile_exists (optarg, FALSE)) {
238 set_profile_name (optarg);
240 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
244 case 'D': /* Print a list of capture devices and exit */
246 if_list = capture_interface_list(&err, &err_str, NULL);
247 if (if_list == NULL) {
249 cmdarg_err("There are no interfaces on which a capture can be done");
251 cmdarg_err("%s", err_str);
259 capture_opts_print_interfaces(if_list);
260 free_interface_list(if_list);
265 #else /* HAVE_LIBPCAP */
266 param_info->capture_option_specified = TRUE;
267 param_info->arg_error = TRUE;
268 #endif /* HAVE_LIBPCAP */
270 case 'h': /* Print help and exit */
271 commandline_print_usage(TRUE);
276 if (strcmp(optarg, "-") == 0)
277 set_stdin_capture(TRUE);
280 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
281 if (!persfilepath_opt(opt, optarg)) {
282 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
286 case 'v': /* Show version and exit */
290 show_version("Wireshark", param_info->comp_info_str, param_info->runtime_info_str);
298 * Extension command line options have to be processed before
299 * we call epan_init() as they are supposed to be used by dissectors
300 * or taps very early in the registration process.
304 case '?': /* Ignore errors - the "real" scan will catch them. */
310 void commandline_other_options(int argc, char *argv[], commandline_param_info_t* param_info, gboolean opt_reset)
319 * To reset the options parser, set optreset to 1 on platforms that
320 * have optreset (documented in *BSD and OS X, apparently present but
321 * not documented in Solaris - the Illumos repository seems to
322 * suggest that the first Solaris getopt_long(), at least as of 2004,
323 * was based on the NetBSD one, it had optreset) and set optind to 1,
324 * and set optind to 0 otherwise (documented as working in the GNU
325 * getopt_long(). Setting optind to 0 didn't originally work in the
326 * NetBSD one, but that was added later - we don't want to depend on
327 * it if we have optreset).
329 * Also reset opterr to 1, so that error messages are printed by
332 * XXX - if we want to control all the command-line option errors, so
333 * that we can display them where we choose (e.g., in a window), we'd
334 * want to leave opterr as 0, and produce our own messages using optopt.
335 * We'd have to check the value of optopt to see if it's a valid option
336 * letter, in which case *presumably* the error is "this option requires
337 * an argument but none was specified", or not a valid option letter,
338 * in which case *presumably* the error is "this option isn't valid".
339 * Some versions of getopt() let you supply a option string beginning
340 * with ':', which means that getopt() will return ':' rather than '?'
341 * for "this option requires an argument but none was specified", but
342 * not all do. But we're now using getopt_long() - what does it do?
354 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
356 /*** capture option specific ***/
357 case 'a': /* autostop criteria */
358 case 'b': /* Ringbuffer option */
359 case 'c': /* Capture xxx packets */
360 case 'f': /* capture filter */
361 case 'k': /* Start capture immediately */
362 case 'H': /* Hide capture info dialog box */
363 case 'p': /* Don't capture in promiscuous mode */
364 case 'i': /* Use interface x */
365 #ifdef HAVE_PCAP_CREATE
366 case 'I': /* Capture in monitor mode, if available */
368 #ifdef HAVE_PCAP_REMOTE
369 case 'A': /* Authentication */
371 case 's': /* Set the snapshot (capture) length */
372 case 'S': /* "Sync" mode: used for following file ala tail -f */
373 case 'w': /* Write to capture file xxx */
374 case 'y': /* Set the pcap data link type */
375 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
376 case 'B': /* Buffer size */
379 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
380 ¶m_info->start_capture);
385 capture_option_specified = TRUE;
386 param_info->arg_error = TRUE;
390 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
391 case 'K': /* Kerberos keytab file */
392 read_keytab_file(optarg);
396 /*** all non capture option specific ***/
398 /* Configuration profile settings were already processed just ignore them this time*/
400 case 'j': /* Search backwards for a matching packet from filter in option J */
401 param_info->jump_backwards = SD_BACKWARD;
403 case 'g': /* Go to packet with the given packet number */
404 param_info->go_to_packet = get_positive_int(optarg, "go to packet");
406 case 'J': /* Jump to the first packet which matches the filter criteria */
407 param_info->jfilter = optarg;
409 case 'l': /* Automatic scrolling in live capture mode */
411 auto_scroll_live = TRUE;
413 param_info->capture_option_specified = TRUE;
414 param_info->arg_error = TRUE;
417 case 'L': /* Print list of link-layer types and exit */
419 param_info->list_link_layer_types = TRUE;
421 param_info->capture_option_specified = TRUE;
422 param_info->arg_error = TRUE;
425 case 'm': /* Fixed-width font for the display */
426 g_free(param_info->prefs_p->gui_gtk2_font_name);
427 param_info->prefs_p->gui_gtk2_font_name = g_strdup(optarg);
429 case 'n': /* No name resolution */
430 disable_name_resolution();
432 case 'N': /* Select what types of addresses/port #s to resolve */
433 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
434 if (badopt != '\0') {
435 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
440 case 'o': /* Override preference from command line */
441 switch (prefs_set_pref(optarg)) {
444 case PREFS_SET_SYNTAX_ERR:
445 cmdarg_err("Invalid -o flag \"%s\"", optarg);
448 case PREFS_SET_NO_SUCH_PREF:
449 /* not a preference, might be a recent setting */
450 switch (recent_set_arg(optarg)) {
453 case PREFS_SET_SYNTAX_ERR:
454 /* shouldn't happen, checked already above */
455 cmdarg_err("Invalid -o flag \"%s\"", optarg);
458 case PREFS_SET_NO_SUCH_PREF:
459 case PREFS_SET_OBSOLETE:
460 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
465 g_assert_not_reached();
468 case PREFS_SET_OBSOLETE:
469 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
474 g_assert_not_reached();
478 /* Path settings were already processed just ignore them this time*/
480 case 'r': /* Read capture file xxx */
481 /* We may set "last_open_dir" to "cf_name", and if we change
482 "last_open_dir" later, we free the old value, so we have to
483 set "cf_name" to something that's been allocated. */
484 param_info->cf_name = g_strdup(optarg);
486 case 'R': /* Read file filter */
487 param_info->rfilter = optarg;
489 case 't': /* Time stamp type */
490 if (strcmp(optarg, "r") == 0)
491 timestamp_set_type(TS_RELATIVE);
492 else if (strcmp(optarg, "a") == 0)
493 timestamp_set_type(TS_ABSOLUTE);
494 else if (strcmp(optarg, "ad") == 0)
495 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
496 else if (strcmp(optarg, "adoy") == 0)
497 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
498 else if (strcmp(optarg, "d") == 0)
499 timestamp_set_type(TS_DELTA);
500 else if (strcmp(optarg, "dd") == 0)
501 timestamp_set_type(TS_DELTA_DIS);
502 else if (strcmp(optarg, "e") == 0)
503 timestamp_set_type(TS_EPOCH);
504 else if (strcmp(optarg, "u") == 0)
505 timestamp_set_type(TS_UTC);
506 else if (strcmp(optarg, "ud") == 0)
507 timestamp_set_type(TS_UTC_WITH_YMD);
508 else if (strcmp(optarg, "udoy") == 0)
509 timestamp_set_type(TS_UTC_WITH_YDOY);
511 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
512 cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
513 cmdarg_err_cont("\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
514 cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
515 cmdarg_err_cont("\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
516 cmdarg_err_cont("or \"udoy\" for absolute UTC with YYYY/DOY date.");
520 case 'u': /* Seconds type */
521 if (strcmp(optarg, "s") == 0)
522 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
523 else if (strcmp(optarg, "hms") == 0)
524 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
526 cmdarg_err("Invalid seconds type \"%s\"", optarg);
527 cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
532 /* ext ops were already processed just ignore them this time*/
535 param_info->dfilter = optarg;
538 /* We won't call the init function for the stat this soon
539 as it would disallow MATE's fields (which are registered
540 by the preferences set callback) from being used as
541 part of a tap filter. Instead, we just add the argument
542 to a list of stat arguments. */
543 if (strcmp("help", optarg) == 0) {
544 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
545 list_stat_cmd_args();
548 if (!process_stat_cmd_arg(optarg)) {
549 cmdarg_err("Invalid -z argument.");
550 cmdarg_err_cont(" -z argument must be one of :");
551 list_stat_cmd_args();
555 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
556 param_info->disable_protocol_slist = g_slist_append(param_info->disable_protocol_slist, optarg);
558 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
559 param_info->enable_heur_slist = g_slist_append(param_info->enable_heur_slist, optarg);
561 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
562 param_info->disable_heur_slist = g_slist_append(param_info->disable_heur_slist, optarg);
565 case '?': /* Bad flag - print usage message */
566 param_info->arg_error = TRUE;
571 if (!param_info->arg_error) {
575 if (param_info->cf_name != NULL) {
577 * Input file name specified with "-r" *and* specified as a regular
578 * command-line argument.
580 cmdarg_err("File name specified both with -r and regular argument");
581 param_info->arg_error = TRUE;
584 * Input file name not specified with "-r", and a command-line argument
585 * was specified; treat it as the input file name.
587 * Yes, this is different from tshark, where non-flag command-line
588 * arguments are a filter, but this works better on GUI desktops
589 * where a command can be specified to be run to open a particular
590 * file - yes, you could have "-r" as the last part of the command,
591 * but that's a bit ugly.
593 #ifndef HAVE_GTKOSXAPPLICATION
595 * For GTK+ Mac Integration, file name passed as free argument passed
596 * through grag-and-drop and opened twice sometimes causing crashes.
597 * Subject to report to GTK+ MAC.
599 param_info->cf_name = g_strdup(argv[0]);
608 * Extra command line arguments were specified; complain.
610 cmdarg_err("Invalid argument: %s", argv[0]);
611 param_info->arg_error = TRUE;
615 if (param_info->arg_error) {
617 if (param_info->capture_option_specified) {
618 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
621 commandline_print_usage(FALSE);
632 * indent-tabs-mode: nil
635 * ex: set shiftwidth=4 tabstop=8 expandtab:
636 * :indentSize=4:tabSize=8:noTabs=true: