Rename "ws_version_info.h", also .c
[metze/wireshark/wip.git] / ui / commandline.c
index 7cb8dd3c53209b626da9c8ea9353a6e9aff73c84..2d77761c47885d65931e120ddc3f1a975712564a 100644 (file)
 #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"
 
+commandline_param_info_t global_commandline_info;
+
 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
 capture_options global_capture_opts;
 #endif
@@ -96,7 +93,11 @@ commandline_print_usage(gboolean for_help_option) {
     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");
@@ -108,8 +109,10 @@ commandline_print_usage(gboolean for_help_option) {
     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");
@@ -138,6 +141,8 @@ commandline_print_usage(gboolean for_help_option) {
     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");
@@ -174,20 +179,34 @@ commandline_print_usage(gboolean for_help_option) {
 #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;
@@ -331,20 +350,20 @@ void commandline_early_options(int argc, char *argv[],
 #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,
@@ -379,19 +398,20 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
     }
 
     /* Initialize with default values */
-    param_info->jump_backwards = SD_FORWARD;
-    param_info->go_to_packet = 0;
-    param_info->jfilter = NULL;
-    param_info->cf_name = NULL;
-    param_info->rfilter = NULL;
-    param_info->dfilter = NULL;
+    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
-    param_info->start_capture = FALSE;
-    param_info->list_link_layer_types = FALSE;
+    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
-    param_info->disable_protocol_slist = NULL;
-    param_info->enable_heur_slist = NULL;
-    param_info->disable_heur_slist = NULL;
+    global_commandline_info.full_screen = FALSE;
 
     while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
         switch (opt) {
@@ -404,6 +424,7 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
             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
@@ -419,7 +440,7 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
 #endif
 #ifdef HAVE_LIBPCAP
                 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
-                                              &param_info->start_capture);
+                                              &global_commandline_info.start_capture);
                 if(status != 0) {
                     exit(status);
                 }
@@ -429,28 +450,18 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
 #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
@@ -462,33 +473,33 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
                 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
                 capture_option_specified = TRUE;
                 arg_error = TRUE;
 #endif
                 break;
-            case 'm':        /* Fixed-width font for the display. GTK+ only. */
-                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:
@@ -520,6 +531,7 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
                         g_assert_not_reached();
                 }
                 break;
+            }
             case 'P':
                 /* Path settings were already processed just ignore them this time*/
                 break;
@@ -527,58 +539,16 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
                 /* 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
@@ -598,14 +568,21 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
                     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 */
@@ -618,7 +595,7 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
         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.
@@ -642,7 +619,7 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
                  * 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--;
@@ -669,18 +646,18 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
     }
 
 #ifdef HAVE_LIBPCAP
-    if (param_info->start_capture && param_info->list_link_layer_types) {
+    if (global_commandline_info.start_capture && list_option_supplied) {
         /* Specifying *both* is bogus. */
-        cmdarg_err("You can't specify both -L and a live capture.");
+        cmdarg_err("You can't specify both %s and a live capture.", list_option_supplied);
         exit(1);
     }
 
-    if (param_info->list_link_layer_types) {
+    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 (param_info->cf_name) {
+        if (global_commandline_info.cf_name) {
             /* Yes - that's bogus. */
-            cmdarg_err("You can't specify -L and a capture file to be read.");
+            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? */
@@ -691,7 +668,7 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
     } else {
         /* We're supposed to do a live capture; did the user also specify
            a capture file to be read? */
-        if (param_info->start_capture && param_info->cf_name) {
+        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);
@@ -710,8 +687,10 @@ void commandline_other_options(int argc, char *argv[], commandline_param_info_t*
                 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) {
-                cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
+            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 */
             }
         }