HTTPS is now needed to download the pkg-config source.
[metze/wireshark/wip.git] / rawshark.c
index c36f156b0c304af6dcb90d974482d5b1acac0dbf..523313c7c5ab2869eb97eea7411e3c626ba056a2 100644 (file)
@@ -1,6 +1,4 @@
 /* rawshark.c
- *
- * $Id$
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * - Prints a status line, followed by fields from a specified list.
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <ctype.h>
 #include <locale.h>
 #include <limits.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
 #endif
 
 #include <errno.h>
 
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#include <signal.h>
-
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-
-#ifndef HAVE_GETOPT
+#ifndef HAVE_GETOPT_LONG
 #include "wsutil/wsgetopt.h"
 #endif
 
 #include <glib.h>
 #include <epan/epan-int.h>
 #include <epan/epan.h>
-#include <epan/filesystem.h>
+
+#include <wsutil/cmdarg_err.h>
 #include <wsutil/crash_info.h>
-#include <wsutil/privileges.h>
+#include <wsutil/filesystem.h>
 #include <wsutil/file_util.h>
+#include <wsutil/plugins.h>
+#include <wsutil/privileges.h>
+#include <wsutil/report_err.h>
+#include <wsutil/ws_diag_control.h>
 
 #include "globals.h"
 #include <epan/packet.h>
+#include <epan/ftypes/ftypes-int.h>
 #include "file.h"
 #include "frame_tvbuff.h"
 #include <epan/disabled_protos.h>
 #include <epan/column.h>
 #include <epan/print.h>
 #include <epan/addr_resolv.h>
+#ifdef HAVE_LIBPCAP
+#include "ui/capture_ui_utils.h"
+#endif
 #include "ui/util.h"
-#include "clopts_common.h"
-#include "cmdarg_err.h"
-#include "version_info.h"
-#include <epan/plugins.h>
 #include "register.h"
 #include "conditions.h"
 #include "capture_stop_conditions.h"
-#include "capture_ui_utils.h"
 #include <epan/epan_dissect.h>
-#include <epan/stat_cmd_args.h>
+#include <epan/stat_tap_ui.h>
 #include <epan/timestamp.h>
 #include <wsutil/unicode-utils.h>
 #include "epan/column-utils.h"
 #include <wiretap/libpcap.h>
 #include <wiretap/pcap-encap.h>
 
+#include <wsutil/clopts_common.h>
+#include <wsutil/ws_version_info.h>
+
+#include "caputils/capture-pcap-util.h"
+
 #ifdef HAVE_LIBPCAP
 #include <setjmp.h>
-#include "capture-pcap-util.h"
 #ifdef _WIN32
-#include "capture-wpcap.h"
+#include "caputils/capture-wpcap.h"
 #endif /* _WIN32 */
 #endif /* HAVE_LIBPCAP */
 #include "log.h"
 
-#ifdef _WIN32
-#include <wsutil/unicode-utils.h>
-#endif /* _WIN32 */
-
+#if 0
 /*
  * This is the template for the decode as option; it is shared between the
  * various functions that output the usage for this parameter.
  */
 static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_as_protocol>";
+#endif
 
 static guint32 cum_bytes;
 static const frame_data *ref;
@@ -143,8 +136,8 @@ static print_format_e print_format = PR_FMT_TEXT;
 static gboolean want_pcap_pkthdr;
 
 cf_status_t raw_cf_open(capture_file *cf, const char *fname);
-static int load_cap_file(capture_file *cf);
-static gboolean process_packet(capture_file *cf, gint64 offset,
+static gboolean load_cap_file(capture_file *cf);
+static gboolean process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
                                struct wtap_pkthdr *whdr, const guchar *pd);
 static void show_print_file_io_error(int err);
 
@@ -153,6 +146,8 @@ static void open_failure_message(const char *filename, int err,
 static void failure_message(const char *msg_format, va_list ap);
 static void read_failure_message(const char *filename, int err);
 static void write_failure_message(const char *filename, int err);
+static void rawshark_cmdarg_err(const char *fmt, va_list ap);
+static void rawshark_cmdarg_err_cont(const char *fmt, va_list ap);
 static void protocolinfo_init(char *field);
 static gboolean parse_field_string_format(char *format);
 
@@ -179,22 +174,8 @@ int encap;
 GPtrArray *string_fmts;
 
 static void
-print_usage(gboolean print_ver)
+print_usage(FILE *output)
 {
-    FILE *output;
-
-    if (print_ver) {
-        output = stdout;
-        fprintf(output,
-                "Rawshark " VERSION "%s\n"
-                "Dump and analyze network traffic.\n"
-                "See http://www.wireshark.org for more information.\n"
-                "\n"
-                "%s",
-                wireshark_svnversion, get_copyright_info());
-    } else {
-        output = stderr;
-    }
     fprintf(output, "\n");
     fprintf(output, "Usage: rawshark [options] ...\n");
     fprintf(output, "\n");
@@ -208,7 +189,7 @@ print_usage(gboolean print_ver)
     fprintf(output, "                           packet encapsulation or protocol\n");
     fprintf(output, "  -F <field>               field to display\n");
     fprintf(output, "  -n                       disable all name resolution (def: all enabled)\n");
-    fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
+    fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtCd\"\n");
     fprintf(output, "  -p                       use the system's packet header format\n");
     fprintf(output, "                           (which may have 64-bit timestamps)\n");
     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
@@ -326,7 +307,7 @@ raw_pipe_open(const char *pipe_name)
             if (err != ERROR_PIPE_BUSY) {
                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
                               NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
-                fprintf(stderr, "rawshark: \"%s\" could not be opened: %s (error %d)\n",
+                fprintf(stderr, "rawshark: \"%s\" could not be opened: %s (error %lu)\n",
                         pipe_name, utf_16to8(err_str), err);
                 LocalFree(err_str);
                 return -1;
@@ -336,14 +317,14 @@ raw_pipe_open(const char *pipe_name)
                 err = GetLastError();
                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
                               NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
-                fprintf(stderr, "rawshark: \"%s\" could not be waited for: %s (error %d)\n",
+                fprintf(stderr, "rawshark: \"%s\" could not be waited for: %s (error %lu)\n",
                         pipe_name, utf_16to8(err_str), err);
                 LocalFree(err_str);
                 return -1;
             }
         }
 
-        rfd = _open_osfhandle((long) hPipe, _O_RDONLY);
+        rfd = _open_osfhandle((intptr_t) hPipe, _O_RDONLY);
         if (rfd == -1) {
             fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
                     pipe_name, g_strerror(errno));
@@ -421,20 +402,6 @@ set_link_type(const char *lt_arg) {
     return FALSE;
 }
 
-static void
-show_version(GString *comp_info_str, GString *runtime_info_str)
-{
-    printf("Rawshark " VERSION "%s\n"
-           "\n"
-           "%s"
-           "\n"
-           "%s"
-           "\n"
-           "%s",
-           wireshark_svnversion, get_copyright_info(), comp_info_str->str,
-           runtime_info_str->str);
-}
-
 int
 main(int argc, char *argv[])
 {
@@ -454,7 +421,6 @@ main(int argc, char *argv[])
     int                  pf_open_errno, pf_read_errno;
     int                  gdp_open_errno, gdp_read_errno;
     int                  dp_open_errno, dp_read_errno;
-    int                  err;
     gchar               *pipe_name = NULL;
     gchar               *rfilters[64];
     e_prefs             *prefs_p;
@@ -463,26 +429,34 @@ main(int argc, char *argv[])
     GPtrArray           *disp_fields = g_ptr_array_new();
     guint                fc;
     gboolean             skip_pcap_header = FALSE;
+    static const struct option long_options[] = {
+      {"help", no_argument, NULL, 'h'},
+      {"version", no_argument, NULL, 'v'},
+      {0, 0, 0, 0 }
+    };
 
 #define OPTSTRING_INIT "d:F:hlnN:o:pr:R:sS:t:v"
 
     static const char    optstring[] = OPTSTRING_INIT;
 
-    /* Assemble the compile-time version information string */
-    comp_info_str = g_string_new("Compiled ");
-    get_compiled_version_info(comp_info_str, NULL, epan_get_compiled_version_info);
+    /* Set the C-language locale to the native environment. */
+    setlocale(LC_ALL, "");
+
+    cmdarg_err_init(rawshark_cmdarg_err, rawshark_cmdarg_err_cont);
+
+    /* Get the compile-time version information string */
+    comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
 
-    /* Assemble the run-time version information string */
-    runtime_info_str = g_string_new("Running ");
-    get_runtime_version_info(runtime_info_str, NULL);
+    /* Get the run-time version information string */
+    runtime_info_str = get_runtime_version_info(NULL);
 
     /* Add it to the information to be reported on a crash. */
-    ws_add_crash_info("Rawshark " VERSION "%s\n"
+    ws_add_crash_info("Rawshark (Wireshark) %s\n"
            "\n"
            "%s"
            "\n"
            "%s",
-        wireshark_svnversion, comp_info_str->str, runtime_info_str->str);
+        get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
 
 #ifdef _WIN32
     arg_list_utf_16to8(argc, argv);
@@ -516,11 +490,6 @@ main(int argc, char *argv[])
                 init_progfile_dir_error);
     }
 
-    /*
-     * Get credential information for later use.
-     */
-    init_process_policies();
-
     /* nothing more than the standard GLib handler, but without a warning */
     log_flags =
         G_LOG_LEVEL_WARNING |
@@ -535,6 +504,9 @@ main(int argc, char *argv[])
                       (GLogLevelFlags)log_flags,
                       log_func_ignore, NULL /* user_data */);
 
+    init_report_err(failure_message, open_failure_message, read_failure_message,
+                    write_failure_message);
+
     timestamp_set_type(TS_RELATIVE);
     timestamp_set_precision(TS_PREC_AUTO);
     timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
@@ -543,12 +515,9 @@ main(int argc, char *argv[])
        "-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);
-
-    /* Set the C-language locale to the native environment. */
-    setlocale(LC_ALL, "");
+    if (!epan_init(register_all_protocols, register_all_protocol_handoffs,
+                   NULL, NULL))
+        return 2;
 
     prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
                          &pf_open_errno, &pf_read_errno, &pf_path);
@@ -578,6 +547,8 @@ main(int argc, char *argv[])
     /* Read the disabled protocols file. */
     read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
                               &dp_path, &dp_open_errno, &dp_read_errno);
+    read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
+                              &dp_path, &dp_open_errno, &dp_read_errno);
     if (gdp_path != NULL) {
         if (gdp_open_errno != 0) {
             cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
@@ -618,7 +589,7 @@ main(int argc, char *argv[])
 
     /* Now get our args */
     /* XXX - We should probably have an option to dump libpcap link types */
-    while ((opt = getopt(argc, argv, optstring)) != -1) {
+    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
         switch (opt) {
             case 'd':        /* Payload type */
                 if (!set_link_type(optarg)) {
@@ -630,7 +601,11 @@ main(int argc, char *argv[])
                 g_ptr_array_add(disp_fields, g_strdup(optarg));
                 break;
             case 'h':        /* Print help and exit */
-                print_usage(TRUE);
+                printf("Rawshark (Wireshark) %s\n"
+                       "Dump and analyze network traffic.\n"
+                       "See https://www.wireshark.org for more information.\n",
+                       get_ws_vcs_version_info());
+                print_usage(stdout);
                 exit(0);
                 break;
             case 'l':        /* "Line-buffer" standard output */
@@ -649,15 +624,12 @@ main(int argc, char *argv[])
                 line_buffered = TRUE;
                 break;
             case 'n':        /* No name resolution */
-                gbl_resolv_flags.mac_name = FALSE;
-                gbl_resolv_flags.network_name = FALSE;
-                gbl_resolv_flags.transport_name = FALSE;
-                gbl_resolv_flags.concurrent_dns = FALSE;
+                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 'm', 'n', and 't'",
+                    cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
                                badopt);
                     exit(1);
                 }
@@ -710,7 +682,9 @@ main(int argc, char *argv[])
                 else if (strcmp(optarg, "a") == 0)
                     timestamp_set_type(TS_ABSOLUTE);
                 else if (strcmp(optarg, "ad") == 0)
-                    timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
+                    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)
@@ -720,18 +694,28 @@ main(int argc, char *argv[])
                 else if (strcmp(optarg, "u") == 0)
                     timestamp_set_type(TS_UTC);
                 else if (strcmp(optarg, "ud") == 0)
-                    timestamp_set_type(TS_UTC_WITH_DATE);
+                    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 \"r\" for relative, \"a\" for absolute,");
-                    cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
+                    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 'v':        /* Show version and exit */
             {
-                show_version(comp_info_str, runtime_info_str);
+                show_version("Rawshark (Wireshark)", comp_info_str, runtime_info_str);
                 g_string_free(comp_info_str, TRUE);
                 g_string_free(runtime_info_str, TRUE);
                 exit(0);
@@ -739,7 +723,7 @@ main(int argc, char *argv[])
             }
             default:
             case '?':        /* Bad flag - print usage message */
-                print_usage(TRUE);
+                print_usage(stderr);
             exit(1);
             break;
         }
@@ -782,7 +766,7 @@ main(int argc, char *argv[])
     }
 
     if (arg_error) {
-        print_usage(FALSE);
+        print_usage(stderr);
         exit(1);
     }
 
@@ -800,6 +784,7 @@ main(int argc, char *argv[])
     /* disabled protocols as per configuration file */
     if (gdp_path == NULL && dp_path == NULL) {
         set_disabled_protos_list();
+        set_disabled_heur_dissector_list();
     }
 
     /* Build the column format array */
@@ -807,8 +792,11 @@ main(int argc, char *argv[])
 
     if (n_rfilters != 0) {
         for (i = 0; i < n_rfilters; i++) {
-            if (!dfilter_compile(rfilters[i], &rfcodes[n_rfcodes])) {
-                cmdarg_err("%s", dfilter_error_msg);
+            gchar *err_msg;
+
+            if (!dfilter_compile(rfilters[i], &rfcodes[n_rfcodes], &err_msg)) {
+                cmdarg_err("%s", err_msg);
+                g_free(err_msg);
                 epan_free(cfile.epan);
                 epan_cleanup();
                 exit(2);
@@ -840,7 +828,7 @@ main(int argc, char *argv[])
             size_t bytes_left = sizeof(struct pcap_hdr) + sizeof(guint32);
             gchar buf[sizeof(struct pcap_hdr) + sizeof(guint32)];
             while (bytes_left != 0) {
-                ssize_t bytes = read(fd, buf, (int)bytes_left);
+                ssize_t bytes = ws_read(fd, buf, (int)bytes_left);
                 if (bytes <= 0) {
                     cmdarg_err("Not enough bytes for pcap header.");
                     exit(2);
@@ -849,39 +837,8 @@ main(int argc, char *argv[])
             }
         }
 
-        /* Set timestamp precision; there should arguably be a command-line
-           option to let the user set this. */
-#if 0
-        switch(wtap_file_tsprecision(cfile.wth)) {
-            case(WTAP_FILE_TSPREC_SEC):
-                timestamp_set_precision(TS_PREC_AUTO_SEC);
-                break;
-            case(WTAP_FILE_TSPREC_DSEC):
-                timestamp_set_precision(TS_PREC_AUTO_DSEC);
-                break;
-            case(WTAP_FILE_TSPREC_CSEC):
-                timestamp_set_precision(TS_PREC_AUTO_CSEC);
-                break;
-            case(WTAP_FILE_TSPREC_MSEC):
-                timestamp_set_precision(TS_PREC_AUTO_MSEC);
-                break;
-            case(WTAP_FILE_TSPREC_USEC):
-                timestamp_set_precision(TS_PREC_AUTO_USEC);
-                break;
-            case(WTAP_FILE_TSPREC_NSEC):
-                timestamp_set_precision(TS_PREC_AUTO_NSEC);
-                break;
-            default:
-                g_assert_not_reached();
-        }
-#else
-        timestamp_set_precision(TS_PREC_AUTO_USEC);
-#endif
-
         /* Process the packets in the file */
-        err = load_cap_file(&cfile);
-
-        if (err != 0) {
+        if (!load_cap_file(&cfile)) {
             epan_free(cfile.epan);
             epan_cleanup();
             exit(2);
@@ -910,13 +867,12 @@ main(int argc, char *argv[])
  * @return TRUE on success, FALSE on failure.
  */
 static gboolean
-raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err_info, gint64 *data_offset) {
+raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, gchar **err_info, gint64 *data_offset) {
     struct pcap_pkthdr mem_hdr;
     struct pcaprec_hdr disk_hdr;
     ssize_t bytes_read = 0;
     size_t bytes_needed = sizeof(disk_hdr);
     guchar *ptr = (guchar*) &disk_hdr;
-    static gchar err_str[100];
 
     if (want_pcap_pkthdr) {
         bytes_needed = sizeof(mem_hdr);
@@ -925,13 +881,14 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err
 
     /* Copied from capture_loop.c */
     while (bytes_needed > 0) {
-        bytes_read = read(fd, ptr, (int)bytes_needed);
+        bytes_read = ws_read(fd, ptr, (int)bytes_needed);
         if (bytes_read == 0) {
             *err = 0;
+            *err_info = NULL;
             return FALSE;
         } else if (bytes_read < 0) {
-            *err = WTAP_ERR_CANT_READ;
-            *err_info = "Error reading header from pipe";
+            *err = errno;
+            *err_info = NULL;
             return FALSE;
         }
         bytes_needed -= bytes_read;
@@ -963,22 +920,21 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err
 #endif
     if (bytes_needed > WTAP_MAX_PACKET_SIZE) {
         *err = WTAP_ERR_BAD_FILE;
-        g_snprintf(err_str, 100, "Bad packet length: %lu\n",
+        *err_info = g_strdup_printf("Bad packet length: %lu\n",
                    (unsigned long) bytes_needed);
-        *err_info = err_str;
         return FALSE;
     }
 
     ptr = pd;
     while (bytes_needed > 0) {
-        bytes_read = read(fd, ptr, (int)bytes_needed);
+        bytes_read = ws_read(fd, ptr, (int)bytes_needed);
         if (bytes_read == 0) {
             *err = WTAP_ERR_SHORT_READ;
-            *err_info = "Got zero bytes reading data from pipe";
+            *err_info = NULL;
             return FALSE;
         } else if (bytes_read < 0) {
-            *err = WTAP_ERR_CANT_READ;
-            *err_info = "Error reading data from pipe";
+            *err = errno;
+            *err_info = NULL;
             return FALSE;
         }
         bytes_needed -= bytes_read;
@@ -988,33 +944,38 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err
     return TRUE;
 }
 
-static int
+static gboolean
 load_cap_file(capture_file *cf)
 {
     int          err;
-    const gchar  *err_info;
+    gchar       *err_info;
     gint64       data_offset = 0;
-    struct wtap_pkthdr  phdr;
-    guchar       pd[WTAP_MAX_PACKET_SIZE];
 
-    memset(&phdr, 0, sizeof(phdr));
+    guchar pd[WTAP_MAX_PACKET_SIZE];
+    struct wtap_pkthdr phdr;
+    epan_dissect_t edt;
+
+    wtap_phdr_init(&phdr);
+
+    epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
 
     while (raw_pipe_read(&phdr, pd, &err, &err_info, &data_offset)) {
-        process_packet(cf, data_offset, &phdr, pd);
+        process_packet(cf, &edt, data_offset, &phdr, pd);
     }
 
+    epan_dissect_cleanup(&edt);
+
+    wtap_phdr_cleanup(&phdr);
+
     if (err != 0) {
         /* Print a message noting that the read failed somewhere along the line. */
         switch (err) {
 
-            case WTAP_ERR_UNSUPPORTED_ENCAP:
-                cmdarg_err("The file \"%s\" has a packet with a network type that Rawshark doesn't support.\n(%s)",
-                           cf->filename, err_info);
-                break;
-
-            case WTAP_ERR_CANT_READ:
-                cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
-                           cf->filename);
+            case WTAP_ERR_UNSUPPORTED:
+                cmdarg_err("The file \"%s\" contains record data that Rawshark doesn't support.\n(%s)",
+                           cf->filename,
+                           err_info != NULL ? err_info : "no information supplied");
+                g_free(err_info);
                 break;
 
             case WTAP_ERR_SHORT_READ:
@@ -1024,12 +985,16 @@ load_cap_file(capture_file *cf)
 
             case WTAP_ERR_BAD_FILE:
                 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
-                           cf->filename, err_info);
+                           cf->filename,
+                           err_info != NULL ? err_info : "no information supplied");
+                g_free(err_info);
                 break;
 
             case WTAP_ERR_DECOMPRESS:
                 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n(%s)",
-                           cf->filename, err_info);
+                           cf->filename,
+                           err_info != NULL ? err_info : "no information supplied");
+                g_free(err_info);
                 break;
 
             default:
@@ -1037,18 +1002,17 @@ load_cap_file(capture_file *cf)
                            cf->filename, wtap_strerror(err));
                 break;
         }
+        return FALSE;
     }
 
-    return err;
+    return TRUE;
 }
 
 static gboolean
-process_packet(capture_file *cf, gint64 offset, struct wtap_pkthdr *whdr,
-               const guchar *pd)
+process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
+               struct wtap_pkthdr *whdr, const guchar *pd)
 {
     frame_data fdata;
-    gboolean create_proto_tree;
-    epan_dissect_t edt;
     gboolean passed;
     int i;
 
@@ -1075,18 +1039,12 @@ process_packet(capture_file *cf, gint64 offset, struct wtap_pkthdr *whdr,
     frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
 
     passed = TRUE;
-    create_proto_tree = TRUE;
-
-    /* The protocol tree will be "visible", i.e., printed, only if we're
-       printing packet details, which is true if we're in verbose mode ("verbose"
-       is true). */
-    epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
 
     /* If we're running a read filter, prime the epan_dissect_t with that
        filter. */
     if (n_rfilters > 0) {
         for(i = 0; i < n_rfcodes; i++) {
-            epan_dissect_prime_dfilter(&edt, rfcodes[i]);
+            epan_dissect_prime_dfilter(edt, rfcodes[i]);
         }
     }
 
@@ -1103,7 +1061,7 @@ process_packet(capture_file *cf, gint64 offset, struct wtap_pkthdr *whdr,
     /* We only need the columns if we're printing packet info but we're
      *not* verbose; in verbose mode, we print the protocol tree, not
      the protocol summary. */
-    epan_dissect_run_with_taps(&edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, &cf->cinfo);
+    epan_dissect_run_with_taps(edt, cf->cd_t, whdr, frame_tvbuff_new(&fdata, pd), &fdata, &cf->cinfo);
 
     frame_data_set_after_dissect(&fdata, &cum_bytes);
     prev_dis_frame = fdata;
@@ -1115,7 +1073,7 @@ process_packet(capture_file *cf, gint64 offset, struct wtap_pkthdr *whdr,
     for(i = 0; i < n_rfilters; i++) {
         /* Run the read filter if we have one. */
         if (rfcodes[i])
-            passed = dfilter_apply_edt(rfcodes[i], &edt);
+            passed = dfilter_apply_edt(rfcodes[i], edt);
         else
             passed = TRUE;
 
@@ -1153,7 +1111,7 @@ process_packet(capture_file *cf, gint64 offset, struct wtap_pkthdr *whdr,
         exit(2);
     }
 
-    epan_dissect_cleanup(&edt);
+    epan_dissect_reset(edt);
     frame_data_destroy(&fdata);
 
     return passed;
@@ -1241,6 +1199,10 @@ static const char* ftenum_to_string(header_field_info *hfi)
             return "FT_OID";
         case FT_REL_OID:
             return "FT_REL_OID";
+        case FT_SYSTEM_ID:
+            return "FT_SYSTEM_ID";
+        case FT_STRINGZPAD:
+            return "FT_STRIGZPAD";
         case FT_NUM_TYPES:
             return "FT_NUM_TYPES";
         default:
@@ -1260,7 +1222,7 @@ static const char* absolute_time_display_e_to_string(absolute_time_display_e atd
     }
 }
 
-static const char* base_display_e_to_string(base_display_e bd)
+static const char* field_display_e_to_string(field_display_e bd)
 {
     switch(bd) {
         case BASE_NONE:
@@ -1317,18 +1279,18 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
          * this field has an associated value,
          * e.g: ip.hdr_len
          */
-        fs_len = fvalue_string_repr_len(&finfo->value, FTREPR_DFILTER);
+        fs_len = fvalue_string_repr_len(&finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
         while (fs_buf_len < fs_len) {
             fs_buf_len *= 2;
             fs_buf = (char *)g_realloc(fs_buf, fs_buf_len + 1);
             fs_ptr = fs_buf;
         }
         fvalue_to_string_repr(&finfo->value,
-                              FTREPR_DFILTER,
+                              FTREPR_DFILTER, finfo->hfinfo->display,
                               fs_buf);
 
         /* String types are quoted. Remove them. */
-        if ((finfo->value.ftype->ftype == FT_STRING || finfo->value.ftype->ftype == FT_STRINGZ) && fs_len > 2) {
+        if (IS_FT_STRING(finfo->value.ftype->ftype) && fs_len > 2) {
             fs_buf[fs_len - 1] = '\0';
             fs_ptr++;
         }
@@ -1364,14 +1326,17 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
                                 if (hfinfo->display & BASE_RANGE_STRING) {
                                     g_string_append(label_s, rval_to_str_const(svalue, RVALS(hfinfo->strings), "Unknown"));
                                 } else if (hfinfo->display & BASE_EXT_STRING) {
-                                    g_string_append(label_s, val_to_str_ext_const(svalue, (const value_string_ext *) hfinfo->strings, "Unknown"));
+                                    g_string_append(label_s, val_to_str_ext_const(svalue, (value_string_ext *) hfinfo->strings, "Unknown"));
                                 } else {
                                     g_string_append(label_s, val_to_str_const(svalue, cVALS(hfinfo->strings), "Unknown"));
                                 }
                                 break;
+                            case FT_INT40: /* XXX: Shouldn't these be as smart as FT_INT{8,16,24,32}? */
+                            case FT_INT48:
+                            case FT_INT56:
                             case FT_INT64:
                                 DISSECTOR_ASSERT(!hfinfo->bitmask);
-                                svalue64 = (gint64)fvalue_get_integer64(&finfo->value);
+                                svalue64 = (gint64)fvalue_get_sinteger64(&finfo->value);
                                 if (hfinfo->display & BASE_VAL64_STRING) {
                                     g_string_append(label_s, val64_to_str_const(svalue64, (const val64_string *)(hfinfo->strings), "Unknown"));
                                 }
@@ -1380,18 +1345,22 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
                             case FT_UINT16:
                             case FT_UINT24:
                             case FT_UINT32:
+                                DISSECTOR_ASSERT(!hfinfo->bitmask);
                                 uvalue = fvalue_get_uinteger(&finfo->value);
                                 if (!hfinfo->bitmask && hfinfo->display & BASE_RANGE_STRING) {
                                     g_string_append(label_s, rval_to_str_const(uvalue, RVALS(hfinfo->strings), "Unknown"));
                                 } else if (hfinfo->display & BASE_EXT_STRING) {
-                                    g_string_append(label_s, val_to_str_ext_const(uvalue, (const value_string_ext *) hfinfo->strings, "Unknown"));
+                                    g_string_append(label_s, val_to_str_ext_const(uvalue, (value_string_ext *) hfinfo->strings, "Unknown"));
                                 } else {
                                     g_string_append(label_s, val_to_str_const(uvalue, cVALS(hfinfo->strings), "Unknown"));
                                 }
                                 break;
+                            case FT_UINT40: /* XXX: Shouldn't these be as smart as FT_INT{8,16,24,32}? */
+                            case FT_UINT48:
+                            case FT_UINT56:
                             case FT_UINT64:
                                 DISSECTOR_ASSERT(!hfinfo->bitmask);
-                                uvalue64 = fvalue_get_integer64(&finfo->value);
+                                uvalue64 = fvalue_get_uinteger64(&finfo->value);
                                 if (hfinfo->display & BASE_VAL64_STRING) {
                                     g_string_append(label_s, val64_to_str_const(uvalue64, (const val64_string *)(hfinfo->strings), "Unknown"));
                                 }
@@ -1405,13 +1374,13 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
                 }
             }
         }
-        printf(" %u=\"%s\"", cmd_line_index, label_s->str);
+        printf(" %d=\"%s\"", cmd_line_index, label_s->str);
         return TRUE;
     }
 
     if(finfo->value.ftype->val_to_string_repr)
     {
-        printf(" %u=\"%s\"", cmd_line_index, fs_ptr);
+        printf(" %d=\"%s\"", cmd_line_index, fs_ptr);
         return TRUE;
     }
 
@@ -1420,7 +1389,7 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
      * e.g. http
      * We return n.a.
      */
-    printf(" %u=\"n.a.\"", cmd_line_index);
+    printf(" %d=\"n.a.\"", cmd_line_index);
     return TRUE;
 }
 
@@ -1468,17 +1437,17 @@ protocolinfo_init(char *field)
     switch (hfi->type) {
 
         case FT_ABSOLUTE_TIME:
-            printf("%u %s %s - ",
+            printf("%d %s %s - ",
                    g_cmd_line_index,
                    ftenum_to_string(hfi),
                    absolute_time_display_e_to_string((absolute_time_display_e)hfi->display));
             break;
 
         default:
-            printf("%u %s %s - ",
+            printf("%d %s %s - ",
                    g_cmd_line_index,
                    ftenum_to_string(hfi),
-                   base_display_e_to_string((base_display_e)hfi->display));
+                   field_display_e_to_string((field_display_e)hfi->display));
             break;
     }
 
@@ -1662,7 +1631,8 @@ raw_cf_open(capture_file *cf, const char *fname)
     /* No user changes yet. */
     cf->unsaved_changes = FALSE;
 
-    cf->cd_t      = WTAP_FILE_UNKNOWN;
+    cf->cd_t      = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
+    cf->open_type = WTAP_TYPE_AUTO;
     cf->count     = 0;
     cf->drops_known = FALSE;
     cf->drops     = 0;
@@ -1711,33 +1681,24 @@ write_failure_message(const char *filename, int err)
 /*
  * Report an error in command-line arguments.
  */
-void
-cmdarg_err(const char *fmt, ...)
+static void
+rawshark_cmdarg_err(const char *fmt, va_list ap)
 {
-    va_list ap;
-
-    va_start(ap, fmt);
     fprintf(stderr, "rawshark: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    va_end(ap);
 }
 
 /*
  * Report additional information for an error in command-line arguments.
  */
-void
-cmdarg_err_cont(const char *fmt, ...)
+static void
+rawshark_cmdarg_err_cont(const char *fmt, va_list ap)
 {
-    va_list ap;
-
-    va_start(ap, fmt);
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    va_end(ap);
 }
 
-
 /*
  * Editor modelines
  *