Register a few more file extensions as belonging to Wireshark.
[metze/wireshark/wip.git] / wiretap / file_access.c
index 1255a94f8c5de24bc451fae6b94d853d2588b4b2..f138376428b358d5ffc30e05459dddebdeae85bb 100644 (file)
 
 #include "config.h"
 
-#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #include <errno.h>
 
 #include <wsutil/file_util.h>
+#include <wsutil/tempfile.h>
 
 #include "wtap-int.h"
 #include "file_wrappers.h"
-#include "buffer.h"
+#include <wsutil/buffer.h>
 #include "lanalyzer.h"
 #include "ngsniffer.h"
 #include "radcom.h"
@@ -65,6 +57,8 @@
 #include "erf.h"
 #include "hcidump.h"
 #include "logcat.h"
+#include "logcat_text.h"
+#include "json.h"
 #include "network_instruments.h"
 #include "k12.h"
 #include "ber.h"
 #include "vwr.h"
 #include "camins.h"
 #include "stanag4607.h"
+#include "capsa.h"
 #include "pcap-encap.h"
+#include "nettrace_3gpp_32_423.h"
+#include "mplog.h"
 
 /*
  * Add an extension, and all compressed versions thereof, to a GSList
  * of extensions.
  */
-static GSList *add_extensions(GSList *extensions, const gchar *extension,
-    GSList *compressed_file_extensions)
+static GSList *
+add_extensions(GSList *extensions, const gchar *extension,
+    const char **compressed_file_extensions)
 {
-       GSList *compressed_file_extension;
+       const char **compressed_file_extensionp;
 
        /*
         * Add the specified extension.
@@ -106,12 +104,12 @@ static GSList *add_extensions(GSList *extensions, const gchar *extension,
         * Now add the extensions for compressed-file versions of
         * that extension.
         */
-       for (compressed_file_extension = compressed_file_extensions;
-           compressed_file_extension != NULL;
-           compressed_file_extension = g_slist_next(compressed_file_extension)) {
+       for (compressed_file_extensionp = compressed_file_extensions;
+           *compressed_file_extensionp != NULL;
+           compressed_file_extensionp++) {
                extensions = g_slist_append(extensions,
                    g_strdup_printf("%s.%s", extension,
-                     (gchar *)compressed_file_extension->data));
+                     *compressed_file_extensionp));
        }
 
        return extensions;
@@ -119,6 +117,11 @@ static GSList *add_extensions(GSList *extensions, const gchar *extension,
 
 /*
  * File types that can be identified by file extensions.
+ *
+ * These are used in file open dialogs to offer choices of extensions
+ * for which to filter.  Note that the first field can list more than
+ * one type of file, because, for example, ".cap" is a popular
+ * extension used by a number of capture file types.
  */
 static const struct file_extension_info file_type_extensions_base[] = {
        { "Wireshark/tcpdump/... - pcap", "pcap;cap;dmp" },
@@ -126,17 +129,19 @@ static const struct file_extension_info file_type_extensions_base[] = {
        { "Network Monitor, Surveyor, NetScaler", "cap" },
        { "InfoVista 5View capture", "5vw" },
        { "Sniffer (DOS)", "cap;enc;trc;fdc;syc" },
-       { "NetXRay, Sniffer (Windows)", "cap;caz" },
+       { "Cinco NetXRay, Sniffer (Windows)", "cap;caz" },
        { "Endace ERF capture", "erf" },
        { "EyeSDN USB S0/E1 ISDN trace format", "trc" },
        { "HP-UX nettl trace", "trc0;trc1" },
        { "Network Instruments Observer", "bfr" },
+       { "Colasoft Capsa", "cscpkt" },
        { "Novell LANalyzer", "tr1" },
        { "Tektronix K12xx 32-bit .rf5 format", "rf5" },
-       { "WildPackets *Peek", "pkt;tpc;apc;wpz" },
+       { "Savvius *Peek", "pkt;tpc;apc;wpz" },
        { "Catapult DCT2000 trace (.out format)", "out" },
+       { "Micropross mplog", "mplog" },
        { "MPEG files", "mpg;mp3" },
-       { "CommView", "ncf" },
+       { "TamoSoft CommView", "ncf" },
        { "Symbian OS btsnoop", "log" },
        { "Transport-Neutral Encapsulation Format", "tnef" },
        { "XML files (including Gammu DCT3 traces)", "xml" },
@@ -148,6 +153,7 @@ static const struct file_extension_info file_type_extensions_base[] = {
        { "MPEG2 transport stream", "mp2t;ts;mpg" },
        { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr" },
        { "CAM Inspector file", "camins" },
+       { "JavaScript Object Notation file", "json" }
 };
 
 #define        N_FILE_TYPE_EXTENSIONS  (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
@@ -157,7 +163,9 @@ static const struct file_extension_info* file_type_extensions = NULL;
 static GArray* file_type_extensions_arr = NULL;
 
 /* initialize the extensions array if it has not been initialized yet */
-static void init_file_type_extensions(void) {
+static void
+init_file_type_extensions(void)
+{
 
        if (file_type_extensions_arr) return;
 
@@ -168,7 +176,9 @@ static void init_file_type_extensions(void) {
        file_type_extensions = (struct file_extension_info*)(void *)file_type_extensions_arr->data;
 }
 
-void wtap_register_file_type_extension(const struct file_extension_info *ei) {
+void
+wtap_register_file_type_extension(const struct file_extension_info *ei)
+{
        init_file_type_extensions();
 
        g_array_append_val(file_type_extensions_arr,*ei);
@@ -176,18 +186,21 @@ void wtap_register_file_type_extension(const struct file_extension_info *ei) {
        file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
 }
 
-int wtap_get_num_file_type_extensions(void)
+int
+wtap_get_num_file_type_extensions(void)
 {
        return file_type_extensions_arr->len;
 }
 
-const char *wtap_get_file_extension_type_name(int extension_type)
+const char *
+wtap_get_file_extension_type_name(int extension_type)
 {
        return file_type_extensions[extension_type].name;
 }
 
-static GSList *add_extensions_for_file_extensions_type(int extension_type,
-    GSList *extensions, GSList *compressed_file_extensions)
+static GSList *
+add_extensions_for_file_extensions_type(int extension_type,
+    GSList *extensions, const char **compressed_file_extensions)
 {
        gchar **extensions_set, **extensionp, *extension;
 
@@ -220,9 +233,9 @@ static GSList *add_extensions_for_file_extensions_type(int extension_type,
 
    All strings in the list are allocated with g_malloc() and must be freed
    with g_free(). */
-GSList *wtap_get_file_extension_type_extensions(guint extension_type)
+GSList *
+wtap_get_file_extension_type_extensions(guint extension_type)
 {
-       GSList *compressed_file_extensions;
        GSList *extensions;
 
        if (extension_type >= file_type_extensions_arr->len)
@@ -230,19 +243,13 @@ GSList *wtap_get_file_extension_type_extensions(guint extension_type)
 
        extensions = NULL;      /* empty list, to start with */
 
-       /*
-        * Get the list of compressed-file extensions.
-        */
-       compressed_file_extensions = wtap_get_compressed_file_extensions();
-
        /*
         * Add all this file extension type's extensions, with compressed
         * variants.
         */
        extensions = add_extensions_for_file_extensions_type(extension_type,
-           extensions, compressed_file_extensions);
+           extensions, compressed_file_extension_table);
 
-       g_slist_free(compressed_file_extensions);
        return extensions;
 }
 
@@ -252,9 +259,9 @@ GSList *wtap_get_file_extension_type_extensions(guint extension_type)
 
    All strings in the list are allocated with g_malloc() and must be freed
    with g_free(). */
-GSList *wtap_get_all_file_extensions_list(void)
+GSList *
+wtap_get_all_file_extensions_list(void)
 {
-       GSList *compressed_file_extensions;
        GSList *extensions;
        unsigned int i;
 
@@ -262,25 +269,20 @@ GSList *wtap_get_all_file_extensions_list(void)
 
        extensions = NULL;      /* empty list, to start with */
 
-       /*
-        * Get the list of compressed-file extensions.
-        */
-       compressed_file_extensions = wtap_get_compressed_file_extensions();
-
        for (i = 0; i < file_type_extensions_arr->len; i++) {
                /*
                 * Add all this file extension type's extensions, with
                 * compressed variants.
                 */
                extensions = add_extensions_for_file_extensions_type(i,
-                   extensions, compressed_file_extensions);
+                   extensions, compressed_file_extension_table);
        }
 
-       g_slist_free(compressed_file_extensions);
        return extensions;
 }
 
-/* The open_file_* routines should return:
+/*
+ * The open_file_* routines should return:
  *
  *     -1 on an I/O error;
  *
@@ -298,81 +300,106 @@ GSList *wtap_get_all_file_extensions_list(void)
  * However, the caller does have to free the private data pointer when
  * returning 0, since the next file type will be called and will likely
  * just overwrite the pointer.
+ *
+ * The names are used in file open dialogs to select, for files that
+ * don't have magic numbers and that could potentially be files of
+ * more than one type based on the heuristics, a particular file
+ * type to interpret it as, if the file name has no extension, the
+ * extension isn't sufficient to determine the appropriate file type,
+ * or the extension is wrong.
+ *
+ * NOTE: when adding file formats to this list you may also want to add them
+ * to the following files so that the various desktop environments will
+ * know that Wireshark can open the file:
+ *     1) wireshark-mime-package.xml (for freedesktop.org environments)
+ *     2) packaging/macosx/Info.plist.in (for OS X)
+ *     3) packaging/nsis/AdditionalTasksPage.ini, packaging/nsis/common.nsh,
+ *        and packaging/wix/ComponentGroups.wxi (for Windows)
+ *
+ * If your file format has an expected extension (e.g., ".pcap") then you
+ * should probably also add it to file_type_extensions_base[] (in this file).
  */
-
 static struct open_info open_info_base[] = {
-    { "Pcap",                        OPEN_INFO_MAGIC,     libpcap_open,             "pcap",     NULL, NULL },
-    { "PcapNG",                      OPEN_INFO_MAGIC,     pcapng_open,              "pcapng",   NULL, NULL },
-    { "NgSniffer",                   OPEN_INFO_MAGIC,     ngsniffer_open,           NULL,       NULL, NULL },
-    { "Snoop",                       OPEN_INFO_MAGIC,     snoop_open,               NULL,       NULL, NULL },
-    { "IP Trace",                    OPEN_INFO_MAGIC,     iptrace_open,             NULL,       NULL, NULL },
-    { "Netmon",                      OPEN_INFO_MAGIC,     netmon_open,              NULL,       NULL, NULL },
-    { "Netxray",                     OPEN_INFO_MAGIC,     netxray_open,             NULL,       NULL, NULL },
-    { "Radcom",                      OPEN_INFO_MAGIC,     radcom_open,              NULL,       NULL, NULL },
-    { "Nettl",                       OPEN_INFO_MAGIC,     nettl_open,               NULL,       NULL, NULL },
-    { "Visual",                      OPEN_INFO_MAGIC,     visual_open,              NULL,       NULL, NULL },
-    { "5 Views",                     OPEN_INFO_MAGIC,     _5views_open,             NULL,       NULL, NULL },
-    { "Network Instruments",         OPEN_INFO_MAGIC,     network_instruments_open, NULL,       NULL, NULL },
-    { "Peek Tagged",                 OPEN_INFO_MAGIC,     peektagged_open,          NULL,       NULL, NULL },
-    { "DBS Etherwatch",              OPEN_INFO_MAGIC,     dbs_etherwatch_open,      NULL,       NULL, NULL },
-    { "K12",                         OPEN_INFO_MAGIC,     k12_open,                 NULL,       NULL, NULL },
-    { "Catapult DCT 2000",           OPEN_INFO_MAGIC,     catapult_dct2000_open,    NULL,       NULL, NULL },
-    { "Aethra",                      OPEN_INFO_MAGIC,     aethra_open,              NULL,       NULL, NULL },
-    { "BTSNOOP",                     OPEN_INFO_MAGIC,     btsnoop_open,             "log",      NULL, NULL },
-    { "EYESDN",                      OPEN_INFO_MAGIC,     eyesdn_open,              NULL,       NULL, NULL },
-    { "TNEF",                        OPEN_INFO_MAGIC,     tnef_open,                NULL,       NULL, NULL },
-    { "MIME Files with Magic Bytes", OPEN_INFO_MAGIC,     mime_file_open,           NULL,       NULL, NULL },
-    { "Lanalyzer",                   OPEN_INFO_HEURISTIC, lanalyzer_open,           "tr1",      NULL, NULL },
-    /*
-     * PacketLogger must come before MPEG, because its files
-     * are sometimes grabbed by mpeg_open.
-     */
-    { "Packet Logger",               OPEN_INFO_HEURISTIC, packetlogger_open,        "pklg",     NULL, NULL },
-    /* Some MPEG files have magic numbers, others just have heuristics. */
-    { "Mpeg",                        OPEN_INFO_HEURISTIC, mpeg_open,                "mpg;mp3",  NULL, NULL },
-    { "DCT3 Trace",                  OPEN_INFO_HEURISTIC, dct3trace_open,           "xml",      NULL, NULL },
-    { "Daintree SNA",                OPEN_INFO_HEURISTIC, daintree_sna_open,        "dcf",      NULL, NULL },
-    { "Stanag 4607",                 OPEN_INFO_HEURISTIC, stanag4607_open,          NULL,       NULL, NULL },
-    { "BER",                         OPEN_INFO_HEURISTIC, ber_open,                 NULL,       NULL, NULL },
-    /* I put NetScreen *before* erf, because there were some
-     * false positives with my test-files (Sake Blok, July 2007)
-     *
-     * I put VWR *after* ERF, because there were some cases where
-     * ERF files were misidentified as vwr files (Stephen
-     * Donnelly, August 2013; see bug 9054)
-     *
-     * I put VWR *after* Peek Classic, CommView, iSeries text,
-     * Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
-     * because there were some cases where files of those types were
-     * misidentified as vwr files (Guy Harris, December 2013)
-     */
-    { "Netscreen",                   OPEN_INFO_HEURISTIC, netscreen_open,           "txt",      NULL, NULL },
-    { "ERF",                         OPEN_INFO_HEURISTIC, erf_open,                 "erf",      NULL, NULL },
-    { "IPfix",                       OPEN_INFO_HEURISTIC, ipfix_open,               "pfx;ipfix",NULL, NULL },
-    { "K12 Text",                    OPEN_INFO_HEURISTIC, k12text_open,             "txt",      NULL, NULL },
-    { "Peek Classic",                OPEN_INFO_HEURISTIC, peekclassic_open,         "pkt;tpc;apc;wpz", NULL, NULL },
-    { "PPP Dump",                    OPEN_INFO_HEURISTIC, pppdump_open,             NULL,       NULL, NULL },
-    { "iSeries",                     OPEN_INFO_HEURISTIC, iseries_open,             "txt",      NULL, NULL },
-    { "i4btrace",                    OPEN_INFO_HEURISTIC, i4btrace_open,            NULL,       NULL, NULL },
-    { "Mp2t",                        OPEN_INFO_HEURISTIC, mp2t_open,                "ts;mpg",   NULL, NULL },
-    { "Csids",                       OPEN_INFO_HEURISTIC, csids_open,               NULL,       NULL, NULL },
-    { "VMS",                         OPEN_INFO_HEURISTIC, vms_open,                 "txt",      NULL, NULL },
-    { "Cosine",                      OPEN_INFO_HEURISTIC, cosine_open,              "txt",      NULL, NULL },
-    { "Hcidump",                     OPEN_INFO_HEURISTIC, hcidump_open,             NULL,       NULL, NULL },
-    { "Commview",                    OPEN_INFO_HEURISTIC, commview_open,            "ncf",      NULL, NULL },
-    { "Nstrace",                     OPEN_INFO_HEURISTIC, nstrace_open,             "txt",      NULL, NULL },
-    { "Logcat ",                     OPEN_INFO_HEURISTIC, logcat_open,              "logcat",   NULL, NULL },
-    /* ASCII trace files from Telnet sessions. */
-    { "Ascend",                      OPEN_INFO_HEURISTIC, ascend_open,              "txt",      NULL, NULL },
-    { "Toshiba",                     OPEN_INFO_HEURISTIC, toshiba_open,             "txt",      NULL, NULL },
-    /* Extremely weak heuristics - put them at the end. */
-    { "VWR",                         OPEN_INFO_HEURISTIC, vwr_open,                 "vwr",      NULL, NULL },
-    { "Camins",                      OPEN_INFO_HEURISTIC, camins_open,              "camins",   NULL, NULL },
+       { "Wireshark/tcpdump/... - pcap",           OPEN_INFO_MAGIC,     libpcap_open,             "pcap",     NULL, NULL },
+       { "Wireshark/... - pcapng",                 OPEN_INFO_MAGIC,     pcapng_open,              "pcapng",   NULL, NULL },
+       { "Sniffer (DOS)",                          OPEN_INFO_MAGIC,     ngsniffer_open,           NULL,       NULL, NULL },
+       { "Snoop, Shomiti/Finisar Surveyor",        OPEN_INFO_MAGIC,     snoop_open,               NULL,       NULL, NULL },
+       { "AIX iptrace",                            OPEN_INFO_MAGIC,     iptrace_open,             NULL,       NULL, NULL },
+       { "Microsoft Network Monitor",              OPEN_INFO_MAGIC,     netmon_open,              NULL,       NULL, NULL },
+       { "Cinco NetXray/Sniffer (Windows)",        OPEN_INFO_MAGIC,     netxray_open,             NULL,       NULL, NULL },
+       { "RADCOM WAN/LAN analyzer",                OPEN_INFO_MAGIC,     radcom_open,              NULL,       NULL, NULL },
+       { "HP-UX nettl trace",                      OPEN_INFO_MAGIC,     nettl_open,               NULL,       NULL, NULL },
+       { "Visual Networks traffic capture",        OPEN_INFO_MAGIC,     visual_open,              NULL,       NULL, NULL },
+       { "InfoVista 5View capture",                OPEN_INFO_MAGIC,     _5views_open,             NULL,       NULL, NULL },
+       { "Network Instruments Observer",           OPEN_INFO_MAGIC,     network_instruments_open, NULL,       NULL, NULL },
+       { "Savvius tagged",                         OPEN_INFO_MAGIC,     peektagged_open,          NULL,       NULL, NULL },
+       { "Colasoft Capsa",                         OPEN_INFO_MAGIC,     capsa_open,               NULL,       NULL, NULL },
+       { "DBS Etherwatch (VMS)",                   OPEN_INFO_MAGIC,     dbs_etherwatch_open,      NULL,       NULL, NULL },
+       { "Tektronix K12xx 32-bit .rf5 format",     OPEN_INFO_MAGIC,     k12_open,                 NULL,       NULL, NULL },
+       { "Catapult DCT2000 trace (.out format)",   OPEN_INFO_MAGIC,     catapult_dct2000_open,    NULL,       NULL, NULL },
+       { "Aethra .aps file",                       OPEN_INFO_MAGIC,     aethra_open,              NULL,       NULL, NULL },
+       { "Symbian OS btsnoop",                     OPEN_INFO_MAGIC,     btsnoop_open,             "log",      NULL, NULL },
+       { "EyeSDN USB S0/E1 ISDN trace format",     OPEN_INFO_MAGIC,     eyesdn_open,              NULL,       NULL, NULL },
+       { "Transport-Neutral Encapsulation Format", OPEN_INFO_MAGIC,     tnef_open,                NULL,       NULL, NULL },
+       /* 3GPP TS 32.423 Trace must come before MIME Files as it's XML based*/
+       { "3GPP TS 32.423 Trace format",            OPEN_INFO_MAGIC,     nettrace_3gpp_32_423_file_open, NULL, NULL, NULL },
+       /* Gammu DCT3 trace must come before MIME files as it's XML based*/
+       { "Gammu DCT3 trace",                       OPEN_INFO_MAGIC,     dct3trace_open,           NULL,       NULL, NULL },
+       { "MIME Files Format",                      OPEN_INFO_MAGIC,     mime_file_open,           NULL,       NULL, NULL },
+       { "Micropross mplog",                       OPEN_INFO_MAGIC,     mplog_open,               "mplog",    NULL, NULL },
+       { "Novell LANalyzer",                       OPEN_INFO_HEURISTIC, lanalyzer_open,           "tr1",      NULL, NULL },
+       /*
+        * PacketLogger must come before MPEG, because its files
+        * are sometimes grabbed by mpeg_open.
+        */
+       { "OS X PacketLogger",                      OPEN_INFO_HEURISTIC, packetlogger_open,        "pklg",     NULL, NULL },
+       /* Some MPEG files have magic numbers, others just have heuristics. */
+       { "MPEG",                                   OPEN_INFO_HEURISTIC, mpeg_open,                "mpg;mp3",  NULL, NULL },
+       { "Daintree SNA",                           OPEN_INFO_HEURISTIC, daintree_sna_open,        "dcf",      NULL, NULL },
+       { "STANAG 4607 Format",                     OPEN_INFO_HEURISTIC, stanag4607_open,          NULL,       NULL, NULL },
+       { "ASN.1 Basic Encoding Rules",             OPEN_INFO_HEURISTIC, ber_open,                 NULL,       NULL, NULL },
+       /*
+        * I put NetScreen *before* erf, because there were some
+        * false positives with my test-files (Sake Blok, July 2007)
+        *
+        * I put VWR *after* ERF, because there were some cases where
+        * ERF files were misidentified as vwr files (Stephen
+        * Donnelly, August 2013; see bug 9054)
+        *
+        * I put VWR *after* Peek Classic, CommView, iSeries text,
+        * Toshiba text, K12 text, VMS tcpiptrace text, and NetScaler,
+        * because there were some cases where files of those types were
+        * misidentified as vwr files (Guy Harris, December 2013)
+        */
+       { "NetScreen snoop text file",              OPEN_INFO_HEURISTIC, netscreen_open,           "txt",      NULL, NULL },
+       { "Endace ERF capture",                     OPEN_INFO_HEURISTIC, erf_open,                 "erf",      NULL, NULL },
+       { "IPFIX File Format",                      OPEN_INFO_HEURISTIC, ipfix_open,               "pfx;ipfix",NULL, NULL },
+       { "K12 text file",                          OPEN_INFO_HEURISTIC, k12text_open,             "txt",      NULL, NULL },
+       { "Savvius classic",                        OPEN_INFO_HEURISTIC, peekclassic_open,         "pkt;tpc;apc;wpz", NULL, NULL },
+       { "pppd log (pppdump format)",              OPEN_INFO_HEURISTIC, pppdump_open,             NULL,       NULL, NULL },
+       { "IBM iSeries comm. trace",                OPEN_INFO_HEURISTIC, iseries_open,             "txt",      NULL, NULL },
+       { "I4B ISDN trace",                         OPEN_INFO_HEURISTIC, i4btrace_open,            NULL,       NULL, NULL },
+       { "MPEG2 transport stream",                 OPEN_INFO_HEURISTIC, mp2t_open,                "ts;mpg",   NULL, NULL },
+       { "CSIDS IPLog",                            OPEN_INFO_HEURISTIC, csids_open,               NULL,       NULL, NULL },
+       { "TCPIPtrace (VMS)",                       OPEN_INFO_HEURISTIC, vms_open,                 "txt",      NULL, NULL },
+       { "CoSine IPSX L2 capture",                 OPEN_INFO_HEURISTIC, cosine_open,              "txt",      NULL, NULL },
+       { "Bluetooth HCI dump",                     OPEN_INFO_HEURISTIC, hcidump_open,             NULL,       NULL, NULL },
+       { "TamoSoft CommView",                      OPEN_INFO_HEURISTIC, commview_open,            "ncf",      NULL, NULL },
+       { "NetScaler",                              OPEN_INFO_HEURISTIC, nstrace_open,             "cap",      NULL, NULL },
+       { "Android Logcat Binary format",           OPEN_INFO_HEURISTIC, logcat_open,              "logcat",   NULL, NULL },
+       { "Android Logcat Text formats",            OPEN_INFO_HEURISTIC, logcat_text_open,         "txt",      NULL, NULL },
+       /* ASCII trace files from Telnet sessions. */
+       { "Lucent/Ascend access server trace",      OPEN_INFO_HEURISTIC, ascend_open,              "txt",      NULL, NULL },
+       { "Toshiba Compact ISDN Router snoop",      OPEN_INFO_HEURISTIC, toshiba_open,             "txt",      NULL, NULL },
+       /* Extremely weak heuristics - put them at the end. */
+       { "Ixia IxVeriWave .vwr Raw Capture",       OPEN_INFO_HEURISTIC, vwr_open,                 "vwr",      NULL, NULL },
+       { "CAM Inspector file",                     OPEN_INFO_HEURISTIC, camins_open,              "camins",   NULL, NULL },
+       { "JavaScript Object Notation",             OPEN_INFO_HEURISTIC, json_open,                "json",     NULL, NULL }
 };
 
 /* this is only used to build the dynamic array on load, do NOT use this
  * for anything else, because the size of the actual array will change if
- *  Lua scripts register a new file reader.
+ * Lua scripts register a new file reader.
  */
 #define N_OPEN_INFO_ROUTINES  ((sizeof open_info_base / sizeof open_info_base[0]))
 
@@ -384,7 +411,9 @@ struct open_info *open_routines = NULL;
 /* this points to the first OPEN_INFO_HEURISTIC type in the array */
 static guint heuristic_open_routine_idx = 0;
 
-static void set_heuristic_routine(void) {
+static void
+set_heuristic_routine(void)
+{
        guint i;
        g_assert(open_info_arr != NULL);
 
@@ -400,62 +429,67 @@ static void set_heuristic_routine(void) {
        g_assert(heuristic_open_routine_idx > 0);
 }
 
-void init_open_routines(void) {
-    unsigned int i;
-    struct open_info *i_open;
+void
+init_open_routines(void)
+{
+       unsigned int i;
+       struct open_info *i_open;
 
-    if (open_info_arr)
-        return;
+       if (open_info_arr)
+               return;
 
-    open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
+       open_info_arr = g_array_new(TRUE,TRUE,sizeof(struct open_info));
 
-    g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
+       g_array_append_vals(open_info_arr, open_info_base, N_OPEN_INFO_ROUTINES);
 
-    open_routines = (struct open_info *)(void*) open_info_arr->data;
+       open_routines = (struct open_info *)(void*) open_info_arr->data;
 
-    /* Populate the extensions_set list now */
-    for (i = 0, i_open = open_routines; i < open_info_arr->len; i++, i_open++) {
-        if (i_open->extensions != NULL)
-            i_open->extensions_set = g_strsplit(i_open->extensions, ";", 0);
-    }
+       /* Populate the extensions_set list now */
+       for (i = 0, i_open = open_routines; i < open_info_arr->len; i++, i_open++) {
+               if (i_open->extensions != NULL)
+                       i_open->extensions_set = g_strsplit(i_open->extensions, ";", 0);
+       }
 
-    set_heuristic_routine();
+       set_heuristic_routine();
 }
 
-/* Registers a new file reader - currently only called by wslua code for Lua readers.
+/*
+ * Registers a new file reader - currently only called by wslua code for Lua readers.
  * If first_routine is true, it's added before other readers of its type (magic or heuristic).
  * Also, it checks for an existing reader of the same name and errors if it finds one; if
  * you want to handle that condition more gracefully, call wtap_has_open_info() first.
  */
-void wtap_register_open_info(struct open_info *oi, const gboolean first_routine) {
-    init_open_routines();
+void
+wtap_register_open_info(struct open_info *oi, const gboolean first_routine)
+{
+       init_open_routines();
 
-    if (!oi || !oi->name) {
-        g_error("No open_info name given to register");
-        return;
-    }
+       if (!oi || !oi->name) {
+               g_error("No open_info name given to register");
+               return;
+       }
 
-    /* verify name doesn't already exist */
-    if (wtap_has_open_info(oi->name)) {
-        g_error("Name given to register_open_info already exists");
-        return;
-    }
+       /* verify name doesn't already exist */
+       if (wtap_has_open_info(oi->name)) {
+               g_error("Name given to register_open_info already exists");
+               return;
+       }
 
-    if (oi->extensions != NULL)
-        oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
+       if (oi->extensions != NULL)
+               oi->extensions_set = g_strsplit(oi->extensions, ";", 0);
 
-    /* if it's magic and first, prepend it; if it's heuristic and not first,
-       append it; if it's anything else, stick it in the middle */
-    if (first_routine && oi->type == OPEN_INFO_MAGIC) {
-        g_array_prepend_val(open_info_arr, *oi);
-    } else if (!first_routine && oi->type == OPEN_INFO_HEURISTIC) {
-        g_array_append_val(open_info_arr, *oi);
-    } else {
-        g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
-    }
+       /* if it's magic and first, prepend it; if it's heuristic and not first,
+          append it; if it's anything else, stick it in the middle */
+       if (first_routine && oi->type == OPEN_INFO_MAGIC) {
+               g_array_prepend_val(open_info_arr, *oi);
+       } else if (!first_routine && oi->type == OPEN_INFO_HEURISTIC) {
+               g_array_append_val(open_info_arr, *oi);
+       } else {
+               g_array_insert_val(open_info_arr, heuristic_open_routine_idx, *oi);
+       }
 
-    open_routines = (struct open_info *)(void*) open_info_arr->data;
-    set_heuristic_routine();
+       open_routines = (struct open_info *)(void*) open_info_arr->data;
+       set_heuristic_routine();
 }
 
 /* De-registers a file reader by removign it from the GArray based on its name.
@@ -463,47 +497,51 @@ void wtap_register_open_info(struct open_info *oi, const gboolean first_routine)
  * Note: this function will error if it doesn't find the given name; if you want to handle
  * that condition more gracefully, call wtap_has_open_info() first.
  */
-void wtap_deregister_open_info(const gchar *name) {
-    guint i;
-    init_open_routines();
+void
+wtap_deregister_open_info(const gchar *name)
+{
+       guint i;
+       init_open_routines();
 
-    if (!name) {
-        g_error("Missing open_info name to de-register");
-        return;
-    }
+       if (!name) {
+               g_error("Missing open_info name to de-register");
+               return;
+       }
 
-    for (i = 0; i < open_info_arr->len; i++) {
-        if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
-            if (open_routines[i].extensions_set != NULL)
-                g_strfreev(open_routines[i].extensions_set);
-            open_info_arr = g_array_remove_index(open_info_arr, i);
-            set_heuristic_routine();
-            return;
-        }
-    }
+       for (i = 0; i < open_info_arr->len; i++) {
+               if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
+                       if (open_routines[i].extensions_set != NULL)
+                               g_strfreev(open_routines[i].extensions_set);
+                       open_info_arr = g_array_remove_index(open_info_arr, i);
+                       set_heuristic_routine();
+                       return;
+               }
+       }
 
-    g_error("deregister_open_info: name not found");
+       g_error("deregister_open_info: name not found");
 }
 
 /* Determines if a open routine short name already exists
  */
-gboolean wtap_has_open_info(const gchar *name) {
-    guint i;
-    init_open_routines();
+gboolean
+wtap_has_open_info(const gchar *name)
+{
+       guint i;
+       init_open_routines();
 
-    if (!name) {
-        g_error("No name given to wtap_has_open_info!");
-        return FALSE;
-    }
+       if (!name) {
+               g_error("No name given to wtap_has_open_info!");
+               return FALSE;
+       }
 
 
-    for (i = 0; i < open_info_arr->len; i++) {
-        if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
-            return TRUE;
-        }
-    }
+       for (i = 0; i < open_info_arr->len; i++) {
+               if (open_routines[i].name && strcmp(open_routines[i].name, name) == 0) {
+                       return TRUE;
+               }
+       }
 
-    return FALSE;
+       return FALSE;
 }
 
 /*
@@ -529,7 +567,8 @@ gboolean wtap_has_open_info(const gchar *name) {
    passed-in name (the name in the open_info struct). It returns WTAP_TYPE_AUTO
    on failure, which is the number 0. The 'type' number is the entry's index+1,
    because that's what wtap_open_offline() expects it to be. */
-unsigned int open_info_name_to_type(const char *name)
+unsigned int
+open_info_name_to_type(const char *name)
 {
        unsigned int i;
        init_open_routines();
@@ -539,19 +578,20 @@ unsigned int open_info_name_to_type(const char *name)
 
        for (i = 0; i < open_info_arr->len; i++) {
                if (open_routines[i].name != NULL &&
-                       strcmp(name, open_routines[i].name) == 0)
+                   strcmp(name, open_routines[i].name) == 0)
                        return i+1;
        }
 
        return WTAP_TYPE_AUTO; /* no such file type */
 }
 
-static char *get_file_extension(const char *pathname)
+static char *
+get_file_extension(const char *pathname)
 {
        gchar *filename;
        gchar **components;
        size_t ncomponents;
-       GSList *compressed_file_extensions, *compressed_file_extension;
+       const char **compressed_file_extensionp;
        gchar *extensionp;
 
        /*
@@ -598,21 +638,11 @@ static char *get_file_extension(const char *pathname)
         * Is the last component one of the extensions used for compressed
         * files?
         */
-       compressed_file_extensions = wtap_get_compressed_file_extensions();
-       if (compressed_file_extensions == NULL) {
-               /*
-                * We don't support reading compressed files, so just
-                * return a copy of whatever extension we did find.
-                */
-               extensionp = g_strdup(components[ncomponents - 1]);
-               g_strfreev(components);
-               return extensionp;
-       }
        extensionp = components[ncomponents - 1];
-       for (compressed_file_extension = compressed_file_extensions;
-           compressed_file_extension != NULL;
-           compressed_file_extension = g_slist_next(compressed_file_extension)) {
-               if (strcmp(extensionp, (char *)compressed_file_extension->data) == 0) {
+       for (compressed_file_extensionp = compressed_file_extension_table;
+           *compressed_file_extensionp != NULL;
+           compressed_file_extensionp++) {
+               if (strcmp(extensionp, *compressed_file_extensionp) == 0) {
                        /*
                         * Yes, it's one of the compressed-file extensions.
                         * Is there an extension before that?
@@ -643,7 +673,8 @@ static char *get_file_extension(const char *pathname)
 /*
  * Check if file extension is used in this heuristic
  */
-static gboolean heuristic_uses_extension(unsigned int i, const char *extension)
+static gboolean
+heuristic_uses_extension(unsigned int i, const char *extension)
 {
        gchar **extensionp;
 
@@ -673,8 +704,9 @@ static gboolean heuristic_uses_extension(unsigned int i, const char *extension)
    so that it can do sequential I/O to a capture file that's being
    written to as new packets arrive independently of random I/O done
    to display protocol trees for packets when they're selected. */
-wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
-                       gboolean do_random)
+wtap *
+wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_info,
+                 gboolean do_random)
 {
        int     fd;
        ws_statb64 statb;
@@ -683,6 +715,11 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
        gboolean use_stdin = FALSE;
        gchar *extension;
 
+       *err = 0;
+       *err_info = NULL;
+
+       init_open_routines();
+
        /* open standard input if filename is '-' */
        if (strcmp(filename, "-") == 0)
                use_stdin = TRUE;
@@ -704,13 +741,12 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
                 * Opens of FIFOs are allowed only when not opening
                 * for random access.
                 *
-                * XXX - currently, we do seeking when trying to find
-                * out the file type, so we don't actually support
-                * opening FIFOs.  However, we may eventually
-                * do buffering that allows us to do at least some
-                * file type determination even on pipes, so we
-                * allow FIFO opens and let things fail later when
-                * we try to seek.
+                * Currently, we do seeking when trying to find out
+                * the file type, but our I/O routines do some amount
+                * of buffering, and do backward seeks within the buffer
+                * if possible, so at least some file types can be
+                * opened from pipes, so we don't completely disallow opens
+                * of pipes.
                 */
                if (do_random) {
                        *err = WTAP_ERR_RANDOM_OPEN_PIPE;
@@ -794,14 +830,15 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
        wth->file_encap = WTAP_ENCAP_UNKNOWN;
        wth->subtype_sequential_close = NULL;
        wth->subtype_close = NULL;
-       wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+       wth->file_tsprec = WTAP_TSPREC_USEC;
        wth->priv = NULL;
        wth->wslua_data = NULL;
+       wth->shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
 
        /* Initialize the array containing a list of interfaces. pcapng_open and
         * erf_open needs this (and libpcap_open for ERF encapsulation types).
         * Always initing it here saves checking for a NULL ptr later. */
-       wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+       wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
 
        if (wth->random_fh) {
                wth->fast_seek = g_ptr_array_new();
@@ -829,16 +866,16 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
                result = (*open_routines[type - 1].open_routine)(wth, err, err_info);
 
                switch (result) {
-                       case -1:
-                               /* I/O error - give up */
+                       case WTAP_OPEN_ERROR:
+                               /* Error - give up */
                                wtap_close(wth);
                                return NULL;
 
-                       case 0:
-                               /* No I/O error, but not that type of file */
+                       case WTAP_OPEN_NOT_MINE:
+                               /* No error, but not that type of file */
                                goto fail;
 
-                       case 1:
+                       case WTAP_OPEN_MINE:
                                /* We found the file type */
                                goto success;
                }
@@ -854,7 +891,7 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
 
                   Initialize the data offset while we're at it. */
                if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
-                       /* I/O error - give up */
+                       /* Error - give up */
                        wtap_close(wth);
                        return NULL;
                }
@@ -867,16 +904,16 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
 
                switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
 
-               case -1:
-                       /* I/O error - give up */
+               case WTAP_OPEN_ERROR:
+                       /* Error - give up */
                        wtap_close(wth);
                        return NULL;
 
-               case 0:
-                       /* No I/O error, but not that type of file */
+               case WTAP_OPEN_NOT_MINE:
+                       /* No error, but not that type of file */
                        break;
 
-               case 1:
+               case WTAP_OPEN_MINE:
                        /* We found the file type */
                        goto success;
                }
@@ -892,7 +929,7 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
                        if (heuristic_uses_extension(i, extension)) {
                                /* Yes. */
                                if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
-                                       /* I/O error - give up */
+                                       /* Error - give up */
                                        g_free(extension);
                                        wtap_close(wth);
                                        return NULL;
@@ -906,17 +943,17 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
                                switch ((*open_routines[i].open_routine)(wth,
                                    err, err_info)) {
 
-                               case -1:
-                                       /* I/O error - give up */
+                               case WTAP_OPEN_ERROR:
+                                       /* Error - give up */
                                        g_free(extension);
                                        wtap_close(wth);
                                        return NULL;
 
-                               case 0:
-                                       /* No I/O error, but not that type of file */
+                               case WTAP_OPEN_NOT_MINE:
+                                       /* No error, but not that type of file */
                                        break;
 
-                               case 1:
+                               case WTAP_OPEN_MINE:
                                        /* We found the file type */
                                        g_free(extension);
                                        goto success;
@@ -924,13 +961,66 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
                        }
                }
 
-               /* Now try the ones that don't use it. */
+               /*
+                * Now try the heuristic types that have no extensions
+                * to check; we try those before the ones that have
+                * extensions that *don't* match this file's extension,
+                * on the theory that files of those types generally
+                * have one of the type's extensions, and, as this file
+                * *doesn't* have one of those extensions, it's probably
+                * *not* one of those files.
+                */
                for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
-                       /* Does this type use that extension? */
-                       if (!heuristic_uses_extension(i, extension)) {
+                       /* Does this type have any extensions? */
+                       if (open_routines[i].extensions == NULL) {
                                /* No. */
                                if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
-                                       /* I/O error - give up */
+                                       /* Error - give up */
+                                       g_free(extension);
+                                       wtap_close(wth);
+                                       return NULL;
+                               }
+
+                               /* Set wth with wslua data if any - this is how we pass the data
+                                * to the file reader, kind of like priv but not free'd later.
+                                */
+                               wth->wslua_data = open_routines[i].wslua_data;
+
+                               switch ((*open_routines[i].open_routine)(wth,
+                                   err, err_info)) {
+
+                               case WTAP_OPEN_ERROR:
+                                       /* Error - give up */
+                                       g_free(extension);
+                                       wtap_close(wth);
+                                       return NULL;
+
+                               case WTAP_OPEN_NOT_MINE:
+                                       /* No error, but not that type of file */
+                                       break;
+
+                               case WTAP_OPEN_MINE:
+                                       /* We found the file type */
+                                       g_free(extension);
+                                       goto success;
+                               }
+                       }
+               }
+
+               /*
+                * Now try the ones that have extensions where none of
+                * them matches this file's extensions.
+                */
+               for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
+                       /*
+                        * Does this type have extensions and is this file's
+                        * extension one of them?
+                        */
+                       if (open_routines[i].extensions != NULL &&
+                           !heuristic_uses_extension(i, extension)) {
+                               /* Yes and no. */
+                               if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
+                                       /* Error - give up */
                                        g_free(extension);
                                        wtap_close(wth);
                                        return NULL;
@@ -944,17 +1034,17 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
                                switch ((*open_routines[i].open_routine)(wth,
                                    err, err_info)) {
 
-                               case -1:
-                                       /* I/O error - give up */
+                               case WTAP_OPEN_ERROR:
+                                       /* Error - give up */
                                        g_free(extension);
                                        wtap_close(wth);
                                        return NULL;
 
-                               case 0:
-                                       /* No I/O error, but not that type of file */
+                               case WTAP_OPEN_NOT_MINE:
+                                       /* No error, but not that type of file */
                                        break;
 
-                               case 1:
+                               case WTAP_OPEN_MINE:
                                        /* We found the file type */
                                        g_free(extension);
                                        goto success;
@@ -967,7 +1057,7 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
                for (i = heuristic_open_routine_idx; i < open_info_arr->len; i++) {
 
                        if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
-                               /* I/O error - give up */
+                               /* Error - give up */
                                wtap_close(wth);
                                return NULL;
                        }
@@ -979,16 +1069,16 @@ wtap* wtap_open_offline(const char *filename, unsigned int type, int *err, char
 
                        switch ((*open_routines[i].open_routine)(wth, err, err_info)) {
 
-                       case -1:
-                               /* I/O error - give up */
+                       case WTAP_OPEN_ERROR:
+                               /* Error - give up */
                                wtap_close(wth);
                                return NULL;
 
-                       case 0:
-                               /* No I/O error, but not that type of file */
+                       case WTAP_OPEN_NOT_MINE:
+                               /* No error, but not that type of file */
                                break;
 
-                       case 1:
+                       case WTAP_OPEN_MINE:
                                /* We found the file type */
                                goto success;
                        }
@@ -1004,28 +1094,29 @@ fail:
 
 success:
        wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer));
-       buffer_init(wth->frame_buffer, 1500);
-
-       if(wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP){
-
-               wtapng_if_descr_t descr;
-
-               descr.wtap_encap = wth->file_encap;
-               descr.time_units_per_second = 1000000; /* default microsecond resolution */
-               descr.link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
-               descr.snap_len = wth->snapshot_length;
-               descr.opt_comment = NULL;
-               descr.if_name = NULL;
-               descr.if_description = NULL;
-               descr.if_speed = 0;
-               descr.if_tsresol = 6;
-               descr.if_filter_str= NULL;
-               descr.bpf_filter_len= 0;
-               descr.if_filter_bpf_bytes= NULL;
-               descr.if_os = NULL;
-               descr.if_fcslen = -1;
-               descr.num_stat_entries = 0;          /* Number of ISB:s */
-               descr.interface_statistics = NULL;
+       ws_buffer_init(wth->frame_buffer, 1500);
+
+       if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) ||
+               (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) {
+
+               wtap_optionblock_t descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+               wtapng_if_descr_mandatory_t* descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+
+               descr_mand->wtap_encap = wth->file_encap;
+               if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) {
+                       descr_mand->time_units_per_second = 1000000000; /* nanosecond resolution */
+                       wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 9);
+                       descr_mand->tsprecision = WTAP_TSPREC_NSEC;
+               } else {
+                       descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+                       wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 6);
+                       descr_mand->tsprecision = WTAP_TSPREC_USEC;
+               }
+               descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
+               descr_mand->snap_len = wth->snapshot_length;
+
+               descr_mand->num_stat_entries = 0;          /* Number of ISB:s */
+               descr_mand->interface_statistics = NULL;
                g_array_append_val(wth->interface_data, descr);
 
        }
@@ -1094,8 +1185,17 @@ wtap_fdreopen(wtap *wth, const char *filename, int *err)
        return TRUE;
 }
 
-/* Table of the file types we know about.
-   Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending order */
+/* Table of the file types and subtypes for which we have built-in support.
+   Entries must be sorted by WTAP_FILE_TYPE_SUBTYPE_xxx values in ascending
+   order.
+
+   These are used to report what type and subtype a given file is and
+   to let the user select a format when writing out packets.
+
+   This table is what we start with, but it can be modified.
+   If we need to modify it, we allocate a GArray, copy the entries
+   in the above table to that GArray, use the copy as the table, and
+   make all changes to the copy. */
 static const struct file_type_subtype_info dump_open_table_base[] = {
        /* WTAP_FILE_TYPE_SUBTYPE_UNKNOWN (only used internally for initialization) */
        { NULL, NULL, NULL, NULL,
@@ -1103,7 +1203,7 @@ static const struct file_type_subtype_info dump_open_table_base[] = {
          NULL, NULL, NULL },
 
        /* WTAP_FILE_TYPE_SUBTYPE_PCAP */
-        /* Gianluca Varenni suggests that we add "deprecated" to the description. */
+       /* Gianluca Varenni suggests that we add "deprecated" to the description. */
        { "Wireshark/tcpdump/... - pcap", "pcap", "pcap", "cap;dmp",
          FALSE, FALSE, 0,
          libpcap_dump_can_write_encap, libpcap_dump_open, NULL },
@@ -1314,17 +1414,17 @@ static const struct file_type_subtype_info dump_open_table_base[] = {
          visual_dump_can_write_encap, visual_dump_open, NULL },
 
        /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V56 */
-       { "WildPackets classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
+       { "Savvius classic (V5 and V6)", "peekclassic56", "pkt", "tpc;apc;wpz",
          FALSE, FALSE, 0,
          NULL, NULL, NULL },
 
        /* WTAP_FILE_TYPE_SUBTYPE_PEEKCLASSIC_V7 */
-       { "WildPackets classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
+       { "Savvius classic (V7)", "peekclassic7", "pkt", "tpc;apc;wpz",
          FALSE, FALSE, 0,
          NULL, NULL, NULL },
 
        /* WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED */
-       { "WildPackets tagged", "peektagged", "pkt", "tpc;apc;wpz",
+       { "Savvius tagged", "peektagged", "pkt", "tpc;apc;wpz",
          FALSE, FALSE, 0,
          NULL, NULL, NULL },
 
@@ -1364,7 +1464,7 @@ static const struct file_type_subtype_info dump_open_table_base[] = {
          NULL, NULL, NULL },
 
        /* WTAP_FILE_TYPE_SUBTYPE_PACKETLOGGER */
-       { "PacketLogger", "pklg", "pklg", NULL,
+       { "OS X PacketLogger", "pklg", "pklg", NULL,
          FALSE, FALSE, 0,
          NULL, NULL, NULL },
 
@@ -1428,47 +1528,107 @@ static const struct file_type_subtype_info dump_open_table_base[] = {
          FALSE, FALSE, 0,
          NULL, NULL, NULL },
 
-       /* WTAP_FILE_NETSCALER_3_0 */
+       /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 */
        { "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL,
          TRUE, FALSE, 0,
          nstrace_30_dump_can_write_encap, nstrace_dump_open, NULL },
 
-       /* WTAP_FILE_LOGCAT */
-       { "Android Logcat Binary format",          "logcat",         "logcat", NULL,
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT */
+       { "Android Logcat Binary format", "logcat", "logcat", NULL,
          FALSE, FALSE, 0,
          logcat_dump_can_write_encap, logcat_binary_dump_open, NULL },
-       { "Android Logcat Brief text format",      "logcat-brief",      NULL, NULL,
-         FALSE, FALSE, 0,
-         logcat_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
-       { "Android Logcat Process text format",    "logcat-process",    NULL, NULL,
+
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_BRIEF */
+       { "Android Logcat Brief text format", "logcat-brief", NULL, NULL,
          FALSE, FALSE, 0,
-         logcat_dump_can_write_encap, logcat_text_process_dump_open, NULL },
-       { "Android Logcat Tag text format",        "logcat-tag",        NULL, NULL,
+         logcat_text_brief_dump_can_write_encap, logcat_text_brief_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_PROCESS */
+       { "Android Logcat Process text format", "logcat-process", NULL, NULL,
          FALSE, FALSE, 0,
-         logcat_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
-       { "Android Logcat Time text format",       "logcat-time",       NULL, NULL,
+         logcat_text_process_dump_can_write_encap, logcat_text_process_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TAG */
+       { "Android Logcat Tag text format", "logcat-tag", NULL, NULL,
          FALSE, FALSE, 0,
-         logcat_dump_can_write_encap, logcat_text_time_dump_open, NULL },
-       { "Android Logcat Thread text format",     "logcat-thread",     NULL, NULL,
+         logcat_text_tag_dump_can_write_encap, logcat_text_tag_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREAD */
+       { "Android Logcat Thread text format", "logcat-thread", NULL, NULL,
+          FALSE, FALSE, 0,
+          logcat_text_thread_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME */
+       { "Android Logcat Time text format", "logcat-time", NULL, NULL,
          FALSE, FALSE, 0,
-         logcat_dump_can_write_encap, logcat_text_thread_dump_open, NULL },
+         logcat_text_time_dump_can_write_encap, logcat_text_time_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME */
        { "Android Logcat Threadtime text format", "logcat-threadtime", NULL, NULL,
          FALSE, FALSE, 0,
-         logcat_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
-       { "Android Logcat Long text format",       "logcat-long",       NULL, NULL,
+         logcat_text_threadtime_dump_can_write_encap, logcat_text_threadtime_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG */
+       { "Android Logcat Long text format", "logcat-long", NULL, NULL,
+         FALSE, FALSE, 0,
+         logcat_text_long_dump_can_write_encap, logcat_text_long_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_CAPSA */
+       { "Colasoft Capsa format", "capsa", "cscpkt", NULL,
+         FALSE, FALSE, 0,
+         NULL, NULL, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_COLASOFT_PACKET_BUILDER */
+       { "Colasoft Packet Builder format", "colasoft-pb", "cscpkt", NULL,
+         FALSE, FALSE, 0,
+         NULL, NULL, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_JSON */
+       { "JavaScript Object Notation", "json", "json", "NULL",
+         FALSE, FALSE, 0,
+         NULL, NULL, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5 */
+       { "NetScaler Trace (Version 3.5)", "nstrace35", "cap", NULL,
+         TRUE, FALSE, 0,
+         nstrace_35_dump_can_write_encap, nstrace_dump_open, NULL },
+
+       /* WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423 */
+       { "3GPP TS 32.423 Trace", "3gpp32423", NULL, NULL,
          FALSE, FALSE, 0,
-         logcat_dump_can_write_encap, logcat_text_long_dump_open, NULL }
+         NULL, NULL, NULL },
 
+       /* WTAP_FILE_TYPE_MPLOG */
+       { "Micropross mplog file", "mplog", "mplog", NULL,
+         FALSE, FALSE, 0,
+         NULL, NULL, NULL }
 };
 
+/*
+ * Pointer to the table we're currently using.  It's initialized to point
+ * to the static table, but, if we have to allocate the GArray, it's
+ * changed to point to the data in the GArray.
+ */
+static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
+
+/*
+ * Number of elements in the table we're currently using.  It's initialized
+ * to the number of elements in the static table, but, if we have to
+ * allocate the GArray, it's changed to have the size of the GArray.
+ */
 gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
 
+/*
+ * Pointer to the GArray; NULL until it's needed.
+ */
 static GArray*  dump_open_table_arr = NULL;
-static const struct file_type_subtype_info* dump_open_table = dump_open_table_base;
-
-/* initialize the file types array if it has not being initialized yet */
-static void init_file_types_subtypes(void) {
 
+/*
+ * Create the GArray from the static table if it hasn't already been created.
+ */
+static void
+init_file_types_subtypes_garray(void)
+{
        if (dump_open_table_arr) return;
 
        dump_open_table_arr = g_array_new(FALSE,TRUE,sizeof(struct file_type_subtype_info));
@@ -1480,9 +1640,10 @@ static void init_file_types_subtypes(void) {
 
 /* if subtype is WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, then create a new subtype as well as register it, else replace the
    existing entry in that spot */
-int wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype) {
-       struct file_type_subtype_info* finfo = NULL;
-       init_file_types_subtypes();
+int
+wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, const int subtype)
+{
+       struct file_type_subtype_info* finfo;
 
        if (!fi || !fi->name || !fi->short_name || subtype > wtap_num_file_types_subtypes) {
                g_error("no file type info or invalid file type to register");
@@ -1497,6 +1658,11 @@ int wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, co
                        return subtype;
                }
 
+               /*
+                * Create the GArray if it hasn't already been created.
+                */
+               init_file_types_subtypes_garray();
+
                g_array_append_val(dump_open_table_arr,*fi);
 
                dump_open_table = (const struct file_type_subtype_info*)(void *)dump_open_table_arr->data;
@@ -1510,8 +1676,16 @@ int wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, co
                return subtype;
        }
 
-       /* yes, we're going to cast to change its const-ness */
-       finfo = (struct file_type_subtype_info*)(&dump_open_table[subtype]);
+       /*
+        * Create the GArray if it hasn't already been created.
+        */
+       init_file_types_subtypes_garray();
+
+       /*
+        * Get the pointer from the GArray, so that we get a non-const
+        * pointer.
+        */
+       finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
        /*finfo->name = fi->name;*/
        /*finfo->short_name = fi->short_name;*/
        finfo->default_file_extension     = fi->default_file_extension;
@@ -1528,16 +1702,26 @@ int wtap_register_file_type_subtypes(const struct file_type_subtype_info* fi, co
 
 /* De-registers a file writer - they can never be removed from the GArray, but we can "clear" an entry.
  */
-void wtap_deregister_file_type_subtype(const int subtype) {
-       struct file_type_subtype_info* finfo = NULL;
+void
+wtap_deregister_file_type_subtype(const int subtype)
+{
+       struct file_type_subtype_info* finfo;
 
        if (subtype < 0 || subtype >= wtap_num_file_types_subtypes) {
                g_error("invalid file type to de-register");
                return;
        }
 
-       /* yes, we're going to cast to change its const-ness */
-       finfo = (struct file_type_subtype_info*)(&dump_open_table[subtype]);
+       /*
+        * Create the GArray if it hasn't already been created.
+        */
+       init_file_types_subtypes_garray();
+
+       /*
+        * Get the pointer from the GArray, so that we get a non-const
+        * pointer.
+        */
+       finfo = &g_array_index(dump_open_table_arr, struct file_type_subtype_info, subtype);
        /* unfortunately, it's not safe to null-out the name or short_name; bunch of other code doesn't guard aainst that, afaict */
        /*finfo->name = NULL;*/
        /*finfo->short_name = NULL;*/
@@ -1551,7 +1735,8 @@ void wtap_deregister_file_type_subtype(const int subtype) {
        finfo->wslua_info = NULL;
 }
 
-int wtap_get_num_file_types_subtypes(void)
+int
+wtap_get_num_file_types_subtypes(void)
 {
        return wtap_num_file_types_subtypes;
 }
@@ -1662,20 +1847,21 @@ wtap_dump_can_write_format(int ft, const GArray *file_encaps,
 gboolean
 wtap_dump_can_write(const GArray *file_encaps, guint32 required_comment_types)
 {
-  int ft;
+       int ft;
 
-  for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
-    /* To save a file with Wiretap, Wiretap has to handle that format,
-       and its code to handle that format must be able to write a file
-       with this file's encapsulation types. */
-    if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
-      /* OK, we can write it out in this type. */
-      return TRUE;
-    }
-  }
+       for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
+               /* To save a file with Wiretap, Wiretap has to handle that format,
+                * and its code to handle that format must be able to write a file
+                * with this file's encapsulation types.
+                */
+               if (wtap_dump_can_write_format(ft, file_encaps, required_comment_types)) {
+                       /* OK, we can write it out in this type. */
+                       return TRUE;
+               }
+       }
 
-  /* No, we couldn't save it in any format. */
-  return FALSE;
+       /* No, we couldn't save it in any format. */
+       return FALSE;
 }
 
 /**
@@ -1694,7 +1880,7 @@ wtap_get_savable_file_types_subtypes(int file_type_subtype,
 
        /* Can we save this file in its own file type/subtype? */
        if (wtap_dump_can_write_format(file_type_subtype, file_encaps,
-                                      required_comment_types)) {
+                                      required_comment_types)) {
                /* Yes - make that the default file type/subtype. */
                default_file_type_subtype = file_type_subtype;
        } else {
@@ -1702,7 +1888,7 @@ wtap_get_savable_file_types_subtypes(int file_type_subtype,
                default_file_type_subtype = -1;
                for (ft = 0; ft < WTAP_NUM_FILE_TYPES_SUBTYPES; ft++) {
                        if (wtap_dump_can_write_format(ft, file_encaps,
-                                                      required_comment_types)) {
+                                                      required_comment_types)) {
                                /* OK, got it. */
                                default_file_type_subtype = ft;
                        }
@@ -1726,11 +1912,11 @@ wtap_get_savable_file_types_subtypes(int file_type_subtype,
           pcap format. */
        if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
                if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAPNG, file_encaps,
-                                              required_comment_types))
+                                              required_comment_types))
                        other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
        } else if (default_file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
                if (wtap_dump_can_write_format(WTAP_FILE_TYPE_SUBTYPE_PCAP, file_encaps,
-                                              required_comment_types))
+                                              required_comment_types))
                        other_file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PCAP;
        }
        if (other_file_type_subtype != -1)
@@ -1743,7 +1929,7 @@ wtap_get_savable_file_types_subtypes(int file_type_subtype,
                if (ft == default_file_type_subtype || ft == other_file_type_subtype)
                        continue;       /* we've already done this one */
                if (wtap_dump_can_write_format(ft, file_encaps,
-                                              required_comment_types)) {
+                                              required_comment_types)) {
                        /* OK, we can write it out in this type. */
                        g_array_append_val(savable_file_types_subtypes, ft);
                }
@@ -1753,7 +1939,8 @@ wtap_get_savable_file_types_subtypes(int file_type_subtype,
 }
 
 /* Name that should be somewhat descriptive. */
-const char *wtap_file_type_subtype_string(int file_type_subtype)
+const char *
+wtap_file_type_subtype_string(int file_type_subtype)
 {
        if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes) {
                g_error("Unknown capture file type %d", file_type_subtype);
@@ -1764,7 +1951,8 @@ const char *wtap_file_type_subtype_string(int file_type_subtype)
 }
 
 /* Name to use in, say, a command-line flag specifying the type/subtype. */
-const char *wtap_file_type_subtype_short_string(int file_type_subtype)
+const char *
+wtap_file_type_subtype_short_string(int file_type_subtype)
 {
        if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
                return NULL;
@@ -1773,7 +1961,8 @@ const char *wtap_file_type_subtype_short_string(int file_type_subtype)
 }
 
 /* Translate a short name to a capture file type/subtype. */
-int wtap_short_string_to_file_type_subtype(const char *short_name)
+int
+wtap_short_string_to_file_type_subtype(const char *short_name)
 {
        int file_type_subtype;
 
@@ -1796,7 +1985,7 @@ int wtap_short_string_to_file_type_subtype(const char *short_name)
 
 static GSList *
 add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
-    GSList *compressed_file_extensions)
+    const char **compressed_file_extensions)
 {
        gchar **extensions_set, **extensionp;
        gchar *extension;
@@ -1847,10 +2036,13 @@ add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
 
    All strings in the list are allocated with g_malloc() and must be freed
    with g_free(). */
-GSList *wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
+GSList *
+wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed)
 {
-       GSList *compressed_file_extensions;
        GSList *extensions;
+       static const char *no_compressed_extensions[] = {
+               NULL
+       };
 
        if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
                return NULL;    /* not a valid file type */
@@ -1860,23 +2052,13 @@ GSList *wtap_get_file_extensions_list(int file_type_subtype, gboolean include_co
 
        extensions = NULL;      /* empty list, to start with */
 
-       /*
-        * If include_compressions is true, get the list of compressed-file
-        * extensions.
-        */
-       if (include_compressed)
-               compressed_file_extensions = wtap_get_compressed_file_extensions();
-       else
-               compressed_file_extensions = NULL;
-
        /*
         * Add all this file type's extensions, with compressed
-        * variants.
+        * variants if include_compressed is true.
         */
        extensions = add_extensions_for_file_type_subtype(file_type_subtype, extensions,
-           compressed_file_extensions);
+           include_compressed ? compressed_file_extension_table : no_compressed_extensions);
 
-       g_slist_free(compressed_file_extensions);
        return extensions;
 }
 
@@ -1884,7 +2066,8 @@ GSList *wtap_get_file_extensions_list(int file_type_subtype, gboolean include_co
  * Free a list returned by wtap_get_file_extension_type_extensions(),
  * wtap_get_all_file_extensions_list, or wtap_get_file_extensions_list().
  */
-void wtap_free_extensions_list(GSList *extensions)
+void
+wtap_free_extensions_list(GSList *extensions)
 {
        GSList *extension;
 
@@ -1897,7 +2080,8 @@ void wtap_free_extensions_list(GSList *extensions)
 
 /* Return the default file extension to use with the specified file type;
    that's just the extension, without any ".". */
-const char *wtap_default_file_extension(int file_type_subtype)
+const char *
+wtap_default_file_extension(int file_type_subtype)
 {
        if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes)
                return NULL;
@@ -1905,7 +2089,8 @@ const char *wtap_default_file_extension(int file_type_subtype)
                return dump_open_table[file_type_subtype].default_file_extension;
 }
 
-gboolean wtap_dump_can_open(int file_type_subtype)
+gboolean
+wtap_dump_can_open(int file_type_subtype)
 {
        if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
            || dump_open_table[file_type_subtype].dump_open == NULL)
@@ -1914,8 +2099,9 @@ gboolean wtap_dump_can_open(int file_type_subtype)
        return TRUE;
 }
 
-#ifdef HAVE_LIBZ
-gboolean wtap_dump_can_compress(int file_type_subtype)
+#ifdef HAVE_ZLIB
+gboolean
+wtap_dump_can_compress(int file_type_subtype)
 {
        /*
         * If this is an unknown file type, or if we have to
@@ -1929,13 +2115,15 @@ gboolean wtap_dump_can_compress(int file_type_subtype)
        return TRUE;
 }
 #else
-gboolean wtap_dump_can_compress(int file_type_subtype _U_)
+gboolean
+wtap_dump_can_compress(int file_type_subtype _U_)
 {
        return FALSE;
 }
 #endif
 
-gboolean wtap_dump_has_name_resolution(int file_type_subtype)
+gboolean
+wtap_dump_has_name_resolution(int file_type_subtype)
 {
        if (file_type_subtype < 0 || file_type_subtype >= wtap_num_file_types_subtypes
            || dump_open_table[file_type_subtype].has_name_resolution == FALSE)
@@ -1944,7 +2132,8 @@ gboolean wtap_dump_has_name_resolution(int file_type_subtype)
        return TRUE;
 }
 
-gboolean wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
+gboolean
+wtap_dump_supports_comment_types(int file_type_subtype, guint32 comment_types)
 {
        guint32 supported_comment_types;
 
@@ -1967,17 +2156,19 @@ static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename);
 static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd);
 static int wtap_dump_file_close(wtap_dumper *wdh);
 
-wtap_dumper* wtap_dump_open(const char *filename, int file_type_subtype, int encap,
-                               int snaplen, gboolean compressed, int *err)
-{
-       return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, err);
-}
-
 static wtap_dumper *
 wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
-    wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+                      wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                      wtap_optionblock_t nrb_hdr, int *err)
 {
        wtap_dumper *wdh;
+       wtap_optionblock_t descr, file_int_data;
+       wtapng_if_descr_mandatory_t *descr_mand, *file_int_data_mand;
+
+       /* Check whether we can open a capture file with that file type
+          and that encapsulation. */
+       if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
+               return NULL;
 
        /* Allocate a data structure for the output stream. */
        wdh = wtap_dump_alloc_wdh(file_type_subtype, encap, snaplen, compressed, err);
@@ -1986,136 +2177,237 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co
 
        /* Set Section Header Block data */
        wdh->shb_hdr = shb_hdr;
+       /* Set Name Resolution Block data */
+       wdh->nrb_hdr = nrb_hdr;
        /* Set Interface Description Block data */
        if ((idb_inf != NULL) && (idb_inf->interface_data->len > 0)) {
-               wdh->interface_data = idb_inf->interface_data;
+               guint itf_count;
+
+               /* XXX: what free's this stuff? */
+               wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
+               for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) {
+                       file_int_data = g_array_index(idb_inf->interface_data, wtap_optionblock_t, itf_count);
+                       file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(file_int_data);
+                       descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+                       wtap_optionblock_copy_options(descr, file_int_data);
+                       if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data_mand->wtap_encap)) {
+                               descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+                               descr_mand->wtap_encap = encap;
+                               descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
+                       }
+                       g_array_append_val(wdh->interface_data, descr);
+               }
        } else {
-               wtapng_if_descr_t descr;
-
-               descr.wtap_encap = encap;
-               descr.time_units_per_second = 1000000; /* default microsecond resolution */
-               descr.link_type = wtap_wtap_encap_to_pcap_encap(encap);
-               descr.snap_len = snaplen;
-               descr.opt_comment = NULL;
-               descr.if_name = g_strdup("Unknown/not available in original file format(libpcap)");
-               descr.if_description = NULL;
-               descr.if_speed = 0;
-               descr.if_tsresol = 6;
-               descr.if_filter_str= NULL;
-               descr.bpf_filter_len= 0;
-               descr.if_filter_bpf_bytes= NULL;
-               descr.if_os = NULL;
-               descr.if_fcslen = -1;
-               descr.num_stat_entries = 0;          /* Number of ISB:s */
-               descr.interface_statistics = NULL;
+               descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+               descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+               descr_mand->wtap_encap = encap;
+               descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+               descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
+               descr_mand->snap_len = snaplen;
+               wtap_optionblock_set_option_string(descr, OPT_IDB_NAME, "Unknown/not available in original file format(libpcap)",
+                                                                                                               strlen("Unknown/not available in original file format(libpcap)"));
+
+               descr_mand->num_stat_entries = 0;          /* Number of ISB:s */
+               descr_mand->interface_statistics = NULL;
+               wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
                g_array_append_val(wdh->interface_data, descr);
        }
        return wdh;
 }
 
-wtap_dumper* wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
-                               int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+wtap_dumper *
+wtap_dump_open(const char *filename, int file_type_subtype, int encap,
+              int snaplen, gboolean compressed, int *err)
+{
+       return wtap_dump_open_ng(filename, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
+}
+
+wtap_dumper *
+wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
+                 int snaplen, gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                 wtap_optionblock_t nrb_hdr, int *err)
 {
        wtap_dumper *wdh;
        WFILE_T fh;
 
-       /* Check whether we can open a capture file with that file type
-          and that encapsulation. */
-       if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
+       /* Allocate and initialize a data structure for the output stream. */
+       wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
+           shb_hdr, idb_inf, nrb_hdr, err);
+       if (wdh == NULL)
                return NULL;
 
+       /* In case "fopen()" fails but doesn't set "errno", set "errno"
+          to a generic "the open failed" error. */
+       errno = WTAP_ERR_CANT_OPEN;
+       fh = wtap_dump_file_open(wdh, filename);
+       if (fh == NULL) {
+               *err = errno;
+               g_free(wdh);
+               return NULL;    /* can't create file */
+       }
+       wdh->fh = fh;
+
+       if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
+               /* Get rid of the file we created; we couldn't finish
+                  opening it. */
+               wtap_dump_file_close(wdh);
+               ws_unlink(filename);
+               g_free(wdh);
+               return NULL;
+       }
+       return wdh;
+}
+
+wtap_dumper *
+wtap_dump_open_tempfile(char **filenamep, const char *pfx,
+                       int file_type_subtype, int encap,
+                       int snaplen, gboolean compressed, int *err)
+{
+       return wtap_dump_open_tempfile_ng(filenamep, pfx, file_type_subtype, encap,snaplen, compressed, NULL, NULL, NULL, err);
+}
+
+wtap_dumper *
+wtap_dump_open_tempfile_ng(char **filenamep, const char *pfx,
+                          int file_type_subtype, int encap,
+                          int snaplen, gboolean compressed,
+                          wtap_optionblock_t shb_hdr,
+                          wtapng_iface_descriptions_t *idb_inf,
+                          wtap_optionblock_t nrb_hdr, int *err)
+{
+       int fd;
+       char *tmpname;
+       wtap_dumper *wdh;
+       WFILE_T fh;
+
+       /* No path name for the temporary file yet. */
+       *filenamep = NULL;
+
        /* Allocate and initialize a data structure for the output stream. */
        wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
-           shb_hdr, idb_inf, err);
+           shb_hdr, idb_inf, nrb_hdr, err);
        if (wdh == NULL)
                return NULL;
 
-       /* "-" means stdout */
-       if (strcmp(filename, "-") == 0) {
-               if (compressed) {
-                       *err = EINVAL;  /* XXX - return a Wiretap error code for this */
-                       g_free(wdh);
-                       return NULL;    /* compress won't work on stdout */
-               }
-#ifdef _WIN32
-               if (_setmode(fileno(stdout), O_BINARY) == -1) {
-                       /* "Should not happen" */
-                       *err = errno;
-                       g_free(wdh);
-                       return NULL;    /* couldn't put standard output in binary mode */
-               }
-#endif
-               wdh->fh = stdout;
-       } else {
-               /* In case "fopen()" fails but doesn't set "errno", set "errno"
-                  to a generic "the open failed" error. */
-               errno = WTAP_ERR_CANT_OPEN;
-               fh = wtap_dump_file_open(wdh, filename);
-               if (fh == NULL) {
-                       *err = errno;
-                       g_free(wdh);
-                       return NULL;    /* can't create file */
-               }
-               wdh->fh = fh;
+       /* Choose a random name for the file */
+       fd = create_tempfile(&tmpname, pfx);
+       if (fd == -1) {
+               *err = errno;
+               g_free(wdh);
+               return NULL;    /* can't create file */
+       }
+       *filenamep = tmpname;
+
+       /* In case "fopen()" fails but doesn't set "errno", set "errno"
+          to a generic "the open failed" error. */
+       errno = WTAP_ERR_CANT_OPEN;
+       fh = wtap_dump_file_fdopen(wdh, fd);
+       if (fh == NULL) {
+               *err = errno;
+               ws_close(fd);
+               g_free(wdh);
+               return NULL;    /* can't create file */
        }
+       wdh->fh = fh;
 
        if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
                /* Get rid of the file we created; we couldn't finish
                   opening it. */
-               if (wdh->fh != stdout) {
-                       wtap_dump_file_close(wdh);
-                       ws_unlink(filename);
-               }
+               wtap_dump_file_close(wdh);
+               ws_unlink(tmpname);
                g_free(wdh);
                return NULL;
        }
        return wdh;
 }
 
-wtap_dumper* wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
-                               gboolean compressed, int *err)
+wtap_dumper *
+wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
+                gboolean compressed, int *err)
 {
-       return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, err);
+       return wtap_dump_fdopen_ng(fd, file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
 }
 
-wtap_dumper* wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
-                               gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
+wtap_dumper *
+wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
+                   gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                   wtap_optionblock_t nrb_hdr, int *err)
 {
        wtap_dumper *wdh;
        WFILE_T fh;
 
-       /* Check whether we can open a capture file with that file type
-          and that encapsulation. */
-       if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err))
+       /* Allocate and initialize a data structure for the output stream. */
+       wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
+           shb_hdr, idb_inf, nrb_hdr, err);
+       if (wdh == NULL)
                return NULL;
 
+       /* In case "fopen()" fails but doesn't set "errno", set "errno"
+          to a generic "the open failed" error. */
+       errno = WTAP_ERR_CANT_OPEN;
+       fh = wtap_dump_file_fdopen(wdh, fd);
+       if (fh == NULL) {
+               *err = errno;
+               g_free(wdh);
+               return NULL;    /* can't create standard I/O stream */
+       }
+       wdh->fh = fh;
+
+       if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
+               wtap_dump_file_close(wdh);
+               g_free(wdh);
+               return NULL;
+       }
+       return wdh;
+}
+
+wtap_dumper *
+wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen,
+                     gboolean compressed, int *err)
+{
+       return wtap_dump_open_stdout_ng(file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err);
+}
+
+wtap_dumper *
+wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
+                        gboolean compressed, wtap_optionblock_t shb_hdr,
+                        wtapng_iface_descriptions_t *idb_inf,
+                        wtap_optionblock_t nrb_hdr, int *err)
+{
+       wtap_dumper *wdh;
+       WFILE_T fh;
+
        /* Allocate and initialize a data structure for the output stream. */
        wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
-           shb_hdr, idb_inf, err);
+           shb_hdr, idb_inf, nrb_hdr, err);
        if (wdh == NULL)
                return NULL;
 
 #ifdef _WIN32
-       if (fd == 1) {
-               if (_setmode(fileno(stdout), O_BINARY) == -1) {
-                       /* "Should not happen" */
-                       *err = errno;
-                       g_free(wdh);
-                       return NULL;    /* couldn't put standard output in binary mode */
-               }
+       /*
+        * Put the standard output into binary mode.
+        *
+        * XXX - even if the file format we're writing is a text
+        * format?
+        */
+       if (_setmode(1, O_BINARY) == -1) {
+               /* "Should not happen" */
+               *err = errno;
+               g_free(wdh);
+               return NULL;    /* couldn't put standard output in binary mode */
        }
 #endif
 
        /* In case "fopen()" fails but doesn't set "errno", set "errno"
           to a generic "the open failed" error. */
        errno = WTAP_ERR_CANT_OPEN;
-       fh = wtap_dump_file_fdopen(wdh, fd);
+       fh = wtap_dump_file_fdopen(wdh, 1);
        if (fh == NULL) {
                *err = errno;
                g_free(wdh);
                return NULL;    /* can't create standard I/O stream */
        }
        wdh->fh = fh;
+       wdh->is_stdout = TRUE;
 
        if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
                wtap_dump_file_close(wdh);
@@ -2125,11 +2417,12 @@ wtap_dumper* wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int s
        return wdh;
 }
 
-static gboolean wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
+static gboolean
+wtap_dump_open_check(int file_type_subtype, int encap, gboolean compressed, int *err)
 {
        if (!wtap_dump_can_open(file_type_subtype)) {
                /* Invalid type, or type we don't know how to write. */
-               *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
+               *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
                return FALSE;
        }
 
@@ -2158,8 +2451,8 @@ static gboolean wtap_dump_open_check(int file_type_subtype, int encap, gboolean
        return TRUE;
 }
 
-static wtap_dumper* wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen,
-                                       gboolean compressed, int *err)
+static wtap_dumper *
+wtap_dump_alloc_wdh(int file_type_subtype, int encap, int snaplen, gboolean compressed, int *err)
 {
        wtap_dumper *wdh;
 
@@ -2177,7 +2470,8 @@ static wtap_dumper* wtap_dump_alloc_wdh(int file_type_subtype, int encap, int sn
        return wdh;
 }
 
-static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
+static gboolean
+wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, gboolean compressed, int *err)
 {
        int fd;
        gboolean cant_seek;
@@ -2187,12 +2481,12 @@ static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, g
        if(compressed) {
                cant_seek = TRUE;
        } else {
-               fd = fileno((FILE *)wdh->fh);
-               if (lseek(fd, 1, SEEK_CUR) == -1)
+               fd = ws_fileno((FILE *)wdh->fh);
+               if (ws_lseek64(fd, 1, SEEK_CUR) == (off_t) -1)
                        cant_seek = TRUE;
                else {
                        /* Undo the seek. */
-                       lseek(fd, 0, SEEK_SET);
+                       ws_lseek64(fd, 0, SEEK_SET);
                        cant_seek = FALSE;
                }
        }
@@ -2217,15 +2511,19 @@ static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int file_type_subtype, g
        return TRUE;    /* success! */
 }
 
-gboolean wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
-                  const guint8 *pd, int *err)
+gboolean
+wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
+         const guint8 *pd, int *err, gchar **err_info)
 {
-       return (wdh->subtype_write)(wdh, phdr, pd, err);
+       *err = 0;
+       *err_info = NULL;
+       return (wdh->subtype_write)(wdh, phdr, pd, err, err_info);
 }
 
-void wtap_dump_flush(wtap_dumper *wdh)
+void
+wtap_dump_flush(wtap_dumper *wdh)
 {
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
        if(wdh->compressed) {
                gzwfile_flush((GZWFILE_T)wdh->fh);
        } else
@@ -2235,31 +2533,26 @@ void wtap_dump_flush(wtap_dumper *wdh)
        }
 }
 
-gboolean wtap_dump_close(wtap_dumper *wdh, int *err)
+gboolean
+wtap_dump_close(wtap_dumper *wdh, int *err)
 {
        gboolean ret = TRUE;
 
-       if (wdh->subtype_close != NULL) {
-               /* There's a close routine for this dump stream. */
-               if (!(wdh->subtype_close)(wdh, err))
+       if (wdh->subtype_finish != NULL) {
+               /* There's a finish routine for this dump stream. */
+               if (!(wdh->subtype_finish)(wdh, err))
                        ret = FALSE;
        }
        errno = WTAP_ERR_CANT_CLOSE;
-       /* Don't close stdout */
-       if (wdh->fh != stdout) {
-               if (wtap_dump_file_close(wdh) == EOF) {
-                       if (ret) {
-                               /* The per-format close function succeeded,
-                                  but the fclose didn't.  Save the reason
-                                  why, if our caller asked for it. */
-                               if (err != NULL)
-                                       *err = errno;
-                       }
-                       ret = FALSE;
+       if (wtap_dump_file_close(wdh) == EOF) {
+               if (ret) {
+                       /* The per-format finish function succeeded,
+                          but the stream close didn't.  Save the
+                          reason why, if our caller asked for it. */
+                       if (err != NULL)
+                               *err = errno;
                }
-       } else {
-               /* as we don't close stdout, at least try to flush it */
-               wtap_dump_flush(wdh);
+               ret = FALSE;
        }
        if (wdh->priv != NULL)
                g_free(wdh->priv);
@@ -2267,17 +2560,20 @@ gboolean wtap_dump_close(wtap_dumper *wdh, int *err)
        return ret;
 }
 
-gint64 wtap_get_bytes_dumped(wtap_dumper *wdh)
+gint64
+wtap_get_bytes_dumped(wtap_dumper *wdh)
 {
        return wdh->bytes_dumped;
 }
 
-void wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
+void
+wtap_set_bytes_dumped(wtap_dumper *wdh, gint64 bytes_dumped)
 {
        wdh->bytes_dumped = bytes_dumped;
 }
 
-gboolean wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
+gboolean
+wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinfo_lists)
 {
        if (!wdh || wdh->file_type_subtype < 0 || wdh->file_type_subtype >= wtap_num_file_types_subtypes
                || dump_open_table[wdh->file_type_subtype].has_name_resolution == FALSE)
@@ -2287,8 +2583,9 @@ gboolean wtap_dump_set_addrinfo_list(wtap_dumper *wdh, addrinfo_lists_t *addrinf
 }
 
 /* internally open a file for writing (compressed or not) */
-#ifdef HAVE_LIBZ
-static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
+#ifdef HAVE_ZLIB
+static WFILE_T
+wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
 {
        if(wdh->compressed) {
                return gzwfile_open(filename);
@@ -2297,38 +2594,41 @@ static WFILE_T wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
        }
 }
 #else
-static WFILE_T wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
+static WFILE_T
+wtap_dump_file_open(wtap_dumper *wdh _U_, const char *filename)
 {
        return ws_fopen(filename, "wb");
 }
 #endif
 
 /* internally open a file for writing (compressed or not) */
-#ifdef HAVE_LIBZ
-static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
+#ifdef HAVE_ZLIB
+static WFILE_T
+wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
 {
        if(wdh->compressed) {
                return gzwfile_fdopen(fd);
        } else {
-               return fdopen(fd, "wb");
+               return ws_fdopen(fd, "wb");
        }
 }
 #else
-static WFILE_T wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
+static WFILE_T
+wtap_dump_file_fdopen(wtap_dumper *wdh _U_, int fd)
 {
-       return fdopen(fd, "wb");
+       return ws_fdopen(fd, "wb");
 }
 #endif
 
 /* internally writing raw bytes (compressed or not) */
-gboolean wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize,
-                    int *err)
+gboolean
+wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize, int *err)
 {
        size_t nwritten;
 
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
        if (wdh->compressed) {
-               nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned) bufsize);
+               nwritten = gzwfile_write((GZWFILE_T)wdh->fh, buf, (unsigned int) bufsize);
                /*
                 * gzwfile_write() returns 0 on error.
                 */
@@ -2339,6 +2639,7 @@ gboolean wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize,
        } else
 #endif
        {
+               errno = WTAP_ERR_CANT_WRITE;
                nwritten = fwrite(buf, 1, bufsize, (FILE *)wdh->fh);
                /*
                 * At least according to the Mac OS X man page,
@@ -2356,21 +2657,34 @@ gboolean wtap_dump_file_write(wtap_dumper *wdh, const void *buf, size_t bufsize,
 }
 
 /* internally close a file for writing (compressed or not) */
-static int wtap_dump_file_close(wtap_dumper *wdh)
+static int
+wtap_dump_file_close(wtap_dumper *wdh)
 {
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
        if(wdh->compressed) {
-               return gzwfile_close((GZWFILE_T)wdh->fh);
+               /*
+                * Tell gzwfile_close() whether to close the descriptor
+                * or not.
+                */
+               return gzwfile_close((GZWFILE_T)wdh->fh, wdh->is_stdout);
        } else
 #endif
        {
-               return fclose((FILE *)wdh->fh);
+               /*
+                * Don't close the standard output.
+                *
+                * XXX - this really should do everything fclose() does,
+                * including freeing all allocated data structures,
+                * *except* for actually closing the file descriptor.
+                */
+               return wdh->is_stdout ? fflush((FILE *)wdh->fh) : fclose((FILE *)wdh->fh);
        }
 }
 
-gint64 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
+gint64
+wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err)
 {
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
        if(wdh->compressed) {
                *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
                return -1;
@@ -2386,10 +2700,12 @@ gint64 wtap_dump_file_seek(wtap_dumper *wdh, gint64 offset, int whence, int *err
                }
        }
 }
-gint64 wtap_dump_file_tell(wtap_dumper *wdh, int *err)
+
+gint64
+wtap_dump_file_tell(wtap_dumper *wdh, int *err)
 {
        gint64 rval;
-#ifdef HAVE_LIBZ
+#ifdef HAVE_ZLIB
        if(wdh->compressed) {
                *err = WTAP_ERR_CANT_SEEK_COMPRESSED;
                return -1;
@@ -2405,3 +2721,16 @@ gint64 wtap_dump_file_tell(wtap_dumper *wdh, int *err)
                }
        }
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */