Bugfixes of ASTERIX I034
[metze/wireshark/wip.git] / wiretap / vwr.c
1 /* vwr.c
2  * Copyright (c) 2011 by Tom Alexander <talexander@ixiacom.com>
3  *
4  * Wiretap Library
5  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  */
10 #include "config.h"
11
12 #include <errno.h>
13 #include <string.h>
14
15 #include "wtap-int.h"
16 #include "file_wrappers.h"
17
18 #include "vwr.h"
19
20 /* platform-specific definitions for portability */
21
22 /* unsigned long long constants */
23 #   define NS_IN_US             G_GUINT64_CONSTANT(1000)        /* nanoseconds-to-microseconds */
24 #   define NS_IN_SEC            G_GUINT64_CONSTANT(1000000000)  /* nanoseconds-to-seconds */
25 #   define US_IN_SEC            G_GUINT64_CONSTANT(1000000)     /* microseconds-to-seconds */
26 #   define LL_ZERO              G_GUINT64_CONSTANT(0)           /* zero in unsigned long long */
27
28 /*
29  * Fetch a 64-bit value in "Corey-endian" form.
30  */
31 #define pcoreytohll(p)  ((guint64)*((const guint8 *)(p)+4)<<56|  \
32                          (guint64)*((const guint8 *)(p)+5)<<48|  \
33                          (guint64)*((const guint8 *)(p)+6)<<40|  \
34                          (guint64)*((const guint8 *)(p)+7)<<32|  \
35                          (guint64)*((const guint8 *)(p)+0)<<24|  \
36                          (guint64)*((const guint8 *)(p)+1)<<16|  \
37                          (guint64)*((const guint8 *)(p)+2)<<8|   \
38                          (guint64)*((const guint8 *)(p)+3)<<0)
39
40 /*
41  * Fetch a 48-bit value in "Corey-endian" form; it's stored as
42  * a 64-bit Corey-endian value, with the upper 16 bits ignored.
43  */
44 #define pcorey48tohll(p)  ((guint64)*((const guint8 *)(p)+6)<<40|  \
45                            (guint64)*((const guint8 *)(p)+7)<<32|  \
46                            (guint64)*((const guint8 *)(p)+0)<<24|  \
47                            (guint64)*((const guint8 *)(p)+1)<<16|  \
48                            (guint64)*((const guint8 *)(p)+2)<<8|   \
49                            (guint64)*((const guint8 *)(p)+3)<<0)
50
51 /* .vwr log file defines */
52 #define B_SIZE      32768                           /* max var len message = 32 kB */
53 #define VT_FRAME    0                               /* varlen msg is a frame */
54 #define VT_CPMSG    1                               /* varlen msg is a CP<->PP msg */
55 #define VT_UNKNOWN -1                               /* varlen msg is unknown */
56 #define MAX_TRACKED_CLIENTS 1024                    /* track 1024 clients */
57 #define MAX_TRACKED_FLOWS   65536                   /* and 64K flows */
58
59 /*
60  * The file consists of a sequence of records.
61  * A record begins with a 16-byte header, the first 8 bytes of which
62  * begin with a byte containing a command plus transmit-receive flags.
63  *
64  * Following that are two big-endian 32-bit quantities; for some records
65  * one or the other of them is the length of the rest of the record.
66  * Other records contain only the header.
67  */
68 #define VW_RECORD_HEADER_LENGTH 16
69
70 /* Command byte values */
71 #define COMMAND_RX   0x21
72 #define COMMAND_TX   0x31
73 #define COMMAND_RFN  0x30
74 #define COMMAND_RF   0x38
75 #define COMMAND_RFRX 0x39
76
77 /*
78  * The data in packet records begins with a sequence of metadata headers.
79  *
80  * For packet records from FPGA versions < 48:
81  *
82  *    The first header is the IxVeriWave common header, and that's
83  *    followed either by a WLAN metadata header or an Ethernet
84  *    metadata header.  The port type field indicates whether it's
85  *    a WLAN packet or an Ethernet packet.  Following that may, for
86  *    WLAN, be 1 octet of information from the FPGA and 16 bytes of
87  *    data including the PLCP header.  After that comes the WLAN or
88  *    Ethernet frame, beginning with the MAC header.
89  *
90  * For packet records from FPGA versions >= 48:
91  *
92  *    The first header contains only a 1-octet port type value, which
93  *    has a packet type value in the upper 4 bits and zero in the lower
94  *    4 bits.  NOTE: this is indistinguishable from an old FPGA header
95  *    if the packet type value is 0.
96  *
97  *    If the packet type value isn't 3, the port type value is followed
98  *    by a 1-octet FPGA version number, which is followed by a timestamp
99  *    header.
100  *
101  *    If the packet type value is 3 or 4, the next item is an RF metadata
102  *    header.  For type 3, that immediately follows the port number octet,
103  *    otherwise it immediately follows the timestamp header.
104  *
105  *    If the packet type isn't 3, the next item is a WLAN metadata header,
106  *    in a format different from the WLAN metadata header for FPGA versions
107  *    < 48.  That is followed by a PLCP header, which is followed by a
108  *    header giving additional layer 2 through 4 metadata.
109  *
110  * Following those headers is the WLAN or Ethernet frame, beginning with
111  * the MAC header.
112  */
113
114 /*
115  * IxVeriWave common header:
116  *
117  * 1 octet - port type
118  * 1 octet - FPGA version, or 0
119  * 2 octets - length of the common header
120  * 2 octets - MSDU length
121  * 4 octets - flow ID
122  * 2 octets - VC ID
123  * 2 octets - flow sequence number
124  * 4 octets - latency or 0
125  * 4 octets - lower 32 bits of signature time stamp
126  * 8 octets - start time
127  * 8 octets - end time
128  * 4 octets - delta(?) time
129  */
130
131 /* Size of the IxVeriWave common header */
132 #define STATS_COMMON_FIELDS_LEN (1+1+2+2+4+2+2+4+4+8+8+4)
133
134 /* Port type */
135 #define WLAN_PORT               0
136 #define ETHERNET_PORT           1
137
138 /* For VeriWave WLAN and Ethernet metadata headers vw_flags field */
139 #define VW_FLAGS_TXF        0x01                /* frame was transmitted */
140 #define VW_FLAGS_FCSERR     0x02                /* FCS error detected */
141
142 /*
143  * VeriWave WLAN metadata header:
144  *
145  * 2 octets - header length
146  * 2 octets - rflags
147  * 2 octets - channel flags
148  * 2 octets - PHY rate
149  * 1 octet - PLCP type
150  * 1 octet - MCS index
151  * 1 octet - number of spatial streams
152  * 1 octet - RSSI
153  * 1 octet - antenna b signal power, or 100 if missing
154  * 1 octet - antenna c signal power, or 100 if missing
155  * 1 octet - antenna d signal power, or 100 if missing
156  * 1 octet - padding
157  * 2 octets - VeriWave flags
158  * 2 octets - HT len
159  * 2 octets - info
160  * 2 octets - errors
161  */
162
163 /* Size of the VeriWave WLAN metadata header */
164 #define EXT_WLAN_FIELDS_LEN (2+2+2+2+1+1+1+1+1+1+1+1+2+2+2+4)
165
166 /* Flags, for rflags field */
167 #define FLAGS_SHORTPRE      0x0002              /* sent/received with short preamble */
168 #define FLAGS_WEP           0x0004              /* sent/received with WEP encryption */
169 #define FLAGS_CHAN_HT       0x0040              /* In HT mode */
170 #define FLAGS_CHAN_VHT      0x0080              /* VHT Mode */
171 #define FLAGS_CHAN_SHORTGI  0x0100              /* Short guard interval */
172 #define FLAGS_CHAN_40MHZ    0x0200              /* 40 Mhz channel bandwidth */
173 #define FLAGS_CHAN_80MHZ    0x0400              /* 80 Mhz channel bandwidth */
174 #define FLAGS_CHAN_160MHZ   0x0800              /* 160 Mhz channel bandwidth */
175
176 /* Channel flags, for channel flags field */
177 #define CHAN_CCK            0x0020              /* CCK channel */
178 #define CHAN_OFDM           0x0040              /* OFDM channel */
179
180 /* For VeriWave WLAN metadata header vw_flags field */
181 #define VW_FLAGS_RETRERR    0x04                /* excess retry error detected */
182 #define VW_FLAGS_DCRERR     0x10                /* decrypt error detected (WLAN) */
183 #define VW_FLAGS_ENCMSK     0x60                /* encryption type mask */
184                                                 /* 0 = none, 1 = WEP, 2 = TKIP, 3 = CCKM */
185 #define VW_FLAGS_IS_WEP     0x20                /* WEP */
186 #define VW_FLAGS_IS_TKIP    0x40                /* TKIP */
187 #define VW_FLAGS_IS_CCMP    0x60                /* CCMP */
188
189 /*
190  * VeriWave Ethernet metadata header:
191  *
192  * 2 octets - header length
193  * 2 octets - VeriWave flags
194  * 2 octets - info
195  * 4 octets - errors
196  * 4 octets - layer 4 ID
197  * 4 octets - pad
198  *
199  * Ethernet frame follows, beginning with the MAC header
200  */
201
202 /* Size of the VeriWave Ethernet metadata header */
203 #define EXT_ETHERNET_FIELDS_LEN (2+2+2+4+4+4)
204
205 /*
206  * OCTO timestamp header.
207  *
208  * 4 octets - latency or 0
209  * 4 octets - lower 32 bits of signature time stamp
210  * 8 octets - start time
211  * 8 octets - end time
212  * 4 octets - delta(?) time
213  */
214
215 /* Size of Timestamp header */
216 #define OCTO_TIMESTAMP_FIELDS_LEN   (4+4+8+8+4+4)
217
218 /*
219  * OCTO layer 1-4 header:
220  *
221  * 2 octets - header length
222  * 1 octet - l1p_1
223  * 1 octet - number of spatial streams
224  * 2 octets - PHY rate
225  * 1 octet - l1p_2
226  * 1 octet - RSSI
227  * 1 octet - antenna b signal power, or 100 if missing
228  * 1 octet - antenna c signal power, or 100 if missing
229  * 1 octet - antenna d signal power, or 100 if missing
230  * 1 octet - signal bandwidth mask
231  * 1 octet - antenna port energy detect and VU_MASK
232  * 1 octet - L1InfoC or 0
233  * 2 octets - MSDU length
234  * 16 octets - PLCP?
235  * 4 octets - BM, BV, CV, BSSID and ClientID
236  * 2 octets - FV, QT, HT, L4V, TID and WLAN type
237  * 1 octets - flow sequence number
238  * 3 octets - flow ID
239  * 2 octets - layer 4 ID
240  * 4 octets - payload decode
241  * 3 octets - info
242  * 4 octets - errors
243  */
244
245 /* Size of Layer-1, PLCP, and Layer-2/4 header incase of OCTO version FPGA */
246 #define OCTO_LAYER1TO4_LEN          (2+14+16+23)
247
248 /*
249  * OCTO modified RF layer:
250  *
251  * 1 octet - RF ID
252  * 3 octets - unused (zero)
253  * 8 octets - noise for 4 ports
254  * 8 octets - signal/noise ration for 4 ports
255  * 8 octets - PFE for 4 ports
256  * 8 octets - EVM SIG data for 4 ports
257  * 8 octets - EVM SIG pilot for 4 ports
258  * 8 octets - EVM Data data for 4 ports
259  * 8 octets - EVM Data pilot for 4 ports
260  * 8 octets - EVM worst symbol for 4 ports
261  * 8 octets - CONTEXT_P for 4 ports
262  *
263  * Not supplied:
264  * 24 octets of additional data
265  */
266
267 /* Size of RF header, if all fields were supplied */
268 #define OCTO_RF_MOD_ACTUAL_LEN      100             /* */
269
270 /* Size of RF header with the fields we do supply */
271 #define OCTO_MODIFIED_RF_LEN        76              /* 24 bytes of RF are not displayed*/
272
273 /*Offset of differnt parameters of RF header for port-1*/
274 #define RF_PORT_1_NOISE_OFF         4
275 #define RF_PORT_1_SNR_OFF           6
276 #define RF_PORT_1_PFE_OFF           8
277 #define RF_PORT_1_CONTEXT_OFF       10
278 #define RF_PORT_1_EVM_SD_SIG_OFF    12
279 #define RF_PORT_1_EVM_SP_SIG_OFF    14
280 #define RF_PORT_1_EVM_SD_DATA_OFF   16
281 #define RF_PORT_1_EVM_SP_DATA_OFF   18
282 #define RF_PORT_1_DSYMBOL_IDX_OFF   22
283 #define RF_INTER_PORT_GAP_OFF       24              /*As size of RF information per port is 24 bytes*/
284 #define RF_NUMBER_OF_PORTS          4
285
286 /* FPGA-generated frame buffer STATS block offsets and definitions */
287
288 /* definitions for v2.2 frames, Ethernet format */
289 #define v22_E_STATS_LEN          44                 /* length of stats block trailer */
290 #define v22_E_VALID_OFF           0                 /* bit 6 (0x40) is flow-is-valid flag */
291 #define v22_E_MTYPE_OFF           1                 /* offset of modulation type */
292 #define v22_E_VCID_OFF            2                 /* offset of VC ID */
293 #define v22_E_FLOWSEQ_OFF         4                 /* offset of signature sequence number */
294 #define v22_E_FLOWID_OFF          5                 /* offset of flow ID */
295 #define v22_E_OCTET_OFF           8                 /* offset of octets */
296 #define v22_E_ERRORS_OFF         10                 /* offset of error vector */
297 #define v22_E_PATN_OFF           12                 /* offset of pattern match vector */
298 #define v22_E_L4ID_OFF           12
299 #define v22_E_IPLEN_OFF          14
300 #define v22_E_FRAME_TYPE_OFF     16                 /* offset of frame type, 32 bits */
301 #define v22_E_RSSI_OFF           21                 /* RSSI (NOTE: invalid for Ethernet) */
302 #define v22_E_STARTT_OFF         20                 /* offset of start time, 64 bits */
303 #define v22_E_ENDT_OFF           28                 /* offset of end time, 64 bits */
304 #define v22_E_LATVAL_OFF         36                 /* offset of latency, 32 bits */
305 #define v22_E_INFO_OFF           40                 /* NO INFO FIELD IN ETHERNET STATS! */
306 #define v22_E_DIFFERENTIATOR_OFF  0                 /* offset to determine whether */
307                                                     /* eth/802.11, 8 bits */
308 /* Media types */
309 #define v22_E_MT_10_HALF    0                       /* 10 Mb/s half-duplex */
310 #define v22_E_MT_10_FULL    1                       /* 10 Mb/s full-duplex */
311 #define v22_E_MT_100_HALF   2                       /* 100 Mb/s half-duplex */
312 #define v22_E_MT_100_FULL   3                       /* 100 Mb/s full-duplex */
313 #define v22_E_MT_1G_HALF    4                       /* 1 Gb/s half-duplex */
314 #define v22_E_MT_1G_FULL    5                       /* 1 Gb/s full-duplex */
315
316 /* Error flags */
317 #define v22_E_FCS_ERROR           0x0002            /* FCS error flag in error vector */
318 #define v22_E_CRYPTO_ERR          0x1f00            /* RX decrypt error flags (UNUSED) */
319 #define v22_E_SIG_ERR             0x0004            /* signature magic byte mismatch */
320 #define v22_E_PAYCHK_ERR          0x0008            /* payload checksum failure */
321 #define v22_E_RETRY_ERR           0x0400            /* excessive retries on TX fail (UNUSED)*/
322
323 /* Masks and defines */
324 #define v22_E_IS_RX               0x08              /* TX/RX bit in STATS block */
325 #define v22_E_MT_MASK             0x07              /* modulation type mask (UNUSED) */
326
327 #define v22_E_VCID_MASK           0x03ff            /* VC ID is only 10 bits */
328
329 #define v22_E_FLOW_VALID          0x40              /* flow-is-valid flag (else force to 0) */
330
331 #define v22_E_DIFFERENTIATOR_MASK 0x3F              /* mask to differentiate ethernet from */
332
333 /* Bits in FRAME_TYPE field */
334 #define v22_E_IS_TCP              0x00000040        /* TCP bit in FRAME_TYPE field */
335 #define v22_E_IS_UDP              0x00000010        /* UDP bit in FRAME_TYPE field */
336 #define v22_E_IS_ICMP             0x00000020        /* ICMP bit in FRAME_TYPE field */
337 #define v22_E_IS_IGMP             0x00000080        /* IGMP bit in FRAME_TYPE field */
338
339 /* Bits in MTYPE field (WLAN only) */
340 #define v22_E_IS_QOS              0x80              /* QoS bit in MTYPE field (WLAN only) */
341
342 #define v22_E_IS_VLAN             0x00200000
343
344 #define v22_E_RX_DECRYPTS   0x0007                  /* RX-frame-was-decrypted (UNUSED) */
345 #define v22_E_TX_DECRYPTS   0x0007                  /* TX-frame-was-decrypted (UNUSED) */
346
347 #define v22_E_FC_PROT_BIT   0x40                    /* Protected Frame bit in FC1 of frame */
348
349 #define v22_E_IS_ETHERNET   0x00700000              /* bits set in frame type if ethernet */
350 #define v22_E_IS_80211      0x7F000000              /* bits set in frame type if 802.11 */
351
352 /* definitions for v2.2 frames, WLAN format for VW510006 FPGA*/
353 #define v22_W_STATS_LEN          64                 /* length of stats block trailer */
354 #define v22_W_VALID_OFF           0                 /* bit 6 (0x40) is flow-is-valid flag */
355 #define v22_W_MTYPE_OFF           1                 /* offset of modulation type */
356 #define v22_W_VCID_OFF            2                 /* offset of VC ID */
357 #define v22_W_FLOWSEQ_OFF         4                 /* offset of signature sequence number */
358 #define v22_W_FLOWID_OFF          5                 /* offset of flow ID */
359 #define v22_W_OCTET_OFF           8                 /* offset of octets */
360 #define v22_W_ERRORS_OFF         10                 /* offset of error vector */
361 #define v22_W_PATN_OFF           12
362 #define v22_W_L4ID_OFF           12
363 #define v22_W_IPLEN_OFF          14
364 #define v22_W_FRAME_TYPE_OFF     16                 /* offset of frame type, 32 bits */
365 #define v22_W_RSSI_OFF           21                 /* RSSI (NOTE: RSSI must be negated!) */
366 #define v22_W_STARTT_OFF         24                 /* offset of start time, 64 bits */
367 #define v22_W_ENDT_OFF           32                 /* offset of end time, 64 bits */
368 #define v22_W_LATVAL_OFF         40                 /* offset of latency, 32 bits */
369 #define v22_W_INFO_OFF           54                 /* offset of INFO field, 16 LSBs */
370 #define v22_W_DIFFERENTIATOR_OFF 20                 /* offset to determine whether */
371                                                     /*  eth/802.11, 32 bits */
372
373 #define v22_W_PLCP_LENGTH_OFF     4                 /* LENGTH field in the plcp header */
374
375 /* Modulation types */
376 #define v22_W_MT_CCKL       0                       /* CCK modulation, long preamble */
377 #define v22_W_MT_CCKS       1                       /* CCK modulation, short preamble */
378 #define v22_W_MT_OFDM       2                       /* OFDM modulation */
379
380 /* Bits in FRAME_TYPE field */
381 #define v22_W_IS_TCP            0x00000040          /* TCP bit in FRAME_TYPE field */
382 #define v22_W_IS_UDP            0x00000010          /* UDP bit in FRAME_TYPE field */
383 #define v22_W_IS_ICMP           0x00000020          /* ICMP bit in FRAME_TYPE field */
384 #define v22_W_IS_IGMP           0x00000080          /* IGMP bit in FRAME_TYPE field */
385
386 /* Bits in MTYPE field (WLAN only) */
387 #define v22_W_IS_QOS            0x80                /* QoS */
388
389 /* Error flags */
390 #define v22_W_FCS_ERROR     0x0002                  /* FCS error flag in error vector */
391 #define v22_W_CRYPTO_ERR    0x1f00                  /* RX decrypt error flags */
392 #define v22_W_SIG_ERR       0x0004                  /* signature magic byte mismatch */
393 #define v22_W_PAYCHK_ERR    0x0008                  /* payload checksum failure */
394 #define v22_W_RETRY_ERR     0x0400                  /* excessive retries on TX failure */
395
396 /* Masks and defines */
397 #define v22_W_IS_RX         0x08                    /* TX/RX bit in STATS block */
398 #define v22_W_MT_MASK       0x07                    /* modulation type mask */
399
400 #define v22_W_VCID_MASK     0x01ff                  /* VC ID is only 9 bits */
401
402 #define v22_W_FLOW_VALID    0x40                    /* flow-is-valid flag (else force to 0) */
403
404 #define v22_W_DIFFERENTIATOR_MASK 0xf0ff            /* mask to differentiate ethernet from */
405                                                     /* 802.11 capture */
406
407 #define v22_W_RX_DECRYPTS   0x0007                  /* RX-frame-was-decrypted bits */
408 #define v22_W_TX_DECRYPTS   0x0007                  /* TX-frame-was-decrypted bits */
409
410 /* Info bits */
411 #define v22_W_WEPTYPE               0x0001          /* WEP frame */
412 #define v22_W_TKIPTYPE              0x0002          /* TKIP frame */
413 #define v22_W_CCMPTYPE              0x0004          /* CCMP frame */
414 #define v22_W_MPDU_OF_A_MPDU        0x0400          /* MPDU of A-MPDU */
415 #define v22_W_FIRST_MPDU_OF_A_MPDU  0x0800          /* first MPDU of A-MPDU */
416 #define v22_W_LAST_MPDU_OF_A_MPDU   0x1000          /* last MPDU of A-MPDU */
417 #define v22_W_MSDU_OF_A_MSDU        0x2000          /* MSDU of A-MSDU */
418 #define v22_W_FIRST_MSDU_OF_A_MSDU  0x4000          /* first MSDU of A-MSDU */
419 #define v22_W_LAST_MSDU_OF_A_MSDU   0x8000          /* last MSDU of A-MSDU */
420
421 /* All aggregation flags */
422 #define v22_W_AGGREGATE_FLAGS \
423     (v22_W_MPDU_OF_A_MPDU | \
424      v22_W_FIRST_MPDU_OF_A_MPDU | \
425      v22_W_LAST_MPDU_OF_A_MPDU | \
426      v22_W_MSDU_OF_A_MSDU | \
427      v22_W_FIRST_MSDU_OF_A_MSDU | \
428      v22_W_LAST_MSDU_OF_A_MSDU)
429
430 #define v22_W_FC_PROT_BIT   0x40                    /* Protected Frame bit in FC1 of frame */
431
432 #define v22_W_IS_ETHERNET   0x00100000              /* bits set in frame type if ethernet */
433 #define v22_W_IS_80211      0x7F000000              /* bits set in frame type if 802.11 */
434
435 /* definitions for VW510021 FPGA, WLAN format */
436 /* FORMAT:
437     16 BYTE header
438     8 bytes of stat block
439     plcp stuff (11 bytes plcp + 1 byte pad)
440     data
441     remaining 48 bytes of stat block
442 */
443 /* offsets in the stats block */
444 #define vVW510021_W_STATS_HEADER_LEN     8          /* length of stats block header at beginning of record data */
445 #define vVW510021_W_STATS_TRAILER_LEN   48          /* length of stats block trailer after the plcp portion*/
446 #define vVW510021_W_STARTT_OFF           0          /* offset of start time, 64 bits */
447 #define vVW510021_W_ENDT_OFF             8          /* offset of end time, 64 bits */
448 #define vVW510021_W_ERRORS_OFF          16          /* offset of error vector */
449 #define vVW510021_W_VALID_OFF           20          /* 2 Bytes with different validity bits */
450 #define vVW510021_W_INFO_OFF            22          /* offset of INFO field, 16 LSBs */
451 #define vVW510021_W_FRAME_TYPE_OFF      24
452 #define vVW510021_W_L4ID_OFF            28
453 #define vVW510021_W_IPLEN_OFF           30          /* offset of IP Total Length field */
454 #define vVW510021_W_FLOWSEQ_OFF         32          /* offset of signature sequence number */
455 #define vVW510021_W_FLOWID_OFF          33          /* offset of flow ID */
456 #define vVW510021_W_LATVAL_OFF          36          /* offset of delay/flowtimestamp, 32b */
457 #define vVW510021_W_DEBUG_OFF           40          /* offset of debug, 16 bits */
458 #define S2_W_FPGA_VERSION_OFF           44          /* offset of fpga version, 16 bits */
459 #define vVW510021_W_MATCH_OFF           47          /* offset of pattern match vector */
460
461 /* offsets in the header block */
462 #define vVW510021_W_HEADER_LEN          16          /* length of FRAME header */
463 #define vVW510021_W_RXTX_OFF             0          /* rxtx offset, cmd byte of header */
464 #define vVW510021_W_HEADER_VERSION_OFF   9          /* version, 2bytes */
465 #define vVW510021_MSG_LENGTH_OFF        10          /* MSG LENGTH, 2bytes */
466 #define vVW510021_W_DEVICE_TYPE_OFF      8          /* version, 2bytes */
467
468 /* offsets that occur right after the header */
469 #define vVW510021_W_AFTERHEADER_LEN      8          /* length of STATs info directly after header */
470 #define vVW510021_W_L1P_1_OFF            0          /* offset of 1st byte of layer one info */
471 #define vVW510021_W_L1P_2_OFF            1          /* offset of 2nd byte of layer one info */
472 #define vVW510021_W_MTYPE_OFF           vVW510021_W_L1P_2_OFF
473 #define vVW510021_W_PREAMBLE_OFF        vVW510021_W_L1P_1_OFF
474 #define vVW510021_W_RSSI_TXPOWER_OFF     2          /* RSSI (NOTE: RSSI must be negated!) */
475 #define vVW510021_W_MSDU_LENGTH_OFF      3          /* 7:0 of length, next byte 11:8 in top 4 bits */
476 #define vVW510021_W_BVCV_VALID_OFF       4          /* BV,CV Determine validaity of bssid and txpower */
477 #define vVW510021_W_VCID_OFF             6          /* offset of VC (client) ID */
478 #define vVW510021_W_PLCP_LENGTH_OFF     12          /* LENGTH field in the plcp header */
479
480 /* Masks and defines */
481 #define vVW510021_W_IS_BV               0x04        /* BV bit in STATS block */
482 #define vVW510021_W_IS_CV               0x02        /* BV bit in STATS block */
483 #define vVW510021_W_FLOW_VALID          0x8000      /* valid_off flow-is-valid flag (else 0) */
484 #define vVW510021_W_QOS_VALID           0x4000
485 #define vVW510021_W_HT_VALID            0x2000
486 #define vVW510021_W_L4ID_VALID          0x1000
487 #define vVW510021_W_MCS_MASK            0x3f        /* mcs index (a/b) type mask */
488 #define vVW510021_W_MOD_SCHEME_MASK     0x3f        /* modulation type mask */
489 #define vVW510021_W_PLCPC_MASK          0x03        /* PLPCP type mask */
490 #define vVW510021_W_SEL_MASK            0x80
491 #define vVW510021_W_WEP_MASK            0x0001
492 #define vVW510021_W_CBW_MASK            0xC0
493
494 #define vVW510024_W_VCID_MASK           0x03ff      /* VC ID is only 10 bits */
495
496 #define vVW510021_W_MT_SEL_LEGACY       0x00
497
498 #define vVW510021_W_IS_WEP              0x0001
499
500 /* L1p byte 1 info */
501
502 /* Common to Series II and Series III */
503
504 #define vVW510021_W_IS_LONGPREAMBLE     0x40        /* short/long preamble bit */
505 #define vVW510021_W_IS_LONGGI           0x40        /* short/long guard interval bit */
506
507 /* Series II */
508
509 /*
510  * Pre-HT - contains rate index.
511  */
512 #define vVW510021_W_S2_RATE_INDEX(l1p_1) ((l1p_1) & 0x3f) /* rate index for pre-HT */
513
514 /*
515  * HT - contains MCS index.
516  *
517  * XXX - MCS indices for HT go up to 76, which doesn't fit in 6 bits;
518  * either the mask is wrong, or the hardware can't receive packets
519  * with an MCS of 64 through 76, or the hardware can but misreports
520  * the MCS.
521  */
522 #define vVW510021_W_S2_MCS_INDEX_HT(l1p_1) ((l1p_1) & 0x3f)
523
524 /*
525  * VHT - contains MCS index and number of spatial streams.
526  * The number of spatial streams from the FPGA is zero-based, so we add
527  * 1 to it.
528  */
529 #define vVW510021_W_S2_MCS_INDEX_VHT(l1p_1) ((l1p_1) & 0x0f) /* MCS index for VHT */
530 #define vVW510021_W_S2_NSS_VHT(l1p_1)       (((l1p_1) >> 4) + 1) /* NSS */
531
532 /* Series III */
533
534 /*
535  * Pre-HT - contains rate index.
536  */
537 #define vVW510021_W_S3_RATE_INDEX(l1p_1)  ((l1p_1) & 0x3f)
538
539 /*
540  * HT - contains MCS index.
541  *
542  * XXX - MCS indices for HT go up to 76, which doesn't fit in 6 bits;
543  * either the mask is wrong, or the hardware can't receive packets
544  * with an MCS of 64 through 76, or the hardware can but misreports
545  * the MCS.
546  */
547 #define vVW510021_W_S3_MCS_INDEX_HT(l1p_1)  ((l1p_1) & 0x3f)
548
549 /*
550  * VHT - contains MCS index and number of spatial streams.
551  * The number of spatial streams from the FPGA is zero-based, so we add
552  * 1 to it.
553  */
554 #define vVW510021_W_S3_MCS_INDEX_VHT(l1p_1) ((l1p_1) & 0x0f) /* MCS index */
555 #define vVW510021_W_S3_NSS_VHT(l1p_1)       ((((l1p_1) >> 4) & 0x03) + 1) /* NSS */
556
557 /* L1p byte 2 info */
558
559 /* Common to Series II and Series III */
560 #define vVW510021_W_BANDWIDTH_VHT(l1p_2) (((l1p_2) >> 4) & 0xf)
561 /* 3 = 40 MHz, 4 = 80 MHz; what about 20 and 160 MHz? */
562
563 /* Series II */
564 #define vVW510021_W_S2_PLCP_TYPE(l1p_2) ((l1p_2) & 0x03) /* PLCP type */
565
566 /* Series III */
567 #define vVW510021_W_S3_PLCP_TYPE(l1p_2) ((l1p_2) & 0x0f) /* PLCP type */
568
569 /* PLCP types */
570 #define vVW510021_W_PLCP_LEGACY         0x00        /* pre-HT (11b/a/g) */
571 #define vVW510021_W_PLCP_MIXED          0x01        /* HT, mixed (11n) */
572 #define vVW510021_W_PLCP_GREENFIELD     0x02        /* HT, greenfield (11n) */
573 #define vVW510021_W_PLCP_VHT_MIXED      0x03        /* VHT (11ac) */
574
575 /* Bits in FRAME_TYPE field */
576 #define vVW510021_W_IS_TCP          0x01000000      /* TCP */
577 #define vVW510021_W_IS_UDP          0x00100000      /* UDP */
578 #define vVW510021_W_IS_ICMP         0x00001000      /* ICMP */
579 #define vVW510021_W_IS_IGMP         0x00010000      /* IGMP */
580
581 #define vVW510021_W_HEADER_VERSION      0x00
582 #define vVW510021_W_DEVICE_TYPE         0x15
583 #define vVW510021_W_11n_DEVICE_TYPE     0x20
584 #define S2_W_FPGA_VERSION               0x000C
585 #define vVW510021_W_11n_FPGA_VERSION    0x000D
586
587 /* Error flags */
588 #define vVW510021_W_FCS_ERROR           0x01
589
590 #define vVW510021_W_CRYPTO_ERROR        0x50000
591
592 #define vVW510021_W_WEPTYPE             0x0001      /* WEP frame */
593 #define vVW510021_W_TKIPTYPE            0x0002      /* TKIP frame */
594 #define vVW510021_W_CCMPTYPE            0x0004      /* CCMP frame */
595
596 /* definitions for VW510024 FPGA, wired ethernet format */
597 /* FORMAT:
598     16 BYTE header
599     52 bytes of stats block trailer
600 */
601 /* offsets in the stats block */
602 #define vVW510024_E_STATS_LEN           48          /* length of stats block trailer */
603 #define vVW510024_E_MSDU_LENGTH_OFF      0          /* MSDU 16 BITS */
604 #define vVW510024_E_BMCV_VALID_OFF       2          /* BM,CV Determine validITY */
605 #define vVW510024_E_VCID_OFF             2          /* offset of VC (client) ID 13:8, */
606                                                     /*  7:0 IN offset 7*/
607 #define vVW510024_E_STARTT_OFF           4          /* offset of start time, 64 bits */
608 #define vVW510024_E_ENDT_OFF            12          /* offset of end time, 64 bits */
609 #define vVW510024_E_ERRORS_OFF          22          /* offset of error vector */
610 #define vVW510024_E_VALID_OFF           24          /* 2 Bytes with different validity bits */
611 #define vVW510024_E_INFO_OFF            26          /* offset of INFO field, 16 LSBs */
612 #define vVW510024_E_FRAME_TYPE_OFF      28
613 #define vVW510024_E_L4ID_OFF            32
614 #define vVW510024_E_IPLEN_OFF           34
615 #define vVW510024_E_FLOWSEQ_OFF         36          /* offset of signature sequence number */
616 #define vVW510024_E_FLOWID_OFF          37          /* offset of flow ID */
617 #define vVW510024_E_LATVAL_OFF          40          /* offset of delay/flowtimestamp, 32 bits */
618 #define vVW510024_E_FPGA_VERSION_OFF    20          /* offset of fpga version, 16 bits */
619 #define vVW510024_E_MATCH_OFF           51          /* offset of pattern match vector */
620
621 /* offsets in the header block */
622 #define vVW510024_E_HEADER_LEN          vVW510021_W_HEADER_LEN      /* length of FRAME header */
623 #define vVW510024_E_RXTX_OFF            vVW510021_W_RXTX_OFF        /* rxtx offset, cmd byte */
624 #define vVW510024_E_HEADER_VERSION_OFF  16                          /* version, 2bytes */
625 #define vVW510024_E_MSG_LENGTH_OFF      vVW510021_MSG_LENGTH_OFF    /* MSG LENGTH, 2bytes */
626 #define vVW510024_E_DEVICE_TYPE_OFF     vVW510021_W_DEVICE_TYPE_OFF /* Device Type, 2bytes */
627
628 /* Masks and defines */
629 #define vVW510024_E_IS_BV               0x80                    /* Bm bit in STATS block */
630 #define vVW510024_E_IS_CV               0x40                    /* cV bit in STATS block */
631 #define vVW510024_E_FLOW_VALID          0x8000                  /* valid_off flow-is-valid flag (else force to 0) */
632 #define vVW510024_E_QOS_VALID           0x0000                  /** not valid for ethernet **/
633 #define vVW510024_E_L4ID_VALID          0x1000
634 #define vVW510024_E_CBW_MASK            0xC0
635 #define vVW510024_E_VCID_MASK           0x3FFF                  /* VCID is only 14 bits */
636
637 #define vVW510024_E_IS_TCP          0x01000000                  /* TCP bit in FRAME_TYPE field */
638 #define vVW510024_E_IS_UDP          0x00100000                  /* UDP bit in FRAME_TYPE field */
639 #define vVW510024_E_IS_ICMP         0x00001000                  /* ICMP bit in FRAME_TYPE field */
640 #define vVW510024_E_IS_IGMP         0x00010000
641 #define vVW510024_E_IS_VLAN         0x00004000
642
643 #define vVW510024_E_HEADER_VERSION      0x00
644 #define vVW510024_E_DEVICE_TYPE         0x18
645 #define vVW510024_E_FPGA_VERSION        0x0001
646
647 #define FPGA_VER_NOT_APPLICABLE         0
648
649 #define UNKNOWN_FPGA                    0
650 #define S2_W_FPGA                       1
651 #define S1_W_FPGA                       2
652 #define vVW510012_E_FPGA                3
653 #define vVW510024_E_FPGA                4
654 #define S3_W_FPGA                       5
655
656     /* the flow signature is:
657     Byte Description
658 0   Magic Number (0xDD)
659 1   Chassis Number[7:0]
660 2   Slot Number[7:0]
661 3   Port Number[7:0]
662 4   Flow ID[7:0]
663 5   Flow ID[15:8]
664 6   Flow ID[23:16]
665 7   Flow Sequence Number[7:0]
666 8   Timestamp[7:0]
667 9   Timestamp[15:8]
668 10  Timestamp[23:16]
669 11  Timestamp[31:24]
670 12  Timestamp[39:32]
671 13  Timestamp[47:40]
672 14  CRC16
673 15  CRC16
674
675 */
676 #define SIG_SIZE        16                           /* size of signature field, bytes     */
677 #define SIG_FID_OFF      4                           /* offset of flow ID in signature     */
678 #define SIG_FSQ_OFF      7                           /* offset of flow seqnum in signature */
679 #define SIG_TS_OFF       8                           /* offset of flow seqnum in signature */
680
681
682
683 /*--------------------------------------------------------------------------------------*/
684 /* Per-capture file private data structure */
685
686 typedef struct {
687     /* offsets in stats block; these are dependent on the frame type (Ethernet/WLAN) and */
688     /* version number of .vwr file, and are set up by setup_defaults() */
689     guint32      STATS_LEN;                      /* length of stats block trailer */
690     guint32      STATS_START_OFF;                /* STATS OFF AFTER HEADER */
691     guint32      VALID_OFF;                      /* bit 6 (0x40) is flow-is-valid flag */
692     guint32      MTYPE_OFF;                      /* offset of modulation type */
693     guint32      VCID_OFF;                       /* offset of VC ID */
694     guint32      FLOWSEQ_OFF;                    /* offset of signature sequence number */
695     guint32      FLOWID_OFF;                     /* offset of flow ID */
696     guint32      OCTET_OFF;                      /* offset of octets */
697     guint32      ERRORS_OFF;                     /* offset of error vector */
698     guint32      PATN_OFF;                       /* offset of pattern match vector */
699     guint32      RSSI_OFF;                       /* RSSI (NOTE: RSSI must be negated!) */
700     guint32      STARTT_OFF;                     /* offset of start time, 64 bits */
701     guint32      ENDT_OFF;                       /* offset of end time, 64 bits */
702     guint32      LATVAL_OFF;                     /* offset of latency, 32 bits */
703     guint32      INFO_OFF;                       /* offset of INFO field, 16 bits */
704     guint32      L1P_1_OFF;                      /* offset 1ST Byte of l1params */
705     guint32      L1P_2_OFF;                      /* offset 2nd Byte of l1params */
706     guint32      L4ID_OFF;                       /* LAYER 4 id offset*/
707     guint32      IPLEN_OFF;                      /* */
708     guint32      PLCP_LENGTH_OFF;                /* offset of length field in the PLCP header */
709     guint32      FPGA_VERSION_OFF;               /* offset of fpga version field, 16 bits */
710     guint32      HEADER_VERSION_OFF;             /* offset of header version, 16 bits */
711     guint32      RXTX_OFF;                       /* offset of CMD bit, rx or tx */
712     guint32      FRAME_TYPE_OFF;
713
714     /* other information about the file in question */
715     guint32      MT_10_HALF;                     /* 10 Mb/s half-duplex */
716     guint32      MT_10_FULL;                     /* 10 Mb/s full-duplex */
717     guint32      MT_100_HALF;                    /* 100 Mb/s half-duplex */
718     guint32      MT_100_FULL;                    /* 100 Mb/s full-duplex */
719     guint32      MT_1G_HALF;                     /* 1 Gb/s half-duplex */
720     guint32      MT_1G_FULL;                     /* 1 Gb/s full-duplex */
721     guint32      FCS_ERROR;                      /* FCS error in frame */
722     guint32      CRYPTO_ERR;                     /* RX decrypt error flags */
723     guint32      PAYCHK_ERR;                     /* payload checksum failure */
724     guint32      RETRY_ERR;                      /* excessive retries on TX failure */
725     guint8       IS_RX;                          /* TX/RX bit in STATS block */
726     guint8       MT_MASK;                        /* modulation type mask */
727     guint16      VCID_MASK;                      /* VC ID might not be a full 16 bits */
728     guint32      FLOW_VALID;                     /* flow-is-valid flag (else force to 0) */
729     guint16      QOS_VALID;
730     guint32      RX_DECRYPTS;                    /* RX-frame-was-decrypted bits */
731     guint32      TX_DECRYPTS;                    /* TX-frame-was-decrypted bits */
732     guint32      FC_PROT_BIT;                    /* Protected Frame bit in FC1 of frame */
733     guint32      MT_CCKL;                        /* CCK modulation, long preamble */
734     guint32      MT_CCKS;                        /* CCK modulation, short preamble */
735     guint32      MT_OFDM;                        /* OFDM modulation */
736     guint32      MCS_INDEX_MASK;                 /* mcs index type mask */
737     guint32      FPGA_VERSION;
738     guint32      WEPTYPE;                        /* frame is WEP */
739     guint32      TKIPTYPE;                       /* frame is TKIP */
740     guint32      CCMPTYPE;                       /* frame is CCMP */
741     guint32      IS_TCP;
742     guint32      IS_UDP;
743     guint32      IS_ICMP;
744     guint32      IS_IGMP;
745     guint16      IS_QOS;
746     guint32      IS_VLAN;
747     guint32      MPDU_OFF;
748     guint32      OCTO_VERSION;
749 } vwr_t;
750
751 /*
752  * NSS for various MCS values.
753  */
754 #define MAX_HT_MCS 76
755 static guint nss_for_mcs[MAX_HT_MCS+1] = {
756         1, 1, 1, 1, 1, 1, 1, 1,                               /* 0-7 */
757         2, 2, 2, 2, 2, 2, 2, 2,                               /* 8-15 */
758         3, 3, 3, 3, 3, 3, 3, 3,                               /* 16-23 */
759         4, 4, 4, 4, 4, 4, 4, 4,                               /* 24-31 */
760         1,                                                    /* 32 */
761         2, 2, 2, 2, 2, 2,                                     /* 33-38 */
762         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,             /* 39-52 */
763         4, 4, 4, 4, 4, 4,                                     /* 53-58 */
764         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4  /* 59-76 */
765 };
766
767 /* internal utility functions */
768 static int          decode_msg(vwr_t *vwr, register guint8 *, int *, int *, int *);
769 static guint8       get_ofdm_rate(const guint8 *);
770 static guint8       get_cck_rate(const guint8 *plcp);
771 static void         setup_defaults(vwr_t *, guint16);
772
773 static gboolean     vwr_read(wtap *, int *, gchar **, gint64 *);
774 static gboolean     vwr_seek_read(wtap *, gint64, wtap_rec *record,
775                                   Buffer *, int *, gchar **);
776
777 static gboolean     vwr_read_rec_header(vwr_t *, FILE_T, int *, int *, int *, int *, gchar **);
778 static gboolean     vwr_process_rec_data(FILE_T fh, int rec_size,
779                                          wtap_rec *record, Buffer *buf,
780                                          vwr_t *vwr, int IS_TX, int log_mode, int *err,
781                                          gchar **err_info);
782
783 static int          vwr_get_fpga_version(wtap *, int *, gchar **);
784
785 static gboolean     vwr_read_s1_W_rec(vwr_t *, wtap_rec *, Buffer *,
786                                       const guint8 *, int, int *, gchar **);
787 static gboolean     vwr_read_s2_W_rec(vwr_t *, wtap_rec *, Buffer *,
788                                       const guint8 *, int, int, int *,
789                                       gchar **);
790 /* For FPGA version >= 48 (OCTO Platform), following function will be used */
791 static gboolean     vwr_read_s3_W_rec(vwr_t *, wtap_rec *, Buffer *,
792                                       const guint8 *, int, int, int, int *,
793                                       gchar **);
794 static gboolean     vwr_read_rec_data_ethernet(vwr_t *, wtap_rec *,
795                                                Buffer *, const guint8 *, int,
796                                                int, int *, gchar **);
797
798 static int          find_signature(const guint8 *, int, int, register guint32, register guint8);
799 static guint64      get_signature_ts(const guint8 *, int, int);
800 static float        get_legacy_rate(guint8);
801 static float        get_ht_rate(guint8, guint16);
802 static float        get_vht_rate(guint8, guint16, guint8);
803
804 /* Open a .vwr file for reading */
805 /* This does very little, except setting the wiretap header for a VWR file type */
806 /*  and setting the timestamp precision to microseconds.                        */
807
808 wtap_open_return_val vwr_open(wtap *wth, int *err, gchar **err_info)
809 {
810     int    fpgaVer;
811     vwr_t *vwr;
812
813     *err = 0;
814
815     fpgaVer = vwr_get_fpga_version(wth, err, err_info);
816     if (fpgaVer == -1) {
817         return WTAP_OPEN_ERROR; /* I/O error */
818     }
819     if (fpgaVer == UNKNOWN_FPGA) {
820         return WTAP_OPEN_NOT_MINE; /* not a VWR file */
821     }
822
823     /* This is a vwr file */
824     vwr = (vwr_t *)g_malloc0(sizeof(vwr_t));
825     wth->priv = (void *)vwr;
826
827     vwr->FPGA_VERSION = fpgaVer;
828     /* set the local module options first */
829     setup_defaults(vwr, fpgaVer);
830
831     wth->snapshot_length = 0;
832     wth->subtype_read = vwr_read;
833     wth->subtype_seek_read = vwr_seek_read;
834     wth->file_tsprec = WTAP_TSPREC_USEC;
835     wth->file_encap = WTAP_ENCAP_IXVERIWAVE;
836
837     if (fpgaVer == S2_W_FPGA || fpgaVer == S1_W_FPGA || fpgaVer == S3_W_FPGA)
838         wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_VWR_80211;
839     else if (fpgaVer == vVW510012_E_FPGA || fpgaVer == vVW510024_E_FPGA)
840         wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_VWR_ETH;
841
842     return WTAP_OPEN_MINE;
843 }
844
845
846 /* Read the next packet */
847 /* Note that the VWR file format consists of a sequence of fixed 16-byte record headers of */
848 /*  different types; some types, including frame record headers, are followed by           */
849 /*  variable-length data.                                                                  */
850 /* A frame record consists of: the above 16-byte record header, a 1-16384 byte raw PLCP    */
851 /*  frame, and a 64-byte statistics block trailer.                                         */
852 /* The PLCP frame consists of a 4-byte or 6-byte PLCP header, followed by the MAC frame    */
853
854 static gboolean vwr_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
855 {
856     vwr_t *vwr      = (vwr_t *)wth->priv;
857     int    rec_size = 0, IS_TX, log_mode;
858
859     /* read the next frame record header in the capture file; if no more frames, return */
860     if (!vwr_read_rec_header(vwr, wth->fh, &rec_size, &IS_TX, &log_mode, err, err_info))
861         return FALSE;                                   /* Read error or EOF */
862
863     /*
864      * We're past the header; return the offset of the header, not of
865      * the data past the header.
866      */
867     *data_offset = (file_tell(wth->fh) - VW_RECORD_HEADER_LENGTH);
868
869     /* got a frame record; read and process it */
870     if (!vwr_process_rec_data(wth->fh, rec_size, &wth->rec,
871                               wth->rec_data, vwr, IS_TX, log_mode, err, err_info))
872        return FALSE;
873
874     return TRUE;
875 }
876
877 /* read a random record in the middle of a file; the start of the record is @ seek_off */
878
879 static gboolean vwr_seek_read(wtap *wth, gint64 seek_off,
880     wtap_rec *record, Buffer *buf, int *err, gchar **err_info)
881 {
882     vwr_t *vwr = (vwr_t *)wth->priv;
883     int    rec_size, IS_TX, log_mode;
884
885     /* first seek to the indicated record header */
886     if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
887         return FALSE;
888
889     /* read in the record header */
890     if (!vwr_read_rec_header(vwr, wth->random_fh, &rec_size, &IS_TX, &log_mode, err, err_info))
891         return FALSE;                                  /* Read error or EOF */
892
893     return vwr_process_rec_data(wth->random_fh, rec_size, record, buf,
894                                 vwr, IS_TX, log_mode, err, err_info);
895 }
896
897 /* Scan down in the input capture file to find the next frame header.       */
898 /* Decode and skip over all non-frame messages that are in the way.         */
899 /* Return TRUE on success, FALSE on EOF or error.                           */
900 /* Also return the frame size in bytes and the "is transmitted frame" flag. */
901
902 static gboolean vwr_read_rec_header(vwr_t *vwr, FILE_T fh, int *rec_size, int *IS_TX, int *log_mode, int *err, gchar **err_info)
903 {
904     int     f_len, v_type;
905     guint8  header[VW_RECORD_HEADER_LENGTH];
906
907     *rec_size = 0;
908
909     /* Read out the file data in 16-byte messages, stopping either after we find a frame,  */
910     /*  or if we run out of data.                                                          */
911     /* Each 16-byte message is decoded; if we run across a non-frame message followed by a */
912     /*  variable-length item, we read the variable length item out and discard it.         */
913     /* If we find a frame, we return (with the header in the passed buffer).               */
914     while (1) {
915         if (!wtap_read_bytes_or_eof(fh, header, VW_RECORD_HEADER_LENGTH, err, err_info))
916             return FALSE;
917
918         /* Got a header; invoke decode-message function to parse and process it.     */
919         /* If the function returns a length, then a frame or variable-length message */
920         /*  follows the 16-byte message.                                             */
921         /* If the variable length message is not a frame, simply skip over it.       */
922         if ((f_len = decode_msg(vwr, header, &v_type, IS_TX, log_mode)) != 0) {
923             if (f_len > B_SIZE) {
924                 *err = WTAP_ERR_BAD_FILE;
925                 *err_info = g_strdup_printf("vwr: Invalid message record length %d", f_len);
926                 return FALSE;
927             }
928             else if (v_type != VT_FRAME) {
929                 if (!wtap_read_bytes(fh, NULL, f_len, err, err_info))
930                     return FALSE;
931             }
932             else {
933                 *rec_size = f_len;
934                 return TRUE;
935             }
936         }
937     }
938 }
939
940 /* Figure out the FPGA version (and also see whether this is a VWR file type. */
941 /* Return FPGA version if it's a known version, UNKNOWN_FPGA if it's not,     */
942 /*  and -1 on an I/O error.                                                   */
943
944 static int vwr_get_fpga_version(wtap *wth, int *err, gchar **err_info)
945 {
946     guint8  *rec;         /* local buffer (holds input record) */
947     guint8   header[VW_RECORD_HEADER_LENGTH];
948     int      rec_size     = 0;
949     guint8   i;
950     guint8  *s_510006_ptr = NULL;
951     guint8  *s_510024_ptr = NULL;
952     guint8  *s_510012_ptr = NULL; /* stats pointers */
953     gint64   filePos      = -1;
954     guint32  frame_type   = 0;
955     int      f_len, v_type;
956     guint16  data_length  = 0;
957     guint16  fpga_version;
958     gboolean valid_but_empty_file = FALSE;
959
960     filePos = file_tell(wth->fh);
961     if (filePos == -1) {
962         *err = file_error(wth->fh, err_info);
963         return -1;
964     }
965
966     fpga_version = 1000;
967     rec = (guint8*)g_malloc(B_SIZE);
968     /* Got a frame record; see if it is vwr  */
969     /* If we don't get it all, then declare an error, we can't process the frame.          */
970     /* Read out the file data in 16-byte messages, stopping either after we find a frame,  */
971     /*  or if we run out of data.                                                          */
972     /* Each 16-byte message is decoded; if we run across a non-frame message followed by a */
973     /*  variable-length item, we read the variable length item out and discard it.         */
974     /* If we find a frame, we return (with the header in the passed buffer).               */
975     while (wtap_read_bytes(wth->fh, header, VW_RECORD_HEADER_LENGTH, err, err_info)) {
976         /* Got a header; invoke decode-message function to parse and process it.     */
977         /* If the function returns a length, then a frame or variable-length message */
978         /*  follows the 16-byte message.                                             */
979         /* If the variable length message is not a frame, simply skip over it.       */
980         if ((f_len = decode_msg(NULL, header, &v_type, NULL, NULL)) != 0) {
981             if (f_len > B_SIZE) {
982                 g_free(rec);
983                 /* Treat this here as an indication that the file probably */
984                 /*  isn't a vwr file. */
985                 return UNKNOWN_FPGA;
986             }
987             else if (v_type != VT_FRAME) {
988                 if (!wtap_read_bytes(wth->fh, NULL, f_len, err, err_info)) {
989                     g_free(rec);
990                     if (*err == WTAP_ERR_SHORT_READ)
991                         return UNKNOWN_FPGA; /* short read - not a vwr file */
992                     return -1;
993                 }
994                 else if (v_type == VT_CPMSG)
995                     valid_but_empty_file = TRUE;
996             }
997             else {
998                 rec_size = f_len;
999                 /* Got a frame record; read over entire record (frame + trailer) into a local buffer */
1000                 /* If we don't get it all, assume this isn't a vwr file */
1001                 if (!wtap_read_bytes(wth->fh, rec, rec_size, err, err_info)) {
1002                     g_free(rec);
1003                     if (*err == WTAP_ERR_SHORT_READ)
1004                         return UNKNOWN_FPGA; /* short read - not a vwr file */
1005                     return -1;
1006                 }
1007
1008                 /*  I'll grab the bytes where the Ethernet "octets" field should be and the bytes where */
1009                 /*   the 802.11 "octets" field should be. Then if I do rec_size - octets -              */
1010                 /*   size_of_stats_block and it's 0, I can select the correct type.                     */
1011                 /*  octets + stats_len = rec_size only when octets have been incremented to nearest     */
1012                 /*   number divisible by 4.                                                             */
1013
1014                 /* First check for series I WLAN since the check is more rigorous. */
1015                 if (rec_size > v22_W_STATS_LEN) {
1016                     s_510006_ptr = &(rec[rec_size - v22_W_STATS_LEN]);      /* point to 510006 WLAN */
1017                                                                             /* stats block */
1018
1019                     data_length = pntoh16(&s_510006_ptr[v22_W_OCTET_OFF]);
1020                     i = 0;
1021                     while (((data_length + i) % 4) != 0)
1022                         i = i + 1;
1023
1024                     frame_type = pntoh32(&s_510006_ptr[v22_W_FRAME_TYPE_OFF]);
1025
1026                     if (rec_size == (data_length + v22_W_STATS_LEN + i) && (frame_type & v22_W_IS_80211) == 0x1000000) {
1027                         fpga_version = S1_W_FPGA;
1028                     }
1029                 }
1030
1031                 /* Next for the series I Ethernet */
1032                 if ((rec_size > v22_E_STATS_LEN) && (fpga_version == 1000)) {
1033                     s_510012_ptr = &(rec[rec_size - v22_E_STATS_LEN]);      /* point to 510012 enet */
1034                                                                             /* stats block */
1035                     data_length = pntoh16(&s_510012_ptr[v22_E_OCTET_OFF]);
1036                     i = 0;
1037                     while (((data_length + i) % 4) != 0)
1038                         i = i + 1;
1039
1040                     if (rec_size == (data_length + v22_E_STATS_LEN + i))
1041                         fpga_version = vVW510012_E_FPGA;
1042                 }
1043
1044
1045                 /* Next the series II WLAN */
1046                 if ((rec_size > vVW510021_W_STATS_TRAILER_LEN) && (fpga_version == 1000)) {
1047                     /* stats block */
1048
1049                     if ((header[8] == 48) || (header[8] == 61) || (header[8] == 68))
1050                         fpga_version = S3_W_FPGA;
1051                     else {
1052                         data_length = (256 * (rec[vVW510021_W_MSDU_LENGTH_OFF + 1] & 0x1f)) + rec[vVW510021_W_MSDU_LENGTH_OFF];
1053
1054                         i = 0;
1055                         while (((data_length + i) % 4) != 0)
1056                             i = i + 1;
1057
1058                         /*the 12 is from the 12 bytes of plcp header */
1059                         if (rec_size == (data_length + vVW510021_W_STATS_TRAILER_LEN +vVW510021_W_AFTERHEADER_LEN+12+i))
1060                             fpga_version = S2_W_FPGA;
1061                     }
1062                 }
1063
1064                 /* Finally the Series II Ethernet */
1065                 if ((rec_size > vVW510024_E_STATS_LEN) && (fpga_version == 1000)) {
1066                     s_510024_ptr = &(rec[rec_size - vVW510024_E_STATS_LEN]);    /* point to 510024 ENET */
1067                     data_length = pntoh16(&s_510024_ptr[vVW510024_E_MSDU_LENGTH_OFF]);
1068
1069                     i = 0;
1070                     while (((data_length + i) % 4) != 0)
1071                         i = i + 1;
1072
1073                     if (rec_size == (data_length + vVW510024_E_STATS_LEN + i))
1074                         fpga_version = vVW510024_E_FPGA;
1075                 }
1076
1077                 if (fpga_version != 1000)
1078                 {
1079                     /* reset the file position offset */
1080                     if (file_seek (wth->fh, filePos, SEEK_SET, err) == -1) {
1081                         g_free(rec);
1082                         return (-1);
1083                     }
1084
1085                     /* We found an FPGA that works */
1086                     g_free(rec);
1087                     return fpga_version;
1088                 }
1089             }
1090         }
1091     }
1092
1093     /* Is this a valid but empty file?  If so, claim it's the S3_W_FPGA FPGA. */
1094     if (valid_but_empty_file) {
1095         g_free(rec);
1096         return(S3_W_FPGA);
1097     }
1098
1099     if (*err == WTAP_ERR_SHORT_READ) {
1100         g_free(rec);
1101         return UNKNOWN_FPGA; /* short read - not a vwr file */
1102     }
1103
1104     /*
1105      * Read error.
1106      */
1107     g_free(rec);
1108     return -1;
1109 }
1110
1111 /* Copy the actual packet data from the capture file into the target data block. */
1112 /* The packet is constructed as a 38-byte VeriWave metadata header plus the raw */
1113 /*  MAC octets. */
1114
1115 static gboolean vwr_read_s1_W_rec(vwr_t *vwr, wtap_rec *record,
1116                                   Buffer *buf, const guint8 *rec, int rec_size,
1117                                   int *err, gchar **err_info)
1118 {
1119     guint8           *data_ptr;
1120     int              bytes_written = 0;                   /* bytes output to buf so far */
1121     const guint8     *s_ptr, *m_ptr;                      /* stats pointer */
1122     guint16          msdu_length, actual_octets;          /* octets in frame */
1123     guint16          plcp_hdr_len;                        /* PLCP header length */
1124     guint16          rflags;
1125     guint8           m_type;                              /* mod type (CCK-L/CCK-S/OFDM), seqnum */
1126     guint            flow_seq;
1127     guint64          s_time = LL_ZERO, e_time = LL_ZERO;  /* start/end */
1128                                                           /* times, nsec */
1129     guint32          latency;
1130     guint64          start_time, s_sec, s_usec = LL_ZERO; /* start time, sec + usec */
1131     guint64          end_time;                            /* end time */
1132     guint32          info;                                /* INFO/ERRORS fields in stats blk */
1133     gint8            rssi;                                /* RSSI, signed 8-bit number */
1134     int              f_tx;                                /* flag: if set, is a TX frame */
1135     guint8           rate_index;                          /* pre-HT only */
1136     guint16          vc_id, ht_len=0;                     /* VC ID, total ip length */
1137     guint            flow_id;                             /* flow ID */
1138     guint32          d_time, errors;                      /* packet duration & errors */
1139     int              sig_off, pay_off;                    /* MAC+SNAP header len, signature offset */
1140     guint64          sig_ts;                              /* 32 LSBs of timestamp in signature */
1141     guint16          phyRate;
1142     guint16          vw_flags;                            /* VeriWave-specific packet flags */
1143
1144     /*
1145      * The record data must be large enough to hold the statistics trailer.
1146      */
1147     if (rec_size < v22_W_STATS_LEN) {
1148         *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1149                                     rec_size, v22_W_STATS_LEN);
1150         *err = WTAP_ERR_BAD_FILE;
1151         return FALSE;
1152     }
1153
1154     /* Calculate the start of the statistics block in the buffer */
1155     /* Also get a bunch of fields from the stats block */
1156     s_ptr    = &(rec[rec_size - v22_W_STATS_LEN]); /* point to it */
1157     m_type   = s_ptr[v22_W_MTYPE_OFF] & v22_E_MT_MASK;
1158     f_tx     = !(s_ptr[v22_W_MTYPE_OFF] & v22_E_IS_RX);
1159     actual_octets   = pntoh16(&s_ptr[v22_W_OCTET_OFF]);
1160     vc_id    = pntoh16(&s_ptr[v22_W_VCID_OFF]) & v22_E_VCID_MASK;
1161     flow_seq = s_ptr[v22_W_FLOWSEQ_OFF];
1162
1163     latency = (guint32)pcorey48tohll(&s_ptr[v22_W_LATVAL_OFF]);
1164
1165     flow_id = pntoh16(&s_ptr[v22_W_FLOWID_OFF+1]);  /* only 16 LSBs kept */
1166     errors  = pntoh16(&s_ptr[v22_W_ERRORS_OFF]);
1167
1168     info = pntoh16(&s_ptr[v22_W_INFO_OFF]);
1169     rssi = (s_ptr[v22_W_RSSI_OFF] & 0x80) ? (-1 * (s_ptr[v22_W_RSSI_OFF] & 0x7f)) : s_ptr[v22_W_RSSI_OFF];
1170
1171     /*
1172      * Sanity check the octets field to determine if it's greater than
1173      * the packet data available in the record - i.e., the record size
1174      * minus the length of the statistics block.
1175      *
1176      * Report an error if it is.
1177      */
1178     if (actual_octets > rec_size - v22_W_STATS_LEN) {
1179         *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
1180                                     actual_octets);
1181         *err = WTAP_ERR_BAD_FILE;
1182         return FALSE;
1183     }
1184
1185     /* Decode OFDM or CCK PLCP header and determine rate and short preamble flag. */
1186     /* The SIGNAL byte is always the first byte of the PLCP header in the frame.  */
1187     if (m_type == vwr->MT_OFDM)
1188         rate_index = get_ofdm_rate(rec);
1189     else if ((m_type == vwr->MT_CCKL) || (m_type == vwr->MT_CCKS))
1190         rate_index = get_cck_rate(rec);
1191     else
1192         rate_index = 1;
1193     rflags  = (m_type == vwr->MT_CCKS) ? FLAGS_SHORTPRE : 0;
1194     /* Calculate the MPDU size/ptr stuff; MPDU starts at 4 or 6 depending on OFDM/CCK. */
1195     /* Note that the number of octets in the frame also varies depending on OFDM/CCK,  */
1196     /*  because the PLCP header is prepended to the actual MPDU.                       */
1197     plcp_hdr_len = (m_type == vwr->MT_OFDM) ? 4 : 6;
1198     if (actual_octets >= plcp_hdr_len)
1199        actual_octets -= plcp_hdr_len;
1200     else {
1201         *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include %u-byte PLCP header)",
1202                                     actual_octets, plcp_hdr_len);
1203         *err = WTAP_ERR_BAD_FILE;
1204         return FALSE;
1205     }
1206     m_ptr = &rec[plcp_hdr_len];
1207     msdu_length = actual_octets;
1208
1209     /*
1210      * The MSDU length includes the FCS.
1211      *
1212      * The packet data does *not* include the FCS - it's just 4 bytes
1213      * of junk - so we have to remove it.
1214      *
1215      * We'll be stripping off that junk, so make sure we have at least
1216      * 4 octets worth of packet data.
1217      *
1218      * There seems to be a special case of a length of 0.
1219      */
1220     if (actual_octets < 4) {
1221         if (actual_octets != 0) {
1222             *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include %u-byte PLCP header and 4 bytes of FCS)",
1223                                         actual_octets, plcp_hdr_len);
1224             *err = WTAP_ERR_BAD_FILE;
1225             return FALSE;
1226         }
1227     } else {
1228         actual_octets -= 4;
1229     }
1230
1231     /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
1232     /* 64-bit times are "Corey-endian" */
1233     s_time = pcoreytohll(&s_ptr[v22_W_STARTT_OFF]);
1234     e_time = pcoreytohll(&s_ptr[v22_W_ENDT_OFF]);
1235
1236     /* find the packet duration (difference between start and end times) */
1237     d_time = (guint32)((e_time - s_time) / NS_IN_US);   /* find diff, converting to usec */
1238
1239     /* also convert the packet start time to seconds and microseconds */
1240     start_time = s_time / NS_IN_US;                /* convert to microseconds first  */
1241     s_sec      = (start_time / US_IN_SEC);         /* get the number of seconds      */
1242     s_usec     = start_time - (s_sec * US_IN_SEC); /* get the number of microseconds */
1243
1244     /* also convert the packet end time to seconds and microseconds */
1245     end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
1246
1247     /* extract the 32 LSBs of the signature timestamp field from the data block*/
1248     pay_off = 42;    /* 24 (MAC) + 8 (SNAP) + IP */
1249     sig_off = find_signature(m_ptr, rec_size - 6, pay_off, flow_id, flow_seq);
1250     if (m_ptr[sig_off] == 0xdd)
1251         sig_ts = get_signature_ts(m_ptr, sig_off, rec_size - v22_W_STATS_LEN);
1252     else
1253         sig_ts = 0;
1254
1255     /*
1256      * Fill up the per-packet header.
1257      *
1258      * We include the length of the metadata headers in the packet lengths.
1259      *
1260      * The maximum value of actual_octets is 8191, which, even after
1261      * adding the lengths of the metadata headers, is less than
1262      * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
1263      */
1264     record->rec_header.packet_header.len = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1265     record->rec_header.packet_header.caplen = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1266
1267     record->ts.secs   = (time_t)s_sec;
1268     record->ts.nsecs  = (int)(s_usec * 1000);
1269     record->rec_header.packet_header.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
1270
1271     record->rec_type = REC_TYPE_PACKET;
1272     record->presence_flags = WTAP_HAS_TS;
1273
1274     ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
1275     data_ptr = ws_buffer_start_ptr(buf);
1276
1277     /*
1278      * Generate and copy out the common metadata headers,
1279      * set the port type to 0 (WLAN).
1280      *
1281      * All values are copied out in little-endian byte order.
1282      */
1283     /* 1st octet of record for port_type and command (command is 0, hence RX) */
1284     phtole8(&data_ptr[bytes_written], WLAN_PORT);
1285     bytes_written += 1;
1286     /* 2nd octet of record for fpga version (0, hence pre-OCTO) */
1287     phtole8(&data_ptr[bytes_written], 0);
1288     bytes_written += 1;
1289
1290     phtoles(&data_ptr[bytes_written], STATS_COMMON_FIELDS_LEN); /* it_len */
1291     bytes_written += 2;
1292     phtoles(&data_ptr[bytes_written], msdu_length);
1293     bytes_written += 2;
1294     phtolel(&data_ptr[bytes_written], flow_id);
1295     bytes_written += 4;
1296     phtoles(&data_ptr[bytes_written], vc_id);
1297     bytes_written += 2;
1298     phtoles(&data_ptr[bytes_written], flow_seq);
1299     bytes_written += 2;
1300     if (!f_tx && sig_ts != 0) {
1301         phtolel(&data_ptr[bytes_written], latency);
1302     } else {
1303         phtolel(&data_ptr[bytes_written], 0);
1304     }
1305     bytes_written += 4;
1306     phtolel(&data_ptr[bytes_written], sig_ts); /* 32 LSBs of signature timestamp (nsec) */
1307     bytes_written += 4;
1308     phtolell(&data_ptr[bytes_written], start_time); /* record start & end times of frame */
1309     bytes_written += 8;
1310     phtolell(&data_ptr[bytes_written], end_time);
1311     bytes_written += 8;
1312     phtolel(&data_ptr[bytes_written], d_time);
1313     bytes_written += 4;
1314
1315     /*
1316      * Generate and copy out the WLAN metadata headers.
1317      *
1318      * All values are copied out in little-endian byte order.
1319      */
1320     phtoles(&data_ptr[bytes_written], EXT_WLAN_FIELDS_LEN);
1321     bytes_written += 2;
1322     phtoles(&data_ptr[bytes_written], rflags);
1323     bytes_written += 2;
1324     if (m_type == vwr->MT_OFDM) {
1325         phtoles(&data_ptr[bytes_written], CHAN_OFDM);
1326     } else {
1327         phtoles(&data_ptr[bytes_written], CHAN_CCK);
1328     }
1329     bytes_written += 2;
1330     phyRate = (guint16)(get_legacy_rate(rate_index) * 10);
1331     phtoles(&data_ptr[bytes_written], phyRate);
1332     bytes_written += 2;
1333     data_ptr[bytes_written] = vVW510021_W_PLCP_LEGACY; /* pre-HT */
1334     bytes_written += 1;
1335     data_ptr[bytes_written] = rate_index;
1336     bytes_written += 1;
1337     data_ptr[bytes_written] = 1; /* pre-VHT, so NSS = 1 */
1338     bytes_written += 1;
1339     data_ptr[bytes_written] = rssi;
1340     bytes_written += 1;
1341     /* antennae b, c, d signal power */
1342     data_ptr[bytes_written] = 100;
1343     bytes_written += 1;
1344     data_ptr[bytes_written] = 100;
1345     bytes_written += 1;
1346     data_ptr[bytes_written] = 100;
1347     bytes_written += 1;
1348     /* padding */
1349     data_ptr[bytes_written] = 0;
1350     bytes_written += 1;
1351
1352     /* fill in the VeriWave flags field */
1353     vw_flags = 0;
1354     if (f_tx)
1355         vw_flags |= VW_FLAGS_TXF;
1356     if (errors & vwr->FCS_ERROR)
1357         vw_flags |= VW_FLAGS_FCSERR;
1358     if (!f_tx && (errors & vwr->CRYPTO_ERR))
1359         vw_flags |= VW_FLAGS_DCRERR;
1360     if (!f_tx && (errors & vwr->RETRY_ERR))
1361         vw_flags |= VW_FLAGS_RETRERR;
1362     if (info & vwr->WEPTYPE)
1363         vw_flags |= VW_FLAGS_IS_WEP;
1364     else if (info & vwr->TKIPTYPE)
1365         vw_flags |= VW_FLAGS_IS_TKIP;
1366     else if (info & vwr->CCMPTYPE)
1367         vw_flags |= VW_FLAGS_IS_CCMP;
1368     phtoles(&data_ptr[bytes_written], vw_flags);
1369     bytes_written += 2;
1370
1371     phtoles(&data_ptr[bytes_written], ht_len);
1372     bytes_written += 2;
1373     phtoles(&data_ptr[bytes_written], info);
1374     bytes_written += 2;
1375     phtolel(&data_ptr[bytes_written], errors);
1376     bytes_written += 4;
1377
1378     /*
1379      * Finally, copy the whole MAC frame to the packet buffer as-is.
1380      * This does not include the PLCP; the MPDU starts at 4 or 6
1381      * depending on OFDM/CCK.
1382      * This also does not include the last 4 bytes, as those don't
1383      * contain an FCS, they just contain junk.
1384      */
1385     memcpy(&data_ptr[bytes_written], &rec[plcp_hdr_len], actual_octets);
1386
1387     return TRUE;
1388 }
1389
1390
1391 static gboolean vwr_read_s2_W_rec(vwr_t *vwr, wtap_rec *record,
1392                                   Buffer *buf, const guint8 *rec, int rec_size,
1393                                   int IS_TX, int *err, gchar **err_info)
1394 {
1395     guint8           *data_ptr;
1396     int              bytes_written = 0;                   /* bytes output to buf so far */
1397     const guint8     *s_start_ptr,*s_trail_ptr, *plcp_ptr, *m_ptr; /* stats & MPDU ptr */
1398     guint32          msdu_length, actual_octets;          /* octets in frame */
1399     guint8           l1p_1, l1p_2, plcp_type, rate_mcs_index, nss;  /* mod (CCK-L/CCK-S/OFDM) */
1400     guint            flow_seq;
1401     guint64          s_time = LL_ZERO, e_time = LL_ZERO;  /* start/end */
1402                                                           /*  times, nsec */
1403     guint64          latency = LL_ZERO;
1404     guint64          start_time, s_sec, s_usec = LL_ZERO; /* start time, sec + usec */
1405     guint64          end_time;                            /* end time */
1406     guint16          info;                                /* INFO/ERRORS fields in stats blk */
1407     guint32          errors;
1408     gint8            rssi[] = {0,0,0,0};                  /* RSSI, signed 8-bit number */
1409     int              f_tx;                                /* flag: if set, is a TX frame */
1410     guint16          vc_id, ht_len=0;                     /* VC ID , total ip length*/
1411     guint32          flow_id, d_time;                     /* flow ID, packet duration*/
1412     int              sig_off, pay_off;                    /* MAC+SNAP header len, signature offset */
1413     guint64          sig_ts, tsid;                        /* 32 LSBs of timestamp in signature */
1414     guint16          chanflags = 0;                       /* channel flags for WLAN metadata header */
1415     guint16          radioflags = 0;                      /* flags for WLAN metadata header */
1416     guint64          delta_b;                             /* Used for calculating latency */
1417     float            rate;
1418     guint16          phyRate;
1419     guint16          vw_flags;                            /* VeriWave-specific packet flags */
1420
1421     /*
1422      * The record data must be large enough to hold the statistics header,
1423      * the PLCP, and the statistics trailer.
1424      */
1425     if ((guint)rec_size < vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN) {
1426         *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1427                                     rec_size,
1428                                     vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1429         *err = WTAP_ERR_BAD_FILE;
1430         return FALSE;
1431     }
1432
1433     /* Calculate the start of the statistics blocks in the buffer */
1434     /* Also get a bunch of fields from the stats blocks */
1435     s_start_ptr = &(rec[0]);                              /* point to stats header */
1436     s_trail_ptr = &(rec[rec_size - vVW510021_W_STATS_TRAILER_LEN]);      /* point to stats trailer */
1437
1438     l1p_1 = s_start_ptr[vVW510021_W_L1P_1_OFF];
1439     l1p_2 = s_start_ptr[vVW510021_W_L1P_2_OFF];
1440     plcp_type = vVW510021_W_S2_PLCP_TYPE(l1p_2);
1441     /* we do the range checks at the end before copying the values
1442        into the wtap header */
1443     msdu_length = ((s_start_ptr[vVW510021_W_MSDU_LENGTH_OFF+1] & 0x1f) << 8)
1444                     + s_start_ptr[vVW510021_W_MSDU_LENGTH_OFF];
1445
1446     vc_id = pntoh16(&s_start_ptr[vVW510021_W_VCID_OFF]);
1447     if (IS_TX)
1448     {
1449         rssi[0] = (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x80) ?
1450                    -1 * (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x7f) :
1451                    s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x7f;
1452     }
1453     else
1454     {
1455         rssi[0] = (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x80) ?
1456                   (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF]- 256) :
1457                   s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF];
1458     }
1459     rssi[1] = 100;
1460     rssi[2] = 100;
1461     rssi[3] = 100;
1462
1463     plcp_ptr = &(rec[8]);
1464
1465     actual_octets = msdu_length;
1466
1467     /*
1468      * Sanity check the octets field to determine if it's greater than
1469      * the packet data available in the record - i.e., the record size
1470      * minus the sum of (length of statistics header + PLCP) and
1471      * (length of statistics trailer).
1472      *
1473      * Report an error if it is.
1474      */
1475     if (actual_octets > rec_size - (vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN)) {
1476         *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
1477                                     actual_octets);
1478         *err = WTAP_ERR_BAD_FILE;
1479         return FALSE;
1480     }
1481
1482     f_tx = IS_TX;
1483     flow_seq = s_trail_ptr[vVW510021_W_FLOWSEQ_OFF];
1484
1485     latency = 0x00000000;                        /* clear latency */
1486     flow_id = pntoh24(&s_trail_ptr[vVW510021_W_FLOWID_OFF]);         /* all 24 bits valid */
1487     /* For tx latency is duration, for rx latency is timestamp */
1488     /* Get 48-bit latency value */
1489     tsid = pcorey48tohll(&s_trail_ptr[vVW510021_W_LATVAL_OFF]);
1490
1491     errors = pntoh32(&s_trail_ptr[vVW510021_W_ERRORS_OFF]);
1492     info = pntoh16(&s_trail_ptr[vVW510021_W_INFO_OFF]);
1493     if ((info & v22_W_AGGREGATE_FLAGS) != 0)
1494     /* this length includes the Start_Spacing + Delimiter + MPDU + Padding for each piece of the aggregate*/
1495         ht_len = pletoh16(&s_start_ptr[vwr->PLCP_LENGTH_OFF]);
1496
1497
1498     /* decode OFDM or CCK PLCP header and determine rate and short preamble flag */
1499     /* the SIGNAL byte is always the first byte of the PLCP header in the frame */
1500     switch (plcp_type)
1501     {
1502     case vVW510021_W_PLCP_LEGACY:
1503         /*
1504          * From IEEE Std 802.11-2012:
1505          *
1506          * According to section 17.2.2 "PPDU format", the PLCP header
1507          * for the High Rate DSSS PHY (11b) has a SIGNAL field that's
1508          * 8 bits, followed by a SERVICE field that's 8 bits, followed
1509          * by a LENGTH field that's 16 bits, followed by a CRC field
1510          * that's 16 bits.  The PSDU follows it.  Section 17.2.3 "PPDU
1511          * field definitions" describes those fields.
1512          *
1513          * According to sections 18.3.2 "PLCP frame format" and 18.3.4
1514          * "SIGNAL field", the PLCP for the OFDM PHY (11a) has a SIGNAL
1515          * field that's 24 bits, followed by a service field that's
1516          * 16 bits, followed by the PSDU.  Section 18.3.5.2 "SERVICE
1517          * field" describes the SERVICE field.
1518          *
1519          * According to section 19.3.2 "PPDU format", the frames for the
1520          * Extended Rate PHY (11g) either extend the 11b format, using
1521          * additional bits in the SERVICE field, or extend the 11a
1522          * format.
1523          */
1524         rate_mcs_index = vVW510021_W_S2_RATE_INDEX(l1p_1);
1525         if (rate_mcs_index < 4) {
1526             chanflags |= CHAN_CCK;
1527         }
1528         else {
1529             chanflags |= CHAN_OFDM;
1530         }
1531         rate = get_legacy_rate(rate_mcs_index);
1532         nss = 0;
1533         break;
1534
1535     case vVW510021_W_PLCP_MIXED:
1536         /*
1537          * According to section 20.3.2 "PPDU format", the HT-mixed
1538          * PLCP header has a "Non-HT SIGNAL field" (L-SIG), which
1539          * looks like an 11a SIGNAL field, followed by an HT SIGNAL
1540          * field (HT-SIG) described in section 20.3.9.4.3 "HT-SIG
1541          * definition".
1542          *
1543          * This means that the first octet of HT-SIG is at
1544          * plcp_ptr[3], skipping the 3 octets of the L-SIG field.
1545          *
1546          * 0x80 is the CBW 20/40 bit of HT-SIG.
1547          */
1548         /* set the appropriate flags to indicate HT mode and CB */
1549         rate_mcs_index = vVW510021_W_S2_MCS_INDEX_HT(l1p_1);
1550         radioflags |= FLAGS_CHAN_HT | ((plcp_ptr[3] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
1551                       ((l1p_1 & vVW510021_W_IS_LONGGI) ? 0 : FLAGS_CHAN_SHORTGI);
1552         chanflags  |= CHAN_OFDM;
1553         nss = (rate_mcs_index < MAX_HT_MCS) ? nss_for_mcs[rate_mcs_index] : 0;
1554         rate = get_ht_rate(rate_mcs_index, radioflags);
1555         break;
1556
1557     case vVW510021_W_PLCP_GREENFIELD:
1558         /*
1559          * According to section 20.3.2 "PPDU format", the HT-greenfield
1560          * PLCP header just has the HT SIGNAL field (HT-SIG) above, with
1561          * no L-SIG field.
1562          *
1563          * This means that the first octet of HT-SIG is at
1564          * plcp_ptr[0], as there's no L-SIG field to skip.
1565          *
1566          * 0x80 is the CBW 20/40 bit of HT-SIG.
1567          */
1568         /* set the appropriate flags to indicate HT mode and CB */
1569         rate_mcs_index = vVW510021_W_S2_MCS_INDEX_HT(l1p_1);
1570         radioflags |= FLAGS_CHAN_HT | ((plcp_ptr[0] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
1571                       ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
1572         chanflags  |= CHAN_OFDM;
1573         nss = (rate_mcs_index < MAX_HT_MCS) ? nss_for_mcs[rate_mcs_index] : 0;
1574         rate = get_ht_rate(rate_mcs_index, radioflags);
1575         break;
1576
1577     case vVW510021_W_PLCP_VHT_MIXED:
1578         /*
1579          * According to section 22.3.2 "VHT PPDU format" of IEEE Std
1580          * 802.11ac-2013, the VHT PLCP header has a "non-HT SIGNAL field"
1581          * (L-SIG), which looks like an 11a SIGNAL field, followed by
1582          * a VHT Signal A field (VHT-SIG-A) described in section
1583          * 22.3.8.3.3 "VHT-SIG-A definition", with training fields
1584          * between it and a VHT Signal B field (VHT-SIG-B) described
1585          * in section 22.3.8.3.6 "VHT-SIG-B definition", followed by
1586          * the PSDU.
1587          */
1588         {
1589             guint8 SBW = vVW510021_W_BANDWIDTH_VHT(l1p_2);
1590             rate_mcs_index = vVW510021_W_S2_MCS_INDEX_VHT(l1p_1);
1591             radioflags |= FLAGS_CHAN_VHT | ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
1592             chanflags |= CHAN_OFDM;
1593             if (SBW == 3)
1594                 radioflags |= FLAGS_CHAN_40MHZ;
1595             else if (SBW == 4)
1596                 radioflags |= FLAGS_CHAN_80MHZ;
1597             nss = vVW510021_W_S2_NSS_VHT(l1p_1);
1598             rate = get_vht_rate(rate_mcs_index, radioflags, nss);
1599         }
1600         break;
1601
1602     default:
1603         rate_mcs_index = 0;
1604         nss = 0;
1605         rate = 0.0f;
1606         break;
1607     }
1608
1609     /*
1610      * The MSDU length includes the FCS.
1611      *
1612      * The packet data does *not* include the FCS - it's just 4 bytes
1613      * of junk - so we have to remove it.
1614      *
1615      * We'll be stripping off that junk, so make sure we have at least
1616      * 4 octets worth of packet data.
1617      *
1618      * There seems to be a special case of a length of 0.
1619      */
1620     if (actual_octets < 4) {
1621         if (actual_octets != 0) {
1622             *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include 4 bytes of FCS)",
1623                                         actual_octets);
1624             *err = WTAP_ERR_BAD_FILE;
1625             return FALSE;
1626         }
1627     } else {
1628         actual_octets -= 4;
1629     }
1630
1631     /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
1632     /* 64-bit times are "Corey-endian" */
1633     s_time = pcoreytohll(&s_trail_ptr[vVW510021_W_STARTT_OFF]);
1634     e_time = pcoreytohll(&s_trail_ptr[vVW510021_W_ENDT_OFF]);
1635
1636     /* find the packet duration (difference between start and end times) */
1637     d_time = (guint32)((e_time - s_time) / NS_IN_US);  /* find diff, converting to usec */
1638
1639     /* also convert the packet start time to seconds and microseconds */
1640     start_time = s_time / NS_IN_US;                     /* convert to microseconds first */
1641     s_sec = (start_time / US_IN_SEC);                   /* get the number of seconds */
1642     s_usec = start_time - (s_sec * US_IN_SEC);          /* get the number of microseconds */
1643
1644     /* also convert the packet end time to seconds and microseconds */
1645     end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
1646
1647     /* extract the 32 LSBs of the signature timestamp field */
1648     m_ptr = &(rec[8+12]);
1649     pay_off = 42;         /* 24 (MAC) + 8 (SNAP) + IP */
1650     sig_off = find_signature(m_ptr, rec_size - 20, pay_off, flow_id, flow_seq);
1651     if (m_ptr[sig_off] == 0xdd)
1652         sig_ts = get_signature_ts(m_ptr, sig_off, rec_size - vVW510021_W_STATS_TRAILER_LEN);
1653     else
1654         sig_ts = 0;
1655
1656     /* Set latency based on rx/tx and signature timestamp */
1657     if (!IS_TX) {
1658         if (tsid < s_time) {
1659             latency = s_time - tsid;
1660           } else {
1661             /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
1662             /* we look for a large difference between l_time and s_time. */
1663             delta_b = tsid - s_time;
1664             if (delta_b >  0x10000000)
1665               latency = 0;
1666             else
1667               latency = delta_b;
1668           }
1669     }
1670
1671     /*
1672      * Fill up the per-packet header.
1673      *
1674      * We include the length of the metadata headers in the packet lengths.
1675      *
1676      * The maximum value of actual_octets is 8191, which, even after
1677      * adding the lengths of the metadata headers, is less than
1678      * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
1679      */
1680     record->rec_header.packet_header.len = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1681     record->rec_header.packet_header.caplen = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1682
1683     record->ts.secs   = (time_t)s_sec;
1684     record->ts.nsecs  = (int)(s_usec * 1000);
1685
1686     record->rec_type = REC_TYPE_PACKET;
1687     record->presence_flags = WTAP_HAS_TS;
1688
1689     ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
1690     data_ptr = ws_buffer_start_ptr(buf);
1691
1692     /*
1693      * Generate and copy out the common metadata headers,
1694      * set the port type to 0 (WLAN).
1695      *
1696      * All values are copied out in little-endian byte order.
1697      */
1698     /*** msdu_length = msdu_length + 16; ***/
1699     /* 1st octet of record for port_type and command (command is 0, hence RX) */
1700     phtole8(&data_ptr[bytes_written], WLAN_PORT);
1701     bytes_written += 1;
1702     /* 2nd octet of record for fpga version (0, hence pre-OCTO) */
1703     phtole8(&data_ptr[bytes_written], 0);
1704     bytes_written += 1;
1705
1706     phtoles(&data_ptr[bytes_written], STATS_COMMON_FIELDS_LEN); /* it_len */
1707     bytes_written += 2;
1708     phtoles(&data_ptr[bytes_written], msdu_length);
1709     bytes_written += 2;
1710     phtolel(&data_ptr[bytes_written], flow_id);
1711     bytes_written += 4;
1712     phtoles(&data_ptr[bytes_written], vc_id);
1713     bytes_written += 2;
1714     phtoles(&data_ptr[bytes_written], flow_seq);
1715     bytes_written += 2;
1716     if (!f_tx && sig_ts != 0) {
1717         phtolel(&data_ptr[bytes_written], latency);
1718     } else {
1719         phtolel(&data_ptr[bytes_written], 0);
1720     }
1721     bytes_written += 4;
1722     phtolel(&data_ptr[bytes_written], sig_ts); /* 32 LSBs of signature timestamp (nsec) */
1723     bytes_written += 4;
1724     phtolell(&data_ptr[bytes_written], start_time); /* record start & end times of frame */
1725     bytes_written += 8;
1726     phtolell(&data_ptr[bytes_written], end_time);
1727     bytes_written += 8;
1728     phtolel(&data_ptr[bytes_written], d_time);
1729     bytes_written += 4;
1730
1731     /*
1732      * Generate and copy out the WLAN metadata headers.
1733      *
1734      * All values are copied out in little-endian byte order.
1735      */
1736     phtoles(&data_ptr[bytes_written], EXT_WLAN_FIELDS_LEN);
1737     bytes_written += 2;
1738     if (info & vVW510021_W_IS_WEP)
1739         radioflags |= FLAGS_WEP;
1740     if (!(l1p_1 & vVW510021_W_IS_LONGPREAMBLE) && (plcp_type == vVW510021_W_PLCP_LEGACY))
1741         radioflags |= FLAGS_SHORTPRE;
1742     phtoles(&data_ptr[bytes_written], radioflags);
1743     bytes_written += 2;
1744     phtoles(&data_ptr[bytes_written], chanflags);
1745     bytes_written += 2;
1746     phyRate = (guint16)(rate * 10);
1747     phtoles(&data_ptr[bytes_written], phyRate);
1748     bytes_written += 2;
1749
1750     data_ptr[bytes_written] = plcp_type;
1751     bytes_written += 1;
1752
1753     data_ptr[bytes_written] = rate_mcs_index;
1754     bytes_written += 1;
1755
1756     data_ptr[bytes_written] = nss;
1757     bytes_written += 1;
1758     data_ptr[bytes_written] = rssi[0];
1759     bytes_written += 1;
1760     data_ptr[bytes_written] = rssi[1];
1761     bytes_written += 1;
1762     data_ptr[bytes_written] = rssi[2];
1763     bytes_written += 1;
1764     data_ptr[bytes_written] = rssi[3];
1765     bytes_written += 1;
1766     /* padding */
1767     data_ptr[bytes_written] = 0;
1768     bytes_written += 1;
1769
1770     /* fill in the VeriWave flags field */
1771     vw_flags  = 0;
1772     if (f_tx)
1773         vw_flags |= VW_FLAGS_TXF;
1774     if (errors & 0x1f)  /* If any error is flagged, then set the FCS error bit */
1775         vw_flags |= VW_FLAGS_FCSERR;
1776     if (!f_tx && (errors & vwr->CRYPTO_ERR))
1777         vw_flags |= VW_FLAGS_DCRERR;
1778     if (!f_tx && (errors & vwr->RETRY_ERR))
1779         vw_flags |= VW_FLAGS_RETRERR;
1780     if (info & vwr->WEPTYPE)
1781         vw_flags |= VW_FLAGS_IS_WEP;
1782     else if (info & vwr->TKIPTYPE)
1783         vw_flags |= VW_FLAGS_IS_TKIP;
1784     else if (info & vwr->CCMPTYPE)
1785         vw_flags |= VW_FLAGS_IS_CCMP;
1786     phtoles(&data_ptr[bytes_written], vw_flags);
1787     bytes_written += 2;
1788
1789     phtoles(&data_ptr[bytes_written], ht_len);
1790     bytes_written += 2;
1791     phtoles(&data_ptr[bytes_written], info);
1792     bytes_written += 2;
1793     phtolel(&data_ptr[bytes_written], errors);
1794     bytes_written += 4;
1795
1796     /* Finally, copy the whole MAC frame to the packet buffer as-is.
1797      * This does not include the stats header or the PLCP.
1798      * This also does not include the last 4 bytes, as those don't
1799      * contain an FCS, they just contain junk.
1800      */
1801     memcpy(&data_ptr[bytes_written], &rec[vwr->MPDU_OFF], actual_octets);
1802
1803     return TRUE;
1804 }
1805
1806 static gboolean vwr_read_s3_W_rec(vwr_t *vwr, wtap_rec *record,
1807                                   Buffer *buf, const guint8 *rec, int rec_size,
1808                                   int IS_TX, int log_mode, int *err,
1809                                   gchar **err_info)
1810 {
1811     guint8           *data_ptr;
1812     int              bytes_written = 0;                  /* bytes output to buf so far */
1813     int              i;
1814     int              stats_offset = 0;
1815     const guint8     *s_start_ptr = NULL,*s_trail_ptr = NULL, *plcp_ptr, *m_ptr; /* stats & MPDU ptr */
1816     guint32          msdu_length = 0, actual_octets = 0; /* octets in frame */
1817     guint8           l1p_1 = 0,l1p_2 = 0, plcp_type, rate_mcs_index, nss;   /* mod (CCK-L/CCK-S/OFDM) */
1818     guint64          s_time = LL_ZERO, e_time = LL_ZERO; /* start/end */
1819                                                          /* times, nsec */
1820     guint64          latency = LL_ZERO;
1821     guint64          start_time = 0, s_sec = 0, s_usec = LL_ZERO; /* start time, sec + usec */
1822     guint64          end_time = 0;                                /* end time */
1823     guint16          info = 0;                           /* INFO/ERRORS fields in stats blk */
1824     guint32          errors = 0;
1825     gint8            info_2nd = 0,rssi[] = {0,0,0,0};    /* RSSI, signed 8-bit number */
1826     int              frame_size;
1827     guint32          d_time = 0, flow_id = 0;            /* packet duration, Flow Signature ID*/
1828     int              sig_off, pay_off;                   /* MAC+SNAP header len, signature offset */
1829     guint64          sig_ts = 0, tsid;                   /* 32 LSBs of timestamp in signature */
1830     guint64          delta_b;                            /* Used for calculating latency */
1831     guint8           L1InfoC,port_type,ver_fpga = 0;
1832     guint8           flow_seq =0,plcp_hdr_flag = 0,rf_id = 0;    /* indicates plcp hdr info */
1833     const guint8    *rf_ptr = NULL;
1834     float            rate;
1835     guint16          phyRate;
1836
1837     /*
1838      * The record data must be large enough to hold the statistics header,
1839      * the PLCP, and the statistics trailer.
1840      */
1841     if (IS_TX == 3) {       /*IS_TX =3, i.e., command type is RF Modified*/
1842         if ((guint)rec_size < OCTO_MODIFIED_RF_LEN) {
1843             *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1844                                         rec_size,
1845                                         OCTO_MODIFIED_RF_LEN);
1846             *err = WTAP_ERR_BAD_FILE;
1847             return FALSE;
1848         }
1849         rf_ptr = &(rec[0]);
1850         rf_id = rf_ptr[0];
1851
1852         /*
1853          * Fill up the per-packet header.
1854          *
1855          * We include the length of the metadata headers in the packet lengths.
1856          *
1857          * OCTO_MODIFIED_RF_LEN + 1 is less than WTAP_MAX_PACKET_SIZE_STANDARD will
1858          * ever be, so we don't need to check it.
1859          */
1860         record->rec_header.packet_header.len = OCTO_MODIFIED_RF_LEN + 1;       /* 1st octet is reserved for detecting type of frame while displaying in wireshark */
1861         record->rec_header.packet_header.caplen = OCTO_MODIFIED_RF_LEN + 1;
1862
1863         record->ts.secs   = (time_t)s_sec;
1864         record->ts.nsecs  = (int)(s_usec * 1000);
1865
1866         record->rec_type = REC_TYPE_PACKET;
1867         record->presence_flags = WTAP_HAS_TS;
1868
1869         ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
1870         data_ptr = ws_buffer_start_ptr(buf);
1871
1872         port_type = IS_TX << 4;
1873
1874         nss = 0;
1875         phyRate = 0;
1876     }
1877     else {
1878         /* Calculate the start of the statistics blocks in the buffer */
1879         /* Also get a bunch of fields from the stats blocks */
1880         /* 'stats_offset' variable is use to locate the exact offset.
1881          * When a RX frame contrains RF,
1882          * the postion of Stats, Layer 1-4, PLCP parameters are shifted to
1883          * + OCTO_RF_MOD_ACTUAL_LEN bytes
1884          */
1885         if (IS_TX == 4)     /*IS_TX =4, i.e., command type is RF-RX Modified*/
1886         {
1887             stats_offset = OCTO_RF_MOD_ACTUAL_LEN;
1888             if ((guint)rec_size < stats_offset + vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN) {
1889                 *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1890                                             rec_size,
1891                                             stats_offset + vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1892                 *err = WTAP_ERR_BAD_FILE;
1893                 return FALSE;
1894             }
1895             rf_ptr = &(rec[0]);
1896             rf_id = rf_ptr[0];
1897         }
1898         else
1899         {
1900             stats_offset = 0;
1901             if ((guint)rec_size < vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN) {
1902                 *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1903                                             rec_size,
1904                                             vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1905                 *err = WTAP_ERR_BAD_FILE;
1906                 return FALSE;
1907             }
1908         }
1909
1910         s_start_ptr = &(rec[stats_offset]);         /* point to stats header */
1911         s_trail_ptr = &(rec[rec_size - vVW510021_W_STATS_TRAILER_LEN] );      /* point to stats trailer */
1912
1913         l1p_1 = s_start_ptr[vVW510021_W_L1P_1_OFF];
1914         l1p_2 = s_start_ptr[vVW510021_W_L1P_2_OFF];
1915
1916         plcp_type = vVW510021_W_S3_PLCP_TYPE(l1p_2);
1917         switch (plcp_type)
1918         {
1919         case vVW510021_W_PLCP_LEGACY:
1920             /* pre-HT */
1921             rate_mcs_index = vVW510021_W_S3_RATE_INDEX(l1p_1);
1922             nss = 0;
1923             break;
1924
1925         case vVW510021_W_PLCP_MIXED:
1926         case vVW510021_W_PLCP_GREENFIELD:
1927             rate_mcs_index = vVW510021_W_S3_MCS_INDEX_HT(l1p_1);
1928             nss = (rate_mcs_index < MAX_HT_MCS) ? nss_for_mcs[rate_mcs_index] : 0;
1929             break;
1930
1931         case vVW510021_W_PLCP_VHT_MIXED:
1932             rate_mcs_index = vVW510021_W_S3_MCS_INDEX_VHT(l1p_1);
1933             nss = vVW510021_W_S3_NSS_VHT(l1p_1);
1934             plcp_hdr_flag = 1;
1935             break;
1936
1937         default:
1938             rate_mcs_index = 0;
1939             nss = 0;
1940             plcp_hdr_flag = 0;
1941             break;
1942         }
1943
1944         for (i = 0; i < 4; i++)
1945         {
1946             if (IS_TX == 1)
1947             {
1948                 rssi[i] = (s_start_ptr[4+i] & 0x80) ? -1 * (s_start_ptr[4+i] & 0x7f) : s_start_ptr[4+i] & 0x7f;
1949             }
1950             else
1951             {
1952                 rssi[i] = (s_start_ptr[4+i] >= 128) ? (s_start_ptr[4+i] - 256) : s_start_ptr[4+i];
1953             }
1954         }
1955
1956         if (IS_TX == 0 || IS_TX == 4){
1957             L1InfoC = s_start_ptr[8];
1958         }
1959
1960         msdu_length = pntoh24(&s_start_ptr[9]);
1961
1962         /*** 16 bytes of PLCP header + 1 byte of L1P for user position ***/
1963         plcp_ptr = &(rec[stats_offset+16]);
1964
1965         /*** Add the PLCP length for S3_W_FPGA version VHT frames for Beamforming decode ***/
1966         if (log_mode == 3) {
1967             frame_size = rec_size - (stats_offset + vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1968             if (frame_size > ((int) msdu_length))
1969                 actual_octets = msdu_length;
1970             else {
1971                 /*
1972                  * XXX - does this mean "the packet was cut short during
1973                  * capture" or "this is a malformed record"?
1974                  */
1975                 actual_octets = frame_size;
1976             }
1977         }
1978         else
1979         {
1980             actual_octets = msdu_length;
1981         }
1982         /*
1983          * Sanity check the octets field to determine if it's greater than
1984          * the packet data available in the record - i.e., the record size
1985          * minus the sum of (length of statistics header + PLCP) and
1986          * (length of statistics trailer).
1987          *
1988          * Report an error if it is.
1989          */
1990         if (actual_octets > rec_size - (stats_offset + vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN)) {
1991             *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
1992                                         actual_octets);
1993             *err = WTAP_ERR_BAD_FILE;
1994             return FALSE;
1995         }
1996
1997         flow_seq = s_trail_ptr[vVW510021_W_FLOWSEQ_OFF];
1998
1999         latency = 0x00000000;                        /* clear latency */
2000         flow_id = pntoh24(&s_trail_ptr[vVW510021_W_FLOWID_OFF]);         /* all 24 bits valid */
2001         /* For tx latency is duration, for rx latency is timestamp */
2002         /* Get 48-bit latency value */
2003         tsid = pcorey48tohll(&s_trail_ptr[vVW510021_W_LATVAL_OFF]);
2004
2005         errors = pntoh32(&s_trail_ptr[vVW510021_W_ERRORS_OFF]);
2006         info = pntoh16(&s_trail_ptr[vVW510021_W_INFO_OFF]);
2007
2008         if (IS_TX == 0 || IS_TX == 4)
2009             info_2nd = s_trail_ptr[41];
2010
2011         /*** Calculate Data rate based on
2012         *  PLCP type, MCS index and number of spatial stream
2013         *  radioflags is temporarily calculated, which is used in
2014         *  get_ht_rate() and get_vht_rate().
2015         **/
2016         switch (plcp_type)
2017         {
2018         case vVW510021_W_PLCP_LEGACY:
2019             rate = get_legacy_rate(rate_mcs_index);
2020             break;
2021
2022         case vVW510021_W_PLCP_MIXED:
2023             /*
2024              * According to section 20.3.2 "PPDU format", the HT-mixed
2025              * PLCP header has a "Non-HT SIGNAL field" (L-SIG), which
2026              * looks like an 11a SIGNAL field, followed by an HT SIGNAL
2027              * field (HT-SIG) described in section 20.3.9.4.3 "HT-SIG
2028              * definition".
2029              *
2030              * This means that the first octet of HT-SIG is at
2031              * plcp_ptr[3], skipping the 3 octets of the L-SIG field.
2032              *
2033              * 0x80 is the CBW 20/40 bit of HT-SIG.
2034              */
2035             {
2036                 /* set the appropriate flags to indicate HT mode and CB */
2037                 guint16 radioflags = FLAGS_CHAN_HT | ((plcp_ptr[3] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
2038                                    ((l1p_1 & vVW510021_W_IS_LONGGI) ? 0 : FLAGS_CHAN_SHORTGI);
2039                 rate = get_ht_rate(rate_mcs_index, radioflags);
2040             }
2041             break;
2042
2043         case vVW510021_W_PLCP_GREENFIELD:
2044             /*
2045              * According to section 20.3.2 "PPDU format", the HT-greenfield
2046              * PLCP header just has the HT SIGNAL field (HT-SIG) above, with
2047              * no L-SIG field.
2048              *
2049              * This means that the first octet of HT-SIG is at
2050              * plcp_ptr[0], as there's no L-SIG field to skip.
2051              *
2052              * 0x80 is the CBW 20/40 bit of HT-SIG.
2053              */
2054             {
2055                 /* set the appropriate flags to indicate HT mode and CB */
2056                 guint16 radioflags = FLAGS_CHAN_HT | ((plcp_ptr[0] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
2057                                    ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
2058                 rate = get_ht_rate(rate_mcs_index, radioflags);
2059             }
2060             break;
2061
2062         case vVW510021_W_PLCP_VHT_MIXED:
2063             /*
2064              * According to section 22.3.2 "VHT PPDU format" of IEEE Std
2065              * 802.11ac-2013, the VHT PLCP header has a "non-HT SIGNAL field"
2066              * (L-SIG), which looks like an 11a SIGNAL field, followed by
2067              * a VHT Signal A field (VHT-SIG-A) described in section
2068              * 22.3.8.3.3 "VHT-SIG-A definition", with training fields
2069              * between it and a VHT Signal B field (VHT-SIG-B) described
2070              * in section 22.3.8.3.6 "VHT-SIG-B definition", followed by
2071              * the PSDU.
2072              */
2073             {
2074                 guint8 SBW = vVW510021_W_BANDWIDTH_VHT(l1p_2);
2075                 guint16 radioflags = FLAGS_CHAN_VHT | ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
2076                 if (SBW == 3)
2077                     radioflags |= FLAGS_CHAN_40MHZ;
2078                 else if (SBW == 4)
2079                     radioflags |= FLAGS_CHAN_80MHZ;
2080                 rate = get_vht_rate(rate_mcs_index, radioflags, nss);
2081             }
2082             break;
2083
2084         default:
2085             rate = 0.0f;
2086             break;
2087         }
2088         phyRate = (guint16)(rate * 10);
2089         /* Calculation of Data rate ends*/
2090
2091         /* 'ver_fpga' is the 2nd Octet of each frame.
2092          * msb/lsb nibble indicates log mode/fpga version respectively.
2093          * where log mode = 0 is normal capture and 1 is reduced capture,
2094          * lsb nibble is set to 1 always as this function is applicable for only FPGA version >= 48
2095          */
2096         if (log_mode == 3) {
2097             if (frame_size >= (int) msdu_length) {
2098                 /*
2099                  * The MSDU length includes the FCS.
2100                  *
2101                  * The packet data does *not* include the FCS - it's just 4
2102                  * bytes of junk - so we have to remove it.
2103                  *
2104                  * We'll be stripping off that junk, so make sure we have at
2105                  * least 4 octets worth of packet data.
2106                  *
2107                  * XXX - is the FCS actually present here, as it appears to be
2108                  * if log_mode isn't 3?
2109                  *
2110                  * There seems to be a special case of a length of 0.
2111                  */
2112                 if (actual_octets < 4) {
2113                     if (actual_octets != 0) {
2114                         *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include 4 bytes of FCS)",
2115                                                     actual_octets);
2116                         *err = WTAP_ERR_BAD_FILE;
2117                         return FALSE;
2118                     }
2119                 } else {
2120                     actual_octets -= 4;
2121                 }
2122             }
2123             ver_fpga = 0x11;
2124         } else {
2125             ver_fpga = 0x01;
2126         }
2127
2128         /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
2129         /* 64-bit times are "Corey-endian" */
2130         s_time = pcoreytohll(&s_trail_ptr[vVW510021_W_STARTT_OFF]);
2131         e_time = pcoreytohll(&s_trail_ptr[vVW510021_W_ENDT_OFF]);
2132
2133         /* find the packet duration (difference between start and end times) */
2134         d_time = (guint32)((e_time - s_time) / NS_IN_US);  /* find diff, converting to usec */
2135
2136         /* also convert the packet start time to seconds and microseconds */
2137         start_time = s_time / NS_IN_US;                     /* convert to microseconds first */
2138         s_sec = (start_time / US_IN_SEC);                   /* get the number of seconds */
2139         s_usec = start_time - (s_sec * US_IN_SEC);          /* get the number of microseconds */
2140
2141         /* also convert the packet end time to seconds and microseconds */
2142         end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
2143
2144         /* extract the 32 LSBs of the signature timestamp field */
2145         int m_ptr_offset = stats_offset + 8 + 12;
2146         m_ptr = rec + m_ptr_offset;
2147         pay_off = 42;         /* 24 (MAC) + 8 (SNAP) + IP */
2148         sig_off = find_signature(m_ptr, rec_size - m_ptr_offset, pay_off, flow_id, flow_seq);
2149         if (m_ptr[sig_off] == 0xdd)
2150             sig_ts = get_signature_ts(m_ptr, sig_off, rec_size - vVW510021_W_STATS_TRAILER_LEN);
2151         else
2152             sig_ts = 0;
2153
2154         /* Set latency based on rx/tx and signature timestamp */
2155         if (IS_TX == 0 || IS_TX == 4) {
2156             if (tsid < s_time) {
2157                 latency = s_time - tsid;
2158             } else {
2159                 /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
2160                 /* we look for a large difference between l_time and s_time. */
2161                 delta_b = tsid - s_time;
2162                 if (delta_b >  0x10000000)
2163                     latency = 0;
2164                 else
2165                     latency = delta_b;
2166             }
2167         }
2168
2169         port_type = IS_TX << 4;
2170
2171         /*
2172          * Fill up the per-packet header.
2173          *
2174          * We include the length of the metadata headers in the packet lengths.
2175          */
2176         if (IS_TX == 4) {
2177             record->rec_header.packet_header.len = OCTO_MODIFIED_RF_LEN + OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2178             record->rec_header.packet_header.caplen = OCTO_MODIFIED_RF_LEN + OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2179         } else {
2180             record->rec_header.packet_header.len = OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2181             record->rec_header.packet_header.caplen = OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2182         }
2183         if (record->rec_header.packet_header.caplen > WTAP_MAX_PACKET_SIZE_STANDARD) {
2184             /*
2185              * Probably a corrupt capture file; return an error,
2186              * so that our caller doesn't blow up trying to allocate
2187              * space for an immensely-large packet.
2188              */
2189             *err_info = g_strdup_printf("vwr: File has %u-byte packet, bigger than maximum of %u",
2190                                         record->rec_header.packet_header.caplen, WTAP_MAX_PACKET_SIZE_STANDARD);
2191             *err = WTAP_ERR_BAD_FILE;
2192             return FALSE;
2193         }
2194
2195         record->ts.secs   = (time_t)s_sec;
2196         record->ts.nsecs  = (int)(s_usec * 1000);
2197
2198         record->rec_type = REC_TYPE_PACKET;
2199         record->presence_flags = WTAP_HAS_TS;
2200
2201         ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
2202         data_ptr = ws_buffer_start_ptr(buf);
2203     }
2204
2205     /*
2206      * Generate and copy out the common metadata headers,
2207      * set the port type to port_type (XXX).
2208      *
2209      * All values are copied out in little-endian byte order.
2210      */
2211     /*** msdu_length = msdu_length + 16; ***/
2212
2213     /* 1st octet of record for port_type and other crud */
2214     phtole8(&data_ptr[bytes_written], port_type);
2215     bytes_written += 1;
2216
2217     if (IS_TX != 3) {
2218         phtole8(&data_ptr[bytes_written], ver_fpga); /* 2nd octet of record for FPGA version*/
2219         bytes_written += 1;
2220
2221         phtoles(&data_ptr[bytes_written], OCTO_TIMESTAMP_FIELDS_LEN); /* it_len */
2222         bytes_written += 2;
2223
2224     /*** Time Collapsible header started***/
2225         if (IS_TX == 1 && sig_ts != 0) {
2226             phtolel(&data_ptr[bytes_written], latency);
2227         } else {
2228             phtolel(&data_ptr[bytes_written], 0);
2229         }
2230         bytes_written += 4;
2231         phtolel(&data_ptr[bytes_written], sig_ts); /* 32 LSBs of signature timestamp (nsec) */
2232         bytes_written += 4;
2233         phtolell(&data_ptr[bytes_written], start_time); /* record start & end times of frame */
2234         bytes_written += 8;
2235         phtolell(&data_ptr[bytes_written], end_time);
2236         bytes_written += 8;
2237         phtolel(&data_ptr[bytes_written], d_time);
2238         bytes_written += 4;
2239     /*** Time Collapsible header ends ***/
2240     }
2241
2242     /*** RF Collapsable header starts***/
2243     if (IS_TX == 3 || IS_TX == 4) {
2244         phtole8(&data_ptr[bytes_written], rf_id);
2245         bytes_written += 1;
2246         data_ptr[bytes_written] = 0;
2247         bytes_written += 1;
2248         data_ptr[bytes_written] = 0;
2249         bytes_written += 1;
2250         data_ptr[bytes_written] = 0;
2251         bytes_written += 1;
2252
2253         /*** NOISE for all 4 Ports ***/
2254         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2255         {
2256             if (pntoh16(&rf_ptr[RF_PORT_1_NOISE_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2257                 phtoles(&data_ptr[bytes_written], 0);
2258                 bytes_written += 2;
2259             } else {
2260                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_NOISE_OFF+i*RF_INTER_PORT_GAP_OFF];
2261                 bytes_written += 1;
2262                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_NOISE_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2263                 bytes_written += 1;
2264             }
2265         }
2266
2267         /*** SNR for all 4 Ports ***/
2268         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2269         {
2270             if (pntoh16(&rf_ptr[RF_PORT_1_SNR_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2271                 phtoles(&data_ptr[bytes_written], 0);
2272                 bytes_written += 2;
2273             } else {
2274                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_SNR_OFF+i*RF_INTER_PORT_GAP_OFF];
2275                 bytes_written += 1;
2276                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_SNR_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2277                 bytes_written += 1;
2278             }
2279         }
2280
2281         /*** PFE for all 4 Ports ***/
2282         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2283         {
2284             if (pntoh16(&rf_ptr[RF_PORT_1_PFE_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2285                 phtoles(&data_ptr[bytes_written], 0);
2286                 bytes_written += 2;
2287             } else {
2288                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_PFE_OFF+i*RF_INTER_PORT_GAP_OFF];
2289                 bytes_written += 1;
2290                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_PFE_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2291                 bytes_written += 1;
2292             }
2293         }
2294
2295         /*** EVM SIG Data for all 4 Ports ***/
2296         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2297         {
2298             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SD_SIG_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2299                 phtoles(&data_ptr[bytes_written], 0);
2300                 bytes_written += 2;
2301             } else {
2302                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_SIG_OFF+i*RF_INTER_PORT_GAP_OFF];
2303                 bytes_written += 1;
2304                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_SIG_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2305                 bytes_written += 1;
2306             }
2307         }
2308
2309         /*** EVM SIG PILOT for all 4 Ports ***/
2310         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2311         {
2312             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SP_SIG_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2313                 phtoles(&data_ptr[bytes_written], 0);
2314                 bytes_written += 2;
2315             } else {
2316                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_SIG_OFF+i*RF_INTER_PORT_GAP_OFF];
2317                 bytes_written += 1;
2318                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_SIG_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2319                 bytes_written += 1;
2320             }
2321         }
2322
2323         /*** EVM Data Data for all 4 Ports ***/
2324         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2325         {
2326             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SD_DATA_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2327                 phtoles(&data_ptr[bytes_written], 0);
2328                 bytes_written += 2;
2329             } else {
2330                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_DATA_OFF+i*RF_INTER_PORT_GAP_OFF];
2331                 bytes_written += 1;
2332                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_DATA_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2333                 bytes_written += 1;
2334             }
2335         }
2336
2337         /*** EVM Data PILOT for all 4 Ports ***/
2338         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2339         {
2340             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SP_DATA_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2341                 phtoles(&data_ptr[bytes_written], 0);
2342                 bytes_written += 2;
2343             } else {
2344                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_DATA_OFF+i*RF_INTER_PORT_GAP_OFF];
2345                 bytes_written += 1;
2346                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_DATA_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2347                 bytes_written += 1;
2348             }
2349         }
2350
2351         /*** EVM WORST SYMBOL for all 4 Ports ***/
2352         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2353         {
2354             if (pntoh16(&rf_ptr[RF_PORT_1_DSYMBOL_IDX_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2355                 phtoles(&data_ptr[bytes_written], 0);
2356                 bytes_written += 2;
2357             } else {
2358                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_DSYMBOL_IDX_OFF+i*RF_INTER_PORT_GAP_OFF];
2359                 bytes_written += 1;
2360                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_DSYMBOL_IDX_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2361                 bytes_written += 1;
2362             }
2363         }
2364
2365         /*** CONTEXT_P for all 4 Ports ***/
2366         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2367         {
2368             if (pntoh16(&rf_ptr[RF_PORT_1_CONTEXT_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2369                 phtoles(&data_ptr[bytes_written], 0);
2370                 bytes_written += 2;
2371             } else {
2372                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_CONTEXT_OFF+i*RF_INTER_PORT_GAP_OFF];
2373                 bytes_written += 1;
2374                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_CONTEXT_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2375                 bytes_written += 1;
2376             }
2377         }
2378
2379         /*** FOR rest 24 RF data bytes are commented for future use ***/
2380 /***
2381         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2382         {
2383             if (pntoh16(&rf_ptr[20+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2384                 phtoles(&data_ptr[bytes_written], 0);
2385                 bytes_written += 2;
2386             } else {
2387                 data_ptr[bytes_written] = rf_ptr[20+i*RF_INTER_PORT_GAP_OFF];
2388                 bytes_written += 1;
2389                 data_ptr[bytes_written] = rf_ptr[21+i*RF_INTER_PORT_GAP_OFF];
2390                 bytes_written += 1;
2391             }
2392         }
2393         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2394         {
2395             if (pntoh16(&rf_ptr[24+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2396                 phtoles(&data_ptr[bytes_written], 0);
2397                 bytes_written += 2;
2398             } else {
2399                 data_ptr[bytes_written] = rf_ptr[24+i*RF_INTER_PORT_GAP_OFF];
2400                 bytes_written += 1;
2401                 data_ptr[bytes_written] = rf_ptr[25+i*RF_INTER_PORT_GAP_OFF];
2402                 bytes_written += 1;
2403             }
2404         }
2405         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2406         {
2407             if (pntoh16(&rf_ptr[26+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2408                 phtoles(&data_ptr[bytes_written], 0);
2409                 bytes_written += 2;
2410             } else {
2411                 data_ptr[bytes_written] = rf_ptr[26+i*RF_INTER_PORT_GAP_OFF];
2412                 bytes_written += 1;
2413                 data_ptr[bytes_written] = rf_ptr[27+i*RF_INTER_PORT_GAP_OFF];
2414                 bytes_written += 1;
2415             }
2416         }
2417 ***/
2418     }
2419     /*** RF Collapsable header ends***/
2420
2421     if (IS_TX != 3) {
2422         /*
2423          * Generate and copy out the WLAN metadata headers.
2424          *
2425          * All values are copied out in little-endian byte order.
2426          */
2427         phtoles(&data_ptr[bytes_written], OCTO_LAYER1TO4_LEN);
2428         bytes_written += 2;
2429
2430         /*** Layer-1 Collapsible header started***/
2431         data_ptr[bytes_written] = l1p_1;
2432         bytes_written += 1;
2433
2434         data_ptr[bytes_written] = (nss << 4) | IS_TX;
2435         bytes_written += 1;
2436
2437         phtoles(&data_ptr[bytes_written], phyRate);     /* To dosplay Data rate based on the PLCP type & MCS*/
2438         bytes_written += 2;
2439
2440         data_ptr[bytes_written] = l1p_2;
2441         bytes_written += 1;
2442
2443         data_ptr[bytes_written] = rssi[0];
2444         bytes_written += 1;
2445         data_ptr[bytes_written] = rssi[1];
2446         bytes_written += 1;
2447         data_ptr[bytes_written] = rssi[2];
2448         bytes_written += 1;
2449         data_ptr[bytes_written] = rssi[3];
2450         bytes_written += 1;
2451
2452         /* padding may not be required for S3_W*/
2453
2454         data_ptr[bytes_written] = s_start_ptr[2];    /*** For Signal Bandwidth Mask ***/
2455         bytes_written += 1;
2456         data_ptr[bytes_written] = s_start_ptr[3];    /*** For Antenna Port Energy Detect and MU_MASK ***/
2457         bytes_written += 1;
2458
2459         if (plcp_hdr_flag == 1 && (IS_TX == 0 || IS_TX == 4)) {
2460             data_ptr[bytes_written] = L1InfoC;  /*** For Other plcp type = VHT ***/
2461         } else {
2462             data_ptr[bytes_written] = 0;    /*** For Other plcp type, this offset is set to 0***/
2463         }
2464         bytes_written += 1;
2465
2466         phtoles(&data_ptr[bytes_written], msdu_length);
2467         bytes_written += 2;
2468         /*** Layer-1 Collapsible header Ends ***/
2469
2470         /*** PLCP Collapsible header Starts ***/
2471         memcpy(&data_ptr[bytes_written], &rec[stats_offset+16], 16);
2472         bytes_written += 16;
2473         /*** PLCP Collapsible header Ends ***/
2474
2475         /*** Layer 2-4 Collapsible header Starts ***/
2476
2477         phtolel(&data_ptr[bytes_written], pntoh32(&s_start_ptr[12]));   /*** This 4 bytes includes BM,BV,CV,BSSID and ClientID ***/
2478         bytes_written += 4;
2479         phtoles(&data_ptr[bytes_written], pntoh16(&s_trail_ptr[20]));   /*** 2 bytes includes FV,QT,HT,L4V,TID and WLAN type ***/
2480         bytes_written += 2;
2481         data_ptr[bytes_written] = flow_seq;
2482         bytes_written += 1;
2483         phtole24(&data_ptr[bytes_written], flow_id);
2484         bytes_written += 3;
2485         phtoles(&data_ptr[bytes_written], pntoh16(&s_trail_ptr[28]));   /*** 2 bytes for Layer 4 ID ***/
2486         bytes_written += 2;
2487         phtolel(&data_ptr[bytes_written], pntoh32(&s_trail_ptr[24]));   /*** 4 bytes for Payload Decode ***/
2488         bytes_written += 4;
2489
2490         /*** Incase of RX, Info has 3 bytes of data, whereas for TX, 2 bytes ***/
2491         if (IS_TX == 0 || IS_TX == 4) {
2492             phtoles(&data_ptr[bytes_written], info);
2493             bytes_written += 2;
2494             data_ptr[bytes_written] = info_2nd;
2495             bytes_written += 1;
2496         }
2497         else {
2498             phtoles(&data_ptr[bytes_written], info);
2499             bytes_written += 2;
2500             data_ptr[bytes_written] = 0;
2501             bytes_written += 1;
2502         }
2503
2504         phtolel(&data_ptr[bytes_written], errors);
2505         bytes_written += 4;
2506         /*** Layer 2-4 Collapsible header Ends ***/
2507
2508         /* Finally, copy the whole MAC frame to the packet buffer as-is.
2509          * This does not include the stats header or the PLCP.
2510          * This also does not include the last 4 bytes, as those don't
2511          * contain an FCS, they just contain junk.
2512          */
2513         memcpy(&data_ptr[bytes_written], &rec[stats_offset+(vwr->MPDU_OFF)], actual_octets);
2514     }
2515
2516     return TRUE;
2517 }
2518
2519 /* read an Ethernet packet */
2520 /* Copy the actual packet data from the capture file into the target data block.         */
2521 /* The packet is constructed as a 38-byte VeriWave-extended Radiotap header plus the raw */
2522 /*  MAC octets.                                                                          */
2523 static gboolean vwr_read_rec_data_ethernet(vwr_t *vwr, wtap_rec *record,
2524                                            Buffer *buf, const guint8 *rec,
2525                                            int rec_size, int IS_TX, int *err,
2526                                            gchar **err_info)
2527 {
2528     guint8           *data_ptr;
2529     int              bytes_written = 0;                   /* bytes output to buf so far */
2530     const guint8 *s_ptr, *m_ptr;                          /* stats and MPDU pointers */
2531     guint16          msdu_length, actual_octets;          /* octets in frame */
2532     guint            flow_seq;                            /* seqnum */
2533     guint64          s_time = LL_ZERO, e_time = LL_ZERO;  /* start/end */
2534                                                           /* times, nsec */
2535     guint32          latency = 0;
2536     guint64          start_time, s_sec = LL_ZERO, s_usec = LL_ZERO; /* start time, sec + usec */
2537     guint64          end_time;                            /* end time */
2538     guint            l4id;
2539     guint16          info, validityBits;                  /* INFO/ERRORS fields in stats */
2540     guint32          errors;
2541     guint16          vc_id;                               /* VC ID, total (incl of aggregates) */
2542     guint32          flow_id, d_time;                     /* packet duration */
2543     int              f_flow;                              /* flags: flow valid */
2544     guint32          frame_type;                          /* frame type field */
2545     int              mac_len, sig_off, pay_off;           /* MAC header len, signature offset */
2546     /* XXX - the code here fetched tsid, but never used it! */
2547     guint64          sig_ts/*, tsid*/;                    /* 32 LSBs of timestamp in signature */
2548     guint64          delta_b;                             /* Used for calculating latency */
2549     guint16          vw_flags;                            /* VeriWave-specific packet flags */
2550
2551     if ((guint)rec_size < vwr->STATS_LEN) {
2552         *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)", rec_size, vwr->STATS_LEN);
2553         *err = WTAP_ERR_BAD_FILE;
2554         return FALSE;
2555     }
2556
2557     /* Calculate the start of the statistics block in the buffer. */
2558     /* Also get a bunch of fields from the stats block.           */
2559     m_ptr = &(rec[0]);                              /* point to the data block */
2560     s_ptr = &(rec[rec_size - vwr->STATS_LEN]);      /* point to the stats block */
2561
2562     msdu_length = pntoh16(&s_ptr[vwr->OCTET_OFF]);
2563     actual_octets = msdu_length;
2564
2565     /*
2566      * Sanity check the octets field to determine if it's greater than
2567      * the packet data available in the record - i.e., the record size
2568      * minus the length of the statistics block.
2569      *
2570      * Report an error if it is.
2571      */
2572     if (actual_octets > rec_size - vwr->STATS_LEN) {
2573         *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
2574                                     actual_octets);
2575         *err = WTAP_ERR_BAD_FILE;
2576         return FALSE;
2577     }
2578
2579     vc_id = pntoh16(&s_ptr[vwr->VCID_OFF]) & vwr->VCID_MASK;
2580     flow_seq   = s_ptr[vwr->FLOWSEQ_OFF];
2581     frame_type = pntoh32(&s_ptr[vwr->FRAME_TYPE_OFF]);
2582
2583     if (vwr->FPGA_VERSION == vVW510024_E_FPGA) {
2584         validityBits = pntoh16(&s_ptr[vwr->VALID_OFF]);
2585         f_flow = validityBits & vwr->FLOW_VALID;
2586
2587         mac_len = (validityBits & vwr->IS_VLAN) ? 16 : 14;           /* MAC hdr length based on VLAN tag */
2588
2589
2590         errors = pntoh16(&s_ptr[vwr->ERRORS_OFF]);
2591     }
2592     else {
2593         f_flow  = s_ptr[vwr->VALID_OFF] & vwr->FLOW_VALID;
2594         mac_len = (frame_type & vwr->IS_VLAN) ? 16 : 14;             /* MAC hdr length based on VLAN tag */
2595
2596         /* for older fpga errors is only represented by 16 bits) */
2597         errors = pntoh16(&s_ptr[vwr->ERRORS_OFF]);
2598     }
2599
2600     info = pntoh16(&s_ptr[vwr->INFO_OFF]);
2601     /*  24 LSBs */
2602     flow_id = pntoh24(&s_ptr[vwr->FLOWID_OFF]);
2603
2604 #if 0
2605     /* For tx latency is duration, for rx latency is timestamp. */
2606     /* Get 64-bit latency value. */
2607     tsid = pcorey48tohll(&s_ptr[vwr->LATVAL_OFF]);
2608 #endif
2609
2610     l4id = pntoh16(&s_ptr[vwr->L4ID_OFF]);
2611
2612     /*
2613      * The MSDU length includes the FCS.
2614      *
2615      * The packet data does *not* include the FCS - it's just 4 bytes
2616      * of junk - so we have to remove it.
2617      *
2618      * We'll be stripping off that junk, so make sure we have at least
2619      * 4 octets worth of packet data.
2620      *
2621      * There seems to be a special case of a length of 0.
2622      */
2623     if (actual_octets < 4) {
2624         if (actual_octets != 0) {
2625             *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include 4 bytes of FCS)",
2626                                         actual_octets);
2627             *err = WTAP_ERR_BAD_FILE;
2628             return FALSE;
2629         }
2630     } else {
2631         actual_octets -= 4;
2632     }
2633
2634     /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
2635     /* 64-bit times are "Corey-endian"                                             */
2636     s_time = pcoreytohll(&s_ptr[vwr->STARTT_OFF]);
2637     e_time = pcoreytohll(&s_ptr[vwr->ENDT_OFF]);
2638
2639     /* find the packet duration (difference between start and end times) */
2640     d_time = (guint32)((e_time - s_time));  /* find diff, leaving in nsec for Ethernet */
2641
2642     /* also convert the packet start time to seconds and microseconds */
2643     start_time = s_time / NS_IN_US;                     /* convert to microseconds first */
2644     s_sec = (start_time / US_IN_SEC);                   /* get the number of seconds */
2645     s_usec = start_time - (s_sec * US_IN_SEC);          /* get the number of microseconds */
2646
2647     /* also convert the packet end time to seconds and microseconds */
2648     end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
2649
2650     if (frame_type & vwr->IS_TCP)                       /* signature offset for TCP frame */
2651     {
2652         pay_off = mac_len + 40;
2653     }
2654     else if (frame_type & vwr->IS_UDP)                  /* signature offset for UDP frame */
2655     {
2656         pay_off = mac_len + 28;
2657     }
2658     else if (frame_type & vwr->IS_ICMP)                 /* signature offset for ICMP frame */
2659     {
2660         pay_off = mac_len + 24;
2661     }
2662     else if (frame_type & vwr->IS_IGMP)                 /* signature offset for IGMPv2 frame */
2663     {
2664         pay_off = mac_len + 28;
2665     }
2666     else                                                /* signature offset for raw IP frame */
2667     {
2668         pay_off = mac_len + 20;
2669     }
2670
2671     sig_off = find_signature(m_ptr, rec_size, pay_off, flow_id, flow_seq);
2672     if ((m_ptr[sig_off] == 0xdd) && (f_flow != 0))
2673         sig_ts = get_signature_ts(m_ptr, sig_off, msdu_length);
2674     else
2675         sig_ts = 0;
2676
2677     /* Set latency based on rx/tx and signature timestamp */
2678     if (!IS_TX) {
2679         if (sig_ts < s_time) {
2680             latency = (guint32)(s_time - sig_ts);
2681         } else {
2682             /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
2683             /*  we look for a large difference between l_time and s_time.                       */
2684             delta_b = sig_ts - s_time;
2685             if (delta_b >  0x10000000) {
2686                 latency = 0;
2687             } else
2688                 latency = (guint32)delta_b;
2689         }
2690     }
2691
2692     /*
2693      * Fill up the per-packet header.
2694      *
2695      * We include the length of the metadata headers in the packet lengths.
2696      *
2697      * The maximum value of actual_octets is 65535, which, even after
2698      * adding the lengths of the metadata headers, is less than
2699      * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
2700      */
2701     record->rec_header.packet_header.len = STATS_COMMON_FIELDS_LEN + EXT_ETHERNET_FIELDS_LEN + actual_octets;
2702     record->rec_header.packet_header.caplen = STATS_COMMON_FIELDS_LEN + EXT_ETHERNET_FIELDS_LEN + actual_octets;
2703
2704     record->ts.secs   = (time_t)s_sec;
2705     record->ts.nsecs  = (int)(s_usec * 1000);
2706
2707     record->rec_type = REC_TYPE_PACKET;
2708     record->presence_flags = WTAP_HAS_TS;
2709
2710     /*etap_hdr.vw_ip_length = (guint16)ip_len;*/
2711
2712     ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
2713     data_ptr = ws_buffer_start_ptr(buf);
2714
2715     /*
2716      * Generate and copy out the common metadata headers,
2717      * set the port type to 1 (Ethernet).
2718      *
2719      * All values are copied out in little-endian byte order.
2720      */
2721     /* 1st octet of record for port_type and command (command is 0, hence RX) */
2722     phtole8(&data_ptr[bytes_written], ETHERNET_PORT);
2723     bytes_written += 1;
2724     /* 2nd octet of record for fpga version (Ethernet, hence non-OCTO) */
2725     phtole8(&data_ptr[bytes_written], 0);
2726     bytes_written += 1;
2727
2728     phtoles(&data_ptr[bytes_written], STATS_COMMON_FIELDS_LEN);
2729     bytes_written += 2;
2730     phtoles(&data_ptr[bytes_written], msdu_length);
2731     bytes_written += 2;
2732     phtolel(&data_ptr[bytes_written], flow_id);
2733     bytes_written += 4;
2734     phtoles(&data_ptr[bytes_written], vc_id);
2735     bytes_written += 2;
2736     phtoles(&data_ptr[bytes_written], flow_seq);
2737     bytes_written += 2;
2738     if (!IS_TX && (sig_ts != 0)) {
2739         phtolel(&data_ptr[bytes_written], latency);
2740     } else {
2741         phtolel(&data_ptr[bytes_written], 0);
2742     }
2743     bytes_written += 4;
2744     phtolel(&data_ptr[bytes_written], sig_ts);
2745     bytes_written += 4;
2746     phtolell(&data_ptr[bytes_written], start_time)                  /* record start & end times of frame */
2747     bytes_written += 8;
2748     phtolell(&data_ptr[bytes_written], end_time);
2749     bytes_written += 8;
2750     phtolel(&data_ptr[bytes_written], d_time);
2751     bytes_written += 4;
2752
2753     /*
2754      * Generate and copy out the Ethernet metadata headers.
2755      *
2756      * All values are copied out in little-endian byte order.
2757      */
2758     phtoles(&data_ptr[bytes_written], EXT_ETHERNET_FIELDS_LEN);
2759     bytes_written += 2;
2760     vw_flags = 0;
2761     if (IS_TX)
2762         vw_flags |= VW_FLAGS_TXF;
2763     if (errors & vwr->FCS_ERROR)
2764         vw_flags |= VW_FLAGS_FCSERR;
2765     phtoles(&data_ptr[bytes_written], vw_flags);
2766     bytes_written += 2;
2767     phtoles(&data_ptr[bytes_written], info);
2768     bytes_written += 2;
2769     phtolel(&data_ptr[bytes_written], errors);
2770     bytes_written += 4;
2771     phtolel(&data_ptr[bytes_written], l4id);
2772     bytes_written += 4;
2773
2774     /* Add in pad */
2775     phtolel(&data_ptr[bytes_written], 0);
2776     bytes_written += 4;
2777
2778     /*
2779      * Finally, copy the whole MAC frame to the packet buffer as-is.
2780      * This also does not include the last 4 bytes, as those don't
2781      * contain an FCS, they just contain junk.
2782      */
2783     memcpy(&data_ptr[bytes_written], m_ptr, actual_octets);
2784
2785     return TRUE;
2786 }
2787
2788 /*--------------------------------------------------------------------------------------*/
2789 /* utility to split up and decode a 16-byte message record */
2790
2791 static int decode_msg(vwr_t *vwr, guint8 *rec, int *v_type, int *IS_TX, int *log_mode)
2792 {
2793     guint8  cmd,fpga_log_mode;          /* components of message */
2794     guint32 wd2, wd3;
2795     int     v_size;                     /* size of var-len message */
2796
2797     /* break up the message record into its pieces */
2798     cmd = rec[0];
2799     fpga_log_mode = rec[1];
2800     fpga_log_mode = ((fpga_log_mode & 0x30) >> 4);
2801
2802     wd2 = pntoh32(&rec[8]);
2803     wd3 = pntoh32(&rec[12]);
2804
2805     if (vwr != NULL)
2806         *log_mode = fpga_log_mode;          /* Log mode = 3, when MPDU data is reduced */
2807
2808     /* now decode based on the command byte */
2809     switch (cmd) {
2810         case COMMAND_RX:
2811             if (vwr != NULL) {
2812                 *IS_TX = 0;
2813             }
2814             v_size  = (int)(wd2 & 0xffff);
2815             *v_type = VT_FRAME;
2816             break;
2817
2818         case COMMAND_TX:
2819             if (vwr != NULL) {
2820                 *IS_TX = 1;
2821             }
2822             v_size  = (int)(wd2 & 0xffff);
2823             *v_type = VT_FRAME;
2824             break;
2825
2826 /*
2827         case COMMAND_RFN:
2828             if (vwr != NULL) {
2829                 *IS_TX = 3;
2830             }
2831             v_size  = (int)(wd2 & 0xffff);
2832             *v_type = VT_FRAME;
2833             break;
2834 */
2835
2836         case COMMAND_RF:   /* For RF Modified only */
2837             if (vwr != NULL) {
2838                 *IS_TX = 3;
2839             }
2840             v_size  = (int)(wd2 & 0xffff);
2841             *v_type = VT_FRAME;
2842             break;
2843
2844         case COMMAND_RFRX: /* For RF_RX Modified only */
2845             if (vwr != NULL) {
2846                 *IS_TX = 4;
2847             }
2848             v_size  = (int)(wd2 & 0xffff);
2849             *v_type = VT_FRAME;
2850             break;
2851
2852         case 0xc1:
2853         case 0x8b:
2854         case 0xbb:
2855             if (vwr != NULL) {
2856                 *IS_TX = 2;
2857             }
2858             v_size  = (int)(wd2 & 0xffff);
2859             *v_type = VT_CPMSG;
2860             break;
2861
2862         case 0xfe:
2863             if (vwr != NULL) {
2864                 *IS_TX = 2;
2865             }
2866             v_size  = (int)(wd3 & 0xffff);
2867             *v_type = VT_CPMSG;
2868             break;
2869
2870         default:
2871             if (vwr != NULL) {
2872                 *IS_TX = 2;
2873             }
2874             v_size  = 0;
2875             *v_type = VT_UNKNOWN;
2876             break;
2877     }
2878
2879     return v_size;
2880 }
2881
2882
2883 /*---------------------------------------------------------------------------------------*/
2884 /* Utilities to extract and decode the PHY bit rate from 802.11 PLCP headers (OFDM/CCK). */
2885 /* They are passed a pointer to 4 or 6 consecutive bytes of PLCP header.                 */
2886 /* The integer returned by the get_xxx_rate() functions is in units of 0.5 Mb/s.         */
2887 /* The string returned by the decode_xxx_rate() functions is 3 characters wide.          */
2888
2889 static guint8 get_ofdm_rate(const guint8 *plcp)
2890 {
2891     /* extract the RATE field (LS nibble of first byte) then convert it to the MCS index used by the L1p fields */
2892     switch (plcp[0] & 0x0f) {
2893         case 0x0b:  return  4;
2894         case 0x0f:  return  5;
2895         case 0x0a:  return  6;
2896         case 0x0e:  return  7;
2897         case 0x09:  return  8;
2898         case 0x0d:  return  9;
2899         case 0x08:  return 10;
2900         case 0x0c:  return 11;
2901         default:    return  0;
2902     }
2903 }
2904
2905 static guint8 get_cck_rate(const guint8 *plcp)
2906 {
2907     /* extract rate from the SIGNAL field then convert it to the MCS index used by the L1p fields */
2908     switch (plcp[0]) {
2909         case 0x0a:  return 0;
2910         case 0x14:  return 1;
2911         case 0x37:  return 2;
2912         case 0x6e:  return 3;
2913         default:    return 0;
2914     }
2915 }
2916
2917 /*--------------------------------------------------------------------------------------*/
2918 /* utility to set up offsets and bitmasks for decoding the stats blocks */
2919
2920 static void setup_defaults(vwr_t *vwr, guint16 fpga)
2921 {
2922     switch (fpga) {
2923         /* WLAN frames */
2924         case S2_W_FPGA:
2925             vwr->STATS_LEN          = vVW510021_W_STATS_TRAILER_LEN;
2926
2927             vwr->VALID_OFF          = vVW510021_W_VALID_OFF;
2928             vwr->MTYPE_OFF          = vVW510021_W_MTYPE_OFF;
2929             vwr->VCID_OFF           = vVW510021_W_VCID_OFF;
2930             vwr->FLOWSEQ_OFF        = vVW510021_W_FLOWSEQ_OFF;
2931             vwr->FLOWID_OFF         = vVW510021_W_FLOWID_OFF;
2932
2933             /*vwr->OCTET_OFF        = v22_W_OCTET_OFF;*/
2934
2935             vwr->ERRORS_OFF         = vVW510021_W_ERRORS_OFF;
2936             vwr->PATN_OFF           = vVW510021_W_MATCH_OFF;
2937             vwr->RSSI_OFF           = vVW510021_W_RSSI_TXPOWER_OFF;
2938             vwr->STARTT_OFF         = vVW510021_W_STARTT_OFF;
2939             vwr->ENDT_OFF           = vVW510021_W_ENDT_OFF;
2940             vwr->LATVAL_OFF         = vVW510021_W_LATVAL_OFF;
2941             vwr->INFO_OFF           = vVW510021_W_INFO_OFF;
2942             vwr->FPGA_VERSION_OFF   = S2_W_FPGA_VERSION_OFF;
2943             vwr->HEADER_VERSION_OFF = vVW510021_W_HEADER_VERSION_OFF;
2944             vwr->OCTET_OFF          = vVW510021_W_MSDU_LENGTH_OFF;
2945             vwr->L1P_1_OFF          = vVW510021_W_L1P_1_OFF;
2946             vwr->L1P_2_OFF          = vVW510021_W_L1P_2_OFF;
2947             vwr->L4ID_OFF           = vVW510021_W_L4ID_OFF;
2948             vwr->IPLEN_OFF          = vVW510021_W_IPLEN_OFF;
2949             vwr->PLCP_LENGTH_OFF    = vVW510021_W_PLCP_LENGTH_OFF;
2950
2951             vwr->MT_MASK            = vVW510021_W_SEL_MASK;
2952             vwr->MCS_INDEX_MASK     = vVW510021_W_MCS_MASK;
2953             vwr->VCID_MASK          = 0xffff;
2954             vwr->FLOW_VALID         = vVW510021_W_FLOW_VALID;
2955             vwr->STATS_START_OFF    = vVW510021_W_HEADER_LEN;
2956             vwr->FCS_ERROR          = vVW510021_W_FCS_ERROR;
2957             vwr->CRYPTO_ERR         = v22_W_CRYPTO_ERR;
2958             vwr->RETRY_ERR          = v22_W_RETRY_ERR;
2959
2960             /*vwr->STATS_START_OFF  = 0;*/
2961
2962             vwr->RXTX_OFF           = vVW510021_W_RXTX_OFF;
2963
2964             vwr->MT_10_HALF         = 0;
2965             vwr->MT_10_FULL         = 0;
2966             vwr->MT_100_HALF        = 0;
2967             vwr->MT_100_FULL        = 0;
2968             vwr->MT_1G_HALF         = 0;
2969             vwr->MT_1G_FULL         = 0;
2970             vwr->MT_CCKL            = v22_W_MT_CCKL;
2971             vwr->MT_CCKS            = v22_W_MT_CCKS;
2972             /*vwr->MT_OFDM          = vVW510021_W_MT_OFDM;*/
2973
2974             vwr->WEPTYPE            = vVW510021_W_WEPTYPE;
2975             vwr->TKIPTYPE           = vVW510021_W_TKIPTYPE;
2976             vwr->CCMPTYPE           = vVW510021_W_CCMPTYPE;
2977
2978             vwr->FRAME_TYPE_OFF     =   vVW510021_W_FRAME_TYPE_OFF;
2979             vwr->IS_TCP             =   vVW510021_W_IS_TCP;
2980             vwr->IS_UDP             =   vVW510021_W_IS_UDP;
2981             vwr->IS_ICMP            =   vVW510021_W_IS_ICMP;
2982             vwr->IS_IGMP            =   vVW510021_W_IS_IGMP;
2983             vwr->IS_QOS             =   vVW510021_W_QOS_VALID;
2984
2985             /*
2986              * vVW510021_W_STATS_HEADER_LEN = 8 is:
2987              *
2988              *    2 bytes of l1p_1/l1p_2;
2989              *    1 byte of RSSI;
2990              *    2 bytes of MSDU length + other bits
2991              *    1 byte of XXX;
2992              *    2 bytes of VCID.
2993              *
2994              * The 12 is for 11 bytes of PLCP and 1 byte of pad
2995              * before the data.
2996              */
2997             vwr->MPDU_OFF           = vVW510021_W_STATS_HEADER_LEN + 12;
2998
2999             break;
3000
3001         case S3_W_FPGA:
3002             vwr->STATS_LEN       = vVW510021_W_STATS_TRAILER_LEN;
3003             vwr->PLCP_LENGTH_OFF = 16;
3004
3005             /*
3006              * The 16 + 16 is:
3007              *
3008              *    2 bytes of l1p_1/l1p_2;
3009              *    1 byte of signal bandwidth mask;
3010              *    1 byte of antenna port energy;
3011              *    4 bytes of per-antenna RSSI;
3012              *    1 byte of L1InfoC;
3013              *    3 bytes of MSDU length;
3014              *    4 bytes of something;
3015              *   16 bytes of PLCP.
3016              */
3017             vwr->MPDU_OFF        = 16 + 16;
3018
3019             break;
3020
3021         case vVW510012_E_FPGA:
3022             vwr->STATS_LEN      = v22_E_STATS_LEN;
3023
3024             vwr->VALID_OFF      = v22_E_VALID_OFF;
3025             vwr->MTYPE_OFF      = v22_E_MTYPE_OFF;
3026             vwr->VCID_OFF       = v22_E_VCID_OFF;
3027             vwr->FLOWSEQ_OFF    = v22_E_FLOWSEQ_OFF;
3028             vwr->FLOWID_OFF     = v22_E_FLOWID_OFF;
3029             vwr->OCTET_OFF      = v22_E_OCTET_OFF;
3030             vwr->ERRORS_OFF     = v22_E_ERRORS_OFF;
3031             vwr->PATN_OFF       = v22_E_PATN_OFF;
3032             vwr->RSSI_OFF       = v22_E_RSSI_OFF;
3033             vwr->STARTT_OFF     = v22_E_STARTT_OFF;
3034             vwr->ENDT_OFF       = v22_E_ENDT_OFF;
3035             vwr->LATVAL_OFF     = v22_E_LATVAL_OFF;
3036             vwr->INFO_OFF       = v22_E_INFO_OFF;
3037             vwr->L4ID_OFF       = v22_E_L4ID_OFF;
3038
3039             vwr->IS_RX          = v22_E_IS_RX;
3040             vwr->MT_MASK        = v22_E_MT_MASK;
3041             vwr->VCID_MASK      = v22_E_VCID_MASK;
3042             vwr->FLOW_VALID     = v22_E_FLOW_VALID;
3043             vwr->FCS_ERROR      = v22_E_FCS_ERROR;
3044
3045             vwr->RX_DECRYPTS    = v22_E_RX_DECRYPTS;
3046             vwr->TX_DECRYPTS    = v22_E_TX_DECRYPTS;
3047             vwr->FC_PROT_BIT    = v22_E_FC_PROT_BIT;
3048
3049             vwr->MT_10_HALF     = v22_E_MT_10_HALF;
3050             vwr->MT_10_FULL     = v22_E_MT_10_FULL;
3051             vwr->MT_100_HALF    = v22_E_MT_100_HALF;
3052             vwr->MT_100_FULL    = v22_E_MT_100_FULL;
3053             vwr->MT_1G_HALF     = v22_E_MT_1G_HALF;
3054             vwr->MT_1G_FULL     = v22_E_MT_1G_FULL;
3055             vwr->MT_CCKL        = 0;
3056             vwr->MT_CCKS        = 0;
3057             vwr->MT_OFDM        = 0;
3058
3059             vwr->FRAME_TYPE_OFF =  v22_E_FRAME_TYPE_OFF;
3060             vwr->IS_TCP         =   v22_E_IS_TCP;
3061             vwr->IS_UDP         =   v22_E_IS_UDP;
3062             vwr->IS_ICMP        =   v22_E_IS_ICMP;
3063             vwr->IS_IGMP        =   v22_E_IS_IGMP;
3064             vwr->IS_QOS         =   v22_E_IS_QOS;
3065             vwr->IS_VLAN        =   v22_E_IS_VLAN;
3066
3067             break;
3068
3069             /* WLAN frames */
3070         case S1_W_FPGA:
3071             vwr->STATS_LEN          = v22_W_STATS_LEN;
3072
3073             vwr->MTYPE_OFF          = v22_W_MTYPE_OFF;
3074             vwr->VALID_OFF          = v22_W_VALID_OFF;
3075             vwr->VCID_OFF           = v22_W_VCID_OFF;
3076             vwr->FLOWSEQ_OFF        = v22_W_FLOWSEQ_OFF;
3077             vwr->FLOWID_OFF         = v22_W_FLOWID_OFF;
3078             vwr->OCTET_OFF          = v22_W_OCTET_OFF;
3079             vwr->ERRORS_OFF         = v22_W_ERRORS_OFF;
3080             vwr->PATN_OFF           = v22_W_PATN_OFF;
3081             vwr->RSSI_OFF           = v22_W_RSSI_OFF;
3082             vwr->STARTT_OFF         = v22_W_STARTT_OFF;
3083             vwr->ENDT_OFF           = v22_W_ENDT_OFF;
3084             vwr->LATVAL_OFF         = v22_W_LATVAL_OFF;
3085             vwr->INFO_OFF           = v22_W_INFO_OFF;
3086             vwr->L4ID_OFF           = v22_W_L4ID_OFF;
3087             vwr->IPLEN_OFF          = v22_W_IPLEN_OFF;
3088             vwr->PLCP_LENGTH_OFF    = v22_W_PLCP_LENGTH_OFF;
3089
3090             vwr->FCS_ERROR          = v22_W_FCS_ERROR;
3091             vwr->CRYPTO_ERR         = v22_W_CRYPTO_ERR;
3092             vwr->PAYCHK_ERR         = v22_W_PAYCHK_ERR;
3093             vwr->RETRY_ERR          = v22_W_RETRY_ERR;
3094             vwr->IS_RX              = v22_W_IS_RX;
3095             vwr->MT_MASK            = v22_W_MT_MASK;
3096             vwr->VCID_MASK          = v22_W_VCID_MASK;
3097             vwr->FLOW_VALID         = v22_W_FLOW_VALID;
3098
3099             vwr->RX_DECRYPTS        = v22_W_RX_DECRYPTS;
3100             vwr->TX_DECRYPTS        = v22_W_TX_DECRYPTS;
3101             vwr->FC_PROT_BIT        = v22_W_FC_PROT_BIT;
3102
3103             vwr->MT_10_HALF         = 0;
3104             vwr->MT_10_FULL         = 0;
3105             vwr->MT_100_HALF        = 0;
3106             vwr->MT_100_FULL        = 0;
3107             vwr->MT_1G_HALF         = 0;
3108             vwr->MT_1G_FULL         = 0;
3109             vwr->MT_CCKL            = v22_W_MT_CCKL;
3110             vwr->MT_CCKS            = v22_W_MT_CCKS;
3111             vwr->MT_OFDM            = v22_W_MT_OFDM;
3112
3113             vwr->WEPTYPE            = v22_W_WEPTYPE;
3114             vwr->TKIPTYPE           = v22_W_TKIPTYPE;
3115             vwr->CCMPTYPE           = v22_W_CCMPTYPE;
3116
3117             vwr->FRAME_TYPE_OFF     =   v22_W_FRAME_TYPE_OFF;
3118             vwr->IS_TCP             =   v22_W_IS_TCP;
3119             vwr->IS_UDP             =   v22_W_IS_UDP;
3120             vwr->IS_ICMP            =   v22_W_IS_ICMP;
3121             vwr->IS_IGMP            =   v22_W_IS_IGMP;
3122             vwr->IS_QOS             =   v22_W_IS_QOS;
3123
3124             break;
3125
3126         /* Ethernet frames */
3127         case vVW510024_E_FPGA:
3128             vwr->STATS_LEN          = vVW510024_E_STATS_LEN;
3129
3130             vwr->VALID_OFF          = vVW510024_E_VALID_OFF;
3131             vwr->VCID_OFF           = vVW510024_E_VCID_OFF;
3132             vwr->FLOWSEQ_OFF        = vVW510024_E_FLOWSEQ_OFF;
3133             vwr->FLOWID_OFF         = vVW510024_E_FLOWID_OFF;
3134             vwr->OCTET_OFF          = vVW510024_E_MSDU_LENGTH_OFF;
3135             vwr->ERRORS_OFF         = vVW510024_E_ERRORS_OFF;
3136             vwr->PATN_OFF           = vVW510024_E_MATCH_OFF;
3137             vwr->STARTT_OFF         = vVW510024_E_STARTT_OFF;
3138             vwr->ENDT_OFF           = vVW510024_E_ENDT_OFF;
3139             vwr->LATVAL_OFF         = vVW510024_E_LATVAL_OFF;
3140             vwr->INFO_OFF           = vVW510024_E_INFO_OFF;
3141             vwr->L4ID_OFF           = vVW510024_E_L4ID_OFF;
3142             vwr->IPLEN_OFF          = vVW510024_E_IPLEN_OFF;
3143
3144             vwr->FPGA_VERSION_OFF   = vVW510024_E_FPGA_VERSION_OFF;
3145             vwr->HEADER_VERSION_OFF = vVW510024_E_HEADER_VERSION_OFF;
3146
3147             vwr->VCID_MASK          = vVW510024_E_VCID_MASK;
3148             vwr->FLOW_VALID         = vVW510024_E_FLOW_VALID;
3149             vwr->FCS_ERROR          = v22_E_FCS_ERROR;
3150
3151             vwr->FRAME_TYPE_OFF     =   vVW510024_E_FRAME_TYPE_OFF;
3152             vwr->IS_TCP             =   vVW510024_E_IS_TCP;
3153             vwr->IS_UDP             =   vVW510024_E_IS_UDP;
3154             vwr->IS_ICMP            =   vVW510024_E_IS_ICMP;
3155             vwr->IS_IGMP            =   vVW510024_E_IS_IGMP;
3156             vwr->IS_QOS             =   vVW510024_E_QOS_VALID;
3157             vwr->IS_VLAN            =   vVW510024_E_IS_VLAN;
3158
3159             break;
3160     }
3161 }
3162 #define SIG_SCAN_RANGE  64                          /* range of signature scanning region */
3163
3164 /* Utility routine: check that signature is at specified location; scan for it if not.     */
3165 /* If we can't find a signature at all, then simply return the originally supplied offset. */
3166 int find_signature(const guint8 *m_ptr, int rec_size, int pay_off, guint32 flow_id, guint8 flow_seq)
3167 {
3168     int     tgt;                /* temps */
3169     guint32 fid;
3170
3171     /* initial check is very simple: look for a '0xdd' at the target location */
3172     if (m_ptr[pay_off] == 0xdd)                         /* if magic byte is present */
3173         return pay_off;                                 /* got right offset, return it */
3174
3175     /* Hmmm, signature magic byte is not where it is supposed to be; scan from start of     */
3176     /*  payload until maximum scan range exhausted to see if we can find it.                */
3177     /* The scanning process consists of looking for a '0xdd', then checking for the correct */
3178     /*  flow ID and sequence number at the appropriate offsets.                             */
3179     for (tgt = pay_off; tgt < (rec_size); tgt++) {
3180         if (m_ptr[tgt] == 0xdd) {                       /* found magic byte? check fields */
3181             if ((tgt + 15 < rec_size) && (m_ptr[tgt + 15] == 0xe2)) {
3182                 if (m_ptr[tgt + 4] != flow_seq)
3183                     continue;
3184
3185                 fid = pletoh24(&m_ptr[tgt + 1]);
3186
3187                 if (fid != flow_id)
3188                     continue;
3189
3190                 return (tgt);
3191             }
3192             else if (tgt + SIG_FSQ_OFF < rec_size)
3193             {                                               /* out which one... */
3194                 if (m_ptr[tgt + SIG_FSQ_OFF] != flow_seq)   /* check sequence number */
3195                     continue;                               /* if failed, keep scanning */
3196
3197                 fid = pletoh24(&m_ptr[tgt + SIG_FID_OFF]);  /* assemble flow ID from signature */
3198                 if (fid != flow_id)                         /* check flow ID against expected */
3199                     continue;                               /* if failed, keep scanning */
3200
3201                 /* matched magic byte, sequence number, flow ID; found the signature */
3202                 return (tgt);                               /* return offset of signature */
3203             }
3204         }
3205     }
3206
3207     /* failed to find the signature, return the original offset as default */
3208     return pay_off;
3209 }
3210
3211 /* utility routine: harvest the signature time stamp from the data frame */
3212 guint64 get_signature_ts(const guint8 *m_ptr,int sig_off, int sig_max)
3213 {
3214     int     ts_offset;
3215     guint64 sig_ts;
3216
3217     if (sig_off + 15 >= sig_max)
3218         return 0;
3219
3220     if (m_ptr[sig_off + 15] == 0xe2)
3221         ts_offset = 5;
3222     else
3223         ts_offset = 8;
3224
3225     sig_ts = pletoh32(&m_ptr[sig_off + ts_offset]);
3226
3227     return (sig_ts & 0xffffffff);
3228 }
3229
3230 static float
3231 get_legacy_rate(guint8 rate_index)
3232 {
3233     /* Rate conversion data */
3234     static const float canonical_rate_legacy[]  = {1.0f, 2.0f, 5.5f, 11.0f, 6.0f, 9.0f, 12.0f, 18.0f, 24.0f, 36.0f, 48.0f, 54.0f};
3235
3236     float bitrate  = 0.0f;
3237
3238     if (rate_index < G_N_ELEMENTS(canonical_rate_legacy))
3239         bitrate =  canonical_rate_legacy[rate_index];
3240
3241     return bitrate;
3242 }
3243
3244 static float
3245 get_ht_rate(guint8 mcs_index, guint16 rflags)
3246 {
3247     /* Rate conversion data */
3248     static const int   canonical_ndbps_20_ht[8]  = {26, 52, 78, 104, 156, 208, 234, 260};
3249     static const int   canonical_ndbps_40_ht[8]  = {54, 108, 162, 216, 324, 432, 486, 540};
3250
3251     float symbol_tx_time, bitrate;
3252     int   ndbps;
3253
3254     if (rflags & FLAGS_CHAN_SHORTGI)
3255         symbol_tx_time = 3.6f;
3256     else
3257         symbol_tx_time = 4.0f;
3258
3259     if (rflags & FLAGS_CHAN_40MHZ)
3260         ndbps = canonical_ndbps_40_ht[mcs_index - 8*(int)(mcs_index/8)];
3261     else
3262         ndbps = canonical_ndbps_20_ht[mcs_index - 8*(int)(mcs_index/8)];
3263
3264     bitrate = (ndbps * (((int)(mcs_index >> 3) + 1))) / symbol_tx_time;
3265
3266     return bitrate;
3267 }
3268
3269 static float
3270 get_vht_rate(guint8 mcs_index, guint16 rflags, guint8 nss)
3271 {
3272     /* Rate conversion data */
3273     static const int   canonical_ndbps_20_vht[9] = {26, 52, 78, 104, 156, 208, 234, 260, 312};
3274     static const int   canonical_ndbps_40_vht[10] = {54, 108, 162, 216, 324, 432, 486, 540, 648, 720};
3275     static const int   canonical_ndbps_80_vht[10] = {117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560};
3276
3277     float symbol_tx_time, bitrate;
3278
3279     if (rflags & FLAGS_CHAN_SHORTGI)
3280         symbol_tx_time = 3.6f;
3281     else
3282         symbol_tx_time = 4.0f;
3283
3284     /*
3285      * Check for the out of range mcs_index.
3286      * Should never happen, but if mcs index is greater than 9 just
3287      * return 0.
3288      */
3289     if (mcs_index > 9)
3290         return 0.0f;
3291     if (rflags & FLAGS_CHAN_40MHZ)
3292         bitrate = (canonical_ndbps_40_vht[mcs_index] * nss) / symbol_tx_time;
3293     else if (rflags & FLAGS_CHAN_80MHZ)
3294         bitrate = (canonical_ndbps_80_vht[mcs_index] * nss) / symbol_tx_time;
3295     else
3296     {
3297         if (mcs_index == 9)
3298         {
3299             /* This is a special case for 20 MHz. */
3300             if (nss == 3)
3301                 bitrate = 1040 / symbol_tx_time;
3302             else if (nss == 6)
3303                 bitrate = 2080 / symbol_tx_time;
3304             else
3305                 bitrate = 0.0f;
3306         }
3307         else
3308             bitrate = (canonical_ndbps_20_vht[mcs_index] * nss) / symbol_tx_time;
3309     }
3310
3311     return bitrate;
3312 }
3313
3314 static gboolean
3315 vwr_process_rec_data(FILE_T fh, int rec_size,
3316                      wtap_rec *record, Buffer *buf, vwr_t *vwr,
3317                      int IS_TX, int log_mode, int *err, gchar **err_info)
3318 {
3319     guint8*   rec;       /* local buffer (holds input record) */
3320     gboolean  ret = FALSE;
3321
3322     rec = (guint8*)g_malloc(B_SIZE);
3323
3324     /* Read over the entire record (frame + trailer) into a local buffer.         */
3325     /* If we don't get it all, then declare an error, we can't process the frame. */
3326     if (!wtap_read_bytes(fh, rec, rec_size, err, err_info))
3327     {
3328         g_free(rec);
3329         return FALSE;
3330     }
3331
3332     /* now format up the frame data */
3333     switch (vwr->FPGA_VERSION)
3334     {
3335         case S1_W_FPGA:
3336             ret = vwr_read_s1_W_rec(vwr, record, buf, rec, rec_size, err, err_info);
3337             break;
3338         case S2_W_FPGA:
3339             ret = vwr_read_s2_W_rec(vwr, record, buf, rec, rec_size, IS_TX, err, err_info);
3340             break;
3341         case S3_W_FPGA:
3342             ret = vwr_read_s3_W_rec(vwr, record, buf, rec, rec_size, IS_TX, log_mode, err, err_info);
3343             break;
3344         case vVW510012_E_FPGA:
3345         case vVW510024_E_FPGA:
3346             ret = vwr_read_rec_data_ethernet(vwr, record, buf, rec, rec_size, IS_TX, err, err_info);
3347             break;
3348         default:
3349             g_free(rec);
3350             g_assert_not_reached();
3351             return ret;
3352     }
3353
3354     g_free(rec);
3355     return ret;
3356 }
3357
3358 /*
3359  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3360  *
3361  * Local variables:
3362  * c-basic-offset: 4
3363  * tab-width: 8
3364  * indent-tabs-mode: nil
3365  * End:
3366  *
3367  * vi: set shiftwidth=4 tabstop=8 expandtab:
3368  * :indentSize=4:tabSize=8:noTabs=true:
3369  */