In a Network Monitor capture file, get the starting offsets of frames
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 22 Mar 2000 07:06:59 +0000 (07:06 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 22 Mar 2000 07:06:59 +0000 (07:06 +0000)
from the frame table - Network Monitor 2.x, at least, doesn't always
write frame N+1 right after frame N.

To do that, we need to mallocate a big array to hold the frame table,
and free it when we close the capture file; this requires that we have
capture-file-type-specific close routines as well as
capture-file-type-specific read routines - we let it the pointer to that
routine be null if it's not needed.  Given that, we might as well get
rid of the switch statement in "wtap_close()", in favor of using
capture-file-type-specific close routines, as per the comment before
that switch statement.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@1740 f5534014-38df-0310-8fa8-9805f1628bb7

wiretap/ascend.c
wiretap/file.c
wiretap/lanalyzer.c
wiretap/libpcap.c
wiretap/netmon.c
wiretap/nettl.c
wiretap/netxray.c
wiretap/ngsniffer.c
wiretap/radcom.c
wiretap/wtap.c
wiretap/wtap.h

index 54caaee14b849c789d134542583b42845479e73f..0bf57be1710d46b409da8b6adac1d913a6c5cf3a 100644 (file)
@@ -1,6 +1,6 @@
 /* ascend.c
  *
- * $Id: ascend.c,v 1.12 2000/01/22 06:22:35 guy Exp $
+ * $Id: ascend.c,v 1.13 2000/03/22 07:06:56 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -82,6 +82,7 @@ static const char ascend_w2magic[] = { 'W', 'D', '_', 'D', 'I', 'A', 'L', 'O', '
 #define ASCEND_W2_SIZE (sizeof ascend_w2magic / sizeof ascend_w2magic[0])
 
 static int ascend_read(wtap *wth, int *err);
+static void ascend_close(wtap *wth);
 
 /* Seeks to the beginning of the next packet, and returns the
    byte offset.  Returns -1 on failure.  A valid offset is 0; since
@@ -149,6 +150,7 @@ int ascend_open(wtap *wth, int *err)
   wth->file_type = WTAP_FILE_ASCEND;
   wth->snapshot_length = ASCEND_MAX_PKT_LEN;
   wth->subtype_read = ascend_read;
+  wth->subtype_close = ascend_close;
   wth->capture.ascend = g_malloc(sizeof(ascend_t));
 
   /* MAXen and Pipelines report the time since reboot.  In order to keep 
@@ -212,3 +214,8 @@ int ascend_seek_read (FILE *fh, int seek_off, guint8 *pd, int len)
   file_seek(fh, seek_off - 1, SEEK_SET);
   return parse_ascend(fh, pd, NULL, NULL, len);
 }
+
+static void ascend_close(wtap *wth)
+{
+  g_free(wth->capture.ascend);
+}
index df408fc4a5bb927f20792473d703411965357fc0..5ac32e4576cb2bcda8b5ceeaafbb67537f58b73c 100644 (file)
@@ -1,6 +1,6 @@
 /* file.c
  *
- * $Id: file.c,v 1.48 2000/02/03 06:29:07 guy Exp $
+ * $Id: file.c,v 1.49 2000/03/22 07:06:58 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -151,6 +151,7 @@ wtap* wtap_open_offline(const char *filename, int *err)
        /* initialization */
        wth->file_encap = WTAP_ENCAP_UNKNOWN;
        wth->data_offset = 0;
+       wth->subtype_close = NULL;
 
        /* Try all file types */
        for (i = 0; i < N_FILE_TYPES; i++) {
index 8845420a5a13ec756c1da0f711c54917b51023eb..29ab094361dce4d397c7aab3f8abfe463d15bed8 100644 (file)
@@ -1,6 +1,6 @@
 /* lanalyzer.c
  *
- * $Id: lanalyzer.c,v 1.20 2000/01/22 06:22:38 guy Exp $
+ * $Id: lanalyzer.c,v 1.21 2000/03/22 07:06:58 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -49,6 +49,7 @@
 #define BOARD_325TR            227     /* LANalyzer 325TR (Token-ring) */
 
 static int lanalyzer_read(wtap *wth, int *err);
+static void lanalyzer_close(wtap *wth);
 
 int lanalyzer_open(wtap *wth, int *err)
 {
@@ -86,6 +87,7 @@ int lanalyzer_open(wtap *wth, int *err)
        wth->file_type = WTAP_FILE_LANALYZER;
        wth->capture.lanalyzer = g_malloc(sizeof(lanalyzer_t));
        wth->subtype_read = lanalyzer_read;
+       wth->subtype_close = lanalyzer_close;
        wth->snapshot_length = 0;
 
        /* Read records until we find the start of packets */
@@ -294,3 +296,9 @@ static int lanalyzer_read(wtap *wth, int *err)
 
        return data_offset;
 }
+
+static void
+lanalyzer_close(wtap *wth)
+{
+       g_free(wth->capture.lanalyzer);
+}
index a4a45e673d94a7986e53dbdaea7d2e02aa5781ab..822b2faaed963256c2c36e6eda0bdd60862503e4 100644 (file)
@@ -1,6 +1,6 @@
 /* libpcap.c
  *
- * $Id: libpcap.c,v 1.32 2000/02/19 08:00:06 guy Exp $
+ * $Id: libpcap.c,v 1.33 2000/03/22 07:06:58 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -88,6 +88,7 @@ struct pcaprec_modified_hdr {
 
 static int libpcap_read(wtap *wth, int *err);
 static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
+static void libpcap_close(wtap *wth);
 static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
     const u_char *pd, int *err);
 
@@ -259,6 +260,7 @@ int libpcap_open(wtap *wth, int *err)
        wth->capture.pcap->version_major = hdr.version_major;
        wth->capture.pcap->version_minor = hdr.version_minor;
        wth->subtype_read = libpcap_read;
+       wth->subtype_close = libpcap_close;
        wth->file_encap = pcap_encap[hdr.network];
        wth->snapshot_length = hdr.snaplen;
 
@@ -454,6 +456,12 @@ adjust_header(wtap *wth, struct pcaprec_hdr *hdr)
        }
 }
 
+static void
+libpcap_close(wtap *wth)
+{
+       g_free(wth->capture.pcap);
+}
+
 int wtap_pcap_encap_to_wtap_encap(int encap)
 {
        if (encap < 0 || encap >= NUM_PCAP_ENCAPS)
index 837b6bcfa89da02342e473d3c13c911fa2adda66..a7086606f4f5f057766282ba03f55ae9f5705117 100644 (file)
@@ -1,6 +1,6 @@
 /* netmon.c
  *
- * $Id: netmon.c,v 1.25 2000/02/19 08:00:05 guy Exp $
+ * $Id: netmon.c,v 1.26 2000/03/22 07:06:54 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -95,6 +95,7 @@ struct netmonrec_2_x_hdr {
 };
 
 static int netmon_read(wtap *wth, int *err);
+static void netmon_close(wtap *wth);
 static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
     const u_char *pd, int *err);
 static gboolean netmon_dump_close(wtap_dumper *wdh, int *err);
@@ -121,8 +122,8 @@ int netmon_open(wtap *wth, int *err)
        };
        #define NUM_NETMON_ENCAPS (sizeof netmon_encap / sizeof netmon_encap[0])
        struct tm tm;
+       int frame_table_offset;
        guint32 frame_table_length;
-       guint32 first_frame_table_entry;
 
        /* Read in the string that should be at the start of a Network
         * Monitor file */
@@ -180,6 +181,7 @@ int netmon_open(wtap *wth, int *err)
        wth->file_type = file_type;
        wth->capture.netmon = g_malloc(sizeof(netmon_t));
        wth->subtype_read = netmon_read;
+       wth->subtype_close = netmon_close;
        wth->file_encap = netmon_encap[hdr.network];
        wth->snapshot_length = 16384;   /* XXX - not available in header */
        /*
@@ -213,48 +215,49 @@ int netmon_open(wtap *wth, int *err)
        wth->capture.netmon->version_major = hdr.ver_major;
 
        /*
-        * The "frame index table" appears to come after the last
-        * packet; remember its offset, so we know when we have no
-        * more packets to read.
+        * Get the offset of the frame index table.
         */
-       wth->capture.netmon->end_offset = pletohl(&hdr.frametableoffset);
+       frame_table_offset = pletohl(&hdr.frametableoffset);
 
        /*
         * It appears that some NetMon 2.x files don't have the
         * first packet starting exactly 128 bytes into the file.
-        * So we read the first entry from the frame table, and
-        * use that as the offset of the first packet.
         *
-        * First, make sure the frame table has at least one entry
-        * in it....
+        * Furthermore, it also appears that there are "holes" in
+        * the file, i.e. frame N+1 doesn't always follow immediately
+        * after frame N.
+        *
+        * Therefore, we must read the frame table, and use the offsets
+        * in it as the offsets of the frames.
         */
        frame_table_length = pletohl(&hdr.frametablelength);
-       if (frame_table_length < sizeof first_frame_table_entry) {
+       wth->capture.netmon->frame_table_size = frame_table_length / sizeof (guint32);
+       if ((wth->capture.netmon->frame_table_size * sizeof (guint32)) != frame_table_length) {
+               g_message("netmon: frame table length is %u, which is not a multiple of the size of an entry",
+                   frame_table_length);
+               *err = WTAP_ERR_UNSUPPORTED;
+               return -1;
+       }
+       if (wth->capture.netmon->frame_table_size == 0) {
                g_message("netmon: frame table length is %u, which means it's less than one entry in size",
                    frame_table_length);
                *err = WTAP_ERR_UNSUPPORTED;
                return -1;
        }
-
-       /*
-        * Now read that entry.  (It appears that the N+1st frame immediately
-        * follows the Nth frame, so we don't need any entries after the
-        * first entry.)
-        */
+       wth->capture.netmon->frame_table = g_malloc(frame_table_length);
        errno = WTAP_ERR_CANT_READ;
-       file_seek(wth->fh, wth->capture.netmon->end_offset, SEEK_SET);
-       bytes_read = file_read(&first_frame_table_entry, 1,
-           sizeof first_frame_table_entry, wth->fh);
-       if (bytes_read != sizeof first_frame_table_entry) {
+       file_seek(wth->fh, frame_table_offset, SEEK_SET);
+       bytes_read = file_read(wth->capture.netmon->frame_table, 1,
+           frame_table_length, wth->fh);
+       if (bytes_read != frame_table_length) {
                *err = file_error(wth->fh);
                if (*err != 0)
                        return -1;
                return 0;
        }
 
-       /* Seek to the beginning of the data records. */
-       wth->data_offset = pletohl(&first_frame_table_entry);
-       file_seek(wth->fh, wth->data_offset, SEEK_SET);
+       /* Set up to start reading at the first frame. */
+       wth->capture.netmon->current_frame = 0;
 
        return 1;
 }
@@ -262,6 +265,7 @@ int netmon_open(wtap *wth, int *err)
 /* Read the next packet */
 static int netmon_read(wtap *wth, int *err)
 {
+       netmon_t *netmon = wth->capture.netmon;
        guint32 packet_size = 0;
        int     bytes_read;
        union {
@@ -275,12 +279,24 @@ static int netmon_read(wtap *wth, int *err)
        double  t;
 
        /* Have we reached the end of the packet data? */
-       if (wth->data_offset >= wth->capture.netmon->end_offset) {
+       if (netmon->current_frame >= netmon->frame_table_size) {
                /* Yes. */
                return 0;
        }
+
+       /* Seek to the beginning of the current record, if we're
+          not there already (seeking to the current position
+          may still cause a seek and a read of the underlying file,
+          so we don't want to do it unconditionally). */
+       data_offset = netmon->frame_table[netmon->current_frame];
+       if (wth->data_offset != data_offset) {
+               wth->data_offset = data_offset;
+               file_seek(wth->fh, wth->data_offset, SEEK_SET);
+       }
+       netmon->current_frame++;
+
        /* Read record header. */
-       switch (wth->capture.netmon->version_major) {
+       switch (netmon->version_major) {
 
        case 1:
                hdr_size = sizeof (struct netmonrec_1_x_hdr);
@@ -291,6 +307,7 @@ static int netmon_read(wtap *wth, int *err)
                break;
        }
        errno = WTAP_ERR_CANT_READ;
+
        bytes_read = file_read(&hdr, 1, hdr_size, wth->fh);
        if (bytes_read != hdr_size) {
                *err = file_error(wth->fh);
@@ -304,7 +321,7 @@ static int netmon_read(wtap *wth, int *err)
        }
        wth->data_offset += hdr_size;
 
-       switch (wth->capture.netmon->version_major) {
+       switch (netmon->version_major) {
 
        case 1:
                packet_size = pletohs(&hdr.hdr_1_x.incl_len);
@@ -338,8 +355,8 @@ static int netmon_read(wtap *wth, int *err)
        }
        wth->data_offset += packet_size;
 
-       t = (double)wth->capture.netmon->start_usecs;
-       switch (wth->capture.netmon->version_major) {
+       t = (double)netmon->start_usecs;
+       switch (netmon->version_major) {
 
        case 1:
                t += ((double)pletohl(&hdr.hdr_1_x.ts_delta))*1000;
@@ -352,10 +369,10 @@ static int netmon_read(wtap *wth, int *err)
        }
        secs = (time_t)(t/1000000);
        usecs = (guint32)(t - secs*1000000);
-       wth->phdr.ts.tv_sec = wth->capture.netmon->start_secs + secs;
+       wth->phdr.ts.tv_sec = netmon->start_secs + secs;
        wth->phdr.ts.tv_usec = usecs;
        wth->phdr.caplen = packet_size;
-       switch (wth->capture.netmon->version_major) {
+       switch (netmon->version_major) {
 
        case 1:
                wth->phdr.len = pletohs(&hdr.hdr_1_x.orig_len);
@@ -370,6 +387,13 @@ static int netmon_read(wtap *wth, int *err)
        return data_offset;
 }
 
+static void
+netmon_close(wtap *wth)
+{
+       g_free(wth->capture.netmon->frame_table);
+       g_free(wth->capture.netmon);
+}
+
 static const int wtap_encap[] = {
        -1,             /* WTAP_ENCAP_UNKNOWN -> unsupported */
        1,              /* WTAP_ENCAP_ETHERNET -> NDIS Ethernet */
index 46a17a6832adb4e7a376a890c1fd2afbe159baa7..8e713ea83a30dc2d812fa4af3add1e8179adf39f 100644 (file)
@@ -1,6 +1,6 @@
 /* nettl.c
  *
- * $Id: nettl.c,v 1.8 2000/03/01 10:25:14 oabad Exp $
+ * $Id: nettl.c,v 1.9 2000/03/22 07:06:56 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -67,6 +67,7 @@ struct nettlrec_ns_ls_ip_hdr {
 /* header is followed by data and once again the total length (2 bytes) ! */
 
 static int nettl_read(wtap *wth, int *err);
+static void nettl_close(wtap *wth);
 
 int nettl_open(wtap *wth, int *err)
 {
@@ -110,6 +111,7 @@ int nettl_open(wtap *wth, int *err)
     wth->file_type = WTAP_FILE_NETTL;
     wth->capture.nettl = g_malloc(sizeof(nettl_t));
     wth->subtype_read = nettl_read;
+    wth->subtype_close = nettl_close;
     wth->snapshot_length = 16384;      /* not available in header, only in frame */
 
     wth->capture.nettl->start = 0;
@@ -268,3 +270,8 @@ static int nettl_read(wtap *wth, int *err)
     }
     return data_offset;
 }
+
+static void nettl_close(wtap *wth)
+{
+    g_free(wth->capture.nettl);
+}
index 1f63be7131bbe47c25cac2ee06c85a1ef4469e1b..b7b01fa706c35c89da9d491266c82816fdb3c1d6 100644 (file)
@@ -1,6 +1,6 @@
 /* netxray.c
  *
- * $Id: netxray.c,v 1.24 2000/02/19 08:00:04 guy Exp $
+ * $Id: netxray.c,v 1.25 2000/03/22 07:06:55 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -91,6 +91,7 @@ struct netxrayrec_2_x_hdr {
 };
 
 static int netxray_read(wtap *wth, int *err);
+static void netxray_close(wtap *wth);
 static gboolean netxray_dump_1_1(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
        const u_char *pd, int *err);
 static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err);
@@ -186,6 +187,7 @@ int netxray_open(wtap *wth, int *err)
        wth->file_type = file_type;
        wth->capture.netxray = g_malloc(sizeof(netxray_t));
        wth->subtype_read = netxray_read;
+       wth->subtype_close = netxray_close;
        wth->file_encap = netxray_encap[hdr.network];
        wth->snapshot_length = 16384;   /* XXX - not available in header */
        wth->capture.netxray->start_time = pletohl(&hdr.start_time);
@@ -295,6 +297,12 @@ reread:
        return data_offset;
 }
 
+static void
+netxray_close(wtap *wth)
+{
+       g_free(wth->capture.netxray);
+}
+
 static const int wtap_encap[] = {
     -1,                /* WTAP_ENCAP_UNKNOWN -> unsupported */
     0,         /* WTAP_ENCAP_ETHERNET -> NDIS Ethernet */
index d151d1bf333b831b0401bf4caef06bfb524f7721..632be76b104daea17c6a09b8115dd271984119b3 100644 (file)
@@ -1,6 +1,6 @@
 /* ngsniffer.c
  *
- * $Id: ngsniffer.c,v 1.36 2000/02/19 08:00:07 guy Exp $
+ * $Id: ngsniffer.c,v 1.37 2000/03/22 07:06:57 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -247,6 +247,7 @@ struct frame4_rec {
 static double Usec[] = { 15.0, 0.838096, 15.0, 0.5, 2.0, 1.0, 0.1 };
 
 static int ngsniffer_read(wtap *wth, int *err);
+static void ngsniffer_close(wtap *wth);
 static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
        const u_char *pd, int *err);
 static gboolean ngsniffer_dump_close(wtap_dumper *wdh, int *err);
@@ -370,6 +371,7 @@ int ngsniffer_open(wtap *wth, int *err)
        wth->file_type = WTAP_FILE_NGSNIFFER;
        wth->capture.ngsniffer = g_malloc(sizeof(ngsniffer_t));
        wth->subtype_read = ngsniffer_read;
+       wth->subtype_close = ngsniffer_close;
        wth->snapshot_length = 16384;   /* not available in header, only in frame */
        wth->capture.ngsniffer->timeunit = Usec[version.timeunit];
        wth->file_encap = sniffer_encap[version.network];
@@ -638,6 +640,12 @@ found:
        return data_offset;
 }
 
+static void
+ngsniffer_close(wtap *wth)
+{
+       g_free(wth->capture.ngsniffer);
+}
+
 static const int wtap_encap[] = {
     -1,                /* WTAP_ENCAP_UNKNOWN -> unsupported */
     1,         /* WTAP_ENCAP_ETHERNET */
index 63d4d44aa019efa18c0280db2d44ddea60ce31ae..69dc70a7d4ee511bf2c925b12d9650892d9abda4 100644 (file)
@@ -1,6 +1,6 @@
 /* radcom.c
  *
- * $Id: radcom.c,v 1.18 2000/02/19 08:00:04 guy Exp $
+ * $Id: radcom.c,v 1.19 2000/03/22 07:06:56 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -68,6 +68,7 @@ struct radcomrec_hdr {
 };
 
 static int radcom_read(wtap *wth, int *err);
+static void radcom_close(wtap *wth);
 
 int radcom_open(wtap *wth, int *err)
 {
@@ -135,6 +136,7 @@ int radcom_open(wtap *wth, int *err)
        wth->file_type = WTAP_FILE_RADCOM;
        wth->capture.radcom = g_malloc(sizeof(radcom_t));
        wth->subtype_read = radcom_read;
+       wth->subtype_close = radcom_close;
        wth->snapshot_length = 16384;   /* not available in header, only in frame */
 
        tm.tm_year = pletohs(&start_date.year)-1900;
@@ -301,3 +303,9 @@ static int radcom_read(wtap *wth, int *err)
 
        return data_offset;
 }
+
+static void
+radcom_close(wtap *wth)
+{
+       g_free(wth->capture.radcom);
+}
index c8c752d4379be4d1bc8e0a6316228c210701806e..bb1c4433c9605acad444389830e04663c34f45f6 100644 (file)
@@ -1,6 +1,6 @@
 /* wtap.c
  *
- * $Id: wtap.c,v 1.37 2000/01/22 06:22:44 guy Exp $
+ * $Id: wtap.c,v 1.38 2000/03/22 07:06:55 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -189,50 +189,8 @@ const char *wtap_strerror(int err)
 
 void wtap_close(wtap *wth)
 {
-       /* free up memory. If any capture structure ever allocates
-        * its own memory, it would be better to make a *close() function
-        * for each filetype, like pcap_close(0, lanalyzer_close(), etc.
-        * But for now this will work. */
-       switch(wth->file_type) {
-               case WTAP_FILE_PCAP:
-               case WTAP_FILE_PCAP_MODIFIED:
-                       g_free(wth->capture.pcap);
-                       break;
-
-               case WTAP_FILE_LANALYZER:
-                       g_free(wth->capture.lanalyzer);
-                       break;
-
-               case WTAP_FILE_NGSNIFFER:
-                       g_free(wth->capture.ngsniffer);
-                       break;
-
-               case WTAP_FILE_RADCOM:
-                       g_free(wth->capture.radcom);
-                       break;
-
-               case WTAP_FILE_NETMON_1_x:
-               case WTAP_FILE_NETMON_2_x:
-                       g_free(wth->capture.netmon);
-                       break;
-
-               case WTAP_FILE_NETXRAY_1_0:
-               case WTAP_FILE_NETXRAY_1_1:
-               case WTAP_FILE_NETXRAY_2_001:
-                       g_free(wth->capture.netxray);
-                       break;
-
-               case WTAP_FILE_ASCEND:
-                       g_free(wth->capture.ascend);
-                       break;
-
-               case WTAP_FILE_NETTL:
-                       g_free(wth->capture.nettl);
-                       break;
-
-               /* default:
-                        nothing */
-       }
+       if (wth->subtype_close != NULL)
+               (*wth->subtype_close)(wth);
 
        file_close(wth->fh);
 
index df49f8130bf8383085cb2b914f91282692e8987f..850d4e5e57f563c7a40d46a4336618243fb5f953 100644 (file)
@@ -1,6 +1,6 @@
 /* wtap.h
  *
- * $Id: wtap.h,v 1.64 2000/02/19 08:00:08 guy Exp $
+ * $Id: wtap.h,v 1.65 2000/03/22 07:06:59 guy Exp $
  *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -185,8 +185,8 @@ typedef struct {
        guint32 start_usecs;
        guint8  version_major;
        guint32 *frame_table;
+       int     frame_table_size;
        int     current_frame;
-       int     end_offset;
 } netmon_t;
 
 typedef struct {
@@ -342,6 +342,7 @@ typedef struct wtap {
        } capture;
 
        subtype_read_func       subtype_read;
+       void                    (*subtype_close)(struct wtap*);
        int                     file_encap;     /* per-file, for those
                                                   file formats that have
                                                   per-file encapsulation