wtap_opttypes.c: Fix build error.
[metze/wireshark/wip.git] / wiretap / network_instruments.c
index a574934a223dcc90c5c698f0e2bea5636d1db751..286243a312ce355c5aefe1c93434938511f5a8a0 100644 (file)
@@ -1,7 +1,3 @@
-/*
- * $Id$
- */
-
 /***************************************************************************
                           network_instruments.c  -  description
                              -------------------
  *                                                                         *
  ***************************************************************************/
 
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
 #include "wtap-int.h"
 #include "file_wrappers.h"
-#include "buffer.h"
 #include "network_instruments.h"
 
 static const char network_instruments_magic[] = {"ObserverPktBufferVersion=15.00"};
@@ -103,22 +96,23 @@ static void init_gmt_to_localtime_offset(void)
 static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
     gint64 *data_offset);
 static gboolean observer_seek_read(wtap *wth, gint64 seek_off,
-    union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
-    int *err, gchar **err_info);
-static int read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header, 
+    struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
+static int read_packet_header(wtap *wth, FILE_T fh, union wtap_pseudo_header *pseudo_header,
     packet_entry_header *packet_header, int *err, gchar **err_info);
+static gboolean process_packet_header(wtap *wth,
+    packet_entry_header *packet_header, struct wtap_pkthdr *phdr, int *err,
+    gchar **err_info);
 static int read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_header,
-    guint8 *pd, int length, int *err, char **err_info);
+    Buffer *buf, int length, int *err, char **err_info);
 static gboolean skip_to_next_packet(wtap *wth, int offset_to_next_packet,
     int current_offset_from_packet_header, int *err, char **err_info);
 static gboolean observer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
-    const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err);
+    const guint8 *pd, int *err, gchar **err_info);
 static gint observer_to_wtap_encap(int observer_encap);
 static gint wtap_to_observer_encap(int wtap_encap);
 
-int network_instruments_open(wtap *wth, int *err, gchar **err_info)
+wtap_open_return_val network_instruments_open(wtap *wth, int *err, gchar **err_info)
 {
-    int bytes_read;
     int offset;
     capture_file_header file_header;
     guint i;
@@ -128,23 +122,21 @@ int network_instruments_open(wtap *wth, int *err, gchar **err_info)
     packet_entry_header packet_header;
     observer_dump_private_state * private_state = NULL;
 
-    errno = WTAP_ERR_CANT_READ;
     offset = 0;
 
     /* read in the buffer file header */
-    bytes_read = file_read(&file_header, sizeof file_header, wth->fh);
-    if (bytes_read != sizeof file_header) {
-        *err = file_error(wth->fh, err_info);
-        if (*err != 0)
-            return -1;
-        return 0;
+    if (!wtap_read_bytes(wth->fh, &file_header, sizeof file_header,
+                         err, err_info)) {
+        if (*err != WTAP_ERR_SHORT_READ)
+            return WTAP_OPEN_ERROR;
+        return WTAP_OPEN_NOT_MINE;
     }
-    offset += bytes_read;
+    offset += (int)sizeof file_header;
     CAPTURE_FILE_HEADER_FROM_LE_IN_PLACE(file_header);
 
     /* check if version info is present */
     if (memcmp(file_header.observer_version, network_instruments_magic, true_magic_length)!=0) {
-        return 0;
+        return WTAP_OPEN_NOT_MINE;
     }
 
     /* initialize the private state */
@@ -163,41 +155,33 @@ int network_instruments_open(wtap *wth, int *err, gchar **err_info)
             break;
 
         /* read the TLV header */
-        bytes_read = file_read(&tlvh, sizeof tlvh, wth->fh);
-        if (bytes_read != sizeof tlvh) {
-            *err = file_error(wth->fh, err_info);
-            if (*err == 0)
-                *err = WTAP_ERR_SHORT_READ;
-            return -1;
-        }
-        offset += bytes_read;
+        if (!wtap_read_bytes(wth->fh, &tlvh, sizeof tlvh, err, err_info))
+            return WTAP_OPEN_ERROR;
+        offset += (int)sizeof tlvh;
         TLV_HEADER_FROM_LE_IN_PLACE(tlvh);
 
         if (tlvh.length < sizeof tlvh) {
             *err = WTAP_ERR_BAD_FILE;
             *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)",
                 tlvh.length, (unsigned long)sizeof tlvh);
-            return -1;
+            return WTAP_OPEN_ERROR;
         }
 
         /* process (or skip over) the current TLV */
         switch (tlvh.type) {
         case INFORMATION_TYPE_TIME_INFO:
-            bytes_read = file_read(&private_state->time_format, sizeof private_state->time_format, wth->fh);
-            if (bytes_read != sizeof private_state->time_format) {
-                *err = file_error(wth->fh, err_info);
-                if(*err == 0)
-                    *err = WTAP_ERR_SHORT_READ;
-                return -1;
-            }
+            if (!wtap_read_bytes(wth->fh, &private_state->time_format,
+                                 sizeof private_state->time_format,
+                                 err, err_info))
+                return WTAP_OPEN_ERROR;
             private_state->time_format = GUINT32_FROM_LE(private_state->time_format);
-            offset += bytes_read;
+            offset += (int)sizeof private_state->time_format;
             break;
         default:
             seek_increment = tlvh.length - (int)sizeof tlvh;
             if (seek_increment > 0) {
                 if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
-                    return -1;
+                    return WTAP_OPEN_ERROR;
             }
             offset += seek_increment;
         }
@@ -208,36 +192,32 @@ int network_instruments_open(wtap *wth, int *err, gchar **err_info)
         *err = WTAP_ERR_BAD_FILE;
         *err_info = g_strdup_printf("Observer: bad record (offset to first packet %d < %d)",
             header_offset, offset);
-        return FALSE;
+        return WTAP_OPEN_ERROR;
     }
     seek_increment = header_offset - offset;
     if (seek_increment > 0) {
         if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
-            return -1;
+            return WTAP_OPEN_ERROR;
     }
 
     /* pull off the packet header */
-    bytes_read = file_read(&packet_header, sizeof packet_header, wth->fh);
-    if (bytes_read != sizeof packet_header) {
-        *err = file_error(wth->fh, err_info);
-        if (*err != 0)
-            return -1;
-        return 0;
-    }
+    if (!wtap_read_bytes(wth->fh, &packet_header, sizeof packet_header,
+                         err, err_info))
+        return WTAP_OPEN_ERROR;
     PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(packet_header);
 
     /* check the packet's magic number */
     if (packet_header.packet_magic != observer_packet_magic) {
-        *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+        *err = WTAP_ERR_UNSUPPORTED;
         *err_info = g_strdup_printf("Observer: unsupported packet version %ul", packet_header.packet_magic);
-        return -1;
+        return WTAP_OPEN_ERROR;
     }
 
     /* check the data link type */
     if (observer_to_wtap_encap(packet_header.network_type) == WTAP_ENCAP_UNKNOWN) {
-        *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+        *err = WTAP_ERR_UNSUPPORTED;
         *err_info = g_strdup_printf("Observer: network type %u unknown or unsupported", packet_header.network_type);
-        return -1;
+        return WTAP_OPEN_ERROR;
     }
     wth->file_encap = observer_to_wtap_encap(packet_header.network_type);
 
@@ -249,123 +229,60 @@ int network_instruments_open(wtap *wth, int *err, gchar **err_info)
     wth->subtype_close = NULL;
     wth->subtype_sequential_close = NULL;
     wth->snapshot_length = 0;    /* not available in header */
-    wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
-    wth->file_type = WTAP_FILE_NETWORK_INSTRUMENTS;
+    wth->file_tsprec = WTAP_TSPREC_NSEC;
+    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETWORK_INSTRUMENTS;
 
     /* reset the pointer to the first packet */
-    if (file_seek(wth->fh, header_offset, SEEK_SET,
-        err) == -1)
-        return -1;
-    wth->data_offset = header_offset;
+    if (file_seek(wth->fh, header_offset, SEEK_SET, err) == -1)
+        return WTAP_OPEN_ERROR;
 
     init_gmt_to_localtime_offset();
 
-    return 1;
+    return WTAP_OPEN_MINE;
 }
 
 /* Reads the next packet. */
 static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
     gint64 *data_offset)
 {
-    int bytes_consumed;
-    int offset_from_packet_header = 0;
+    int header_bytes_consumed;
+    int data_bytes_consumed;
     packet_entry_header packet_header;
 
     /* skip records other than data records */
     for (;;) {
-        *data_offset = wth->data_offset;
+        *data_offset = file_tell(wth->fh);
 
         /* process the packet header, including TLVs */
-        bytes_consumed = read_packet_header(wth->fh, &wth->pseudo_header, &packet_header, err,
+        header_bytes_consumed = read_packet_header(wth, wth->fh, &wth->phdr.pseudo_header, &packet_header, err,
             err_info);
-        if (bytes_consumed <= 0)
+        if (header_bytes_consumed <= 0)
             return FALSE;    /* EOF or error */
 
-        wth->data_offset += bytes_consumed;
-
         if (packet_header.packet_type == PACKET_TYPE_DATA_PACKET)
             break;
 
         /* skip to next packet */
-        offset_from_packet_header = (int) (wth->data_offset - *data_offset);
         if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet,
-                offset_from_packet_header, err, err_info)) {
+                header_bytes_consumed, err, err_info)) {
             return FALSE;    /* EOF or error */
         }
     }
 
-    /* neglect frame markers for wiretap */
-    if (packet_header.network_size < 4) {
-        *err = WTAP_ERR_BAD_FILE;
-        *err_info = g_strdup_printf("Observer: bad record: Packet length %u < 4",
-            packet_header.network_size);
+    if (!process_packet_header(wth, &packet_header, &wth->phdr, err, err_info))
         return FALSE;
-    }
-
-    /* set the wiretap packet header fields */
-    wth->phdr.pkt_encap = observer_to_wtap_encap(packet_header.network_type);
-    if(wth->file_encap == WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS) {
-        wth->phdr.len = packet_header.network_size;
-        wth->phdr.caplen = packet_header.captured_size;
-    } else {
-        wth->phdr.len = packet_header.network_size - 4;
-        wth->phdr.caplen = MIN(packet_header.captured_size, wth->phdr.len);
-    }
-
-    /* set the wiretap timestamp, assuming for the moment that Observer encoded it in GMT */
-    wth->phdr.ts.secs = (time_t) ((packet_header.nano_seconds_since_2000 / 1000000000) + ansi_to_observer_epoch_offset);
-    wth->phdr.ts.nsecs = (int) (packet_header.nano_seconds_since_2000 % 1000000000);
-
-    /* adjust to local time, if necessary, also accounting for DST if the frame
-       was captured while it was in effect */
-    if (((observer_dump_private_state*)wth->priv)->time_format == TIME_INFO_LOCAL)
-    {
-        struct tm daylight_tm;
-        struct tm standard_tm;
-        time_t    dst_offset;
-
-        /* the Observer timestamp was encoded as local time, so add a
-           correction from local time to GMT */
-        wth->phdr.ts.secs += gmt_to_localtime_offset;
-
-        /* perform a DST adjustment if necessary */
-        standard_tm = *localtime(&wth->phdr.ts.secs);
-        if (standard_tm.tm_isdst > 0) {
-            daylight_tm = standard_tm;
-            standard_tm.tm_isdst = 0;
-            dst_offset = mktime(&standard_tm) - mktime(&daylight_tm);
-            wth->phdr.ts.secs -= dst_offset;
-        }
-    }
-
-    /* update the pseudo header */
-    switch (wth->file_encap) {
-    case WTAP_ENCAP_ETHERNET:
-        /* There is no FCS in the frame */
-        wth->pseudo_header.eth.fcs_len = 0;
-        break;
-    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
-        /* Updated in read_packet_header */
-        break;
-    }
-
-    /* set-up the packet buffer */
-    buffer_assure_space(wth->frame_buffer, packet_header.captured_size);
 
     /* read the frame data */
-    offset_from_packet_header = (int) (wth->data_offset - *data_offset);
-    bytes_consumed = read_packet_data(wth->fh, packet_header.offset_to_frame,
-            offset_from_packet_header, buffer_start_ptr(wth->frame_buffer),
-            packet_header.captured_size, err, err_info);
-    if (bytes_consumed < 0) {
+    data_bytes_consumed = read_packet_data(wth->fh, packet_header.offset_to_frame,
+            header_bytes_consumed, wth->frame_buffer,
+            wth->phdr.caplen, err, err_info);
+    if (data_bytes_consumed < 0) {
         return FALSE;
     }
-    wth->data_offset += bytes_consumed;
 
     /* skip over any extra bytes following the frame data */
-    offset_from_packet_header = (int) (wth->data_offset - *data_offset);
     if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet,
-            offset_from_packet_header, err, err_info)) {
+            header_bytes_consumed + data_bytes_consumed, err, err_info)) {
         return FALSE;
     }
 
@@ -374,47 +291,40 @@ static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
 
 /* Reads a packet at an offset. */
 static gboolean observer_seek_read(wtap *wth, gint64 seek_off,
-    union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
-    int *err, gchar **err_info)
+    struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
 {
+    union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
     packet_entry_header packet_header;
     int offset;
+    int data_bytes_consumed;
 
     if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
         return FALSE;
 
     /* process the packet header, including TLVs */
-    offset = read_packet_header(wth->random_fh, pseudo_header, &packet_header, err,
+    offset = read_packet_header(wth, wth->random_fh, pseudo_header, &packet_header, err,
         err_info);
     if (offset <= 0)
         return FALSE;    /* EOF or error */
 
-    /* update the pseudo header */
-    switch (wth->file_encap) {
-
-    case WTAP_ENCAP_ETHERNET:
-        /* There is no FCS in the frame */
-        pseudo_header->eth.fcs_len = 0;
-        break;
-    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
-        /* Updated in read_packet_header */
-        break;
-    }
+    if (!process_packet_header(wth, &packet_header, phdr, err, err_info))
+        return FALSE;
 
     /* read the frame data */
-    if (!read_packet_data(wth->random_fh, packet_header.offset_to_frame,
-        offset, pd, length, err, err_info))
+    data_bytes_consumed = read_packet_data(wth->random_fh, packet_header.offset_to_frame,
+        offset, buf, phdr->caplen, err, err_info);
+    if (data_bytes_consumed < 0) {
         return FALSE;
+    }
 
     return TRUE;
 }
 
 static int
-read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header, 
+read_packet_header(wtap *wth, FILE_T fh, union wtap_pseudo_header *pseudo_header,
     packet_entry_header *packet_header, int *err, gchar **err_info)
 {
     int offset;
-    int bytes_read;
     guint i;
     tlv_header tlvh;
     int seek_increment;
@@ -423,14 +333,13 @@ read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
     offset = 0;
 
     /* pull off the packet header */
-    bytes_read = file_read(packet_header, sizeof *packet_header, fh);
-    if (bytes_read != sizeof *packet_header) {
-        *err = file_error(fh, err_info);
+    if (!wtap_read_bytes_or_eof(fh, packet_header, sizeof *packet_header,
+                                err, err_info)) {
         if (*err != 0)
             return -1;
         return 0;    /* EOF */
     }
-    offset += bytes_read;
+    offset += (int)sizeof *packet_header;
     PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(*packet_header);
 
     /* check the packet's magic number */
@@ -458,17 +367,28 @@ read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
         return -1;
     }
 
+    /* initialize the pseudo header */
+    switch (wth->file_encap) {
+    case WTAP_ENCAP_ETHERNET:
+        /* There is no FCS in the frame */
+        pseudo_header->eth.fcs_len = 0;
+        break;
+    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
+        memset(&pseudo_header->ieee_802_11, 0, sizeof(pseudo_header->ieee_802_11));
+        pseudo_header->ieee_802_11.fcs_len = 0;
+        pseudo_header->ieee_802_11.decrypted = FALSE;
+        pseudo_header->ieee_802_11.datapad = FALSE;
+        pseudo_header->ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;
+        /* Updated below */
+        break;
+    }
+
     /* process extra information */
     for (i = 0; i < packet_header->number_of_information_elements; i++) {
         /* read the TLV header */
-        bytes_read = file_read(&tlvh, sizeof tlvh, fh);
-        if (bytes_read != sizeof tlvh) {
-            *err = file_error(fh, err_info);
-            if (*err == 0)
-                *err = WTAP_ERR_SHORT_READ;
+        if (!wtap_read_bytes(fh, &tlvh, sizeof tlvh, err, err_info))
             return -1;
-        }
-        offset += bytes_read;
+        offset += (int)sizeof tlvh;
         TLV_HEADER_FROM_LE_IN_PLACE(tlvh);
 
         if (tlvh.length < sizeof tlvh) {
@@ -481,19 +401,19 @@ read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
         /* process (or skip over) the current TLV */
         switch (tlvh.type) {
         case INFORMATION_TYPE_WIRELESS:
-            bytes_read = file_read(&wireless_header, sizeof wireless_header, fh);
-            if (bytes_read != sizeof wireless_header) {
-                *err = file_error(fh, err_info);
-                if(*err == 0)
-                    *err = WTAP_ERR_SHORT_READ;
+            if (!wtap_read_bytes(fh, &wireless_header, sizeof wireless_header,
+                                 err, err_info))
                 return -1;
-            }
-            /* update the pseudo header */
-            pseudo_header->ieee_802_11.fcs_len = 0;
+            /* set decryption status */
+            /* XXX - what other bits are there in conditions? */
+            pseudo_header->ieee_802_11.decrypted = (wireless_header.conditions & WIRELESS_WEP_SUCCESS) != 0;
+            pseudo_header->ieee_802_11.has_channel = TRUE;
             pseudo_header->ieee_802_11.channel = wireless_header.frequency;
+            pseudo_header->ieee_802_11.has_data_rate = TRUE;
             pseudo_header->ieee_802_11.data_rate = wireless_header.rate;
-            pseudo_header->ieee_802_11.signal_level = wireless_header.strengthPercent;
-            offset += bytes_read;
+            pseudo_header->ieee_802_11.has_signal_percent = TRUE;
+            pseudo_header->ieee_802_11.signal_percent = wireless_header.strengthPercent;
+            offset += (int)sizeof wireless_header;
             break;
         default:
             /* skip the TLV data */
@@ -509,8 +429,85 @@ read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header,
     return offset;
 }
 
+static gboolean
+process_packet_header(wtap *wth, packet_entry_header *packet_header,
+    struct wtap_pkthdr *phdr, int *err, gchar **err_info)
+{
+    /* set the wiretap packet header fields */
+    phdr->rec_type = REC_TYPE_PACKET;
+    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
+    phdr->pkt_encap = observer_to_wtap_encap(packet_header->network_type);
+    if(wth->file_encap == WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS) {
+        phdr->len = packet_header->network_size;
+        phdr->caplen = packet_header->captured_size;
+    } else {
+        /*
+         * XXX - what are those 4 bytes?
+         *
+         * The comment in the code said "neglect frame markers for wiretap",
+         * but in the captures I've seen, there's no actual data corresponding
+         * to them that might be a "frame marker".
+         *
+         * Instead, the packets had a network_size 4 bytes larger than the
+         * captured_size; does the network_size include the CRC, even
+         * though it's not included in a capture?  If so, most other
+         * network analyzers that have a "network size" and a "captured
+         * size" don't include the CRC in the "network size" if they
+         * don't include the CRC in a full-length captured packet; the
+         * "captured size" is less than the "network size" only if a
+         * user-specified "snapshot length" caused the packet to be
+         * sliced at a particular point.
+         *
+         * That's the model that wiretap and Wireshark/TShark use, so
+         * we implement that model here.
+         */
+        if (packet_header->network_size < 4) {
+            *err = WTAP_ERR_BAD_FILE;
+            *err_info = g_strdup_printf("Observer: bad record: Packet length %u < 4",
+                                        packet_header->network_size);
+            return FALSE;
+        }
+
+        phdr->len = packet_header->network_size - 4;
+        phdr->caplen = MIN(packet_header->captured_size, phdr->len);
+    }
+    /*
+     * The maximum value of packet_header->captured_size is 65535, which
+     * is less than WTAP_MAX_PACKET_SIZE will ever be, so we don't need
+     * to check it.
+     */
+
+    /* set the wiretap timestamp, assuming for the moment that Observer encoded it in GMT */
+    phdr->ts.secs = (time_t) ((packet_header->nano_seconds_since_2000 / 1000000000) + ansi_to_observer_epoch_offset);
+    phdr->ts.nsecs = (int) (packet_header->nano_seconds_since_2000 % 1000000000);
+
+    /* adjust to local time, if necessary, also accounting for DST if the frame
+       was captured while it was in effect */
+    if (((observer_dump_private_state*)wth->priv)->time_format == TIME_INFO_LOCAL)
+    {
+        struct tm daylight_tm;
+        struct tm standard_tm;
+        time_t    dst_offset;
+
+        /* the Observer timestamp was encoded as local time, so add a
+           correction from local time to GMT */
+        phdr->ts.secs += gmt_to_localtime_offset;
+
+        /* perform a DST adjustment if necessary */
+        standard_tm = *localtime(&phdr->ts.secs);
+        if (standard_tm.tm_isdst > 0) {
+            daylight_tm = standard_tm;
+            standard_tm.tm_isdst = 0;
+            dst_offset = mktime(&standard_tm) - mktime(&daylight_tm);
+            phdr->ts.secs -= dst_offset;
+        }
+    }
+
+    return TRUE;
+}
+
 static int
-read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_header, guint8 *pd,
+read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_header, Buffer *buf,
     int length, int *err, char **err_info)
 {
     int seek_increment;
@@ -533,8 +530,12 @@ read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_
         bytes_consumed += seek_increment;
     }
 
+    /* set-up the packet buffer */
+    ws_buffer_assure_space(buf, length);
+
     /* read in the packet data */
-    wtap_file_read_expected_bytes(pd, length, fh, err, err_info);
+    if (!wtap_read_packet_bytes(fh, buf, length, err, err_info))
+        return FALSE;
     bytes_consumed += length;
 
     return bytes_consumed;
@@ -559,7 +560,6 @@ skip_to_next_packet(wtap *wth, int offset_to_next_packet, int current_offset_fro
     if (seek_increment > 0) {
         if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
             return FALSE;
-        wth->data_offset += seek_increment;
     }
 
     return TRUE;
@@ -574,7 +574,7 @@ int network_instruments_dump_can_write_encap(int encap)
         return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
 
     if (encap < 0 || (wtap_to_observer_encap(encap) == OBSERVER_UNDEFINED))
-        return WTAP_ERR_UNSUPPORTED_ENCAP;
+        return WTAP_ERR_UNWRITABLE_ENCAP;
 
     return 0;
 }
@@ -674,13 +674,26 @@ gboolean network_instruments_dump_open(wtap_dumper *wdh, int *err)
 /* Write a record for a packet to a dump file.
    Returns TRUE on success, FALSE on failure. */
 static gboolean observer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
-    const union wtap_pseudo_header *pseudo_header _U_, const guint8 *pd,
-    int *err)
+    const guint8 *pd,
+    int *err, gchar **err_info _U_)
 {
     observer_dump_private_state * private_state = NULL;
     packet_entry_header           packet_header;
     guint64                       seconds_since_2000;
 
+    /* We can only write packet records. */
+    if (phdr->rec_type != REC_TYPE_PACKET) {
+        *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
+        return FALSE;
+    }
+
+    /* The captured size field is 16 bits, so there's a hard limit of
+       65535. */
+    if (phdr->caplen > 65535) {
+        *err = WTAP_ERR_PACKET_TOO_LARGE;
+        return FALSE;
+    }
+
     /* convert the number of seconds since epoch from ANSI-relative to
        Observer-relative */
     if (phdr->ts.secs < ansi_to_observer_epoch_offset) {
@@ -761,3 +774,16 @@ static gint wtap_to_observer_encap(int wtap_encap)
     }
     return OBSERVER_UNDEFINED;
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */