#include "wsutil/wsgetopt.h"
#endif
-#include <ws_version_info.h>
+#include <version_info.h>
#include <wsutil/clopts_common.h>
#include <wsutil/cmdarg_err.h>
#include <wsutil/filesystem.h>
#include <epan/ex-opt.h>
-#include <epan/addr_resolv.h>
#include <epan/packet.h>
#include <epan/proto.h>
#include <epan/prefs.h>
#include <epan/prefs-int.h>
-#include <epan/timestamp.h>
#include <epan/stat_tap_ui.h>
#include "capture_opts.h"
#include "recent.h"
#include "decode_as_utils.h"
-#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
-#include <epan/asn1.h>
-#include <epan/dissectors/packet-kerberos.h>
-#endif
-
#include "../file.h"
+#include "ui/dissect_opts.h"
+
#include "ui/commandline.h"
-#ifdef HAVE_LIBPCAP
+commandline_param_info_t global_commandline_info;
+
+#if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
capture_options global_capture_opts;
#endif
fprintf(output, "Capture interface:\n");
fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n");
fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
- fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n");
+#ifdef HAVE_PCAP_CREATE
+ fprintf(output, " -s <snaplen> packet snapshot length (def: appropriate maximum)\n");
+#else
+ fprintf(output, " -s <snaplen> packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
+#endif
fprintf(output, " -p don't capture in promiscuous mode\n");
fprintf(output, " -k start capturing immediately (def: do nothing)\n");
fprintf(output, " -S update packet display when new packets are captured\n");
fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
#endif
fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
+ fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
fprintf(output, " -D print list of interfaces and exit\n");
fprintf(output, " -L print list of link-layer types of iface and exit\n");
+ fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
fprintf(output, "\n");
fprintf(output, "Capture stop conditions:\n");
fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
fprintf(output, " \"Decode As\", see the man page for details\n");
fprintf(output, " Example: tcp.port==8888,http\n");
+ fprintf(output, " --enable-protocol <proto_name>\n");
+ fprintf(output, " enable dissection of proto_name\n");
fprintf(output, " --disable-protocol <proto_name>\n");
fprintf(output, " disable dissection of proto_name\n");
fprintf(output, " --enable-heuristic <short_name>\n");
#ifndef _WIN32
fprintf(output, " --display=DISPLAY X display to use\n");
#endif
+ fprintf(output, " --fullscreen start Wireshark in full screen\n");
#ifdef _WIN32
destroy_console();
#endif
}
-#define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:d:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
+/*
+ * For long options with no corresponding short options, we define values
+ * outside the range of ASCII graphic characters, make that the last
+ * component of the entry for the long option, and have a case for that
+ * option in the switch statement.
+ *
+ * We also pick values >= 65536, so as to leave values from 128 to 65535
+ * for capture and dissection options.
+ */
+#define LONGOPT_FULL_SCREEN 65536
+
+#define OPTSTRING OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "C:g:Hh" "jJ:klm:o:P:r:R:Svw:X:Y:z:"
static const struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"read-file", required_argument, NULL, 'r' },
{"read-filter", required_argument, NULL, 'R' },
{"display-filter", required_argument, NULL, 'Y' },
{"version", no_argument, NULL, 'v'},
+ {"fullscreen", no_argument, NULL, LONGOPT_FULL_SCREEN },
LONGOPT_CAPTURE_COMMON
+ LONGOPT_DISSECT_COMMON
{0, 0, 0, 0 }
};
static const char optstring[] = OPTSTRING;
-void commandline_early_options(int argc, char *argv[], commandline_capture_param_info_t* param_info)
+#ifndef HAVE_LIBPCAP
+static void print_no_capture_support_error(void)
+{
+ cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
+}
+#endif
+
+void commandline_early_options(int argc, char *argv[],
+ GString *comp_info_str, GString *runtime_info_str)
{
int opt;
#ifdef HAVE_LIBPCAP
int err;
GList *if_list;
gchar *err_str;
+#else
+ gboolean capture_option_specified;
#endif
/*
opterr = 0;
#ifndef HAVE_LIBPCAP
- param_info->capture_option_specified = FALSE;
+ capture_option_specified = FALSE;
#endif
while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
switch (opt) {
#endif /* _WIN32 */
exit(0);
#else /* HAVE_LIBPCAP */
- param_info->capture_option_specified = TRUE;
- param_info->arg_error = TRUE;
+ capture_option_specified = TRUE;
#endif /* HAVE_LIBPCAP */
break;
case 'h': /* Print help and exit */
#ifdef _WIN32
create_console();
#endif
- show_version("Wireshark", param_info->comp_info_str, param_info->runtime_info_str);
+ show_version("Wireshark", comp_info_str, runtime_info_str);
#ifdef _WIN32
destroy_console();
#endif
break;
}
}
+
+#ifndef HAVE_LIBPCAP
+ if (capture_option_specified) {
+ print_no_capture_support_error();
+ commandline_print_usage(FALSE);
+ exit(1);
+ }
+#endif
}
-void commandline_other_options(int argc, char *argv[], commandline_param_info_t* param_info, gboolean opt_reset)
+void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
{
int opt;
+ gboolean arg_error = FALSE;
#ifdef HAVE_LIBPCAP
+ const char *list_option_supplied = NULL;
int status;
+#else
+ gboolean capture_option_specified;
#endif
- char badopt;
/*
* To reset the options parser, set optreset to 1 on platforms that
- * have optreset (documented in *BSD and OS X, apparently present but
+ * have optreset (documented in *BSD and macOS, apparently present but
* not documented in Solaris - the Illumos repository seems to
* suggest that the first Solaris getopt_long(), at least as of 2004,
* was based on the NetBSD one, it had optreset) and set optind to 1,
opterr = 1;
}
+ /* Initialize with default values */
+ dissect_opts_init();
+ global_commandline_info.jump_backwards = SD_FORWARD;
+ global_commandline_info.go_to_packet = 0;
+ global_commandline_info.jfilter = NULL;
+ global_commandline_info.cf_name = NULL;
+ global_commandline_info.rfilter = NULL;
+ global_commandline_info.dfilter = NULL;
+#ifdef HAVE_LIBPCAP
+ global_commandline_info.start_capture = FALSE;
+ global_commandline_info.list_link_layer_types = FALSE;
+ global_commandline_info.list_timestamp_types = FALSE;
+ global_commandline_info.quit_after_cap = getenv("WIRESHARK_QUIT_AFTER_CAPTURE") ? TRUE : FALSE;
+#endif
+ global_commandline_info.full_screen = FALSE;
+
while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
switch (opt) {
/*** capture option specific ***/
case 'H': /* Hide capture info dialog box */
case 'p': /* Don't capture in promiscuous mode */
case 'i': /* Use interface x */
+ case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
#ifdef HAVE_PCAP_CREATE
case 'I': /* Capture in monitor mode, if available */
#endif
#endif
#ifdef HAVE_LIBPCAP
status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
- ¶m_info->start_capture);
+ &global_commandline_info.start_capture);
if(status != 0) {
exit(status);
}
#else
- param_info->capture_option_specified = TRUE;
- param_info->arg_error = TRUE;
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
#endif
break;
-#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
- case 'K': /* Kerberos keytab file */
- read_keytab_file(optarg);
- break;
-#endif
-
/*** all non capture option specific ***/
case 'C':
/* Configuration profile settings were already processed just ignore them this time*/
break;
- case 'd': /* Decode as rule */
- if (!decode_as_command_option(optarg))
- exit(1);
- break;
case 'j': /* Search backwards for a matching packet from filter in option J */
- param_info->jump_backwards = SD_BACKWARD;
+ global_commandline_info.jump_backwards = SD_BACKWARD;
break;
case 'g': /* Go to packet with the given packet number */
- param_info->go_to_packet = get_positive_int(optarg, "go to packet");
+ global_commandline_info.go_to_packet = get_nonzero_guint32(optarg, "go to packet");
break;
case 'J': /* Jump to the first packet which matches the filter criteria */
- param_info->jfilter = optarg;
+ global_commandline_info.jfilter = optarg;
break;
case 'l': /* Automatic scrolling in live capture mode */
#ifdef HAVE_LIBPCAP
auto_scroll_live = TRUE;
#else
- param_info->capture_option_specified = TRUE;
- param_info->arg_error = TRUE;
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
#endif
break;
case 'L': /* Print list of link-layer types and exit */
#ifdef HAVE_LIBPCAP
- param_info->list_link_layer_types = TRUE;
+ global_commandline_info.list_link_layer_types = TRUE;
+ list_option_supplied = "-L";
#else
- param_info->capture_option_specified = TRUE;
- param_info->arg_error = TRUE;
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
#endif
break;
- case 'm': /* Fixed-width font for the display */
- g_free(param_info->prefs_p->gui_gtk2_font_name);
- param_info->prefs_p->gui_gtk2_font_name = g_strdup(optarg);
- break;
- case 'n': /* No name resolution */
- disable_name_resolution();
- break;
- case 'N': /* Select what types of addresses/port #s to resolve */
- badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
- if (badopt != '\0') {
- cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
- badopt);
- exit(1);
- }
+ case LONGOPT_LIST_TSTAMP_TYPES:
+#ifdef HAVE_LIBPCAP
+ global_commandline_info.list_timestamp_types = TRUE;
+ list_option_supplied = "--list-time-stamp-types";
+#else
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
+#endif
break;
case 'o': /* Override preference from command line */
- switch (prefs_set_pref(optarg)) {
+ {
+ char *errmsg = NULL;
+
+ switch (prefs_set_pref(optarg, &errmsg)) {
case PREFS_SET_OK:
break;
case PREFS_SET_SYNTAX_ERR:
- cmdarg_err("Invalid -o flag \"%s\"", optarg);
+ cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
+ errmsg ? ": " : "", errmsg ? errmsg : "");
+ g_free(errmsg);
exit(1);
break;
case PREFS_SET_NO_SUCH_PREF:
g_assert_not_reached();
}
break;
+ }
case 'P':
/* Path settings were already processed just ignore them this time*/
break;
/* We may set "last_open_dir" to "cf_name", and if we change
"last_open_dir" later, we free the old value, so we have to
set "cf_name" to something that's been allocated. */
- param_info->cf_name = g_strdup(optarg);
+ global_commandline_info.cf_name = g_strdup(optarg);
break;
case 'R': /* Read file filter */
- param_info->rfilter = optarg;
- break;
- case 't': /* Time stamp type */
- if (strcmp(optarg, "r") == 0)
- timestamp_set_type(TS_RELATIVE);
- else if (strcmp(optarg, "a") == 0)
- timestamp_set_type(TS_ABSOLUTE);
- else if (strcmp(optarg, "ad") == 0)
- timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
- else if (strcmp(optarg, "adoy") == 0)
- timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
- else if (strcmp(optarg, "d") == 0)
- timestamp_set_type(TS_DELTA);
- else if (strcmp(optarg, "dd") == 0)
- timestamp_set_type(TS_DELTA_DIS);
- else if (strcmp(optarg, "e") == 0)
- timestamp_set_type(TS_EPOCH);
- else if (strcmp(optarg, "u") == 0)
- timestamp_set_type(TS_UTC);
- else if (strcmp(optarg, "ud") == 0)
- timestamp_set_type(TS_UTC_WITH_YMD);
- else if (strcmp(optarg, "udoy") == 0)
- timestamp_set_type(TS_UTC_WITH_YDOY);
- else {
- cmdarg_err("Invalid time stamp type \"%s\"", optarg);
- cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
- cmdarg_err_cont("\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
- cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
- cmdarg_err_cont("\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
- cmdarg_err_cont("or \"udoy\" for absolute UTC with YYYY/DOY date.");
- exit(1);
- }
- break;
- case 'u': /* Seconds type */
- if (strcmp(optarg, "s") == 0)
- timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
- else if (strcmp(optarg, "hms") == 0)
- timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
- else {
- cmdarg_err("Invalid seconds type \"%s\"", optarg);
- cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
- exit(1);
- }
+ global_commandline_info.rfilter = optarg;
break;
case 'X':
/* ext ops were already processed just ignore them this time*/
break;
case 'Y':
- param_info->dfilter = optarg;
+ global_commandline_info.dfilter = optarg;
break;
case 'z':
/* We won't call the init function for the stat this soon
exit(1);
}
break;
+ case 'd': /* Decode as rule */
+ case 'K': /* Kerberos keytab file */
+ case 'n': /* No name resolution */
+ case 'N': /* Select what types of addresses/port #s to resolve */
+ case 't': /* time stamp type */
+ case 'u': /* Seconds type */
case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
- param_info->disable_protocol_slist = g_slist_append(param_info->disable_protocol_slist, optarg);
- break;
case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
- param_info->enable_heur_slist = g_slist_append(param_info->enable_heur_slist, optarg);
- break;
case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
- param_info->disable_heur_slist = g_slist_append(param_info->disable_heur_slist, optarg);
+ case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
+ if (!dissect_opts_handle_opt(opt, optarg))
+ exit(1);
+ break;
+ case LONGOPT_FULL_SCREEN:
+ global_commandline_info.full_screen = TRUE;
break;
default:
case '?': /* Bad flag - print usage message */
- param_info->arg_error = TRUE;
+ arg_error = TRUE;
break;
}
}
- if (!param_info->arg_error) {
+ if (!arg_error) {
argc -= optind;
argv += optind;
if (argc >= 1) {
- if (param_info->cf_name != NULL) {
+ if (global_commandline_info.cf_name != NULL) {
/*
* Input file name specified with "-r" *and* specified as a regular
* command-line argument.
*/
cmdarg_err("File name specified both with -r and regular argument");
- param_info->arg_error = TRUE;
+ arg_error = TRUE;
} else {
/*
* Input file name not specified with "-r", and a command-line argument
* through grag-and-drop and opened twice sometimes causing crashes.
* Subject to report to GTK+ MAC.
*/
- param_info->cf_name = g_strdup(argv[0]);
+ global_commandline_info.cf_name = g_strdup(argv[0]);
#endif
}
argc--;
* Extra command line arguments were specified; complain.
*/
cmdarg_err("Invalid argument: %s", argv[0]);
- param_info->arg_error = TRUE;
+ arg_error = TRUE;
}
}
- if (param_info->arg_error) {
+ if (arg_error) {
#ifndef HAVE_LIBPCAP
- if (param_info->capture_option_specified) {
- cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
+ if (capture_option_specified) {
+ print_no_capture_support_error();
}
#endif
commandline_print_usage(FALSE);
exit(1);
}
+
+#ifdef HAVE_LIBPCAP
+ if (global_commandline_info.start_capture && list_option_supplied) {
+ /* Specifying *both* is bogus. */
+ cmdarg_err("You can't specify both %s and a live capture.", list_option_supplied);
+ exit(1);
+ }
+
+ if (list_option_supplied) {
+ /* We're supposed to list the link-layer types for an interface;
+ did the user also specify a capture file to be read? */
+ if (global_commandline_info.cf_name) {
+ /* Yes - that's bogus. */
+ cmdarg_err("You can't specify %s and a capture file to be read.", list_option_supplied);
+ exit(1);
+ }
+ /* No - did they specify a ring buffer option? */
+ if (global_capture_opts.multi_files_on) {
+ cmdarg_err("Ring buffer requested, but a capture isn't being done.");
+ exit(1);
+ }
+ } else {
+ /* We're supposed to do a live capture; did the user also specify
+ a capture file to be read? */
+ if (global_commandline_info.start_capture && global_commandline_info.cf_name) {
+ /* Yes - that's bogus. */
+ cmdarg_err("You can't specify both a live capture and a capture file to be read.");
+ exit(1);
+ }
+
+ /* No - was the ring buffer option specified and, if so, does it make
+ sense? */
+ if (global_capture_opts.multi_files_on) {
+ /* Ring buffer works only under certain conditions:
+ a) ring buffer does not work with temporary files;
+ b) real_time_mode and multi_files_on are mutually exclusive -
+ real_time_mode takes precedence;
+ c) it makes no sense to enable the ring buffer if the maximum
+ file size is set to "infinite". */
+ if (global_capture_opts.save_file == NULL) {
+ cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
+ global_capture_opts.multi_files_on = FALSE;
+ }
+ if (!global_capture_opts.has_autostop_filesize &&
+ !global_capture_opts.has_file_duration &&
+ !global_capture_opts.has_file_interval) {
+ cmdarg_err("Ring buffer requested, but no maximum capture file size, duration or interval were specified.");
+ /* XXX - this must be redesigned as the conditions changed */
+ }
+ }
+ }
+#endif
}
/*