2 * Routines for opening files in what WildPackets calls the tagged file
3 * format in the description of their "PeekRdr Sample Application" (C++
4 * source code to read their capture files, downloading of which requires
5 * a maintenance contract, so it's not free as in beer and probably not
6 * as in speech, either).
8 * As that description says, it's used by AiroPeek and AiroPeek NX 2.0
9 * and later, EtherPeek 6.0 and later, EtherPeek NX 3.0 and later,
10 * EtherPeek VX 1.0 and later, GigaPeek NX 1.0 and later, Omni3 1.0
11 * and later (both OmniPeek and the Remote Engine), and WANPeek NX
12 * 1.0 and later. They also say it'll be used by future WildPackets
16 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38 #include "file_wrappers.h"
39 #include <wsutil/buffer.h>
40 #include "peektagged.h"
44 * This file decoder could not have been writen without examining
45 * http://www.varsanofiev.com/inside/airopeekv9.htm, the help from
46 * Martin Regner and Guy Harris, and the etherpeek.c file (as it
47 * was called before renaming it to peekclassic.c).
53 * A Peek tagged file consists of multiple sections, each of which begins
54 * with a header in the following format.
56 * The section ID is a 4-character string saying what type of section
57 * it is. The section length is a little-endian field giving the
58 * length of the section, in bytes, including the section header
59 * itself. The other field of the section header is a little-endian
60 * constant that always appears to be 0x00000200.
62 * Files we've seen have the following sections, in order:
64 * "\177vers" - version information. The contents are XML, giving
65 * the file format version and application version information.
67 * "sess" - capture session information. The contents are XML, giving
68 * various information about the capture session.
70 * "pkts" - captured packets. The contents are binary records, one for
71 * each packet, with the record being a list of tagged values followed
72 * by the raw packet data.
74 typedef struct peektagged_section_header {
75 gint8 section_id[4]; /* string identifying the section */
76 guint32 section_len; /* little-endian section length */
77 guint32 section_const; /* little-endian 0x00000200 */
78 } peektagged_section_header_t;
81 * Network subtype values.
83 * XXX - do different network subtype values for 802.11 indicate different
84 * network adapter types, with some adapters supplying the FCS and others
85 * not supplying the FCS?
87 #define PEEKTAGGED_NST_ETHERNET 0
88 #define PEEKTAGGED_NST_802_11 1 /* 802.11 with 0's at the end */
89 #define PEEKTAGGED_NST_802_11_2 2 /* 802.11 with 0's at the end */
90 #define PEEKTAGGED_NST_802_11_WITH_FCS 3 /* 802.11 with FCS at the end */
92 /* tags for fields in packet header */
93 #define TAG_PEEKTAGGED_LENGTH 0x0000
94 #define TAG_PEEKTAGGED_TIMESTAMP_LOWER 0x0001
95 #define TAG_PEEKTAGGED_TIMESTAMP_UPPER 0x0002
96 #define TAG_PEEKTAGGED_FLAGS_AND_STATUS 0x0003 /* upper 24 bits unused? */
97 #define TAG_PEEKTAGGED_CHANNEL 0x0004
98 #define TAG_PEEKTAGGED_RATE 0x0005 /* or MCS index for 802.11n */
99 #define TAG_PEEKTAGGED_SIGNAL_PERC 0x0006
100 #define TAG_PEEKTAGGED_SIGNAL_DBM 0x0007
101 #define TAG_PEEKTAGGED_NOISE_PERC 0x0008
102 #define TAG_PEEKTAGGED_NOISE_DBM 0x0009
103 #define TAG_PEEKTAGGED_UNKNOWN_0x000A 0x000A
104 #define TAG_PEEKTAGGED_CENTER_FREQUENCY 0x000D /* Frequency */
105 #define TAG_PEEKTAGGED_UNKNOWN_0x000E 0x000E
106 #define TAG_PEEKTAGGED_UNKNOWN_0x000F 0x000F /* 000F-0013 - dBm values? */
107 #define TAG_PEEKTAGGED_UNKNOWN_0x0010 0x0010
108 #define TAG_PEEKTAGGED_UNKNOWN_0x0011 0x0011
109 #define TAG_PEEKTAGGED_UNKNOWN_0x0012 0x0012
110 #define TAG_PEEKTAGGED_UNKNOWN_0x0013 0x0013
111 #define TAG_PEEKTAGGED_UNKNOWN_0x0014 0x0014
112 #define TAG_PEEKTAGGED_EXT_FLAGS 0x0015 /* Extended flags for 802.11n and beyond */
114 #define TAG_PEEKTAGGED_SLICE_LENGTH 0xffff
119 * We're assuming here that the "remote Peek" flags from bug 9586 are
120 * the same as the "Peek tagged" flags.
122 #define FLAGS_CONTROL_FRAME 0x01 /* Frame is a control frame */
123 #define FLAGS_HAS_CRC_ERROR 0x02 /* Frame has a CRC error */
124 #define FLAGS_HAS_FRAME_ERROR 0x04 /* Frame has a frame error */
129 * Is this in the next 8 bits of the "flags and status" field?
131 #define STATUS_PROTECTED 0x0400 /* Frame is protected (encrypted) */
132 #define STATUS_DECRYPT_ERROR 0x0800 /* Error decrypting protected frame */
133 #define STATUS_SHORT_PREAMBLE 0x4000 /* Short preamble */
138 * Some determined from bug 10637, some determined from bug 9586,
139 * and the ones present in both agree, so we're assuming that
140 * the "remote Peek" protocol and the "Peek tagged" file format
141 * use the same bits (which wouldn't be too surprising, as they
142 * both come from Wildpackets).
144 #define EXT_FLAG_20_MHZ_LOWER 0x00000001
145 #define EXT_FLAG_20_MHZ_UPPER 0x00000002
146 #define EXT_FLAG_40_MHZ 0x00000004
147 #define EXT_FLAG_HALF_GI 0x00000008
148 #define EXT_FLAG_FULL_GI 0x00000010
149 #define EXT_FLAG_AMPDU 0x00000020
150 #define EXT_FLAG_AMSDU 0x00000040
151 #define EXT_FLAG_802_11ac 0x00000080
152 #define EXT_FLAG_MCS_INDEX_USED 0x00000100
155 * XXX - mapping to radiotap, for fields that don't just map to wiretap
158 * FLAGS_CONTROL_FRAME: no equivalent - is it useful? Can just look at FC?
160 * FLAGS_HAS_CRC_ERROR: flags.{frame failed FCS check}
162 * FLAGS_HAS_FRAME_ERROR: no equivalent
164 * STATUS_PROTECTED: flags.{sent/received with WEP encryption}?
166 * STATUS_DECRYPT_ERROR: no equivalent
168 * STATUS_SHORT_PREAMBLE: flags.{sent/received with short preamble}
170 * TAG_PEEKTAGGED_CHANNEL: no equivalent, but could be mapped to Channel
172 * TAG_PEEKTAGGED_RATE: Rate if it's a data rate, MCS.mcs if it's an MCS
173 * Does EXT_FLAG_MCS_INDEX_USED map to the "MCS known" bit ?
175 * TAG_PEEKTAGGED_SIGNAL_PERC: no equivalent
177 * TAG_PEEKTAGGED_SIGNAL_DBM: Antenna signal
179 * TAG_PEEKTAGGED_NOISE_PERC: no equivalent
181 * TAG_PEEKTAGGED_NOISE_DBM: Antenna noise
183 * TAG_PEEKTAGGED_CENTER_FREQUENCY: XChannel.freq
185 * TAG_PEEKTAGGED_UNKNOWN_0x000F - TAG_PEEKTAGGED_UNKNOWN_0x0013: no equivalent
187 * EXT_FLAG_20_MHZ_LOWER
188 * EXT_FLAG_20_MHZ_UPPER
190 * mcs.bandwidth = 0: none of them set
191 * mcs.bandwidth = 1: EXT_FLAG_40_MHZ set
192 * mcs.bandwidth = 2: EXT_FLAG_20_MHZ_LOWER set
193 * mcs.bandwidth = 3: EXT_FLAG_20_MHZ_UPPER set
196 * EXT_FLAG_HALF_GI: mcs.{guard interval} = 1 (short GI)
198 * EXT_FLAG_FULL_GI: mcs.{guard interval} = 0 (long GI)
200 * EXT_FLAG_AMPDU: A-MPDU status present? What about its value?
202 * EXT_FLAG_AMSDU: ???
204 * EXT_FLAG_802_11ac: nothing currently
206 * EXT_FLAG_MCS_INDEX_USED: see above?
209 /* 64-bit time in nanoseconds from the (Windows FILETIME) epoch */
210 typedef struct peektagged_utime {
219 static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
220 gint64 *data_offset);
221 static gboolean peektagged_seek_read(wtap *wth, gint64 seek_off,
222 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
224 static int wtap_file_read_pattern (wtap *wth, const char *pattern, int *err,
233 c = file_getc(wth->fh);
236 *err = file_error(wth->fh, err_info);
237 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
238 return -1; /* error */
251 return (*cp == '\0' ? 1 : 0);
255 static int wtap_file_read_till_separator (wtap *wth, char *buffer, int buflen,
256 const char *separators, int *err,
263 for (cp = buffer, i = 0; i < buflen; i++, cp++)
265 c = file_getc(wth->fh);
268 *err = file_error(wth->fh, err_info);
269 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
270 return -1; /* error */
273 if (strchr (separators, c) != NULL)
285 static int wtap_file_read_number (wtap *wth, guint32 *num, int *err,
293 ret = wtap_file_read_till_separator (wth, str_num, sizeof (str_num)-1, "<",
295 if (ret == 0 || ret == -1) {
296 /* 0 means EOF, which means "not a valid Peek tagged file";
297 -1 means error, and "err" has been set. */
300 value = strtoul (str_num, &p, 10);
301 if (p == str_num || value > G_MAXUINT32)
303 *num = (guint32)value;
308 wtap_open_return_val peektagged_open(wtap *wth, int *err, gchar **err_info)
310 peektagged_section_header_t ap_hdr;
314 guint32 mediaSubType = 0;
316 static const int peektagged_encap[] = {
318 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
319 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
320 WTAP_ENCAP_IEEE_802_11_WITH_RADIO
322 #define NUM_PEEKTAGGED_ENCAPS (sizeof peektagged_encap / sizeof peektagged_encap[0])
323 peektagged_t *peektagged;
325 if (!wtap_read_bytes(wth->fh, &ap_hdr, (int)sizeof(ap_hdr), err, err_info)) {
326 if (*err != WTAP_ERR_SHORT_READ)
327 return WTAP_OPEN_ERROR;
328 return WTAP_OPEN_NOT_MINE;
331 if (memcmp (ap_hdr.section_id, "\177ver", sizeof(ap_hdr.section_id)) != 0)
332 return WTAP_OPEN_NOT_MINE; /* doesn't begin with a "\177ver" section */
335 * XXX - we should get the length of the "\177ver" section, check
336 * that it's followed by a little-endian 0x00000200, and then,
337 * when reading the XML, make sure we don't go past the end of
338 * that section, and skip to the end of that section when
339 * we have the file version (and possibly check to make sure all
340 * tags are properly opened and closed).
342 ret = wtap_file_read_pattern (wth, "<FileVersion>", err, err_info);
344 return WTAP_OPEN_ERROR;
346 /* 0 means EOF, which means "not a valid Peek tagged file" */
347 return WTAP_OPEN_NOT_MINE;
349 ret = wtap_file_read_number (wth, &fileVersion, err, err_info);
351 return WTAP_OPEN_ERROR;
353 /* 0 means EOF, which means "not a valid Peek tagged file" */
354 return WTAP_OPEN_NOT_MINE;
357 /* If we got this far, we assume it's a Peek tagged file. */
358 if (fileVersion != 9) {
359 /* We only support version 9. */
360 *err = WTAP_ERR_UNSUPPORTED;
361 *err_info = g_strdup_printf("peektagged: version %u unsupported",
363 return WTAP_OPEN_ERROR;
367 * XXX - once we've skipped the "\177ver" section, we should
368 * check for a "sess" section and fail if we don't see it.
369 * Then we should get the length of the "sess" section, check
370 * that it's followed by a little-endian 0x00000200, and then,
371 * when reading the XML, make sure we don't go past the end of
372 * that section, and skip to the end of the section when
373 * we have the file version (and possibly check to make sure all
374 * tags are properly opened and closed).
376 ret = wtap_file_read_pattern (wth, "<MediaType>", err, err_info);
378 return WTAP_OPEN_ERROR;
380 *err = WTAP_ERR_BAD_FILE;
381 *err_info = g_strdup("peektagged: <MediaType> tag not found");
382 return WTAP_OPEN_ERROR;
384 /* XXX - this appears to be 0 in both the EtherPeek and AiroPeek
385 files we've seen; should we require it to be 0? */
386 ret = wtap_file_read_number (wth, &mediaType, err, err_info);
388 return WTAP_OPEN_ERROR;
390 *err = WTAP_ERR_BAD_FILE;
391 *err_info = g_strdup("peektagged: <MediaType> value not found");
392 return WTAP_OPEN_ERROR;
395 ret = wtap_file_read_pattern (wth, "<MediaSubType>", err, err_info);
397 return WTAP_OPEN_ERROR;
399 *err = WTAP_ERR_BAD_FILE;
400 *err_info = g_strdup("peektagged: <MediaSubType> tag not found");
401 return WTAP_OPEN_ERROR;
403 ret = wtap_file_read_number (wth, &mediaSubType, err, err_info);
405 return WTAP_OPEN_ERROR;
407 *err = WTAP_ERR_BAD_FILE;
408 *err_info = g_strdup("peektagged: <MediaSubType> value not found");
409 return WTAP_OPEN_ERROR;
411 if (mediaSubType >= NUM_PEEKTAGGED_ENCAPS
412 || peektagged_encap[mediaSubType] == WTAP_ENCAP_UNKNOWN) {
413 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
414 *err_info = g_strdup_printf("peektagged: network type %u unknown or unsupported",
416 return WTAP_OPEN_ERROR;
419 ret = wtap_file_read_pattern (wth, "pkts", err, err_info);
421 return WTAP_OPEN_ERROR;
423 *err = WTAP_ERR_SHORT_READ;
424 return WTAP_OPEN_ERROR;
427 /* skip 8 zero bytes */
428 if (file_seek (wth->fh, 8L, SEEK_CUR, err) == -1)
429 return WTAP_OPEN_NOT_MINE;
432 * This is an Peek tagged file.
434 file_encap = peektagged_encap[mediaSubType];
436 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED;
437 wth->file_encap = file_encap;
438 wth->subtype_read = peektagged_read;
439 wth->subtype_seek_read = peektagged_seek_read;
440 wth->file_tsprec = WTAP_TSPREC_NSEC;
442 peektagged = (peektagged_t *)g_malloc(sizeof(peektagged_t));
443 wth->priv = (void *)peektagged;
444 switch (mediaSubType) {
446 case PEEKTAGGED_NST_ETHERNET:
447 case PEEKTAGGED_NST_802_11:
448 case PEEKTAGGED_NST_802_11_2:
449 peektagged->has_fcs = FALSE;
452 case PEEKTAGGED_NST_802_11_WITH_FCS:
453 peektagged->has_fcs = TRUE;
457 wth->snapshot_length = 0; /* not available in header */
459 return WTAP_OPEN_MINE;
465 peektagged_utime timestamp;
466 struct ieee_802_11_phdr ieee_802_11;
470 * Time stamps appear to be in nanoseconds since the Windows epoch
471 * as used in FILETIMEs, i.e. midnight, January 1, 1601.
473 * This magic number came from "nt_time_to_nstime()" in "packet-smb.c".
474 * 1970-1601 is 369; I'm not sure what the extra 3 days and 6 hours are
475 * that are being subtracted.
477 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
482 * XXX - we should supply the additional radio information;
483 * the pseudo-header should probably be supplied in a fashion
484 * similar to the radiotap radio header, so that the 802.11
485 * dissector can determine which, if any, information items
489 peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
490 Buffer *buf, int *err, gchar **err_info)
492 peektagged_t *peektagged = (peektagged_t *)wth->priv;
497 gboolean saw_length = FALSE;
498 gboolean saw_timestamp_lower = FALSE;
499 gboolean saw_timestamp_upper = FALSE;
503 memset(&hdr_info, 0, sizeof(hdr_info_t));
505 /* Extract the fields from the packet header */
507 /* Get the tag and value.
508 XXX - this assumes all values are 4 bytes long. */
509 if (!wtap_read_bytes_or_eof(fh, tag_value, sizeof tag_value, err, err_info)) {
512 * Short read if we've read something already;
513 * just an EOF if we haven't.
516 *err = WTAP_ERR_SHORT_READ;
520 header_len += (int) sizeof(tag_value);
521 tag = pletoh16(&tag_value[0]);
524 case TAG_PEEKTAGGED_LENGTH:
526 *err = WTAP_ERR_BAD_FILE;
527 *err_info = g_strdup("peektagged: record has two length fields");
530 hdr_info.length = pletoh32(&tag_value[2]);
534 case TAG_PEEKTAGGED_TIMESTAMP_LOWER:
535 if (saw_timestamp_lower) {
536 *err = WTAP_ERR_BAD_FILE;
537 *err_info = g_strdup("peektagged: record has two timestamp-lower fields");
540 hdr_info.timestamp.lower = pletoh32(&tag_value[2]);
541 saw_timestamp_lower = TRUE;
544 case TAG_PEEKTAGGED_TIMESTAMP_UPPER:
545 if (saw_timestamp_upper) {
546 *err = WTAP_ERR_BAD_FILE;
547 *err_info = g_strdup("peektagged: record has two timestamp-upper fields");
550 hdr_info.timestamp.upper = pletoh32(&tag_value[2]);
551 saw_timestamp_upper = TRUE;
554 case TAG_PEEKTAGGED_FLAGS_AND_STATUS:
555 /* XXX - not used yet */
558 case TAG_PEEKTAGGED_CHANNEL:
559 hdr_info.ieee_802_11.channel = pletoh32(&tag_value[2]);
562 case TAG_PEEKTAGGED_RATE:
563 hdr_info.ieee_802_11.data_rate = pletoh32(&tag_value[2]);
566 case TAG_PEEKTAGGED_SIGNAL_PERC:
567 hdr_info.ieee_802_11.signal_level = pletoh32(&tag_value[2]);
570 case TAG_PEEKTAGGED_SIGNAL_DBM:
571 /* XXX - not used yet */
574 case TAG_PEEKTAGGED_NOISE_PERC:
575 /* XXX - not used yet */
578 case TAG_PEEKTAGGED_NOISE_DBM:
579 /* XXX - not used yet */
582 case TAG_PEEKTAGGED_UNKNOWN_0x000A:
583 /* XXX - seen in an OmniPeek 802.11n capture; value unknown */
586 case TAG_PEEKTAGGED_CENTER_FREQUENCY:
587 /* XXX - also seen in an EtherPeek capture; value unknown */
590 case TAG_PEEKTAGGED_UNKNOWN_0x000E:
591 /* XXX - seen in an AiroPeek/OmniPeek capture; value unknown */
594 case TAG_PEEKTAGGED_UNKNOWN_0x000F:
595 /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
598 case TAG_PEEKTAGGED_UNKNOWN_0x0010:
599 /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
602 case TAG_PEEKTAGGED_UNKNOWN_0x0011:
603 /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
606 case TAG_PEEKTAGGED_UNKNOWN_0x0012:
607 /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
610 case TAG_PEEKTAGGED_UNKNOWN_0x0013:
611 /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */
614 case TAG_PEEKTAGGED_UNKNOWN_0x0014:
615 /* XXX - seen in an AiroPeek/OmniPeek capture; value unknown */
618 case TAG_PEEKTAGGED_EXT_FLAGS:
621 case TAG_PEEKTAGGED_SLICE_LENGTH:
622 hdr_info.sliceLength = pletoh32(&tag_value[2]);
628 } while (tag != TAG_PEEKTAGGED_SLICE_LENGTH); /* last tag */
631 *err = WTAP_ERR_BAD_FILE;
632 *err_info = g_strdup("peektagged: record has no length field");
635 if (!saw_timestamp_lower) {
636 *err = WTAP_ERR_BAD_FILE;
637 *err_info = g_strdup("peektagged: record has no timestamp-lower field");
640 if (!saw_timestamp_upper) {
641 *err = WTAP_ERR_BAD_FILE;
642 *err_info = g_strdup("peektagged: record has no timestamp-upper field");
647 * If sliceLength is 0, force it to be the actual length of the packet.
649 if (hdr_info.sliceLength == 0)
650 hdr_info.sliceLength = hdr_info.length;
652 if (hdr_info.sliceLength > WTAP_MAX_PACKET_SIZE) {
654 * Probably a corrupt capture file; don't blow up trying
655 * to allocate space for an immensely-large packet.
657 *err = WTAP_ERR_BAD_FILE;
658 *err_info = g_strdup_printf("peektagged: File has %u-byte packet, bigger than maximum of %u",
659 hdr_info.sliceLength, WTAP_MAX_PACKET_SIZE);
663 phdr->rec_type = REC_TYPE_PACKET;
664 phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
665 phdr->len = hdr_info.length;
666 phdr->caplen = hdr_info.sliceLength;
668 /* calculate and fill in packet time stamp */
669 t = (double) hdr_info.timestamp.lower +
670 (double) hdr_info.timestamp.upper * 4294967296.0;
672 t -= TIME_FIXUP_CONSTANT;
673 phdr->ts.secs = (time_t) t;
674 phdr->ts.nsecs = (guint32) ((t - phdr->ts.secs)*1000000000);
676 switch (wth->file_encap) {
678 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
679 phdr->pseudo_header.ieee_802_11 = hdr_info.ieee_802_11;
680 if (peektagged->has_fcs)
681 phdr->pseudo_header.ieee_802_11.fcs_len = 4;
683 if (phdr->len < 4 || phdr->caplen < 4) {
684 *err = WTAP_ERR_BAD_FILE;
685 *err_info = g_strdup_printf("peektagged: 802.11 packet has length < 4");
688 phdr->pseudo_header.ieee_802_11.fcs_len = 0;
693 phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
696 case WTAP_ENCAP_ETHERNET:
698 * The last 4 bytes appear to be 0 in the captures I've seen;
699 * are there any captures where it's an FCS?
701 if (phdr->len < 4 || phdr->caplen < 4) {
702 *err = WTAP_ERR_BAD_FILE;
703 *err_info = g_strdup_printf("peektagged: Ethernet packet has length < 4");
706 phdr->pseudo_header.eth.fcs_len = 0;
713 /* Read the packet data. */
714 if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
720 static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
725 *data_offset = file_tell(wth->fh);
727 /* Read the packet. */
728 skip_len = peektagged_read_packet(wth, wth->fh, &wth->phdr,
729 wth->frame_buffer, err, err_info);
734 /* Skip extra junk at the end of the packet data. */
735 if (!file_skip(wth->fh, skip_len, err))
743 peektagged_seek_read(wtap *wth, gint64 seek_off,
744 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
746 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
749 /* Read the packet. */
750 if (peektagged_read_packet(wth, wth->random_fh, phdr, buf, err, err_info) == -1) {
752 *err = WTAP_ERR_SHORT_READ;