packet-smb: register a dissector on top of smb_direct
[metze/wireshark/wip.git] / tshark.c
index db098fa99470edd15fa01b2ec690dec70074fd9a..d41818caa90d03eb47327846ef0c319c5c7e8482 100644 (file)
--- a/tshark.c
+++ b/tshark.c
 #endif
 
 #include <glib.h>
+
+#include <epan/exceptions.h>
 #include <epan/epan-int.h>
 #include <epan/epan.h>
-#include <epan/filesystem.h>
 #include <wsutil/crash_info.h>
 #include <wsutil/privileges.h>
 #include <wsutil/file_util.h>
+#include <wsutil/filesystem.h>
+#include <wsutil/report_err.h>
 
 #include "globals.h"
 #include <epan/timestamp.h>
 #include <epan/packet.h>
+#ifdef HAVE_LUA
+#include <epan/wslua/init_wslua.h>
+#endif
 #include "file.h"
 #include "frame_tvbuff.h"
 #include <epan/disabled_protos.h>
 #include <epan/print.h>
 #include <epan/addr_resolv.h>
 #include "ui/util.h"
+#include "ui/ui_util.h"
 #include "clopts_common.h"
 #include "cmdarg_err.h"
 #include "version_info.h"
-#include <epan/plugins.h>
 #include "register.h"
 #include <epan/epan_dissect.h>
 #include <epan/tap.h>
 #include "log.h"
 #include <epan/funnel.h>
 
+#ifdef HAVE_PLUGINS
+#include <wsutil/plugins.h>
+#endif
+
 /*
  * This is the template for the decode as option; it is shared between the
  * various functions that output the usage for this parameter.
@@ -221,13 +231,13 @@ list_capture_types(void) {
   struct string_elem *captypes;
   GSList             *list = NULL;
 
-  captypes = g_new(struct string_elem, WTAP_NUM_FILE_TYPES);
+  captypes = g_new(struct string_elem, WTAP_NUM_FILE_TYPES_SUBTYPES);
 
   fprintf(stderr, "tshark: The available capture file types for the \"-F\" flag are:\n");
-  for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
+  for (i = 0; i < WTAP_NUM_FILE_TYPES_SUBTYPES; i++) {
     if (wtap_dump_can_open(i)) {
-      captypes[i].sstr = wtap_file_type_short_string(i);
-      captypes[i].lstr = wtap_file_type_string(i);
+      captypes[i].sstr = wtap_file_type_subtype_short_string(i);
+      captypes[i].lstr = wtap_file_type_subtype_string(i);
       list = g_slist_insert_sorted(list, &captypes[i], string_compare);
     }
   }
@@ -296,7 +306,8 @@ print_usage(gboolean print_ver)
   fprintf(output, "Processing:\n");
   fprintf(output, "  -2                       perform a two-pass analysis\n");
   fprintf(output, "  -R <read filter>         packet Read filter in Wireshark display filter syntax\n");
-  fprintf(output, "  -Y <display filter>      packet displaY filter in Wireshark display filter syntax\n");
+  fprintf(output, "  -Y <display filter>      packet displaY filter in Wireshark display filter\n");
+  fprintf(output, "                           syntax\n");
   fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
   fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
   fprintf(output, "  -d %s ...\n", decode_as_arg_template);
@@ -320,7 +331,8 @@ print_usage(gboolean print_ver)
   fprintf(output, "  -x                       add output of hex and ASCII dump (Packet Bytes)\n");
   fprintf(output, "  -T pdml|ps|psml|text|fields\n");
   fprintf(output, "                           format of text output (def: text)\n");
-  fprintf(output, "  -e <field>               field to print if -Tfields selected (e.g. tcp.port, _ws.col.Info);\n");
+  fprintf(output, "  -e <field>               field to print if -Tfields selected (e.g. tcp.port,\n");
+  fprintf(output, "                           _ws.col.Info)\n");
   fprintf(output, "                           this option can be repeated to print multiple fields\n");
   fprintf(output, "  -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
   fprintf(output, "     header=y|n            switch headers on and off\n");
@@ -915,9 +927,9 @@ main(int argc, char *argv[])
 #endif
   gboolean             quiet = FALSE;
 #ifdef PCAP_NG_DEFAULT
-  volatile int         out_file_type = WTAP_FILE_PCAPNG;
+  volatile int         out_file_type = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
 #else
-  volatile int         out_file_type = WTAP_FILE_PCAP;
+  volatile int         out_file_type = WTAP_FILE_TYPE_SUBTYPE_PCAP;
 #endif
   volatile gboolean    out_file_name_res = FALSE;
   gchar               *volatile cf_name = NULL;
@@ -1086,6 +1098,9 @@ main(int argc, char *argv[])
 
   initialize_funnel_ops();
 
+  init_report_err(failure_message, open_failure_message, read_failure_message,
+                  write_failure_message);
+
 #ifdef HAVE_LIBPCAP
   capture_opts_init(&global_capture_opts);
   capture_session_init(&global_capture_session, (void *)&cfile);
@@ -1095,13 +1110,24 @@ main(int argc, char *argv[])
   timestamp_set_precision(TS_PREC_AUTO);
   timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
 
+#ifdef HAVE_PLUGINS
+  /* Register all the plugin types we have. */
+  epan_register_plugin_types(); /* Types known to libwireshark */
+  wtap_register_plugin_types(); /* Types known to libwiretap */
+
+  /* Scan for plugins.  This does *not* call their registration routines;
+     that's done later. */
+  scan_plugins();
+
+  /* Register all libwiretap plugin modules. */
+  register_all_wiretap_modules();
+#endif
+
   /* Register all dissectors; we must do this before checking for the
      "-G" flag, as the "-G" flag dumps information registered by the
      dissectors, and we must do it before we read the preferences, in
      case any dissectors register preferences. */
-  epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL,
-            failure_message, open_failure_message, read_failure_message,
-            write_failure_message);
+  epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL);
 
   /* Register all tap listeners; we do this before we parse the arguments,
      as the "-z" argument can specify a registered tap. */
@@ -1145,8 +1171,14 @@ main(int argc, char *argv[])
         proto_registrar_dump_ftypes();
       else if (strcmp(argv[2], "heuristic-decodes") == 0)
         dissector_dump_heur_decodes();
-      else if (strcmp(argv[2], "plugins") == 0)
+      else if (strcmp(argv[2], "plugins") == 0) {
+#ifdef HAVE_PLUGINS
         plugins_dump_all();
+#endif
+#ifdef HAVE_LUA
+        wslua_plugins_dump_all();
+#endif
+      }
       else if (strcmp(argv[2], "protocols") == 0)
         proto_registrar_dump_protocols();
       else if (strcmp(argv[2], "values") == 0)
@@ -1314,7 +1346,7 @@ main(int argc, char *argv[])
       }
       break;
     case 'F':
-      out_file_type = wtap_short_string_to_file_type(optarg);
+      out_file_type = wtap_short_string_to_file_type_subtype(optarg);
       if (out_file_type < 0) {
         cmdarg_err("\"%s\" isn't a valid capture file type", optarg);
         list_capture_types();
@@ -1326,7 +1358,8 @@ main(int argc, char *argv[])
       if (strchr(optarg, 'n')) {
         out_file_name_res = TRUE;
       } else {
-        cmdarg_err("Invalid -W argument \"%s\"", optarg);
+        cmdarg_err("Invalid -W argument \"%s\"; it must be one of:", optarg);
+        cmdarg_err_cont("\t'n' write network address resolution information (pcapng only)");
         return 1;
       }
       break;
@@ -1375,9 +1408,14 @@ main(int argc, char *argv[])
     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';",
+        cmdarg_err("-N specifies unknown resolving option '%c'; valid options are:",
                    badopt);
-        cmdarg_err_cont( "           Valid options are 'm', 'n', 't', and 'C'");
+        cmdarg_err_cont("\t'C' to enable concurrent (asynchronous) DNS lookups\n"
+                        "\t'm' to enable MAC address resolution\n"
+                        "\t'n' to enable network address resolution\n"
+                        "\t'N' to enable using external resolvers (e.g., DNS)\n"
+                        "\t    for network address resolution\n"
+                        "\t't' to enable transport-layer port number resolution");
         return 1;
       }
       break;
@@ -1440,17 +1478,17 @@ main(int argc, char *argv[])
       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.");
+        cmdarg_err("Invalid time stamp type \"%s\"; it must be one of:", optarg);
+        cmdarg_err_cont("\t\"a\"    for absolute\n"
+                        "\t\"ad\"   for absolute with YYYY-MM-DD date\n"
+                        "\t\"adoy\" for absolute with YYYY/DOY date\n"
+                        "\t\"d\"    for delta\n"
+                        "\t\"dd\"   for delta displayed\n"
+                        "\t\"e\"    for epoch\n"
+                        "\t\"r\"    for relative\n"
+                        "\t\"u\"    for absolute UTC\n"
+                        "\t\"ud\"   for absolute UTC with YYYY-MM-DD date\n"
+                        "\t\"udoy\" for absolute UTC with YYYY/DOY date");
         return 1;
       }
       break;
@@ -1474,8 +1512,23 @@ main(int argc, char *argv[])
         print_details = TRUE;   /* Need full tree info */
         print_summary = FALSE;  /* Don't allow summary */
       } else {
-        cmdarg_err("Invalid -T parameter.");
-        cmdarg_err_cont("It must be \"ps\", \"text\", \"pdml\", \"psml\" or \"fields\".");
+        cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg);                   /* x */
+        cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
+                        "\t         specified by the -E option.\n"
+                        "\t\"pdml\"   Packet Details Markup Language, an XML-based format for the\n"
+                        "\t         details of a decoded packet. This information is equivalent to\n"
+                        "\t         the packet details printed with the -V flag.\n"
+                        "\t\"ps\"     PostScript for a human-readable one-line summary of each of\n"
+                        "\t         the packets, or a multi-line view of the details of each of\n"
+                        "\t         the packets, depending on whether the -V flag was specified.\n"
+                        "\t\"psml\"   Packet Summary Markup Language, an XML-based format for the\n"
+                        "\t         summary information of a decoded packet. This information is\n"
+                        "\t         equivalent to the information shown in the one-line summary\n"
+                        "\t         printed by default.\n"
+                        "\t\"text\"   Text of a human-readable one-line summary of each of the\n"
+                        "\t         packets, or a multi-line view of the details of each of the\n"
+                        "\t         packets, depending on whether the -V flag was specified.\n"
+                        "\t         This is the default.");
         return 1;
       }
       break;
@@ -1485,8 +1538,9 @@ main(int argc, char *argv[])
       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.");
+        cmdarg_err("Invalid seconds type \"%s\"; it must be one of:", optarg);
+        cmdarg_err_cont("\t\"s\"   for seconds\n"
+                        "\t\"hms\" for hours, minutes and seconds");
         return 1;
       }
       break;
@@ -1529,8 +1583,7 @@ main(int argc, char *argv[])
           list_stat_cmd_args();
           return 0;
         }
-        cmdarg_err("Invalid -z argument \"%s\".", optarg);
-        cmdarg_err_cont("  -z argument must be one of :");
+        cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
         list_stat_cmd_args();
         return 1;
       }
@@ -1731,15 +1784,25 @@ main(int argc, char *argv[])
       /*
        * "-r" wasn't specified, so we're doing a live capture.
        */
+      if (perform_two_pass_analysis) {
+        /* Two-pass analysis doesn't work with live capture since it requires us
+         * to buffer packets until we've read all of them, but a live capture
+         * has no useful/meaningful definition of "all" */
+        cmdarg_err("Live captures do not support two-pass analysis.");
+        return 1;
+      }
+
       if (global_capture_opts.saving_to_file) {
         /* They specified a "-w" flag, so we'll be saving to a capture file. */
 
         /* When capturing, we only support writing pcap or pcap-ng format. */
-        if (out_file_type != WTAP_FILE_PCAP && out_file_type != WTAP_FILE_PCAPNG) {
+        if (out_file_type != WTAP_FILE_TYPE_SUBTYPE_PCAP &&
+            out_file_type != WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
           cmdarg_err("Live captures can only be saved in libpcap format.");
           return 1;
         }
-        if (global_capture_opts.capture_comment && out_file_type != WTAP_FILE_PCAPNG) {
+        if (global_capture_opts.capture_comment &&
+            out_file_type != WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
           cmdarg_err("A capture comment can only be written to a pcapng file.");
           return 1;
         }
@@ -1855,8 +1918,7 @@ main(int argc, char *argv[])
         if (pc != NULL) {
           if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
             cmdarg_err_cont(
-              "  Note: That read filter code looks like a valid capture filter;");
-            cmdarg_err_cont(
+              "  Note: That read filter code looks like a valid capture filter;\n"
               "        maybe you mixed them up?");
           }
           pcap_close(pc);
@@ -1880,8 +1942,7 @@ main(int argc, char *argv[])
         if (pc != NULL) {
           if (pcap_compile(pc, &fcode, dfilter, 0, 0) != -1) {
             cmdarg_err_cont(
-              "  Note: That display filter code looks like a valid capture filter;");
-            cmdarg_err_cont(
+              "  Note: That display filter code looks like a valid capture filter;\n"
               "        maybe you mixed them up?");
           }
           pcap_close(pc);
@@ -2126,10 +2187,6 @@ main(int argc, char *argv[])
   guint32 packet_count = 0;
 
 
-/* XXX - move to the right position / file */
-/* read from a pipe (callback) */
-typedef gboolean (*pipe_input_cb_t) (gint source, gpointer user_data);
-
 typedef struct pipe_input_tag {
   gint             source;
   gpointer         user_data;
@@ -2474,7 +2531,7 @@ capture_input_cfilter_error_message(capture_session *cap_session, guint i, char
 
   if (dfilter_compile(interface_opts.cfilter, &rfcode) && rfcode != NULL) {
     cmdarg_err(
-      "Invalid capture filter \"%s\" for interface %s!\n"
+      "Invalid capture filter \"%s\" for interface '%s'!\n"
       "\n"
       "That string looks like a valid display filter; however, it isn't a valid\n"
       "capture filter (%s).\n"
@@ -2487,7 +2544,7 @@ capture_input_cfilter_error_message(capture_session *cap_session, guint i, char
     dfilter_free(rfcode);
   } else {
     cmdarg_err(
-      "Invalid capture filter \"%s\" for interface %s!\n"
+      "Invalid capture filter \"%s\" for interface '%s'!\n"
       "\n"
       "That string isn't a valid capture filter (%s).\n"
       "See the User's Guide for a description of the capture filter syntax.",
@@ -2997,7 +3054,8 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
         shb_hdr->shb_user_appl = appname;
     }
 
-    if (linktype != WTAP_ENCAP_PER_PACKET && out_file_type == WTAP_FILE_PCAP)
+    if (linktype != WTAP_ENCAP_PER_PACKET &&
+        out_file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP)
         pdh = wtap_dump_open(save_file, out_file_type, linktype,
             snapshot_length, FALSE /* compressed */, &err);
     else
@@ -3018,7 +3076,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
       case WTAP_ERR_UNSUPPORTED_ENCAP:
       case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
         cmdarg_err("The capture file being read can't be written as a "
-          "\"%s\" file.", wtap_file_type_short_string(out_file_type));
+          "\"%s\" file.", wtap_file_type_subtype_short_string(out_file_type));
         break;
 
       case WTAP_ERR_CANT_OPEN:
@@ -3054,7 +3112,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
   if (pdh && out_file_name_res) {
     if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
       cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
-                 wtap_file_type_short_string(out_file_type));
+                 wtap_file_type_subtype_short_string(out_file_type));
     }
   }
 
@@ -3133,7 +3191,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
       fdata = frame_data_sequence_find(cf->frames, framenum);
       if (wtap_seek_read(cf->wth, fdata->file_off, &cf->phdr,
-          &buf, fdata->cap_len, &err, &err_info)) {
+          &buf, &err, &err_info)) {
         if (process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
                                        tap_flags)) {
           /* Either there's no read filtering or this packet passed the
@@ -3146,8 +3204,9 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
 
               case WTAP_ERR_UNSUPPORTED_ENCAP:
                 /*
-                 * This is a problem with the particular frame we're writing;
-                 * note that, and give the frame number.
+                 * This is a problem with the particular frame we're writing
+                 * and the file type and subtype we're writing; note that,
+                 * and report the frame number and file type/subtype.
                  *
                  * XXX - framenum is not necessarily the frame number in
                  * the input file if there was a read filter.
@@ -3155,7 +3214,22 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
                 fprintf(stderr,
                         "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.\n",
                         framenum, cf->filename,
-                        wtap_file_type_short_string(out_file_type));
+                        wtap_file_type_subtype_short_string(out_file_type));
+                break;
+
+              case WTAP_ERR_PACKET_TOO_LARGE:
+                /*
+                 * This is a problem with the particular frame we're writing
+                 * and the file type and subtype we're writing; note that,
+                 * and report the frame number and file type/subtype.
+                 *
+                 * XXX - framenum is not necessarily the frame number in
+                 * the input file if there was a read filter.
+                 */
+                fprintf(stderr,
+                        "Frame %u of \"%s\" is too large for a \"%s\" file.\n",
+                        framenum, cf->filename,
+                        wtap_file_type_subtype_short_string(out_file_type));
                 break;
 
               default:
@@ -3213,13 +3287,26 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
 
             case WTAP_ERR_UNSUPPORTED_ENCAP:
               /*
-               * This is a problem with the particular frame we're writing;
-               * note that, and give the frame number.
+               * This is a problem with the particular frame we're writing
+               * and the file type and subtype we're writing; note that,
+               * and report the frame number and file type/subtype.
                */
               fprintf(stderr,
                       "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.\n",
                       framenum, cf->filename,
-                      wtap_file_type_short_string(out_file_type));
+                      wtap_file_type_subtype_short_string(out_file_type));
+              break;
+
+            case WTAP_ERR_PACKET_TOO_LARGE:
+              /*
+               * This is a problem with the particular frame we're writing
+               * and the file type and subtype we're writing; note that,
+               * and report the frame number and file type/subtype.
+               */
+              fprintf(stderr,
+                      "Frame %u of \"%s\" is too large for a \"%s\" file.\n",
+                      framenum, cf->filename,
+                      wtap_file_type_subtype_short_string(out_file_type));
               break;
 
             default:
@@ -3886,7 +3973,7 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
   /* No user changes yet. */
   cf->unsaved_changes = FALSE;
 
-  cf->cd_t      = wtap_file_type(cf->wth);
+  cf->cd_t      = wtap_file_type_subtype(cf->wth);
   cf->count     = 0;
   cf->drops_known = FALSE;
   cf->drops     = 0;
@@ -4024,7 +4111,7 @@ cf_open_error_message(int err, gchar *err_info, gboolean for_writing,
       /* Seen only when opening a capture file for writing. */
       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
                  "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
-                 "written to a pipe.", wtap_file_type_short_string(file_type));
+                 "written to a pipe.", wtap_file_type_subtype_short_string(file_type));
       errmsg = errmsg_errno;
       break;
 
@@ -4037,7 +4124,7 @@ cf_open_error_message(int err, gchar *err_info, gboolean for_writing,
       if (for_writing) {
         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
                    "TShark can't save this capture as a \"%s\" file.",
-                   wtap_file_type_short_string(file_type));
+                   wtap_file_type_subtype_short_string(file_type));
       } else {
         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
                  "The file \"%%s\" is a capture for a network type that TShark doesn't support.\n"
@@ -4051,7 +4138,7 @@ cf_open_error_message(int err, gchar *err_info, gboolean for_writing,
       if (for_writing) {
         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
                    "TShark can't save this capture as a \"%s\" file.",
-                   wtap_file_type_short_string(file_type));
+                   wtap_file_type_subtype_short_string(file_type));
         errmsg = errmsg_errno;
       } else
         errmsg = "The file \"%s\" is a capture for a network type that TShark doesn't support.";