2 * Routines for opening files in what Savvius (formerly WildPackets) calls
3 * the tagged file format in the description of their "PeekRdr Sample
4 * Application" (C++ source code to read their capture files, downloading
5 * of which requires a maintenance contract, so it's not free as in beer
6 * and probably not 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 Savvius
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 "peektagged.h"
43 * This file decoder could not have been writen without examining
44 * http://www.varsanofiev.com/inside/airopeekv9.htm, the help from
45 * Martin Regner and Guy Harris, and the etherpeek.c file (as it
46 * was called before renaming it to peekclassic.c).
52 * A Peek tagged file consists of multiple sections, each of which begins
53 * with a header in the following format.
55 * The section ID is a 4-character string saying what type of section
56 * it is. The section length is a little-endian field giving the
57 * length of the section, in bytes, including the section header
58 * itself. The other field of the section header is a little-endian
59 * constant that always appears to be 0x00000200.
61 * Files we've seen have the following sections, in order:
63 * "\177vers" - version information. The contents are XML, giving
64 * the file format version and application version information.
66 * "sess" - capture session information. The contents are XML, giving
67 * various information about the capture session.
69 * "pkts" - captured packets. The contents are binary records, one for
70 * each packet, with the record being a list of tagged values followed
71 * by the raw packet data.
73 typedef struct peektagged_section_header {
74 gint8 section_id[4]; /* string identifying the section */
75 guint32 section_len; /* little-endian section length */
76 guint32 section_const; /* little-endian 0x00000200 */
77 } peektagged_section_header_t;
80 * Network subtype values.
82 * XXX - do different network subtype values for 802.11 indicate different
83 * network adapter types, with some adapters supplying the FCS and others
84 * not supplying the FCS?
86 #define PEEKTAGGED_NST_ETHERNET 0
87 #define PEEKTAGGED_NST_802_11 1 /* 802.11 with 0's at the end */
88 #define PEEKTAGGED_NST_802_11_2 2 /* 802.11 with 0's at the end */
89 #define PEEKTAGGED_NST_802_11_WITH_FCS 3 /* 802.11 with FCS at the end */
91 /* tags for fields in packet header */
92 #define TAG_PEEKTAGGED_LENGTH 0x0000
93 #define TAG_PEEKTAGGED_TIMESTAMP_LOWER 0x0001
94 #define TAG_PEEKTAGGED_TIMESTAMP_UPPER 0x0002
95 #define TAG_PEEKTAGGED_FLAGS_AND_STATUS 0x0003 /* upper 24 bits unused? */
96 #define TAG_PEEKTAGGED_CHANNEL 0x0004
97 #define TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX 0x0005
98 #define TAG_PEEKTAGGED_SIGNAL_PERC 0x0006
99 #define TAG_PEEKTAGGED_SIGNAL_DBM 0x0007
100 #define TAG_PEEKTAGGED_NOISE_PERC 0x0008
101 #define TAG_PEEKTAGGED_NOISE_DBM 0x0009
102 #define TAG_PEEKTAGGED_UNKNOWN_0x000A 0x000A
103 #define TAG_PEEKTAGGED_CENTER_FREQUENCY 0x000D /* Frequency */
104 #define TAG_PEEKTAGGED_UNKNOWN_0x000E 0x000E /* "Band"? */
105 #define TAG_PEEKTAGGED_UNKNOWN_0x000F 0x000F /* antenna 2 signal dBm? */
106 #define TAG_PEEKTAGGED_UNKNOWN_0x0010 0x0010 /* antenna 3 signal dBm? */
107 #define TAG_PEEKTAGGED_UNKNOWN_0x0011 0x0011 /* antenna 4 signal dBm? */
108 #define TAG_PEEKTAGGED_UNKNOWN_0x0012 0x0012 /* antenna 2 noise dBm? */
109 #define TAG_PEEKTAGGED_UNKNOWN_0x0013 0x0013 /* antenna 3 noise dBm? */
110 #define TAG_PEEKTAGGED_UNKNOWN_0x0014 0x0014 /* antenna 4 noise dBm? */
111 #define TAG_PEEKTAGGED_EXT_FLAGS 0x0015 /* Extended flags for 802.11n and beyond */
113 #define TAG_PEEKTAGGED_SLICE_LENGTH 0xffff
118 * We're assuming here that the "remote Peek" flags from bug 9586 are
119 * the same as the "Peek tagged" flags.
121 #define FLAGS_CONTROL_FRAME 0x01 /* Frame is a control frame */
122 #define FLAGS_HAS_CRC_ERROR 0x02 /* Frame has a CRC error */
123 #define FLAGS_HAS_FRAME_ERROR 0x04 /* Frame has a frame error */
128 * Is this in the next 8 bits of the "flags and status" field?
130 #define STATUS_PROTECTED 0x0400 /* Frame is protected (encrypted) */
131 #define STATUS_DECRYPT_ERROR 0x0800 /* Error decrypting protected frame */
132 #define STATUS_SHORT_PREAMBLE 0x4000 /* Short preamble */
137 * Some determined from bug 10637, some determined from bug 9586,
138 * and the ones present in both agree, so we're assuming that
139 * the "remote Peek" protocol and the "Peek tagged" file format
140 * use the same bits (which wouldn't be too surprising, as they
141 * both come from Wildpackets).
143 #define EXT_FLAG_20_MHZ_LOWER 0x00000001
144 #define EXT_FLAG_20_MHZ_UPPER 0x00000002
145 #define EXT_FLAG_40_MHZ 0x00000004
146 #define EXT_FLAGS_BANDWIDTH 0x00000007
147 #define EXT_FLAG_HALF_GI 0x00000008
148 #define EXT_FLAG_FULL_GI 0x00000010
149 #define EXT_FLAGS_GI 0x00000018
150 #define EXT_FLAG_AMPDU 0x00000020
151 #define EXT_FLAG_AMSDU 0x00000040
152 #define EXT_FLAG_802_11ac 0x00000080
153 #define EXT_FLAG_MCS_INDEX_USED 0x00000100
155 /* 64-bit time in nanoseconds from the (Windows FILETIME) epoch */
156 typedef struct peektagged_utime {
165 static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
166 gint64 *data_offset);
167 static gboolean peektagged_seek_read(wtap *wth, gint64 seek_off,
168 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
170 static int wtap_file_read_pattern (wtap *wth, const char *pattern, int *err,
179 c = file_getc(wth->fh);
182 *err = file_error(wth->fh, err_info);
183 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
184 return -1; /* error */
197 return (*cp == '\0' ? 1 : 0);
201 static int wtap_file_read_till_separator (wtap *wth, char *buffer, int buflen,
202 const char *separators, int *err,
209 for (cp = buffer, i = 0; i < buflen; i++, cp++)
211 c = file_getc(wth->fh);
214 *err = file_error(wth->fh, err_info);
215 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
216 return -1; /* error */
219 if (strchr (separators, c) != NULL)
231 static int wtap_file_read_number (wtap *wth, guint32 *num, int *err,
239 ret = wtap_file_read_till_separator (wth, str_num, sizeof (str_num)-1, "<",
241 if (ret == 0 || ret == -1) {
242 /* 0 means EOF, which means "not a valid Peek tagged file";
243 -1 means error, and "err" has been set. */
246 value = strtoul (str_num, &p, 10);
247 if (p == str_num || value > G_MAXUINT32)
249 *num = (guint32)value;
254 wtap_open_return_val peektagged_open(wtap *wth, int *err, gchar **err_info)
256 peektagged_section_header_t ap_hdr;
258 guint32 fileVersion = 0;
260 guint32 mediaSubType = 0;
262 static const int peektagged_encap[] = {
264 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
265 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
266 WTAP_ENCAP_IEEE_802_11_WITH_RADIO
268 #define NUM_PEEKTAGGED_ENCAPS (sizeof peektagged_encap / sizeof peektagged_encap[0])
269 peektagged_t *peektagged;
271 if (!wtap_read_bytes(wth->fh, &ap_hdr, (int)sizeof(ap_hdr), err, err_info)) {
272 if (*err != WTAP_ERR_SHORT_READ)
273 return WTAP_OPEN_ERROR;
274 return WTAP_OPEN_NOT_MINE;
277 if (memcmp (ap_hdr.section_id, "\177ver", sizeof(ap_hdr.section_id)) != 0)
278 return WTAP_OPEN_NOT_MINE; /* doesn't begin with a "\177ver" section */
281 * XXX - we should get the length of the "\177ver" section, check
282 * that it's followed by a little-endian 0x00000200, and then,
283 * when reading the XML, make sure we don't go past the end of
284 * that section, and skip to the end of that section when
285 * we have the file version (and possibly check to make sure all
286 * tags are properly opened and closed).
288 ret = wtap_file_read_pattern (wth, "<FileVersion>", err, err_info);
290 return WTAP_OPEN_ERROR;
292 /* 0 means EOF, which means "not a valid Peek tagged file" */
293 return WTAP_OPEN_NOT_MINE;
295 ret = wtap_file_read_number (wth, &fileVersion, err, err_info);
297 return WTAP_OPEN_ERROR;
299 /* 0 means EOF, which means "not a valid Peek tagged file" */
300 return WTAP_OPEN_NOT_MINE;
303 /* If we got this far, we assume it's a Peek tagged file. */
304 if (fileVersion != 9) {
305 /* We only support version 9. */
306 *err = WTAP_ERR_UNSUPPORTED;
307 *err_info = g_strdup_printf("peektagged: version %u unsupported",
309 return WTAP_OPEN_ERROR;
313 * XXX - once we've skipped the "\177ver" section, we should
314 * check for a "sess" section and fail if we don't see it.
315 * Then we should get the length of the "sess" section, check
316 * that it's followed by a little-endian 0x00000200, and then,
317 * when reading the XML, make sure we don't go past the end of
318 * that section, and skip to the end of the section when
319 * we have the file version (and possibly check to make sure all
320 * tags are properly opened and closed).
322 ret = wtap_file_read_pattern (wth, "<MediaType>", err, err_info);
324 return WTAP_OPEN_ERROR;
326 *err = WTAP_ERR_BAD_FILE;
327 *err_info = g_strdup("peektagged: <MediaType> tag not found");
328 return WTAP_OPEN_ERROR;
330 /* XXX - this appears to be 0 in both the EtherPeek and AiroPeek
331 files we've seen; should we require it to be 0? */
332 ret = wtap_file_read_number (wth, &mediaType, err, err_info);
334 return WTAP_OPEN_ERROR;
336 *err = WTAP_ERR_BAD_FILE;
337 *err_info = g_strdup("peektagged: <MediaType> value not found");
338 return WTAP_OPEN_ERROR;
341 ret = wtap_file_read_pattern (wth, "<MediaSubType>", err, err_info);
343 return WTAP_OPEN_ERROR;
345 *err = WTAP_ERR_BAD_FILE;
346 *err_info = g_strdup("peektagged: <MediaSubType> tag not found");
347 return WTAP_OPEN_ERROR;
349 ret = wtap_file_read_number (wth, &mediaSubType, err, err_info);
351 return WTAP_OPEN_ERROR;
353 *err = WTAP_ERR_BAD_FILE;
354 *err_info = g_strdup("peektagged: <MediaSubType> value not found");
355 return WTAP_OPEN_ERROR;
357 if (mediaSubType >= NUM_PEEKTAGGED_ENCAPS
358 || peektagged_encap[mediaSubType] == WTAP_ENCAP_UNKNOWN) {
359 *err = WTAP_ERR_UNSUPPORTED;
360 *err_info = g_strdup_printf("peektagged: network type %u unknown or unsupported",
362 return WTAP_OPEN_ERROR;
365 ret = wtap_file_read_pattern (wth, "pkts", err, err_info);
367 return WTAP_OPEN_ERROR;
369 *err = WTAP_ERR_SHORT_READ;
370 return WTAP_OPEN_ERROR;
373 /* skip 8 zero bytes */
374 if (file_seek (wth->fh, 8L, SEEK_CUR, err) == -1)
375 return WTAP_OPEN_NOT_MINE;
378 * This is an Peek tagged file.
380 file_encap = peektagged_encap[mediaSubType];
382 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED;
383 wth->file_encap = file_encap;
384 wth->subtype_read = peektagged_read;
385 wth->subtype_seek_read = peektagged_seek_read;
386 wth->file_tsprec = WTAP_TSPREC_NSEC;
388 peektagged = (peektagged_t *)g_malloc(sizeof(peektagged_t));
389 wth->priv = (void *)peektagged;
390 switch (mediaSubType) {
392 case PEEKTAGGED_NST_ETHERNET:
393 case PEEKTAGGED_NST_802_11:
394 case PEEKTAGGED_NST_802_11_2:
395 peektagged->has_fcs = FALSE;
398 case PEEKTAGGED_NST_802_11_WITH_FCS:
399 peektagged->has_fcs = TRUE;
403 wth->snapshot_length = 0; /* not available in header */
405 return WTAP_OPEN_MINE;
411 * XXX - we should supply the additional radio information;
412 * the pseudo-header should probably be supplied in a fashion
413 * similar to the radiotap radio header, so that the 802.11
414 * dissector can determine which, if any, information items
418 peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
419 Buffer *buf, int *err, gchar **err_info)
421 peektagged_t *peektagged = (peektagged_t *)wth->priv;
422 gboolean read_a_tag = FALSE;
425 gboolean saw_length = FALSE;
427 guint32 sliceLength = 0;
428 gboolean saw_timestamp_lower = FALSE;
429 gboolean saw_timestamp_upper = FALSE;
430 peektagged_utime timestamp;
431 guint32 ext_flags = 0;
432 gboolean saw_data_rate_or_mcs_index = FALSE;
433 guint32 data_rate_or_mcs_index = 0;
434 struct ieee_802_11_phdr ieee_802_11;
440 /* Shouldn't be necessary, but squelches a compiler warning. */
441 memset(&ieee_802_11, 0, sizeof ieee_802_11);
442 ieee_802_11.fcs_len = -1; /* Unknown */
443 ieee_802_11.decrypted = FALSE;
444 ieee_802_11.datapad = FALSE;
445 ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;
446 ieee_802_11.presence_flags = 0;
448 /* Extract the fields from the packet header */
450 /* Get the tag and value.
451 XXX - this assumes all values are 4 bytes long. */
452 if (!wtap_read_bytes_or_eof(fh, tag_value, sizeof tag_value, err, err_info)) {
455 * Short read if we've read something already;
456 * just an EOF if we haven't.
459 *err = WTAP_ERR_SHORT_READ;
464 tag = pletoh16(&tag_value[0]);
467 case TAG_PEEKTAGGED_LENGTH:
469 *err = WTAP_ERR_BAD_FILE;
470 *err_info = g_strdup("peektagged: record has two length fields");
473 length = pletoh32(&tag_value[2]);
477 case TAG_PEEKTAGGED_TIMESTAMP_LOWER:
478 if (saw_timestamp_lower) {
479 *err = WTAP_ERR_BAD_FILE;
480 *err_info = g_strdup("peektagged: record has two timestamp-lower fields");
483 timestamp.lower = pletoh32(&tag_value[2]);
484 saw_timestamp_lower = TRUE;
487 case TAG_PEEKTAGGED_TIMESTAMP_UPPER:
488 if (saw_timestamp_upper) {
489 *err = WTAP_ERR_BAD_FILE;
490 *err_info = g_strdup("peektagged: record has two timestamp-upper fields");
493 timestamp.upper = pletoh32(&tag_value[2]);
494 saw_timestamp_upper = TRUE;
497 case TAG_PEEKTAGGED_FLAGS_AND_STATUS:
498 /* XXX - not used yet */
501 case TAG_PEEKTAGGED_CHANNEL:
502 ieee_802_11.presence_flags |= PHDR_802_11_HAS_CHANNEL;
503 ieee_802_11.channel = pletoh32(&tag_value[2]);
506 case TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX:
507 data_rate_or_mcs_index = pletoh32(&tag_value[2]);
508 saw_data_rate_or_mcs_index = TRUE;
511 case TAG_PEEKTAGGED_SIGNAL_PERC:
512 ieee_802_11.presence_flags |= PHDR_802_11_HAS_SIGNAL_PERCENT;
513 ieee_802_11.signal_percent = pletoh32(&tag_value[2]);
516 case TAG_PEEKTAGGED_SIGNAL_DBM:
517 ieee_802_11.presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM;
518 ieee_802_11.signal_dbm = pletoh32(&tag_value[2]);
521 case TAG_PEEKTAGGED_NOISE_PERC:
522 ieee_802_11.presence_flags |= PHDR_802_11_HAS_NOISE_PERCENT;
523 ieee_802_11.noise_percent = pletoh32(&tag_value[2]);
526 case TAG_PEEKTAGGED_NOISE_DBM:
527 ieee_802_11.presence_flags |= PHDR_802_11_HAS_NOISE_DBM;
528 ieee_802_11.noise_dbm = pletoh32(&tag_value[2]);
531 case TAG_PEEKTAGGED_UNKNOWN_0x000A:
533 * XXX - seen in some 802.11 captures.
534 * Always seems to have the value 0 or 5.
538 case TAG_PEEKTAGGED_CENTER_FREQUENCY:
539 /* XXX - also seen in an EtherPeek capture; value unknown */
540 ieee_802_11.presence_flags |= PHDR_802_11_HAS_FREQUENCY;
541 ieee_802_11.frequency = pletoh32(&tag_value[2]);
544 case TAG_PEEKTAGGED_UNKNOWN_0x000E:
546 * XXX - seen in some 802.11 captures.
547 * Usually has the value 4, but, in some packets, has the
550 * Is this the mysterious "band" field that shows up in
551 * some "Peek remote" protocol captures, with values in
552 * the 30x or 40x ranges? It's not always associated
553 * with the "extended flags" tag for HT/VHT information,
554 * so it's probably not 11n/11ac-specific. Values other
555 * than 4 appear, in my captures, only in packets with
556 * the "extended flags" tag. 302 appeared in a packet
557 * with EXT_FLAG_MCS_INDEX_USED; 6 appeared in packets
558 * without EXT_FLAG_MCS_INDEX_USED.
562 case TAG_PEEKTAGGED_UNKNOWN_0x000F:
564 * XXX - seen in some 802.11 captures; dB or dBm value?
569 case TAG_PEEKTAGGED_UNKNOWN_0x0010:
571 * XXX - seen in some 802.11 captures; dB or dBm value?
576 case TAG_PEEKTAGGED_UNKNOWN_0x0011:
578 * XXX - seen in some 802.11 captures; dB or dBm value?
583 case TAG_PEEKTAGGED_UNKNOWN_0x0012:
585 * XXX - seen in some 802.11 captures; dB or dBm value?
590 case TAG_PEEKTAGGED_UNKNOWN_0x0013:
592 * XXX - seen in some 802.11 captures; dB or dBm value?
597 case TAG_PEEKTAGGED_UNKNOWN_0x0014:
599 * XXX - seen in some 802.11 captures; dB or dBm value?
604 case TAG_PEEKTAGGED_EXT_FLAGS:
606 * We assume this is present for HT and VHT frames and absent
609 ext_flags = pletoh32(&tag_value[2]);
610 if (ext_flags & EXT_FLAG_802_11ac) {
611 ieee_802_11.phy = PHDR_802_11_PHY_11AC;
612 ieee_802_11.phy_info.info_11ac.presence_flags = 0;
614 switch (ext_flags & EXT_FLAGS_GI) {
616 case EXT_FLAG_HALF_GI:
617 ieee_802_11.phy_info.info_11ac.presence_flags |= PHDR_802_11AC_HAS_SHORT_GI;
618 ieee_802_11.phy_info.info_11ac.short_gi = 1;
621 case EXT_FLAG_FULL_GI:
622 ieee_802_11.phy_info.info_11ac.presence_flags |= PHDR_802_11AC_HAS_SHORT_GI;
623 ieee_802_11.phy_info.info_11ac.short_gi = 0;
627 /* Mutually exclusive flags set or nothing set */
631 ieee_802_11.phy = PHDR_802_11_PHY_11N;
632 switch (ext_flags & EXT_FLAGS_BANDWIDTH) {
635 ieee_802_11.phy_info.info_11n.presence_flags = PHDR_802_11N_HAS_BANDWIDTH;
636 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_MHZ;
639 case EXT_FLAG_20_MHZ_LOWER:
640 ieee_802_11.phy_info.info_11n.presence_flags = PHDR_802_11N_HAS_BANDWIDTH;
641 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20L;
644 case EXT_FLAG_20_MHZ_UPPER:
645 ieee_802_11.phy_info.info_11n.presence_flags = PHDR_802_11N_HAS_BANDWIDTH;
646 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20U;
649 case EXT_FLAG_40_MHZ:
650 ieee_802_11.phy_info.info_11n.presence_flags = PHDR_802_11N_HAS_BANDWIDTH;
651 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_40_MHZ;
655 /* Mutually exclusive flags set */
656 ieee_802_11.phy_info.info_11n.presence_flags = 0;
660 switch (ext_flags & EXT_FLAGS_GI) {
662 case EXT_FLAG_HALF_GI:
663 ieee_802_11.phy_info.info_11n.presence_flags |= PHDR_802_11N_HAS_SHORT_GI;
664 ieee_802_11.phy_info.info_11n.short_gi = 1;
667 case EXT_FLAG_FULL_GI:
668 ieee_802_11.phy_info.info_11n.presence_flags |= PHDR_802_11N_HAS_SHORT_GI;
669 ieee_802_11.phy_info.info_11n.short_gi = 0;
673 /* Mutually exclusive flags set or nothing set */
679 case TAG_PEEKTAGGED_SLICE_LENGTH:
680 sliceLength = pletoh32(&tag_value[2]);
686 } while (tag != TAG_PEEKTAGGED_SLICE_LENGTH); /* last tag */
689 *err = WTAP_ERR_BAD_FILE;
690 *err_info = g_strdup("peektagged: record has no length field");
693 if (!saw_timestamp_lower) {
694 *err = WTAP_ERR_BAD_FILE;
695 *err_info = g_strdup("peektagged: record has no timestamp-lower field");
698 if (!saw_timestamp_upper) {
699 *err = WTAP_ERR_BAD_FILE;
700 *err_info = g_strdup("peektagged: record has no timestamp-upper field");
705 * If sliceLength is 0, force it to be the actual length of the packet.
707 if (sliceLength == 0)
708 sliceLength = length;
710 if (sliceLength > WTAP_MAX_PACKET_SIZE) {
712 * Probably a corrupt capture file; don't blow up trying
713 * to allocate space for an immensely-large packet.
715 *err = WTAP_ERR_BAD_FILE;
716 *err_info = g_strdup_printf("peektagged: File has %u-byte packet, bigger than maximum of %u",
717 sliceLength, WTAP_MAX_PACKET_SIZE);
721 phdr->rec_type = REC_TYPE_PACKET;
722 phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
724 phdr->caplen = sliceLength;
726 /* calculate and fill in packet time stamp */
727 t = (((guint64) timestamp.upper) << 32) + timestamp.lower;
728 if (!nsfiletime_to_nstime(&phdr->ts, t)) {
729 *err = WTAP_ERR_BAD_FILE;
730 *err_info = g_strdup_printf("peektagged: time stamp outside supported range");
734 switch (wth->file_encap) {
736 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
737 if (saw_data_rate_or_mcs_index) {
738 if (ext_flags & EXT_FLAG_MCS_INDEX_USED) {
739 /* It's an MCS index. */
740 if (ext_flags & EXT_FLAG_802_11ac) {
741 ieee_802_11.phy_info.info_11ac.presence_flags |= PHDR_802_11AC_HAS_MCS_INDEX;
742 ieee_802_11.phy_info.info_11ac.mcs_index = data_rate_or_mcs_index;
744 ieee_802_11.phy_info.info_11n.presence_flags |= PHDR_802_11N_HAS_MCS_INDEX;
745 ieee_802_11.phy_info.info_11n.mcs_index = data_rate_or_mcs_index;
748 /* It's a data rate. */
749 ieee_802_11.presence_flags |= PHDR_802_11_HAS_DATA_RATE;
750 ieee_802_11.data_rate = data_rate_or_mcs_index;
753 phdr->pseudo_header.ieee_802_11 = ieee_802_11;
754 if (peektagged->has_fcs)
755 phdr->pseudo_header.ieee_802_11.fcs_len = 4;
757 if (phdr->len < 4 || phdr->caplen < 4) {
758 *err = WTAP_ERR_BAD_FILE;
759 *err_info = g_strdup_printf("peektagged: 802.11 packet has length < 4");
762 phdr->pseudo_header.ieee_802_11.fcs_len = 0;
767 phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
768 phdr->pseudo_header.ieee_802_11.datapad = FALSE;
771 case WTAP_ENCAP_ETHERNET:
773 * The last 4 bytes appear to be 0 in the captures I've seen;
774 * are there any captures where it's an FCS?
776 if (phdr->len < 4 || phdr->caplen < 4) {
777 *err = WTAP_ERR_BAD_FILE;
778 *err_info = g_strdup_printf("peektagged: Ethernet packet has length < 4");
781 phdr->pseudo_header.eth.fcs_len = 0;
788 /* Read the packet data. */
789 if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
795 static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
800 *data_offset = file_tell(wth->fh);
802 /* Read the packet. */
803 skip_len = peektagged_read_packet(wth, wth->fh, &wth->phdr,
804 wth->frame_buffer, err, err_info);
809 /* Skip extra junk at the end of the packet data. */
810 if (!file_skip(wth->fh, skip_len, err))
818 peektagged_seek_read(wtap *wth, gint64 seek_off,
819 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
821 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
824 /* Read the packet. */
825 if (peektagged_read_packet(wth, wth->random_fh, phdr, buf, err, err_info) == -1) {
827 *err = WTAP_ERR_SHORT_READ;
834 * Editor modelines - http://www.wireshark.org/tools/modelines.html
839 * indent-tabs-mode: nil
842 * vi: set shiftwidth=4 tabstop=8 expandtab:
843 * :indentSize=4:tabSize=8:noTabs=true: