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 * SPDX-License-Identifier: GPL-2.0-or-later
26 #include "file_wrappers.h"
27 #include "peektagged.h"
28 #include <wsutil/frequency-utils.h>
32 * This file decoder could not have been writen without examining
33 * http://www.varsanofiev.com/inside/airopeekv9.htm, the help from
34 * Martin Regner and Guy Harris, and the etherpeek.c file (as it
35 * was called before renaming it to peekclassic.c).
41 * A Peek tagged file consists of multiple sections, each of which begins
42 * with a header in the following format.
44 * The section ID is a 4-character string saying what type of section
45 * it is. The section length is a little-endian field giving the
46 * length of the section, in bytes, including the section header
47 * itself. The other field of the section header is a little-endian
48 * constant that always appears to be 0x00000200.
50 * Files we've seen have the following sections, in order:
52 * "\177vers" - version information. The contents are XML, giving
53 * the file format version and application version information.
55 * "sess" - capture session information. The contents are XML, giving
56 * various information about the capture session.
58 * "pkts" - captured packets. The contents are binary records, one for
59 * each packet, with the record being a list of tagged values followed
60 * by the raw packet data.
62 typedef struct peektagged_section_header {
63 gint8 section_id[4]; /* string identifying the section */
64 guint32 section_len; /* little-endian section length */
65 guint32 section_const; /* little-endian 0x00000200 */
66 } peektagged_section_header_t;
69 * Network subtype values.
71 * XXX - do different network subtype values for 802.11 indicate different
72 * network adapter types, with some adapters supplying the FCS and others
73 * not supplying the FCS?
75 #define PEEKTAGGED_NST_ETHERNET 0
76 #define PEEKTAGGED_NST_802_11 1 /* 802.11 with 0's at the end */
77 #define PEEKTAGGED_NST_802_11_2 2 /* 802.11 with 0's at the end */
78 #define PEEKTAGGED_NST_802_11_WITH_FCS 3 /* 802.11 with FCS at the end */
80 /* tags for fields in packet header */
81 #define TAG_PEEKTAGGED_LENGTH 0x0000
82 #define TAG_PEEKTAGGED_TIMESTAMP_LOWER 0x0001
83 #define TAG_PEEKTAGGED_TIMESTAMP_UPPER 0x0002
84 #define TAG_PEEKTAGGED_FLAGS_AND_STATUS 0x0003 /* upper 24 bits unused? */
85 #define TAG_PEEKTAGGED_CHANNEL 0x0004
86 #define TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX 0x0005
87 #define TAG_PEEKTAGGED_SIGNAL_PERC 0x0006
88 #define TAG_PEEKTAGGED_SIGNAL_DBM 0x0007
89 #define TAG_PEEKTAGGED_NOISE_PERC 0x0008
90 #define TAG_PEEKTAGGED_NOISE_DBM 0x0009
91 #define TAG_PEEKTAGGED_UNKNOWN_0x000A 0x000A
92 #define TAG_PEEKTAGGED_CENTER_FREQUENCY 0x000D /* Frequency */
93 #define TAG_PEEKTAGGED_UNKNOWN_0x000E 0x000E /* "Band"? */
94 #define TAG_PEEKTAGGED_UNKNOWN_0x000F 0x000F /* antenna 2 signal dBm? */
95 #define TAG_PEEKTAGGED_UNKNOWN_0x0010 0x0010 /* antenna 3 signal dBm? */
96 #define TAG_PEEKTAGGED_UNKNOWN_0x0011 0x0011 /* antenna 4 signal dBm? */
97 #define TAG_PEEKTAGGED_UNKNOWN_0x0012 0x0012 /* antenna 2 noise dBm? */
98 #define TAG_PEEKTAGGED_UNKNOWN_0x0013 0x0013 /* antenna 3 noise dBm? */
99 #define TAG_PEEKTAGGED_UNKNOWN_0x0014 0x0014 /* antenna 4 noise dBm? */
100 #define TAG_PEEKTAGGED_EXT_FLAGS 0x0015 /* Extended flags for 802.11n and beyond */
102 #define TAG_PEEKTAGGED_SLICE_LENGTH 0xffff
107 * We're assuming here that the "remote Peek" flags from bug 9586 are
108 * the same as the "Peek tagged" flags.
110 * Are these the same as in "Peek classic"? The first three are.
112 #define FLAGS_CONTROL_FRAME 0x01 /* Frame is a control frame */
113 #define FLAGS_HAS_CRC_ERROR 0x02 /* Frame has a CRC error */
114 #define FLAGS_HAS_FRAME_ERROR 0x04 /* Frame has a frame error */
119 * Is this in the next 8 bits of the "flags and status" field?
121 #define STATUS_PROTECTED 0x0400 /* Frame is protected (encrypted) */
122 #define STATUS_DECRYPT_ERROR 0x0800 /* Error decrypting protected frame */
123 #define STATUS_SHORT_PREAMBLE 0x4000 /* Short preamble */
128 * Some determined from bug 10637, some determined from bug 9586,
129 * and the ones present in both agree, so we're assuming that
130 * the "remote Peek" protocol and the "Peek tagged" file format
131 * use the same bits (which wouldn't be too surprising, as they
132 * both come from Wildpackets).
134 #define EXT_FLAG_20_MHZ_LOWER 0x00000001
135 #define EXT_FLAG_20_MHZ_UPPER 0x00000002
136 #define EXT_FLAG_40_MHZ 0x00000004
137 #define EXT_FLAGS_BANDWIDTH 0x00000007
138 #define EXT_FLAG_HALF_GI 0x00000008
139 #define EXT_FLAG_FULL_GI 0x00000010
140 #define EXT_FLAGS_GI 0x00000018
141 #define EXT_FLAG_AMPDU 0x00000020
142 #define EXT_FLAG_AMSDU 0x00000040
143 #define EXT_FLAG_802_11ac 0x00000080
144 #define EXT_FLAG_MCS_INDEX_USED 0x00000100
146 /* 64-bit time in nanoseconds from the (Windows FILETIME) epoch */
147 typedef struct peektagged_utime {
156 static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
157 gint64 *data_offset);
158 static gboolean peektagged_seek_read(wtap *wth, gint64 seek_off,
159 wtap_rec *rec, Buffer *buf, int *err, gchar **err_info);
161 static int wtap_file_read_pattern (wtap *wth, const char *pattern, int *err,
170 c = file_getc(wth->fh);
173 *err = file_error(wth->fh, err_info);
174 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
175 return -1; /* error */
188 return (*cp == '\0' ? 1 : 0);
192 static int wtap_file_read_till_separator (wtap *wth, char *buffer, int buflen,
193 const char *separators, int *err,
200 for (cp = buffer, i = 0; i < buflen; i++, cp++)
202 c = file_getc(wth->fh);
205 *err = file_error(wth->fh, err_info);
206 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
207 return -1; /* error */
210 if (strchr (separators, c) != NULL)
222 static int wtap_file_read_number (wtap *wth, guint32 *num, int *err,
230 ret = wtap_file_read_till_separator (wth, str_num, sizeof (str_num)-1, "<",
232 if (ret == 0 || ret == -1) {
233 /* 0 means EOF, which means "not a valid Peek tagged file";
234 -1 means error, and "err" has been set. */
237 value = strtoul (str_num, &p, 10);
238 if (p == str_num || value > G_MAXUINT32)
240 *num = (guint32)value;
245 wtap_open_return_val peektagged_open(wtap *wth, int *err, gchar **err_info)
247 peektagged_section_header_t ap_hdr;
249 guint32 fileVersion = 0;
251 guint32 mediaSubType = 0;
253 static const int peektagged_encap[] = {
255 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
256 WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
257 WTAP_ENCAP_IEEE_802_11_WITH_RADIO
259 #define NUM_PEEKTAGGED_ENCAPS (sizeof peektagged_encap / sizeof peektagged_encap[0])
260 peektagged_t *peektagged;
262 if (!wtap_read_bytes(wth->fh, &ap_hdr, (int)sizeof(ap_hdr), err, err_info)) {
263 if (*err != WTAP_ERR_SHORT_READ)
264 return WTAP_OPEN_ERROR;
265 return WTAP_OPEN_NOT_MINE;
268 if (memcmp (ap_hdr.section_id, "\177ver", sizeof(ap_hdr.section_id)) != 0)
269 return WTAP_OPEN_NOT_MINE; /* doesn't begin with a "\177ver" section */
272 * XXX - we should get the length of the "\177ver" section, check
273 * that it's followed by a little-endian 0x00000200, and then,
274 * when reading the XML, make sure we don't go past the end of
275 * that section, and skip to the end of that section when
276 * we have the file version (and possibly check to make sure all
277 * tags are properly opened and closed).
279 ret = wtap_file_read_pattern (wth, "<FileVersion>", err, err_info);
281 return WTAP_OPEN_ERROR;
283 /* 0 means EOF, which means "not a valid Peek tagged file" */
284 return WTAP_OPEN_NOT_MINE;
286 ret = wtap_file_read_number (wth, &fileVersion, err, err_info);
288 return WTAP_OPEN_ERROR;
290 /* 0 means EOF, which means "not a valid Peek tagged file" */
291 return WTAP_OPEN_NOT_MINE;
294 /* If we got this far, we assume it's a Peek tagged file. */
295 if (fileVersion != 9) {
296 /* We only support version 9. */
297 *err = WTAP_ERR_UNSUPPORTED;
298 *err_info = g_strdup_printf("peektagged: version %u unsupported",
300 return WTAP_OPEN_ERROR;
304 * XXX - once we've skipped the "\177ver" section, we should
305 * check for a "sess" section and fail if we don't see it.
306 * Then we should get the length of the "sess" section, check
307 * that it's followed by a little-endian 0x00000200, and then,
308 * when reading the XML, make sure we don't go past the end of
309 * that section, and skip to the end of the section when
310 * we have the file version (and possibly check to make sure all
311 * tags are properly opened and closed).
313 ret = wtap_file_read_pattern (wth, "<MediaType>", err, err_info);
315 return WTAP_OPEN_ERROR;
317 *err = WTAP_ERR_BAD_FILE;
318 *err_info = g_strdup("peektagged: <MediaType> tag not found");
319 return WTAP_OPEN_ERROR;
321 /* XXX - this appears to be 0 in both the EtherPeek and AiroPeek
322 files we've seen; should we require it to be 0? */
323 ret = wtap_file_read_number (wth, &mediaType, err, err_info);
325 return WTAP_OPEN_ERROR;
327 *err = WTAP_ERR_BAD_FILE;
328 *err_info = g_strdup("peektagged: <MediaType> value not found");
329 return WTAP_OPEN_ERROR;
332 ret = wtap_file_read_pattern (wth, "<MediaSubType>", err, err_info);
334 return WTAP_OPEN_ERROR;
336 *err = WTAP_ERR_BAD_FILE;
337 *err_info = g_strdup("peektagged: <MediaSubType> tag not found");
338 return WTAP_OPEN_ERROR;
340 ret = wtap_file_read_number (wth, &mediaSubType, err, err_info);
342 return WTAP_OPEN_ERROR;
344 *err = WTAP_ERR_BAD_FILE;
345 *err_info = g_strdup("peektagged: <MediaSubType> value not found");
346 return WTAP_OPEN_ERROR;
348 if (mediaSubType >= NUM_PEEKTAGGED_ENCAPS
349 || peektagged_encap[mediaSubType] == WTAP_ENCAP_UNKNOWN) {
350 *err = WTAP_ERR_UNSUPPORTED;
351 *err_info = g_strdup_printf("peektagged: network type %u unknown or unsupported",
353 return WTAP_OPEN_ERROR;
356 ret = wtap_file_read_pattern (wth, "pkts", err, err_info);
358 return WTAP_OPEN_ERROR;
360 *err = WTAP_ERR_SHORT_READ;
361 return WTAP_OPEN_ERROR;
364 /* skip 8 zero bytes */
365 if (!wtap_read_bytes (wth->fh, NULL, 8, err, err_info)) {
366 return WTAP_OPEN_ERROR;
370 * This is an Peek tagged file.
372 file_encap = peektagged_encap[mediaSubType];
374 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PEEKTAGGED;
375 wth->file_encap = file_encap;
376 wth->subtype_read = peektagged_read;
377 wth->subtype_seek_read = peektagged_seek_read;
378 wth->file_tsprec = WTAP_TSPREC_NSEC;
380 peektagged = (peektagged_t *)g_malloc(sizeof(peektagged_t));
381 wth->priv = (void *)peektagged;
382 switch (mediaSubType) {
384 case PEEKTAGGED_NST_ETHERNET:
385 case PEEKTAGGED_NST_802_11:
386 case PEEKTAGGED_NST_802_11_2:
387 peektagged->has_fcs = FALSE;
390 case PEEKTAGGED_NST_802_11_WITH_FCS:
391 peektagged->has_fcs = TRUE;
395 wth->snapshot_length = 0; /* not available in header */
397 return WTAP_OPEN_MINE;
403 * XXX - we should supply the additional radio information;
404 * the pseudo-header should probably be supplied in a fashion
405 * similar to the radiotap radio header, so that the 802.11
406 * dissector can determine which, if any, information items
410 peektagged_read_packet(wtap *wth, FILE_T fh, wtap_rec *rec,
411 Buffer *buf, int *err, gchar **err_info)
413 peektagged_t *peektagged = (peektagged_t *)wth->priv;
414 gboolean read_a_tag = FALSE;
417 gboolean saw_length = FALSE;
419 guint32 sliceLength = 0;
420 gboolean saw_timestamp_lower = FALSE;
421 gboolean saw_timestamp_upper = FALSE;
422 peektagged_utime timestamp;
423 guint32 ext_flags = 0;
424 gboolean saw_data_rate_or_mcs_index = FALSE;
425 guint32 data_rate_or_mcs_index = 0;
428 struct ieee_802_11_phdr ieee_802_11;
435 memset(&ieee_802_11, 0, sizeof ieee_802_11);
436 ieee_802_11.fcs_len = -1; /* Unknown */
437 ieee_802_11.decrypted = FALSE;
438 ieee_802_11.datapad = FALSE;
439 ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN;
441 /* Extract the fields from the packet header */
443 /* Get the tag and value.
444 XXX - this assumes all values are 4 bytes long. */
445 if (!wtap_read_bytes_or_eof(fh, tag_value, sizeof tag_value, err, err_info)) {
448 * Short read if we've read something already;
449 * just an EOF if we haven't.
452 *err = WTAP_ERR_SHORT_READ;
457 tag = pletoh16(&tag_value[0]);
460 case TAG_PEEKTAGGED_LENGTH:
462 *err = WTAP_ERR_BAD_FILE;
463 *err_info = g_strdup("peektagged: record has two length fields");
466 length = pletoh32(&tag_value[2]);
470 case TAG_PEEKTAGGED_TIMESTAMP_LOWER:
471 if (saw_timestamp_lower) {
472 *err = WTAP_ERR_BAD_FILE;
473 *err_info = g_strdup("peektagged: record has two timestamp-lower fields");
476 timestamp.lower = pletoh32(&tag_value[2]);
477 saw_timestamp_lower = TRUE;
480 case TAG_PEEKTAGGED_TIMESTAMP_UPPER:
481 if (saw_timestamp_upper) {
482 *err = WTAP_ERR_BAD_FILE;
483 *err_info = g_strdup("peektagged: record has two timestamp-upper fields");
486 timestamp.upper = pletoh32(&tag_value[2]);
487 saw_timestamp_upper = TRUE;
490 case TAG_PEEKTAGGED_FLAGS_AND_STATUS:
491 /* XXX - not used yet */
494 case TAG_PEEKTAGGED_CHANNEL:
495 ieee_802_11.has_channel = TRUE;
496 ieee_802_11.channel = pletoh32(&tag_value[2]);
499 case TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX:
500 data_rate_or_mcs_index = pletoh32(&tag_value[2]);
501 saw_data_rate_or_mcs_index = TRUE;
504 case TAG_PEEKTAGGED_SIGNAL_PERC:
505 ieee_802_11.has_signal_percent = TRUE;
506 ieee_802_11.signal_percent = pletoh32(&tag_value[2]);
509 case TAG_PEEKTAGGED_SIGNAL_DBM:
510 ieee_802_11.has_signal_dbm = TRUE;
511 ieee_802_11.signal_dbm = pletoh32(&tag_value[2]);
514 case TAG_PEEKTAGGED_NOISE_PERC:
515 ieee_802_11.has_noise_percent = TRUE;
516 ieee_802_11.noise_percent = pletoh32(&tag_value[2]);
519 case TAG_PEEKTAGGED_NOISE_DBM:
520 ieee_802_11.has_noise_dbm = TRUE;
521 ieee_802_11.noise_dbm = pletoh32(&tag_value[2]);
524 case TAG_PEEKTAGGED_UNKNOWN_0x000A:
526 * XXX - seen in some 802.11 captures.
527 * Always seems to have the value 0 or 5.
531 case TAG_PEEKTAGGED_CENTER_FREQUENCY:
532 /* XXX - also seen in an EtherPeek capture; value unknown */
533 ieee_802_11.has_frequency = TRUE;
534 ieee_802_11.frequency = pletoh32(&tag_value[2]);
537 case TAG_PEEKTAGGED_UNKNOWN_0x000E:
539 * XXX - seen in some 802.11 captures.
540 * Usually has the value 4, but, in some packets, has the
543 * Is this the mysterious "band" field that shows up in
544 * some "Peek remote" protocol captures, with values in
545 * the 30x or 40x ranges? It's not always associated
546 * with the "extended flags" tag for HT/VHT information,
547 * so it's probably not 11n/11ac-specific. Values other
548 * than 4 appear, in my captures, only in packets with
549 * the "extended flags" tag. 302 appeared in a packet
550 * with EXT_FLAG_MCS_INDEX_USED; 6 appeared in packets
551 * without EXT_FLAG_MCS_INDEX_USED.
555 case TAG_PEEKTAGGED_UNKNOWN_0x000F:
557 * XXX - seen in some 802.11 captures; dB or dBm value?
562 case TAG_PEEKTAGGED_UNKNOWN_0x0010:
564 * XXX - seen in some 802.11 captures; dB or dBm value?
569 case TAG_PEEKTAGGED_UNKNOWN_0x0011:
571 * XXX - seen in some 802.11 captures; dB or dBm value?
576 case TAG_PEEKTAGGED_UNKNOWN_0x0012:
578 * XXX - seen in some 802.11 captures; dB or dBm value?
583 case TAG_PEEKTAGGED_UNKNOWN_0x0013:
585 * XXX - seen in some 802.11 captures; dB or dBm value?
590 case TAG_PEEKTAGGED_UNKNOWN_0x0014:
592 * XXX - seen in some 802.11 captures; dB or dBm value?
597 case TAG_PEEKTAGGED_EXT_FLAGS:
599 * We assume this is present for HT and VHT frames and absent
602 ext_flags = pletoh32(&tag_value[2]);
603 if (ext_flags & EXT_FLAG_802_11ac) {
604 ieee_802_11.phy = PHDR_802_11_PHY_11AC;
606 * XXX - this probably has only one user, so only
607 * one MCS index and only one NSS, but where's the
610 for (i = 0; i < 4; i++)
611 ieee_802_11.phy_info.info_11ac.nss[i] = 0;
613 switch (ext_flags & EXT_FLAGS_GI) {
615 case EXT_FLAG_HALF_GI:
616 ieee_802_11.phy_info.info_11ac.has_short_gi = TRUE;
617 ieee_802_11.phy_info.info_11ac.short_gi = 1;
620 case EXT_FLAG_FULL_GI:
621 ieee_802_11.phy_info.info_11ac.has_short_gi = TRUE;
622 ieee_802_11.phy_info.info_11ac.short_gi = 0;
626 /* Mutually exclusive flags set or nothing set */
630 ieee_802_11.phy = PHDR_802_11_PHY_11N;
631 switch (ext_flags & EXT_FLAGS_BANDWIDTH) {
634 ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
635 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_MHZ;
638 case EXT_FLAG_20_MHZ_LOWER:
639 ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
640 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20L;
643 case EXT_FLAG_20_MHZ_UPPER:
644 ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
645 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20U;
648 case EXT_FLAG_40_MHZ:
649 ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE;
650 ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_40_MHZ;
654 /* Mutually exclusive flags set */
658 switch (ext_flags & EXT_FLAGS_GI) {
660 case EXT_FLAG_HALF_GI:
661 ieee_802_11.phy_info.info_11n.has_short_gi = TRUE;
662 ieee_802_11.phy_info.info_11n.short_gi = 1;
665 case EXT_FLAG_FULL_GI:
666 ieee_802_11.phy_info.info_11n.has_short_gi = TRUE;
667 ieee_802_11.phy_info.info_11n.short_gi = 0;
671 /* Mutually exclusive flags set or nothing set */
677 case TAG_PEEKTAGGED_SLICE_LENGTH:
678 sliceLength = pletoh32(&tag_value[2]);
684 } while (tag != TAG_PEEKTAGGED_SLICE_LENGTH); /* last tag */
687 *err = WTAP_ERR_BAD_FILE;
688 *err_info = g_strdup("peektagged: record has no length field");
691 if (!saw_timestamp_lower) {
692 *err = WTAP_ERR_BAD_FILE;
693 *err_info = g_strdup("peektagged: record has no timestamp-lower field");
696 if (!saw_timestamp_upper) {
697 *err = WTAP_ERR_BAD_FILE;
698 *err_info = g_strdup("peektagged: record has no timestamp-upper field");
703 * If sliceLength is 0, force it to be the actual length of the packet.
705 if (sliceLength == 0)
706 sliceLength = length;
708 if (sliceLength > WTAP_MAX_PACKET_SIZE_STANDARD) {
710 * Probably a corrupt capture file; don't blow up trying
711 * to allocate space for an immensely-large packet.
713 *err = WTAP_ERR_BAD_FILE;
714 *err_info = g_strdup_printf("peektagged: File has %u-byte packet, bigger than maximum of %u",
715 sliceLength, WTAP_MAX_PACKET_SIZE_STANDARD);
719 rec->rec_type = REC_TYPE_PACKET;
720 rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
721 rec->rec_header.packet_header.len = length;
722 rec->rec_header.packet_header.caplen = sliceLength;
724 /* calculate and fill in packet time stamp */
725 t = (((guint64) timestamp.upper) << 32) + timestamp.lower;
726 if (!nsfiletime_to_nstime(&rec->ts, t)) {
727 *err = WTAP_ERR_BAD_FILE;
728 *err_info = g_strdup("peektagged: time stamp outside supported range");
732 switch (wth->file_encap) {
734 case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
735 if (saw_data_rate_or_mcs_index) {
736 if (ext_flags & EXT_FLAG_MCS_INDEX_USED) {
740 * XXX - what about 11ac?
742 if (!(ext_flags & EXT_FLAG_802_11ac)) {
743 ieee_802_11.phy_info.info_11n.has_mcs_index = TRUE;
744 ieee_802_11.phy_info.info_11n.mcs_index = data_rate_or_mcs_index;
747 /* It's a data rate. */
748 ieee_802_11.has_data_rate = TRUE;
749 ieee_802_11.data_rate = data_rate_or_mcs_index;
752 if (ieee_802_11.has_frequency && !ieee_802_11.has_channel) {
753 /* Frequency, but no channel; try to calculate the channel. */
754 channel = ieee80211_mhz_to_chan(ieee_802_11.frequency);
756 ieee_802_11.has_channel = TRUE;
757 ieee_802_11.channel = channel;
759 } else if (ieee_802_11.has_channel && !ieee_802_11.has_frequency) {
761 * If it's 11 legacy DHSS, 11b, or 11g, it's 2.4 GHz,
762 * so we can calculate the frequency.
764 * If it's 11a, it's 5 GHz, so we can calculate the
767 switch (ieee_802_11.phy) {
769 case PHDR_802_11_PHY_11_DSSS:
770 case PHDR_802_11_PHY_11B:
771 case PHDR_802_11_PHY_11G:
772 frequency = ieee80211_chan_to_mhz(ieee_802_11.channel, TRUE);
775 case PHDR_802_11_PHY_11A:
776 frequency = ieee80211_chan_to_mhz(ieee_802_11.channel, FALSE);
780 /* We don't know the band. */
784 if (frequency != 0) {
785 ieee_802_11.has_frequency = TRUE;
786 ieee_802_11.frequency = frequency;
789 rec->rec_header.packet_header.pseudo_header.ieee_802_11 = ieee_802_11;
790 if (peektagged->has_fcs)
791 rec->rec_header.packet_header.pseudo_header.ieee_802_11.fcs_len = 4;
793 if (rec->rec_header.packet_header.len < 4 || rec->rec_header.packet_header.caplen < 4) {
794 *err = WTAP_ERR_BAD_FILE;
795 *err_info = g_strdup_printf("peektagged: 802.11 packet has length < 4");
798 rec->rec_header.packet_header.pseudo_header.ieee_802_11.fcs_len = 0;
799 rec->rec_header.packet_header.len -= 4;
800 rec->rec_header.packet_header.caplen -= 4;
803 rec->rec_header.packet_header.pseudo_header.ieee_802_11.decrypted = FALSE;
804 rec->rec_header.packet_header.pseudo_header.ieee_802_11.datapad = FALSE;
807 case WTAP_ENCAP_ETHERNET:
809 * The last 4 bytes appear to be 0 in the captures I've seen;
810 * are there any captures where it's an FCS?
812 if (rec->rec_header.packet_header.len < 4 || rec->rec_header.packet_header.caplen < 4) {
813 *err = WTAP_ERR_BAD_FILE;
814 *err_info = g_strdup_printf("peektagged: Ethernet packet has length < 4");
817 rec->rec_header.packet_header.pseudo_header.eth.fcs_len = 0;
818 rec->rec_header.packet_header.len -= 4;
819 rec->rec_header.packet_header.caplen -= 4;
824 /* Read the packet data. */
825 if (!wtap_read_packet_bytes(fh, buf, rec->rec_header.packet_header.caplen, err, err_info))
831 static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
836 *data_offset = file_tell(wth->fh);
838 /* Read the packet. */
839 skip_len = peektagged_read_packet(wth, wth->fh, &wth->rec,
840 wth->rec_data, err, err_info);
845 /* Skip extra junk at the end of the packet data. */
846 if (!wtap_read_bytes(wth->fh, NULL, skip_len, err, err_info))
854 peektagged_seek_read(wtap *wth, gint64 seek_off,
855 wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
857 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
860 /* Read the packet. */
861 if (peektagged_read_packet(wth, wth->random_fh, rec, buf, err, err_info) == -1) {
863 *err = WTAP_ERR_SHORT_READ;
870 * Editor modelines - http://www.wireshark.org/tools/modelines.html
875 * indent-tabs-mode: nil
878 * vi: set shiftwidth=4 tabstop=8 expandtab:
879 * :indentSize=4:tabSize=8:noTabs=true: