Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / commandline.c
blob6de24d7f8d62925d644048f28ebd5b637a5cfaa7
1 /* commandline.c
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 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <glib.h>
15 #include <errno.h>
16 #include <string.h>
17 #include <stdio.h>
18 #include <stdlib.h>
20 #include <ws_exit_codes.h>
21 #include <wsutil/ws_getopt.h>
23 #include <wsutil/version_info.h>
25 #include <wsutil/clopts_common.h>
26 #include <wsutil/cmdarg_err.h>
27 #include <wsutil/filesystem.h>
28 #include <wsutil/ws_assert.h>
29 #ifdef _WIN32
30 #include <wsutil/console_win32.h>
31 #endif
33 #include <epan/ex-opt.h>
34 #include <epan/packet.h>
35 #include <epan/proto.h>
36 #include <epan/prefs.h>
37 #include <epan/prefs-int.h>
38 #include <epan/stat_tap_ui.h>
40 #include "capture_opts.h"
41 #include "persfilepath_opt.h"
42 #include "preference_utils.h"
43 #include "recent.h"
44 #include "decode_as_utils.h"
46 #include "../file.h"
48 #include "ui/dissect_opts.h"
50 #include "ui/commandline.h"
52 commandline_param_info_t global_commandline_info;
54 capture_options global_capture_opts;
56 void
57 commandline_print_usage(bool for_help_option) {
58 FILE *output;
60 #ifdef _WIN32
61 create_console();
62 #endif
64 if (for_help_option) {
65 show_help_header("Interactively dump and analyze network traffic.");
66 output = stdout;
67 } else {
68 output = stderr;
70 fprintf(output, "\n");
71 fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
72 fprintf(output, "\n");
74 #ifdef HAVE_LIBPCAP
75 fprintf(output, "Capture interface:\n");
76 fprintf(output, " -i <interface>, --interface <interface>\n");
77 fprintf(output, " name or idx of interface (def: first non-loopback)\n");
78 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
79 fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
80 #ifdef HAVE_PCAP_CREATE
81 fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
82 #else
83 fprintf(output, " packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
84 #endif
85 fprintf(output, " -p, --no-promiscuous-mode\n");
86 fprintf(output, " don't capture in promiscuous mode\n");
87 #ifdef HAVE_PCAP_CREATE
88 fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
89 #endif
90 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
91 fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
92 fprintf(output, " size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
93 #endif
94 fprintf(output, " -y <link type>, --linktype <link type>\n");
95 fprintf(output, " link layer type (def: first appropriate)\n");
96 fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
97 fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
98 fprintf(output, " -L, --list-data-link-types\n");
99 fprintf(output, " print list of link-layer types of iface and exit\n");
100 fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
101 fprintf(output, "\n");
102 fprintf(output, "Capture display:\n");
103 fprintf(output, " -k start capturing immediately (def: do nothing)\n");
104 fprintf(output, " -S update packet display when new packets are captured\n");
105 fprintf(output, " --update-interval interval between updates with new packets (def: %dms)\n", DEFAULT_UPDATE_INTERVAL);
106 fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
107 fprintf(output, "Capture stop conditions:\n");
108 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
109 fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
110 fprintf(output, " duration:NUM - stop after NUM seconds\n");
111 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
112 fprintf(output, " files:NUM - stop after NUM files\n");
113 fprintf(output, " packets:NUM - stop after NUM packets\n");
114 /*fprintf(output, "\n");*/
115 fprintf(output, "Capture output:\n");
116 fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
117 fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
118 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
119 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
120 fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
121 fprintf(output, " interval:NUM - switch to next file when the time is\n");
122 fprintf(output, " an exact multiple of NUM secs\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");
127 #endif
128 /*fprintf(output, "\n");*/
129 fprintf(output, "Input file:\n");
130 fprintf(output, " -r <infile>, --read-file <infile>\n");
131 fprintf(output, " 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>, --read-filter <read filter>\n");
136 fprintf(output, " packet filter in Wireshark display filter syntax\n");
137 fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
138 // Note: the order of the flags here matches the options in the settings dialog e.g. "dsN" only have an effect if "n" is set
139 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mtndsNvg\"\n");
140 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
141 fprintf(output, " \"Decode As\", see the man page for details\n");
142 fprintf(output, " Example: tcp.port==8888,http\n");
143 fprintf(output, " --enable-protocol <proto_name>\n");
144 fprintf(output, " enable dissection of proto_name\n");
145 fprintf(output, " --disable-protocol <proto_name>\n");
146 fprintf(output, " disable dissection of proto_name\n");
147 fprintf(output, " --only-protocols <proto_name>\n");
148 fprintf(output, " Only enable dissection of these protocols, comma\n");
149 fprintf(output, " separated. Disable everything else\n");
150 fprintf(output, " --disable-all-protocols\n");
151 fprintf(output, " Disable dissection of all protocols\n");
152 fprintf(output, " --enable-heuristic <short_name>\n");
153 fprintf(output, " enable dissection of heuristic protocol\n");
154 fprintf(output, " --disable-heuristic <short_name>\n");
155 fprintf(output, " disable dissection of heuristic protocol\n");
157 fprintf(output, "\n");
158 fprintf(output, "User interface:\n");
159 fprintf(output, " -C <config profile> start with specified configuration profile\n");
160 fprintf(output, " -H hide the capture info dialog during packet capture\n");
161 fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
162 fprintf(output, " start with the given display filter\n");
163 fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n");
164 fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n");
165 fprintf(output, " filter\n");
166 fprintf(output, " -j search backwards for a matching packet after \"-J\"\n");
167 fprintf(output, " -t (a|ad|adoy|d|dd|e|r|u|ud|udoy)[.[N]]|.[N]\n");
168 fprintf(output, " format of time stamps (def: r: rel. to first)\n");
169 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
170 fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n");
171 fprintf(output, " -z <statistics> show various statistics, see man page for details\n");
173 fprintf(output, "\n");
174 fprintf(output, "Output:\n");
175 fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
176 #ifdef HAVE_LIBPCAP
177 fprintf(output, " -F <capture type> set the output file type; default is pcapng.\n");
178 fprintf(output, " an empty \"-F\" option will list the file types.\n");
179 fprintf(output, " --capture-comment <comment>\n");
180 fprintf(output, " add a capture file comment, if supported\n");
181 #endif
182 fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
183 fprintf(output, " (default: %s)\n", g_get_tmp_dir());
184 fprintf(output, "\n");
186 ws_log_print_usage(output);
188 fprintf(output, "\n");
189 fprintf(output, "Miscellaneous:\n");
190 fprintf(output, " -h, --help display this help and exit\n");
191 fprintf(output, " -v, --version display version info and exit\n");
192 fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n");
193 fprintf(output, " persdata:path - personal data files\n");
194 fprintf(output, " -o <name>:<value> ... override preference or recent setting\n");
195 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
196 #ifndef _WIN32
197 fprintf(output, " --display <X display> X display to use\n");
198 #endif
199 fprintf(output, " --fullscreen start Wireshark in full screen\n");
201 #ifdef _WIN32
202 destroy_console();
203 #endif
206 #define LONGOPT_FULL_SCREEN LONGOPT_BASE_GUI+1
207 #define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_GUI+2
209 #define OPTSTRING OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON OPTSTRING_READ_CAPTURE_COMMON "C:g:HhjJ:klm:o:P:Svw:X:z:"
210 static const struct ws_option long_options[] = {
211 {"help", ws_no_argument, NULL, 'h'},
212 {"version", ws_no_argument, NULL, 'v'},
213 {"fullscreen", ws_no_argument, NULL, LONGOPT_FULL_SCREEN },
214 {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
215 LONGOPT_CAPTURE_COMMON
216 LONGOPT_DISSECT_COMMON
217 LONGOPT_READ_CAPTURE_COMMON
218 {0, 0, 0, 0 }
220 static const char optstring[] = OPTSTRING;
222 #ifndef HAVE_LIBPCAP
223 static void print_no_capture_support_error(void)
225 cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
227 #endif
229 void commandline_early_options(int argc, char *argv[])
231 int opt;
232 #ifdef HAVE_LIBPCAP
233 int err;
234 GList *if_list;
235 char *err_str;
236 int exit_status;
237 #else
238 bool capture_option_specified;
239 #endif
242 * In order to have the -X opts assigned before the wslua machine starts
243 * we need to call getopt_long before epan_init() gets called.
245 * In addition, we process "console only" parameters (ones where we
246 * send output to the console and exit) here, so we don't start GUI
247 * if we're only showing command-line help or version information.
249 * XXX - this pre-scan is done before we start GUI, so we haven't
250 * run "GUI init function" on the arguments. That means that GUI-specific
251 * arguments have not been removed from the argument list; those arguments
252 * begin with "--", and will be treated as an error by getopt_long().
254 * We thus ignore errors - *and* set "ws_opterr" to 0 to suppress the
255 * error messages.
257 * In order to handle, for example, -o options, we also need to call it
258 * *after* epan_init() gets called, so that the dissectors have had a
259 * chance to register their preferences, so we have another getopt_long()
260 * call later.
262 * XXX - can we do this all with one getopt_long() call, saving the
263 * arguments we can't handle until after initializing libwireshark,
264 * and then process them after initializing libwireshark?
266 * Note that we don't want to initialize libwireshark until after the
267 * GUI is up, as that can take a while, and we want a window of some
268 * sort up to show progress while that's happening.
270 ws_opterr = 0;
272 #ifndef HAVE_LIBPCAP
273 capture_option_specified = false;
274 #endif
275 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
276 switch (opt) {
277 case 'C': /* Configuration Profile */
278 if (profile_exists (ws_optarg, false)) {
279 set_profile_name (ws_optarg);
280 } else if (profile_exists (ws_optarg, true)) {
281 char *pf_dir_path, *pf_dir_path2, *pf_filename;
282 /* Copy from global profile */
283 if (create_persconffile_profile(ws_optarg, &pf_dir_path) == -1) {
284 cmdarg_err("Can't create directory\n\"%s\":\n%s.",
285 pf_dir_path, g_strerror(errno));
287 g_free(pf_dir_path);
288 exit(WS_EXIT_INVALID_FILE);
290 if (copy_persconffile_profile(ws_optarg, ws_optarg, true, &pf_filename,
291 &pf_dir_path, &pf_dir_path2) == -1) {
292 cmdarg_err("Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
293 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
295 g_free(pf_filename);
296 g_free(pf_dir_path);
297 g_free(pf_dir_path2);
298 exit(WS_EXIT_INVALID_FILE);
300 set_profile_name (ws_optarg);
301 } else {
302 cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
303 exit(1);
305 break;
306 case 'D': /* Print a list of capture devices and exit */
307 #ifdef HAVE_LIBPCAP
308 exit_status = EXIT_SUCCESS;
309 if_list = capture_interface_list(&err, &err_str, NULL);
310 if (err != 0) {
312 * An error occurred when fetching the local
313 * interfaces. Report it.
315 #ifdef _WIN32
316 create_console();
317 #endif /* _WIN32 */
318 cmdarg_err("%s", err_str);
319 g_free(err_str);
320 exit_status = WS_EXIT_PCAP_ERROR;
322 if (if_list == NULL) {
324 * No interfaces were found. If that's not the
325 * result of an error when fetching the local
326 * interfaces, let the user know.
328 if (err == 0) {
329 cmdarg_err("There are no interfaces on which a capture can be done");
330 exit_status = WS_EXIT_NO_INTERFACES;
332 exit(exit_status);
334 #ifdef _WIN32
335 create_console();
336 #endif /* _WIN32 */
337 capture_opts_print_interfaces(if_list);
338 free_interface_list(if_list);
339 #ifdef _WIN32
340 destroy_console();
341 #endif /* _WIN32 */
342 exit(exit_status);
343 #else /* HAVE_LIBPCAP */
344 capture_option_specified = true;
345 #endif /* HAVE_LIBPCAP */
346 break;
347 case 'h': /* Print help and exit */
348 commandline_print_usage(true);
349 exit(EXIT_SUCCESS);
350 break;
351 #ifdef _WIN32
352 case 'i':
353 if (strcmp(ws_optarg, "-") == 0)
354 set_stdin_capture(true);
355 break;
356 #endif
357 case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */
358 if (!persfilepath_opt(opt, ws_optarg)) {
359 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", ws_optarg);
360 exit(EXIT_SUCCESS);
362 break;
363 case 'v': /* Show version and exit */
364 #ifdef _WIN32
365 create_console();
366 #endif
367 show_version();
368 #ifdef _WIN32
369 destroy_console();
370 #endif
371 exit(EXIT_SUCCESS);
372 break;
373 case 'X':
375 * Extension command line options have to be processed before
376 * we call epan_init() as they are supposed to be used by dissectors
377 * or taps very early in the registration process.
379 ex_opt_add(ws_optarg);
380 break;
381 case '?': /* Ignore errors - the "real" scan will catch them. */
382 break;
386 #ifndef HAVE_LUA
387 if (ex_opt_count("lua_script") > 0) {
388 cmdarg_err("This version of Wireshark was not built with support for Lua scripting.");
389 exit(1);
391 #endif
393 #ifndef HAVE_LIBPCAP
394 if (capture_option_specified) {
395 print_no_capture_support_error();
396 commandline_print_usage(false);
397 exit(EXIT_SUCCESS);
399 #endif
402 void commandline_override_prefs(int argc, char *argv[], bool opt_reset)
404 int opt;
407 * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
409 * Ignore errors and keep ws_opterr as 0; error messages will be printed
410 * later by command_other_options()
412 if (opt_reset) {
413 ws_optreset = 1;
414 ws_optind = 1;
415 ws_opterr = 0;
418 /* Initialize with default values */
419 global_commandline_info.user_opts = NULL;
421 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
422 switch (opt) {
423 case 'o': /* Override preference from command line */
425 char *errmsg = NULL;
427 switch (prefs_set_pref(ws_optarg, &errmsg)) {
428 case PREFS_SET_OK:
429 global_commandline_info.user_opts =
430 g_slist_prepend(global_commandline_info.user_opts,
431 g_strdup(ws_optarg));
432 break;
433 case PREFS_SET_SYNTAX_ERR:
434 cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
435 errmsg ? ": " : "", errmsg ? errmsg : "");
436 g_free(errmsg);
437 exit_application(1);
438 break;
439 case PREFS_SET_NO_SUCH_PREF:
440 /* not a preference, might be a recent setting */
441 switch (recent_set_arg(ws_optarg)) {
442 case PREFS_SET_OK:
443 break;
444 case PREFS_SET_SYNTAX_ERR:
445 /* shouldn't happen, checked already above */
446 cmdarg_err("Invalid -o flag \"%s\"", ws_optarg);
447 exit_application(1);
448 break;
449 case PREFS_SET_NO_SUCH_PREF:
450 case PREFS_SET_OBSOLETE:
451 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
452 ws_optarg);
453 exit_application(1);
454 break;
455 default:
456 ws_assert_not_reached();
458 break;
459 case PREFS_SET_OBSOLETE:
460 /* obsolete preference, might be a recent setting */
461 if (recent_set_arg(ws_optarg) != PREFS_SET_OK) {
462 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
463 ws_optarg);
464 exit_application(1);
466 break;
467 default:
468 ws_assert_not_reached();
470 break;
472 default:
473 case '?': /* Ignore errors - the "real" scan will catch them. */
474 break;
478 /* Since we prepended each option when processing `-o`, reverse the list
479 * in case the order of options becomes meaningful.
481 global_commandline_info.user_opts = g_slist_reverse(global_commandline_info.user_opts);
485 void commandline_other_options(int argc, char *argv[], bool opt_reset)
487 int opt;
488 bool arg_error = false;
489 #ifdef HAVE_LIBPCAP
490 const char *list_option_supplied = NULL;
491 int status;
492 #else
493 bool capture_option_specified;
494 #endif
497 * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
499 * Also reset ws_opterr to 1, so that error messages are printed by
500 * getopt_long().
502 * XXX - if we want to control all the command-line option errors, so
503 * that we can display them where we choose (e.g., in a window), we'd
504 * want to leave ws_opterr as 0, and produce our own messages using ws_optopt.
505 * We'd have to check the value of ws_optopt to see if it's a valid option
506 * letter, in which case *presumably* the error is "this option requires
507 * an argument but none was specified", or not a valid option letter,
508 * in which case *presumably* the error is "this option isn't valid".
509 * Some versions of getopt() let you supply a option string beginning
510 * with ':', which means that getopt() will return ':' rather than '?'
511 * for "this option requires an argument but none was specified", but
512 * not all do. But we're now using getopt_long() - what does it do?
514 if (opt_reset) {
515 ws_optreset = 1;
516 ws_optind = 1;
517 ws_opterr = 1;
520 /* Initialize with default values */
521 global_commandline_info.jump_backwards = SD_FORWARD;
522 global_commandline_info.go_to_packet = 0;
523 global_commandline_info.jfilter = NULL;
524 global_commandline_info.cf_name = NULL;
525 global_commandline_info.rfilter = NULL;
526 global_commandline_info.dfilter = NULL;
527 #ifdef HAVE_LIBPCAP
528 global_commandline_info.start_capture = false;
529 global_commandline_info.list_link_layer_types = false;
530 global_commandline_info.list_timestamp_types = false;
531 global_commandline_info.quit_after_cap = getenv("WIRESHARK_QUIT_AFTER_CAPTURE") ? true : false;
532 global_commandline_info.capture_comments = NULL;
533 #endif
534 global_commandline_info.full_screen = false;
536 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
537 switch (opt) {
538 /*** capture option specific ***/
539 case 'a': /* autostop criteria */
540 case 'b': /* Ringbuffer option */
541 case 'c': /* Capture xxx packets */
542 case 'f': /* capture filter */
543 case 'F': /* capture file type */
544 case 'H': /* Hide capture info dialog box */
545 case 'p': /* Don't capture in promiscuous mode */
546 case 'i': /* Use interface x */
547 case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
548 case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
549 case LONGOPT_UPDATE_INTERVAL: /* sync pipe update interval */
550 #ifdef HAVE_PCAP_CREATE
551 case 'I': /* Capture in monitor mode, if available */
552 #endif
553 #ifdef HAVE_PCAP_REMOTE
554 case 'A': /* Authentication */
555 #endif
556 case 's': /* Set the snapshot (capture) length */
557 case 'S': /* "Sync" mode: used for following file ala tail -f */
558 case 'w': /* Write to capture file xxx */
559 case 'y': /* Set the pcap data link type */
560 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
561 case 'B': /* Buffer size */
562 #endif
563 #ifdef HAVE_LIBPCAP
564 status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
565 if(status != 0) {
566 exit_application(status);
568 #else
569 capture_option_specified = true;
570 arg_error = true;
571 #endif
572 break;
574 /*** all non capture option specific ***/
575 case 'C':
576 /* Configuration profile settings were already processed just ignore them this time*/
577 break;
578 case 'j': /* Search backwards for a matching packet from filter in option J */
579 global_commandline_info.jump_backwards = SD_BACKWARD;
580 break;
581 case 'g': /* Go to packet with the given packet number */
582 global_commandline_info.go_to_packet = get_nonzero_uint32(ws_optarg, "go to packet");
583 break;
584 case 'J': /* Jump to the first packet which matches the filter criteria */
585 global_commandline_info.jfilter = ws_optarg;
586 break;
587 case 'k': /* Start capture immediately */
588 #ifdef HAVE_LIBPCAP
589 global_commandline_info.start_capture = true;
590 #else
591 capture_option_specified = true;
592 arg_error = true;
593 #endif
594 break;
595 case 'l': /* Automatic scrolling in live capture mode */
596 #ifdef HAVE_LIBPCAP
597 recent.capture_auto_scroll = true;
598 #else
599 capture_option_specified = true;
600 arg_error = true;
601 #endif
602 break;
603 case 'L': /* Print list of link-layer types and exit */
604 #ifdef HAVE_LIBPCAP
605 global_commandline_info.list_link_layer_types = true;
606 list_option_supplied = "-L";
607 #else
608 capture_option_specified = true;
609 arg_error = true;
610 #endif
611 break;
612 case LONGOPT_LIST_TSTAMP_TYPES:
613 #ifdef HAVE_LIBPCAP
614 global_commandline_info.list_timestamp_types = true;
615 list_option_supplied = "--list-time-stamp-types";
616 #else
617 capture_option_specified = true;
618 arg_error = true;
619 #endif
620 break;
621 case 'o': /* Override preference from command line */
622 /* Pref overrides were already processed just ignore them this time*/
623 break;
624 case 'P':
625 /* Path settings were already processed just ignore them this time*/
626 break;
627 case 'r': /* Read capture file xxx */
628 /* We may set "last_open_dir" to "cf_name", and if we change
629 "last_open_dir" later, we free the old value, so we have to
630 set "cf_name" to something that's been allocated. */
631 global_commandline_info.cf_name = g_strdup(ws_optarg);
632 break;
633 case 'R': /* Read file filter */
634 global_commandline_info.rfilter = ws_optarg;
635 break;
636 case 'X':
637 /* ext ops were already processed just ignore them this time*/
638 break;
639 case 'Y':
640 global_commandline_info.dfilter = ws_optarg;
641 break;
642 case 'z':
643 /* We won't call the init function for the stat this soon
644 as it would disallow MATE's fields (which are registered
645 by the preferences set callback) from being used as
646 part of a tap filter. Instead, we just add the argument
647 to a list of stat arguments. */
648 if (strcmp("help", ws_optarg) == 0) {
649 fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
650 list_stat_cmd_args();
651 exit_application(0);
653 if (!process_stat_cmd_arg(ws_optarg)) {
654 cmdarg_err("Invalid -z argument.");
655 cmdarg_err_cont(" -z argument must be one of :");
656 list_stat_cmd_args();
657 exit_application(1);
659 break;
660 case 'd': /* Decode as rule */
661 case 'K': /* Kerberos keytab file */
662 case 'n': /* No name resolution */
663 case 'N': /* Select what types of addresses/port #s to resolve */
664 case 't': /* time stamp type */
665 case 'u': /* Seconds type */
666 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
667 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
668 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
669 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
670 case LONGOPT_ONLY_PROTOCOLS: /* enable dissection of these comma separated protocols only */
671 case LONGOPT_DISABLE_ALL_PROTOCOLS: /* disable dissection of all protocols */
672 if (!dissect_opts_handle_opt(opt, ws_optarg))
673 exit_application(1);
674 break;
675 case LONGOPT_FULL_SCREEN:
676 global_commandline_info.full_screen = true;
677 break;
678 #ifdef HAVE_LIBPCAP
679 case LONGOPT_CAPTURE_COMMENT: /* capture comment */
680 if (global_commandline_info.capture_comments == NULL) {
681 global_commandline_info.capture_comments = g_ptr_array_new_with_free_func(g_free);
683 g_ptr_array_add(global_commandline_info.capture_comments, g_strdup(ws_optarg));
684 #else
685 capture_option_specified = true;
686 arg_error = true;
687 #endif
688 break;
689 default:
690 case '?': /* Bad flag - print usage message */
691 arg_error = true;
692 break;
696 if (!arg_error) {
697 argc -= ws_optind;
698 argv += ws_optind;
699 if (argc >= 1) {
700 if (global_commandline_info.cf_name != NULL) {
702 * Input file name specified with "-r" *and* specified as a regular
703 * command-line argument.
705 cmdarg_err("File name specified both with -r and regular argument");
706 arg_error = true;
707 } else {
709 * Input file name not specified with "-r", and a command-line argument
710 * was specified; treat it as the input file name.
712 * Yes, this is different from tshark, where non-flag command-line
713 * arguments are a filter, but this works better on GUI desktops
714 * where a command can be specified to be run to open a particular
715 * file - yes, you could have "-r" as the last part of the command,
716 * but that's a bit ugly.
718 global_commandline_info.cf_name = g_strdup(argv[0]);
720 argc--;
721 argv++;
724 if (argc != 0) {
726 * Extra command line arguments were specified; complain.
728 cmdarg_err("Invalid argument: %s", argv[0]);
729 arg_error = true;
733 if (arg_error) {
734 #ifdef HAVE_LIBPCAP
735 if (ws_optopt == 'F') {
736 capture_opts_list_file_types();
737 exit_application(1);
739 #else
740 if (capture_option_specified) {
741 print_no_capture_support_error();
743 #endif
744 commandline_print_usage(false);
745 exit_application(1);
748 #ifdef HAVE_LIBPCAP
749 if (global_commandline_info.start_capture && list_option_supplied) {
750 /* Specifying *both* is bogus. */
751 cmdarg_err("You can't specify both %s and a live capture.", list_option_supplied);
752 exit_application(1);
755 if (list_option_supplied) {
756 /* We're supposed to list the link-layer types for an interface;
757 did the user also specify a capture file to be read? */
758 if (global_commandline_info.cf_name) {
759 /* Yes - that's bogus. */
760 cmdarg_err("You can't specify %s and a capture file to be read.", list_option_supplied);
761 exit_application(1);
763 /* No - did they specify a ring buffer option? */
764 if (global_capture_opts.multi_files_on) {
765 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
766 exit_application(1);
768 } else {
769 /* We're supposed to do a live capture; did the user also specify
770 a capture file to be read? */
771 if (global_commandline_info.start_capture && global_commandline_info.cf_name) {
772 /* Yes - that's bogus. */
773 cmdarg_err("You can't specify both a live capture and a capture file to be read.");
774 exit_application(1);
777 /* No - was the ring buffer option specified and, if so, does it make
778 sense? */
779 if (global_capture_opts.multi_files_on) {
780 /* Ring buffer works only under certain conditions:
781 a) ring buffer does not work with temporary files;
782 b) real_time_mode and multi_files_on are mutually exclusive -
783 real_time_mode takes precedence;
784 c) it makes no sense to enable the ring buffer if the maximum
785 file size is set to "infinite". */
786 if (global_capture_opts.save_file == NULL) {
787 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
788 global_capture_opts.multi_files_on = false;
790 if (!global_capture_opts.has_autostop_filesize &&
791 !global_capture_opts.has_file_duration &&
792 !global_capture_opts.has_file_interval &&
793 !global_capture_opts.has_file_packets) {
794 cmdarg_err("Ring buffer requested, but no maximum capture file size, duration, interval or packets were specified.");
795 /* XXX - this must be redesigned as the conditions changed */
799 #endif
802 /* Local function used by commandline_options_drop */
803 static int cl_find_custom(const void *elem_data, const void *search_data) {
804 return memcmp(elem_data, search_data, strlen((char *)search_data));
807 /* Drop any options the user specified on the command line with `-o`
808 * that have the given module and preference names
810 void commandline_options_drop(const char *module_name, const char *pref_name) {
811 GSList *elem;
812 char *opt_prefix;
814 if (global_commandline_info.user_opts == NULL) return;
816 opt_prefix = ws_strdup_printf("%s.%s:", module_name, pref_name);
818 while (NULL != (elem = g_slist_find_custom(global_commandline_info.user_opts,
819 (const void *)opt_prefix, cl_find_custom))) {
820 global_commandline_info.user_opts =
821 g_slist_remove_link(global_commandline_info.user_opts, elem);
822 g_free(elem->data);
823 g_slist_free_1(elem);
825 g_free(opt_prefix);
828 /* Reapply any options the user specified on the command line with `-o`
829 * Called in the Qt UI when reloading Lua plugins
830 * For https://gitlab.com/wireshark/wireshark/-/issues/12331
832 void commandline_options_reapply(void) {
833 char *errmsg = NULL;
834 GSList *entry = NULL;
836 for (entry = global_commandline_info.user_opts; entry != NULL; entry = g_slist_next(entry)) {
837 /* Although these options are from the user-supplied command line,
838 * they were checked for validity before we added them to user_opts,
839 * so we don't check them again here. In the worst case, a pref is
840 * specified for a lua plugin which has been edited after Wireshark
841 * started and has had that pref removed; not worth exiting over.
842 * See #12331
844 prefs_set_pref((char *)entry->data, &errmsg);
845 if (errmsg != NULL) {
846 g_free(errmsg);
847 errmsg = NULL;
852 void commandline_options_apply_extcap(void) {
853 char *errmsg = NULL;
854 GSList *entry = NULL;
855 char *pref_arg;
857 if (prefs.capture_no_extcap)
858 return;
860 for (entry = global_commandline_info.user_opts; entry != NULL; entry = g_slist_next(entry)) {
861 pref_arg = (char *)entry->data;
862 if (g_str_has_prefix(pref_arg, "extcap.")) {
863 switch (prefs_set_pref(pref_arg, &errmsg)) {
864 case PREFS_SET_OK:
865 break;
866 case PREFS_SET_SYNTAX_ERR:
867 cmdarg_err("Invalid -o flag \"%s\"%s%s", pref_arg,
868 errmsg ? ": " : "", errmsg ? errmsg : "");
869 g_free(errmsg);
870 exit_application(1);
871 break;
872 case PREFS_SET_NO_SUCH_PREF:
873 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
874 pref_arg);
875 exit_application(1);
876 break;
877 case PREFS_SET_OBSOLETE:
878 cmdarg_err("-o flag \"%s\" specifies obsolete preference",
879 pref_arg);
880 exit_application(1);
881 break;
882 default:
883 ws_assert_not_reached();
889 /* Free memory used to hold user-specified command line options */
890 void commandline_options_free(void) {
891 g_slist_free_full(g_steal_pointer(&global_commandline_info.user_opts), g_free);