extcap: Tell utilities the wireshark version
[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 *rec,
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 *rec, 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     /* If the per-file encapsulation isn't known, set it to this packet's encapsulation. */
875     /* If it *is* known, and it isn't this packet's encapsulation, set it to             */
876     /*  WTAP_ENCAP_PER_PACKET, as this file doesn't have a single encapsulation for all  */
877     /*  packets in the file.                                                             */
878     if (wth->file_encap == WTAP_ENCAP_UNKNOWN)
879         wth->file_encap = wth->rec.rec_header.packet_header.pkt_encap;
880     else {
881         if (wth->file_encap != wth->rec.rec_header.packet_header.pkt_encap)
882             wth->file_encap = WTAP_ENCAP_PER_PACKET;
883     }
884
885     return TRUE;
886 }
887
888 /* read a random record in the middle of a file; the start of the record is @ seek_off */
889
890 static gboolean vwr_seek_read(wtap *wth, gint64 seek_off,
891     wtap_rec *record, Buffer *buf, int *err, gchar **err_info)
892 {
893     vwr_t *vwr = (vwr_t *)wth->priv;
894     int    rec_size, IS_TX, log_mode;
895
896     /* first seek to the indicated record header */
897     if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
898         return FALSE;
899
900     /* read in the record header */
901     if (!vwr_read_rec_header(vwr, wth->random_fh, &rec_size, &IS_TX, &log_mode, err, err_info))
902         return FALSE;                                  /* Read error or EOF */
903
904     return vwr_process_rec_data(wth->random_fh, rec_size, record, buf,
905                                 vwr, IS_TX, log_mode, err, err_info);
906 }
907
908 /* Scan down in the input capture file to find the next frame header.       */
909 /* Decode and skip over all non-frame messages that are in the way.         */
910 /* Return TRUE on success, FALSE on EOF or error.                           */
911 /* Also return the frame size in bytes and the "is transmitted frame" flag. */
912
913 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)
914 {
915     int     f_len, v_type;
916     guint8  header[VW_RECORD_HEADER_LENGTH];
917
918     *rec_size = 0;
919
920     /* Read out the file data in 16-byte messages, stopping either after we find a frame,  */
921     /*  or if we run out of data.                                                          */
922     /* Each 16-byte message is decoded; if we run across a non-frame message followed by a */
923     /*  variable-length item, we read the variable length item out and discard it.         */
924     /* If we find a frame, we return (with the header in the passed buffer).               */
925     while (1) {
926         if (!wtap_read_bytes_or_eof(fh, header, VW_RECORD_HEADER_LENGTH, err, err_info))
927             return FALSE;
928
929         /* Got a header; invoke decode-message function to parse and process it.     */
930         /* If the function returns a length, then a frame or variable-length message */
931         /*  follows the 16-byte message.                                             */
932         /* If the variable length message is not a frame, simply skip over it.       */
933         if ((f_len = decode_msg(vwr, header, &v_type, IS_TX, log_mode)) != 0) {
934             if (f_len > B_SIZE) {
935                 *err = WTAP_ERR_BAD_FILE;
936                 *err_info = g_strdup_printf("vwr: Invalid message record length %d", f_len);
937                 return FALSE;
938             }
939             else if (v_type != VT_FRAME) {
940                 if (!wtap_read_bytes(fh, NULL, f_len, err, err_info))
941                     return FALSE;
942             }
943             else {
944                 *rec_size = f_len;
945                 return TRUE;
946             }
947         }
948     }
949 }
950
951 /* Figure out the FPGA version (and also see whether this is a VWR file type. */
952 /* Return FPGA version if it's a known version, UNKNOWN_FPGA if it's not,     */
953 /*  and -1 on an I/O error.                                                   */
954
955 static int vwr_get_fpga_version(wtap *wth, int *err, gchar **err_info)
956 {
957     guint8  *rec;         /* local buffer (holds input record) */
958     guint8   header[VW_RECORD_HEADER_LENGTH];
959     int      rec_size     = 0;
960     guint8   i;
961     guint8  *s_510006_ptr = NULL;
962     guint8  *s_510024_ptr = NULL;
963     guint8  *s_510012_ptr = NULL; /* stats pointers */
964     gint64   filePos      = -1;
965     guint32  frame_type   = 0;
966     int      f_len, v_type;
967     guint16  data_length  = 0;
968     guint16  fpga_version;
969     gboolean valid_but_empty_file = FALSE;
970
971     filePos = file_tell(wth->fh);
972     if (filePos == -1) {
973         *err = file_error(wth->fh, err_info);
974         return -1;
975     }
976
977     fpga_version = 1000;
978     rec = (guint8*)g_malloc(B_SIZE);
979     /* Got a frame record; see if it is vwr  */
980     /* If we don't get it all, then declare an error, we can't process the frame.          */
981     /* Read out the file data in 16-byte messages, stopping either after we find a frame,  */
982     /*  or if we run out of data.                                                          */
983     /* Each 16-byte message is decoded; if we run across a non-frame message followed by a */
984     /*  variable-length item, we read the variable length item out and discard it.         */
985     /* If we find a frame, we return (with the header in the passed buffer).               */
986     while (wtap_read_bytes(wth->fh, header, VW_RECORD_HEADER_LENGTH, err, err_info)) {
987         /* Got a header; invoke decode-message function to parse and process it.     */
988         /* If the function returns a length, then a frame or variable-length message */
989         /*  follows the 16-byte message.                                             */
990         /* If the variable length message is not a frame, simply skip over it.       */
991         if ((f_len = decode_msg(NULL, header, &v_type, NULL, NULL)) != 0) {
992             if (f_len > B_SIZE) {
993                 g_free(rec);
994                 /* Treat this here as an indication that the file probably */
995                 /*  isn't a vwr file. */
996                 return UNKNOWN_FPGA;
997             }
998             else if (v_type != VT_FRAME) {
999                 if (!wtap_read_bytes(wth->fh, NULL, f_len, err, err_info)) {
1000                     g_free(rec);
1001                     if (*err == WTAP_ERR_SHORT_READ)
1002                         return UNKNOWN_FPGA; /* short read - not a vwr file */
1003                     return -1;
1004                 }
1005                 else if (v_type == VT_CPMSG)
1006                     valid_but_empty_file = TRUE;
1007             }
1008             else {
1009                 rec_size = f_len;
1010                 /* Got a frame record; read over entire record (frame + trailer) into a local buffer */
1011                 /* If we don't get it all, assume this isn't a vwr file */
1012                 if (!wtap_read_bytes(wth->fh, rec, rec_size, err, err_info)) {
1013                     g_free(rec);
1014                     if (*err == WTAP_ERR_SHORT_READ)
1015                         return UNKNOWN_FPGA; /* short read - not a vwr file */
1016                     return -1;
1017                 }
1018
1019                 /*  I'll grab the bytes where the Ethernet "octets" field should be and the bytes where */
1020                 /*   the 802.11 "octets" field should be. Then if I do rec_size - octets -              */
1021                 /*   size_of_stats_block and it's 0, I can select the correct type.                     */
1022                 /*  octets + stats_len = rec_size only when octets have been incremented to nearest     */
1023                 /*   number divisible by 4.                                                             */
1024
1025                 /* First check for series I WLAN since the check is more rigorous. */
1026                 if (rec_size > v22_W_STATS_LEN) {
1027                     s_510006_ptr = &(rec[rec_size - v22_W_STATS_LEN]);      /* point to 510006 WLAN */
1028                                                                             /* stats block */
1029
1030                     data_length = pntoh16(&s_510006_ptr[v22_W_OCTET_OFF]);
1031                     i = 0;
1032                     while (((data_length + i) % 4) != 0)
1033                         i = i + 1;
1034
1035                     frame_type = pntoh32(&s_510006_ptr[v22_W_FRAME_TYPE_OFF]);
1036
1037                     if (rec_size == (data_length + v22_W_STATS_LEN + i) && (frame_type & v22_W_IS_80211) == 0x1000000) {
1038                         fpga_version = S1_W_FPGA;
1039                     }
1040                 }
1041
1042                 /* Next for the series I Ethernet */
1043                 if ((rec_size > v22_E_STATS_LEN) && (fpga_version == 1000)) {
1044                     s_510012_ptr = &(rec[rec_size - v22_E_STATS_LEN]);      /* point to 510012 enet */
1045                                                                             /* stats block */
1046                     data_length = pntoh16(&s_510012_ptr[v22_E_OCTET_OFF]);
1047                     i = 0;
1048                     while (((data_length + i) % 4) != 0)
1049                         i = i + 1;
1050
1051                     if (rec_size == (data_length + v22_E_STATS_LEN + i))
1052                         fpga_version = vVW510012_E_FPGA;
1053                 }
1054
1055
1056                 /* Next the series II WLAN */
1057                 if ((rec_size > vVW510021_W_STATS_TRAILER_LEN) && (fpga_version == 1000)) {
1058                     /* stats block */
1059
1060                     if ((header[8] == 48) || (header[8] == 61) || (header[8] == 68))
1061                         fpga_version = S3_W_FPGA;
1062                     else {
1063                         data_length = (256 * (rec[vVW510021_W_MSDU_LENGTH_OFF + 1] & 0x1f)) + rec[vVW510021_W_MSDU_LENGTH_OFF];
1064
1065                         i = 0;
1066                         while (((data_length + i) % 4) != 0)
1067                             i = i + 1;
1068
1069                         /*the 12 is from the 12 bytes of plcp header */
1070                         if (rec_size == (data_length + vVW510021_W_STATS_TRAILER_LEN +vVW510021_W_AFTERHEADER_LEN+12+i))
1071                             fpga_version = S2_W_FPGA;
1072                     }
1073                 }
1074
1075                 /* Finally the Series II Ethernet */
1076                 if ((rec_size > vVW510024_E_STATS_LEN) && (fpga_version == 1000)) {
1077                     s_510024_ptr = &(rec[rec_size - vVW510024_E_STATS_LEN]);    /* point to 510024 ENET */
1078                     data_length = pntoh16(&s_510024_ptr[vVW510024_E_MSDU_LENGTH_OFF]);
1079
1080                     i = 0;
1081                     while (((data_length + i) % 4) != 0)
1082                         i = i + 1;
1083
1084                     if (rec_size == (data_length + vVW510024_E_STATS_LEN + i))
1085                         fpga_version = vVW510024_E_FPGA;
1086                 }
1087
1088                 if (fpga_version != 1000)
1089                 {
1090                     /* reset the file position offset */
1091                     if (file_seek (wth->fh, filePos, SEEK_SET, err) == -1) {
1092                         g_free(rec);
1093                         return (-1);
1094                     }
1095
1096                     /* We found an FPGA that works */
1097                     g_free(rec);
1098                     return fpga_version;
1099                 }
1100             }
1101         }
1102     }
1103
1104     /* Is this a valid but empty file?  If so, claim it's the S3_W_FPGA FPGA. */
1105     if (valid_but_empty_file) {
1106         g_free(rec);
1107         return(S3_W_FPGA);
1108     }
1109
1110     if (*err == WTAP_ERR_SHORT_READ) {
1111         g_free(rec);
1112         return UNKNOWN_FPGA; /* short read - not a vwr file */
1113     }
1114
1115     /*
1116      * Read error.
1117      */
1118     g_free(rec);
1119     return -1;
1120 }
1121
1122 /* Copy the actual packet data from the capture file into the target data block. */
1123 /* The packet is constructed as a 38-byte VeriWave metadata header plus the raw */
1124 /*  MAC octets. */
1125
1126 static gboolean vwr_read_s1_W_rec(vwr_t *vwr, wtap_rec *record,
1127                                   Buffer *buf, const guint8 *rec, int rec_size,
1128                                   int *err, gchar **err_info)
1129 {
1130     guint8           *data_ptr;
1131     int              bytes_written = 0;                   /* bytes output to buf so far */
1132     const guint8     *s_ptr, *m_ptr;                      /* stats pointer */
1133     guint16          msdu_length, actual_octets;          /* octets in frame */
1134     guint16          plcp_hdr_len;                        /* PLCP header length */
1135     guint16          rflags;
1136     guint8           m_type;                              /* mod type (CCK-L/CCK-S/OFDM), seqnum */
1137     guint            flow_seq;
1138     guint64          s_time = LL_ZERO, e_time = LL_ZERO;  /* start/end */
1139                                                           /* times, nsec */
1140     guint32          latency;
1141     guint64          start_time, s_sec, s_usec = LL_ZERO; /* start time, sec + usec */
1142     guint64          end_time;                            /* end time */
1143     guint32          info;                                /* INFO/ERRORS fields in stats blk */
1144     gint8            rssi;                                /* RSSI, signed 8-bit number */
1145     int              f_tx;                                /* flag: if set, is a TX frame */
1146     guint8           rate_index;                          /* pre-HT only */
1147     guint16          vc_id, ht_len=0;                     /* VC ID, total ip length */
1148     guint            flow_id;                             /* flow ID */
1149     guint32          d_time, errors;                      /* packet duration & errors */
1150     int              sig_off, pay_off;                    /* MAC+SNAP header len, signature offset */
1151     guint64          sig_ts;                              /* 32 LSBs of timestamp in signature */
1152     guint16          phyRate;
1153     guint16          vw_flags;                            /* VeriWave-specific packet flags */
1154
1155     /*
1156      * The record data must be large enough to hold the statistics trailer.
1157      */
1158     if (rec_size < v22_W_STATS_LEN) {
1159         *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1160                                     rec_size, v22_W_STATS_LEN);
1161         *err = WTAP_ERR_BAD_FILE;
1162         return FALSE;
1163     }
1164
1165     /* Calculate the start of the statistics block in the buffer */
1166     /* Also get a bunch of fields from the stats block */
1167     s_ptr    = &(rec[rec_size - v22_W_STATS_LEN]); /* point to it */
1168     m_type   = s_ptr[v22_W_MTYPE_OFF] & v22_E_MT_MASK;
1169     f_tx     = !(s_ptr[v22_W_MTYPE_OFF] & v22_E_IS_RX);
1170     actual_octets   = pntoh16(&s_ptr[v22_W_OCTET_OFF]);
1171     vc_id    = pntoh16(&s_ptr[v22_W_VCID_OFF]) & v22_E_VCID_MASK;
1172     flow_seq = s_ptr[v22_W_FLOWSEQ_OFF];
1173
1174     latency = (guint32)pcorey48tohll(&s_ptr[v22_W_LATVAL_OFF]);
1175
1176     flow_id = pntoh16(&s_ptr[v22_W_FLOWID_OFF+1]);  /* only 16 LSBs kept */
1177     errors  = pntoh16(&s_ptr[v22_W_ERRORS_OFF]);
1178
1179     info = pntoh16(&s_ptr[v22_W_INFO_OFF]);
1180     rssi = (s_ptr[v22_W_RSSI_OFF] & 0x80) ? (-1 * (s_ptr[v22_W_RSSI_OFF] & 0x7f)) : s_ptr[v22_W_RSSI_OFF];
1181
1182     /*
1183      * Sanity check the octets field to determine if it's greater than
1184      * the packet data available in the record - i.e., the record size
1185      * minus the length of the statistics block.
1186      *
1187      * Report an error if it is.
1188      */
1189     if (actual_octets > rec_size - v22_W_STATS_LEN) {
1190         *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
1191                                     actual_octets);
1192         *err = WTAP_ERR_BAD_FILE;
1193         return FALSE;
1194     }
1195
1196     /* Decode OFDM or CCK PLCP header and determine rate and short preamble flag. */
1197     /* The SIGNAL byte is always the first byte of the PLCP header in the frame.  */
1198     if (m_type == vwr->MT_OFDM)
1199         rate_index = get_ofdm_rate(rec);
1200     else if ((m_type == vwr->MT_CCKL) || (m_type == vwr->MT_CCKS))
1201         rate_index = get_cck_rate(rec);
1202     else
1203         rate_index = 1;
1204     rflags  = (m_type == vwr->MT_CCKS) ? FLAGS_SHORTPRE : 0;
1205     /* Calculate the MPDU size/ptr stuff; MPDU starts at 4 or 6 depending on OFDM/CCK. */
1206     /* Note that the number of octets in the frame also varies depending on OFDM/CCK,  */
1207     /*  because the PLCP header is prepended to the actual MPDU.                       */
1208     plcp_hdr_len = (m_type == vwr->MT_OFDM) ? 4 : 6;
1209     if (actual_octets >= plcp_hdr_len)
1210        actual_octets -= plcp_hdr_len;
1211     else {
1212         *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include %u-byte PLCP header)",
1213                                     actual_octets, plcp_hdr_len);
1214         *err = WTAP_ERR_BAD_FILE;
1215         return FALSE;
1216     }
1217     m_ptr = &rec[plcp_hdr_len];
1218     msdu_length = actual_octets;
1219
1220     /*
1221      * The MSDU length includes the FCS.
1222      *
1223      * The packet data does *not* include the FCS - it's just 4 bytes
1224      * of junk - so we have to remove it.
1225      *
1226      * We'll be stripping off that junk, so make sure we have at least
1227      * 4 octets worth of packet data.
1228      *
1229      * There seems to be a special case of a length of 0.
1230      */
1231     if (actual_octets < 4) {
1232         if (actual_octets != 0) {
1233             *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include %u-byte PLCP header and 4 bytes of FCS)",
1234                                         actual_octets, plcp_hdr_len);
1235             *err = WTAP_ERR_BAD_FILE;
1236             return FALSE;
1237         }
1238     } else {
1239         actual_octets -= 4;
1240     }
1241
1242     /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
1243     /* 64-bit times are "Corey-endian" */
1244     s_time = pcoreytohll(&s_ptr[v22_W_STARTT_OFF]);
1245     e_time = pcoreytohll(&s_ptr[v22_W_ENDT_OFF]);
1246
1247     /* find the packet duration (difference between start and end times) */
1248     d_time = (guint32)((e_time - s_time) / NS_IN_US);   /* find diff, converting to usec */
1249
1250     /* also convert the packet start time to seconds and microseconds */
1251     start_time = s_time / NS_IN_US;                /* convert to microseconds first  */
1252     s_sec      = (start_time / US_IN_SEC);         /* get the number of seconds      */
1253     s_usec     = start_time - (s_sec * US_IN_SEC); /* get the number of microseconds */
1254
1255     /* also convert the packet end time to seconds and microseconds */
1256     end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
1257
1258     /* extract the 32 LSBs of the signature timestamp field from the data block*/
1259     pay_off = 42;    /* 24 (MAC) + 8 (SNAP) + IP */
1260     sig_off = find_signature(m_ptr, rec_size - 6, pay_off, flow_id, flow_seq);
1261     if (m_ptr[sig_off] == 0xdd)
1262         sig_ts = get_signature_ts(m_ptr, sig_off, rec_size - v22_W_STATS_LEN);
1263     else
1264         sig_ts = 0;
1265
1266     /*
1267      * Fill up the per-packet header.
1268      *
1269      * We include the length of the metadata headers in the packet lengths.
1270      *
1271      * The maximum value of actual_octets is 8191, which, even after
1272      * adding the lengths of the metadata headers, is less than
1273      * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
1274      */
1275     record->rec_header.packet_header.len = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1276     record->rec_header.packet_header.caplen = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1277
1278     record->ts.secs   = (time_t)s_sec;
1279     record->ts.nsecs  = (int)(s_usec * 1000);
1280     record->rec_header.packet_header.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
1281
1282     record->rec_type = REC_TYPE_PACKET;
1283     record->presence_flags = WTAP_HAS_TS;
1284
1285     ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
1286     data_ptr = ws_buffer_start_ptr(buf);
1287
1288     /*
1289      * Generate and copy out the common metadata headers,
1290      * set the port type to 0 (WLAN).
1291      *
1292      * All values are copied out in little-endian byte order.
1293      */
1294     /* 1st octet of record for port_type and command (command is 0, hence RX) */
1295     phtole8(&data_ptr[bytes_written], WLAN_PORT);
1296     bytes_written += 1;
1297     /* 2nd octet of record for fpga version (0, hence pre-OCTO) */
1298     phtole8(&data_ptr[bytes_written], 0);
1299     bytes_written += 1;
1300
1301     phtoles(&data_ptr[bytes_written], STATS_COMMON_FIELDS_LEN); /* it_len */
1302     bytes_written += 2;
1303     phtoles(&data_ptr[bytes_written], msdu_length);
1304     bytes_written += 2;
1305     phtolel(&data_ptr[bytes_written], flow_id);
1306     bytes_written += 4;
1307     phtoles(&data_ptr[bytes_written], vc_id);
1308     bytes_written += 2;
1309     phtoles(&data_ptr[bytes_written], flow_seq);
1310     bytes_written += 2;
1311     if (!f_tx && sig_ts != 0) {
1312         phtolel(&data_ptr[bytes_written], latency);
1313     } else {
1314         phtolel(&data_ptr[bytes_written], 0);
1315     }
1316     bytes_written += 4;
1317     phtolel(&data_ptr[bytes_written], sig_ts); /* 32 LSBs of signature timestamp (nsec) */
1318     bytes_written += 4;
1319     phtolell(&data_ptr[bytes_written], start_time); /* record start & end times of frame */
1320     bytes_written += 8;
1321     phtolell(&data_ptr[bytes_written], end_time);
1322     bytes_written += 8;
1323     phtolel(&data_ptr[bytes_written], d_time);
1324     bytes_written += 4;
1325
1326     /*
1327      * Generate and copy out the WLAN metadata headers.
1328      *
1329      * All values are copied out in little-endian byte order.
1330      */
1331     phtoles(&data_ptr[bytes_written], EXT_WLAN_FIELDS_LEN);
1332     bytes_written += 2;
1333     phtoles(&data_ptr[bytes_written], rflags);
1334     bytes_written += 2;
1335     if (m_type == vwr->MT_OFDM) {
1336         phtoles(&data_ptr[bytes_written], CHAN_OFDM);
1337     } else {
1338         phtoles(&data_ptr[bytes_written], CHAN_CCK);
1339     }
1340     bytes_written += 2;
1341     phyRate = (guint16)(get_legacy_rate(rate_index) * 10);
1342     phtoles(&data_ptr[bytes_written], phyRate);
1343     bytes_written += 2;
1344     data_ptr[bytes_written] = vVW510021_W_PLCP_LEGACY; /* pre-HT */
1345     bytes_written += 1;
1346     data_ptr[bytes_written] = rate_index;
1347     bytes_written += 1;
1348     data_ptr[bytes_written] = 1; /* pre-VHT, so NSS = 1 */
1349     bytes_written += 1;
1350     data_ptr[bytes_written] = rssi;
1351     bytes_written += 1;
1352     /* antennae b, c, d signal power */
1353     data_ptr[bytes_written] = 100;
1354     bytes_written += 1;
1355     data_ptr[bytes_written] = 100;
1356     bytes_written += 1;
1357     data_ptr[bytes_written] = 100;
1358     bytes_written += 1;
1359     /* padding */
1360     data_ptr[bytes_written] = 0;
1361     bytes_written += 1;
1362
1363     /* fill in the VeriWave flags field */
1364     vw_flags = 0;
1365     if (f_tx)
1366         vw_flags |= VW_FLAGS_TXF;
1367     if (errors & vwr->FCS_ERROR)
1368         vw_flags |= VW_FLAGS_FCSERR;
1369     if (!f_tx && (errors & vwr->CRYPTO_ERR))
1370         vw_flags |= VW_FLAGS_DCRERR;
1371     if (!f_tx && (errors & vwr->RETRY_ERR))
1372         vw_flags |= VW_FLAGS_RETRERR;
1373     if (info & vwr->WEPTYPE)
1374         vw_flags |= VW_FLAGS_IS_WEP;
1375     else if (info & vwr->TKIPTYPE)
1376         vw_flags |= VW_FLAGS_IS_TKIP;
1377     else if (info & vwr->CCMPTYPE)
1378         vw_flags |= VW_FLAGS_IS_CCMP;
1379     phtoles(&data_ptr[bytes_written], vw_flags);
1380     bytes_written += 2;
1381
1382     phtoles(&data_ptr[bytes_written], ht_len);
1383     bytes_written += 2;
1384     phtoles(&data_ptr[bytes_written], info);
1385     bytes_written += 2;
1386     phtolel(&data_ptr[bytes_written], errors);
1387     bytes_written += 4;
1388
1389     /*
1390      * Finally, copy the whole MAC frame to the packet buffer as-is.
1391      * This does not include the PLCP; the MPDU starts at 4 or 6
1392      * depending on OFDM/CCK.
1393      * This also does not include the last 4 bytes, as those don't
1394      * contain an FCS, they just contain junk.
1395      */
1396     memcpy(&data_ptr[bytes_written], &rec[plcp_hdr_len], actual_octets);
1397
1398     return TRUE;
1399 }
1400
1401
1402 static gboolean vwr_read_s2_W_rec(vwr_t *vwr, wtap_rec *record,
1403                                   Buffer *buf, const guint8 *rec, int rec_size,
1404                                   int IS_TX, int *err, gchar **err_info)
1405 {
1406     guint8           *data_ptr;
1407     int              bytes_written = 0;                   /* bytes output to buf so far */
1408     const guint8     *s_start_ptr,*s_trail_ptr, *plcp_ptr, *m_ptr; /* stats & MPDU ptr */
1409     guint32          msdu_length, actual_octets;          /* octets in frame */
1410     guint8           l1p_1, l1p_2, plcp_type, rate_mcs_index, nss;  /* mod (CCK-L/CCK-S/OFDM) */
1411     guint            flow_seq;
1412     guint64          s_time = LL_ZERO, e_time = LL_ZERO;  /* start/end */
1413                                                           /*  times, nsec */
1414     guint64          latency = LL_ZERO;
1415     guint64          start_time, s_sec, s_usec = LL_ZERO; /* start time, sec + usec */
1416     guint64          end_time;                            /* end time */
1417     guint16          info;                                /* INFO/ERRORS fields in stats blk */
1418     guint32          errors;
1419     gint8            rssi[] = {0,0,0,0};                  /* RSSI, signed 8-bit number */
1420     int              f_tx;                                /* flag: if set, is a TX frame */
1421     guint16          vc_id, ht_len=0;                     /* VC ID , total ip length*/
1422     guint32          flow_id, d_time;                     /* flow ID, packet duration*/
1423     int              sig_off, pay_off;                    /* MAC+SNAP header len, signature offset */
1424     guint64          sig_ts, tsid;                        /* 32 LSBs of timestamp in signature */
1425     guint16          chanflags = 0;                       /* channel flags for WLAN metadata header */
1426     guint16          radioflags = 0;                      /* flags for WLAN metadata header */
1427     guint64          delta_b;                             /* Used for calculating latency */
1428     float            rate;
1429     guint16          phyRate;
1430     guint16          vw_flags;                            /* VeriWave-specific packet flags */
1431
1432     /*
1433      * The record data must be large enough to hold the statistics header,
1434      * the PLCP, and the statistics trailer.
1435      */
1436     if ((guint)rec_size < vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN) {
1437         *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1438                                     rec_size,
1439                                     vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1440         *err = WTAP_ERR_BAD_FILE;
1441         return FALSE;
1442     }
1443
1444     /* Calculate the start of the statistics blocks in the buffer */
1445     /* Also get a bunch of fields from the stats blocks */
1446     s_start_ptr = &(rec[0]);                              /* point to stats header */
1447     s_trail_ptr = &(rec[rec_size - vVW510021_W_STATS_TRAILER_LEN]);      /* point to stats trailer */
1448
1449     l1p_1 = s_start_ptr[vVW510021_W_L1P_1_OFF];
1450     l1p_2 = s_start_ptr[vVW510021_W_L1P_2_OFF];
1451     plcp_type = vVW510021_W_S2_PLCP_TYPE(l1p_2);
1452     /* we do the range checks at the end before copying the values
1453        into the wtap header */
1454     msdu_length = ((s_start_ptr[vVW510021_W_MSDU_LENGTH_OFF+1] & 0x1f) << 8)
1455                     + s_start_ptr[vVW510021_W_MSDU_LENGTH_OFF];
1456
1457     vc_id = pntoh16(&s_start_ptr[vVW510021_W_VCID_OFF]);
1458     if (IS_TX)
1459     {
1460         rssi[0] = (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x80) ?
1461                    -1 * (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x7f) :
1462                    s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x7f;
1463     }
1464     else
1465     {
1466         rssi[0] = (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF] & 0x80) ?
1467                   (s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF]- 256) :
1468                   s_start_ptr[vVW510021_W_RSSI_TXPOWER_OFF];
1469     }
1470     rssi[1] = 100;
1471     rssi[2] = 100;
1472     rssi[3] = 100;
1473
1474     plcp_ptr = &(rec[8]);
1475
1476     actual_octets = msdu_length;
1477
1478     /*
1479      * Sanity check the octets field to determine if it's greater than
1480      * the packet data available in the record - i.e., the record size
1481      * minus the sum of (length of statistics header + PLCP) and
1482      * (length of statistics trailer).
1483      *
1484      * Report an error if it is.
1485      */
1486     if (actual_octets > rec_size - (vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN)) {
1487         *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
1488                                     actual_octets);
1489         *err = WTAP_ERR_BAD_FILE;
1490         return FALSE;
1491     }
1492
1493     f_tx = IS_TX;
1494     flow_seq = s_trail_ptr[vVW510021_W_FLOWSEQ_OFF];
1495
1496     latency = 0x00000000;                        /* clear latency */
1497     flow_id = pntoh24(&s_trail_ptr[vVW510021_W_FLOWID_OFF]);         /* all 24 bits valid */
1498     /* For tx latency is duration, for rx latency is timestamp */
1499     /* Get 48-bit latency value */
1500     tsid = pcorey48tohll(&s_trail_ptr[vVW510021_W_LATVAL_OFF]);
1501
1502     errors = pntoh32(&s_trail_ptr[vVW510021_W_ERRORS_OFF]);
1503     info = pntoh16(&s_trail_ptr[vVW510021_W_INFO_OFF]);
1504     if ((info & v22_W_AGGREGATE_FLAGS) != 0)
1505     /* this length includes the Start_Spacing + Delimiter + MPDU + Padding for each piece of the aggregate*/
1506         ht_len = pletoh16(&s_start_ptr[vwr->PLCP_LENGTH_OFF]);
1507
1508
1509     /* decode OFDM or CCK PLCP header and determine rate and short preamble flag */
1510     /* the SIGNAL byte is always the first byte of the PLCP header in the frame */
1511     switch (plcp_type)
1512     {
1513     case vVW510021_W_PLCP_LEGACY:
1514         /*
1515          * From IEEE Std 802.11-2012:
1516          *
1517          * According to section 17.2.2 "PPDU format", the PLCP header
1518          * for the High Rate DSSS PHY (11b) has a SIGNAL field that's
1519          * 8 bits, followed by a SERVICE field that's 8 bits, followed
1520          * by a LENGTH field that's 16 bits, followed by a CRC field
1521          * that's 16 bits.  The PSDU follows it.  Section 17.2.3 "PPDU
1522          * field definitions" describes those fields.
1523          *
1524          * According to sections 18.3.2 "PLCP frame format" and 18.3.4
1525          * "SIGNAL field", the PLCP for the OFDM PHY (11a) has a SIGNAL
1526          * field that's 24 bits, followed by a service field that's
1527          * 16 bits, followed by the PSDU.  Section 18.3.5.2 "SERVICE
1528          * field" describes the SERVICE field.
1529          *
1530          * According to section 19.3.2 "PPDU format", the frames for the
1531          * Extended Rate PHY (11g) either extend the 11b format, using
1532          * additional bits in the SERVICE field, or extend the 11a
1533          * format.
1534          */
1535         rate_mcs_index = vVW510021_W_S2_RATE_INDEX(l1p_1);
1536         if (rate_mcs_index < 4) {
1537             chanflags |= CHAN_CCK;
1538         }
1539         else {
1540             chanflags |= CHAN_OFDM;
1541         }
1542         rate = get_legacy_rate(rate_mcs_index);
1543         nss = 0;
1544         break;
1545
1546     case vVW510021_W_PLCP_MIXED:
1547         /*
1548          * According to section 20.3.2 "PPDU format", the HT-mixed
1549          * PLCP header has a "Non-HT SIGNAL field" (L-SIG), which
1550          * looks like an 11a SIGNAL field, followed by an HT SIGNAL
1551          * field (HT-SIG) described in section 20.3.9.4.3 "HT-SIG
1552          * definition".
1553          *
1554          * This means that the first octet of HT-SIG is at
1555          * plcp_ptr[3], skipping the 3 octets of the L-SIG field.
1556          *
1557          * 0x80 is the CBW 20/40 bit of HT-SIG.
1558          */
1559         /* set the appropriate flags to indicate HT mode and CB */
1560         rate_mcs_index = vVW510021_W_S2_MCS_INDEX_HT(l1p_1);
1561         radioflags |= FLAGS_CHAN_HT | ((plcp_ptr[3] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
1562                       ((l1p_1 & vVW510021_W_IS_LONGGI) ? 0 : FLAGS_CHAN_SHORTGI);
1563         chanflags  |= CHAN_OFDM;
1564         nss = (rate_mcs_index < MAX_HT_MCS) ? nss_for_mcs[rate_mcs_index] : 0;
1565         rate = get_ht_rate(rate_mcs_index, radioflags);
1566         break;
1567
1568     case vVW510021_W_PLCP_GREENFIELD:
1569         /*
1570          * According to section 20.3.2 "PPDU format", the HT-greenfield
1571          * PLCP header just has the HT SIGNAL field (HT-SIG) above, with
1572          * no L-SIG field.
1573          *
1574          * This means that the first octet of HT-SIG is at
1575          * plcp_ptr[0], as there's no L-SIG field to skip.
1576          *
1577          * 0x80 is the CBW 20/40 bit of HT-SIG.
1578          */
1579         /* set the appropriate flags to indicate HT mode and CB */
1580         rate_mcs_index = vVW510021_W_S2_MCS_INDEX_HT(l1p_1);
1581         radioflags |= FLAGS_CHAN_HT | ((plcp_ptr[0] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
1582                       ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
1583         chanflags  |= CHAN_OFDM;
1584         nss = (rate_mcs_index < MAX_HT_MCS) ? nss_for_mcs[rate_mcs_index] : 0;
1585         rate = get_ht_rate(rate_mcs_index, radioflags);
1586         break;
1587
1588     case vVW510021_W_PLCP_VHT_MIXED:
1589         /*
1590          * According to section 22.3.2 "VHT PPDU format" of IEEE Std
1591          * 802.11ac-2013, the VHT PLCP header has a "non-HT SIGNAL field"
1592          * (L-SIG), which looks like an 11a SIGNAL field, followed by
1593          * a VHT Signal A field (VHT-SIG-A) described in section
1594          * 22.3.8.3.3 "VHT-SIG-A definition", with training fields
1595          * between it and a VHT Signal B field (VHT-SIG-B) described
1596          * in section 22.3.8.3.6 "VHT-SIG-B definition", followed by
1597          * the PSDU.
1598          */
1599         {
1600             guint8 SBW = vVW510021_W_BANDWIDTH_VHT(l1p_2);
1601             rate_mcs_index = vVW510021_W_S2_MCS_INDEX_VHT(l1p_1);
1602             radioflags |= FLAGS_CHAN_VHT | ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
1603             chanflags |= CHAN_OFDM;
1604             if (SBW == 3)
1605                 radioflags |= FLAGS_CHAN_40MHZ;
1606             else if (SBW == 4)
1607                 radioflags |= FLAGS_CHAN_80MHZ;
1608             nss = vVW510021_W_S2_NSS_VHT(l1p_1);
1609             rate = get_vht_rate(rate_mcs_index, radioflags, nss);
1610         }
1611         break;
1612
1613     default:
1614         rate_mcs_index = 0;
1615         nss = 0;
1616         rate = 0.0f;
1617         break;
1618     }
1619
1620     /*
1621      * The MSDU length includes the FCS.
1622      *
1623      * The packet data does *not* include the FCS - it's just 4 bytes
1624      * of junk - so we have to remove it.
1625      *
1626      * We'll be stripping off that junk, so make sure we have at least
1627      * 4 octets worth of packet data.
1628      *
1629      * There seems to be a special case of a length of 0.
1630      */
1631     if (actual_octets < 4) {
1632         if (actual_octets != 0) {
1633             *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include 4 bytes of FCS)",
1634                                         actual_octets);
1635             *err = WTAP_ERR_BAD_FILE;
1636             return FALSE;
1637         }
1638     } else {
1639         actual_octets -= 4;
1640     }
1641
1642     /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
1643     /* 64-bit times are "Corey-endian" */
1644     s_time = pcoreytohll(&s_trail_ptr[vVW510021_W_STARTT_OFF]);
1645     e_time = pcoreytohll(&s_trail_ptr[vVW510021_W_ENDT_OFF]);
1646
1647     /* find the packet duration (difference between start and end times) */
1648     d_time = (guint32)((e_time - s_time) / NS_IN_US);  /* find diff, converting to usec */
1649
1650     /* also convert the packet start time to seconds and microseconds */
1651     start_time = s_time / NS_IN_US;                     /* convert to microseconds first */
1652     s_sec = (start_time / US_IN_SEC);                   /* get the number of seconds */
1653     s_usec = start_time - (s_sec * US_IN_SEC);          /* get the number of microseconds */
1654
1655     /* also convert the packet end time to seconds and microseconds */
1656     end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
1657
1658     /* extract the 32 LSBs of the signature timestamp field */
1659     m_ptr = &(rec[8+12]);
1660     pay_off = 42;         /* 24 (MAC) + 8 (SNAP) + IP */
1661     sig_off = find_signature(m_ptr, rec_size - 20, pay_off, flow_id, flow_seq);
1662     if (m_ptr[sig_off] == 0xdd)
1663         sig_ts = get_signature_ts(m_ptr, sig_off, rec_size - vVW510021_W_STATS_TRAILER_LEN);
1664     else
1665         sig_ts = 0;
1666
1667     /* Set latency based on rx/tx and signature timestamp */
1668     if (!IS_TX) {
1669         if (tsid < s_time) {
1670             latency = s_time - tsid;
1671           } else {
1672             /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
1673             /* we look for a large difference between l_time and s_time. */
1674             delta_b = tsid - s_time;
1675             if (delta_b >  0x10000000)
1676               latency = 0;
1677             else
1678               latency = delta_b;
1679           }
1680     }
1681
1682     /*
1683      * Fill up the per-packet header.
1684      *
1685      * We include the length of the metadata headers in the packet lengths.
1686      *
1687      * The maximum value of actual_octets is 8191, which, even after
1688      * adding the lengths of the metadata headers, is less than
1689      * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
1690      */
1691     record->rec_header.packet_header.len = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1692     record->rec_header.packet_header.caplen = STATS_COMMON_FIELDS_LEN + EXT_WLAN_FIELDS_LEN + actual_octets;
1693
1694     record->ts.secs   = (time_t)s_sec;
1695     record->ts.nsecs  = (int)(s_usec * 1000);
1696     record->rec_header.packet_header.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
1697
1698     record->rec_type = REC_TYPE_PACKET;
1699     record->presence_flags = WTAP_HAS_TS;
1700
1701     ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
1702     data_ptr = ws_buffer_start_ptr(buf);
1703
1704     /*
1705      * Generate and copy out the common metadata headers,
1706      * set the port type to 0 (WLAN).
1707      *
1708      * All values are copied out in little-endian byte order.
1709      */
1710     /*** msdu_length = msdu_length + 16; ***/
1711     /* 1st octet of record for port_type and command (command is 0, hence RX) */
1712     phtole8(&data_ptr[bytes_written], WLAN_PORT);
1713     bytes_written += 1;
1714     /* 2nd octet of record for fpga version (0, hence pre-OCTO) */
1715     phtole8(&data_ptr[bytes_written], 0);
1716     bytes_written += 1;
1717
1718     phtoles(&data_ptr[bytes_written], STATS_COMMON_FIELDS_LEN); /* it_len */
1719     bytes_written += 2;
1720     phtoles(&data_ptr[bytes_written], msdu_length);
1721     bytes_written += 2;
1722     phtolel(&data_ptr[bytes_written], flow_id);
1723     bytes_written += 4;
1724     phtoles(&data_ptr[bytes_written], vc_id);
1725     bytes_written += 2;
1726     phtoles(&data_ptr[bytes_written], flow_seq);
1727     bytes_written += 2;
1728     if (!f_tx && sig_ts != 0) {
1729         phtolel(&data_ptr[bytes_written], latency);
1730     } else {
1731         phtolel(&data_ptr[bytes_written], 0);
1732     }
1733     bytes_written += 4;
1734     phtolel(&data_ptr[bytes_written], sig_ts); /* 32 LSBs of signature timestamp (nsec) */
1735     bytes_written += 4;
1736     phtolell(&data_ptr[bytes_written], start_time); /* record start & end times of frame */
1737     bytes_written += 8;
1738     phtolell(&data_ptr[bytes_written], end_time);
1739     bytes_written += 8;
1740     phtolel(&data_ptr[bytes_written], d_time);
1741     bytes_written += 4;
1742
1743     /*
1744      * Generate and copy out the WLAN metadata headers.
1745      *
1746      * All values are copied out in little-endian byte order.
1747      */
1748     phtoles(&data_ptr[bytes_written], EXT_WLAN_FIELDS_LEN);
1749     bytes_written += 2;
1750     if (info & vVW510021_W_IS_WEP)
1751         radioflags |= FLAGS_WEP;
1752     if (!(l1p_1 & vVW510021_W_IS_LONGPREAMBLE) && (plcp_type == vVW510021_W_PLCP_LEGACY))
1753         radioflags |= FLAGS_SHORTPRE;
1754     phtoles(&data_ptr[bytes_written], radioflags);
1755     bytes_written += 2;
1756     phtoles(&data_ptr[bytes_written], chanflags);
1757     bytes_written += 2;
1758     phyRate = (guint16)(rate * 10);
1759     phtoles(&data_ptr[bytes_written], phyRate);
1760     bytes_written += 2;
1761
1762     data_ptr[bytes_written] = plcp_type;
1763     bytes_written += 1;
1764
1765     data_ptr[bytes_written] = rate_mcs_index;
1766     bytes_written += 1;
1767
1768     data_ptr[bytes_written] = nss;
1769     bytes_written += 1;
1770     data_ptr[bytes_written] = rssi[0];
1771     bytes_written += 1;
1772     data_ptr[bytes_written] = rssi[1];
1773     bytes_written += 1;
1774     data_ptr[bytes_written] = rssi[2];
1775     bytes_written += 1;
1776     data_ptr[bytes_written] = rssi[3];
1777     bytes_written += 1;
1778     /* padding */
1779     data_ptr[bytes_written] = 0;
1780     bytes_written += 1;
1781
1782     /* fill in the VeriWave flags field */
1783     vw_flags  = 0;
1784     if (f_tx)
1785         vw_flags |= VW_FLAGS_TXF;
1786     if (errors & 0x1f)  /* If any error is flagged, then set the FCS error bit */
1787         vw_flags |= VW_FLAGS_FCSERR;
1788     if (!f_tx && (errors & vwr->CRYPTO_ERR))
1789         vw_flags |= VW_FLAGS_DCRERR;
1790     if (!f_tx && (errors & vwr->RETRY_ERR))
1791         vw_flags |= VW_FLAGS_RETRERR;
1792     if (info & vwr->WEPTYPE)
1793         vw_flags |= VW_FLAGS_IS_WEP;
1794     else if (info & vwr->TKIPTYPE)
1795         vw_flags |= VW_FLAGS_IS_TKIP;
1796     else if (info & vwr->CCMPTYPE)
1797         vw_flags |= VW_FLAGS_IS_CCMP;
1798     phtoles(&data_ptr[bytes_written], vw_flags);
1799     bytes_written += 2;
1800
1801     phtoles(&data_ptr[bytes_written], ht_len);
1802     bytes_written += 2;
1803     phtoles(&data_ptr[bytes_written], info);
1804     bytes_written += 2;
1805     phtolel(&data_ptr[bytes_written], errors);
1806     bytes_written += 4;
1807
1808     /* Finally, copy the whole MAC frame to the packet buffer as-is.
1809      * This does not include the stats header or the PLCP.
1810      * This also does not include the last 4 bytes, as those don't
1811      * contain an FCS, they just contain junk.
1812      */
1813     memcpy(&data_ptr[bytes_written], &rec[vwr->MPDU_OFF], actual_octets);
1814
1815     return TRUE;
1816 }
1817
1818 static gboolean vwr_read_s3_W_rec(vwr_t *vwr, wtap_rec *record,
1819                                   Buffer *buf, const guint8 *rec, int rec_size,
1820                                   int IS_TX, int log_mode, int *err,
1821                                   gchar **err_info)
1822 {
1823     guint8           *data_ptr;
1824     int              bytes_written = 0;                  /* bytes output to buf so far */
1825     int              i;
1826     int              stats_offset = 0;
1827     const guint8     *s_start_ptr = NULL,*s_trail_ptr = NULL, *plcp_ptr, *m_ptr; /* stats & MPDU ptr */
1828     guint32          msdu_length = 0, actual_octets = 0; /* octets in frame */
1829     guint8           l1p_1 = 0,l1p_2 = 0, plcp_type, rate_mcs_index, nss;   /* mod (CCK-L/CCK-S/OFDM) */
1830     guint64          s_time = LL_ZERO, e_time = LL_ZERO; /* start/end */
1831                                                          /* times, nsec */
1832     guint64          latency = LL_ZERO;
1833     guint64          start_time = 0, s_sec = 0, s_usec = LL_ZERO; /* start time, sec + usec */
1834     guint64          end_time = 0;                                /* end time */
1835     guint16          info = 0;                           /* INFO/ERRORS fields in stats blk */
1836     guint32          errors = 0;
1837     gint8            info_2nd = 0,rssi[] = {0,0,0,0};    /* RSSI, signed 8-bit number */
1838     int              frame_size;
1839     guint32          d_time = 0, flow_id = 0;            /* packet duration, Flow Signature ID*/
1840     int              sig_off, pay_off;                   /* MAC+SNAP header len, signature offset */
1841     guint64          sig_ts = 0, tsid;                   /* 32 LSBs of timestamp in signature */
1842     guint64          delta_b;                            /* Used for calculating latency */
1843     guint8           L1InfoC,port_type,ver_fpga = 0;
1844     guint8           flow_seq =0,plcp_hdr_flag = 0,rf_id = 0;    /* indicates plcp hdr info */
1845     const guint8    *rf_ptr = NULL;
1846     float            rate;
1847     guint16          phyRate;
1848
1849     /*
1850      * The record data must be large enough to hold the statistics header,
1851      * the PLCP, and the statistics trailer.
1852      */
1853     if (IS_TX == 3) {       /*IS_TX =3, i.e., command type is RF Modified*/
1854         if ((guint)rec_size < OCTO_MODIFIED_RF_LEN) {
1855             *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1856                                         rec_size,
1857                                         OCTO_MODIFIED_RF_LEN);
1858             *err = WTAP_ERR_BAD_FILE;
1859             return FALSE;
1860         }
1861         rf_ptr = &(rec[0]);
1862         rf_id = rf_ptr[0];
1863
1864         /*
1865          * Fill up the per-packet header.
1866          *
1867          * We include the length of the metadata headers in the packet lengths.
1868          *
1869          * OCTO_MODIFIED_RF_LEN + 1 is less than WTAP_MAX_PACKET_SIZE_STANDARD will
1870          * ever be, so we don't need to check it.
1871          */
1872         record->rec_header.packet_header.len = OCTO_MODIFIED_RF_LEN + 1;       /* 1st octet is reserved for detecting type of frame while displaying in wireshark */
1873         record->rec_header.packet_header.caplen = OCTO_MODIFIED_RF_LEN + 1;
1874
1875         record->ts.secs   = (time_t)s_sec;
1876         record->ts.nsecs  = (int)(s_usec * 1000);
1877         record->rec_header.packet_header.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
1878
1879         record->rec_type = REC_TYPE_PACKET;
1880         record->presence_flags = WTAP_HAS_TS;
1881
1882         ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
1883         data_ptr = ws_buffer_start_ptr(buf);
1884
1885         port_type = IS_TX << 4;
1886
1887         nss = 0;
1888         phyRate = 0;
1889     }
1890     else {
1891         /* Calculate the start of the statistics blocks in the buffer */
1892         /* Also get a bunch of fields from the stats blocks */
1893         /* 'stats_offset' variable is use to locate the exact offset.
1894          * When a RX frame contrains RF,
1895          * the postion of Stats, Layer 1-4, PLCP parameters are shifted to
1896          * + OCTO_RF_MOD_ACTUAL_LEN bytes
1897          */
1898         if (IS_TX == 4)     /*IS_TX =4, i.e., command type is RF-RX Modified*/
1899         {
1900             stats_offset = OCTO_RF_MOD_ACTUAL_LEN;
1901             if ((guint)rec_size < stats_offset + 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                                             stats_offset + vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1905                 *err = WTAP_ERR_BAD_FILE;
1906                 return FALSE;
1907             }
1908             rf_ptr = &(rec[0]);
1909             rf_id = rf_ptr[0];
1910         }
1911         else
1912         {
1913             stats_offset = 0;
1914             if ((guint)rec_size < vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN) {
1915                 *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)",
1916                                             rec_size,
1917                                             vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1918                 *err = WTAP_ERR_BAD_FILE;
1919                 return FALSE;
1920             }
1921         }
1922
1923         s_start_ptr = &(rec[stats_offset]);         /* point to stats header */
1924         s_trail_ptr = &(rec[rec_size - vVW510021_W_STATS_TRAILER_LEN] );      /* point to stats trailer */
1925
1926         l1p_1 = s_start_ptr[vVW510021_W_L1P_1_OFF];
1927         l1p_2 = s_start_ptr[vVW510021_W_L1P_2_OFF];
1928
1929         plcp_type = vVW510021_W_S3_PLCP_TYPE(l1p_2);
1930         switch (plcp_type)
1931         {
1932         case vVW510021_W_PLCP_LEGACY:
1933             /* pre-HT */
1934             rate_mcs_index = vVW510021_W_S3_RATE_INDEX(l1p_1);
1935             nss = 0;
1936             break;
1937
1938         case vVW510021_W_PLCP_MIXED:
1939         case vVW510021_W_PLCP_GREENFIELD:
1940             rate_mcs_index = vVW510021_W_S3_MCS_INDEX_HT(l1p_1);
1941             nss = (rate_mcs_index < MAX_HT_MCS) ? nss_for_mcs[rate_mcs_index] : 0;
1942             break;
1943
1944         case vVW510021_W_PLCP_VHT_MIXED:
1945             rate_mcs_index = vVW510021_W_S3_MCS_INDEX_VHT(l1p_1);
1946             nss = vVW510021_W_S3_NSS_VHT(l1p_1);
1947             plcp_hdr_flag = 1;
1948             break;
1949
1950         default:
1951             rate_mcs_index = 0;
1952             nss = 0;
1953             plcp_hdr_flag = 0;
1954             break;
1955         }
1956
1957         for (i = 0; i < 4; i++)
1958         {
1959             if (IS_TX == 1)
1960             {
1961                 rssi[i] = (s_start_ptr[4+i] & 0x80) ? -1 * (s_start_ptr[4+i] & 0x7f) : s_start_ptr[4+i] & 0x7f;
1962             }
1963             else
1964             {
1965                 rssi[i] = (s_start_ptr[4+i] >= 128) ? (s_start_ptr[4+i] - 256) : s_start_ptr[4+i];
1966             }
1967         }
1968
1969         if (IS_TX == 0 || IS_TX == 4){
1970             L1InfoC = s_start_ptr[8];
1971         }
1972
1973         msdu_length = pntoh24(&s_start_ptr[9]);
1974
1975         /*** 16 bytes of PLCP header + 1 byte of L1P for user position ***/
1976         plcp_ptr = &(rec[stats_offset+16]);
1977
1978         /*** Add the PLCP length for S3_W_FPGA version VHT frames for Beamforming decode ***/
1979         if (log_mode == 3) {
1980             frame_size = rec_size - (stats_offset + vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN);
1981             if (frame_size > ((int) msdu_length))
1982                 actual_octets = msdu_length;
1983             else {
1984                 /*
1985                  * XXX - does this mean "the packet was cut short during
1986                  * capture" or "this is a malformed record"?
1987                  */
1988                 actual_octets = frame_size;
1989             }
1990         }
1991         else
1992         {
1993             actual_octets = msdu_length;
1994         }
1995         /*
1996          * Sanity check the octets field to determine if it's greater than
1997          * the packet data available in the record - i.e., the record size
1998          * minus the sum of (length of statistics header + PLCP) and
1999          * (length of statistics trailer).
2000          *
2001          * Report an error if it is.
2002          */
2003         if (actual_octets > rec_size - (stats_offset + vwr->MPDU_OFF + vVW510021_W_STATS_TRAILER_LEN)) {
2004             *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
2005                                         actual_octets);
2006             *err = WTAP_ERR_BAD_FILE;
2007             return FALSE;
2008         }
2009
2010         flow_seq = s_trail_ptr[vVW510021_W_FLOWSEQ_OFF];
2011
2012         latency = 0x00000000;                        /* clear latency */
2013         flow_id = pntoh24(&s_trail_ptr[vVW510021_W_FLOWID_OFF]);         /* all 24 bits valid */
2014         /* For tx latency is duration, for rx latency is timestamp */
2015         /* Get 48-bit latency value */
2016         tsid = pcorey48tohll(&s_trail_ptr[vVW510021_W_LATVAL_OFF]);
2017
2018         errors = pntoh32(&s_trail_ptr[vVW510021_W_ERRORS_OFF]);
2019         info = pntoh16(&s_trail_ptr[vVW510021_W_INFO_OFF]);
2020
2021         if (IS_TX == 0 || IS_TX == 4)
2022             info_2nd = s_trail_ptr[41];
2023
2024         /*** Calculate Data rate based on
2025         *  PLCP type, MCS index and number of spatial stream
2026         *  radioflags is temporarily calculated, which is used in
2027         *  get_ht_rate() and get_vht_rate().
2028         **/
2029         switch (plcp_type)
2030         {
2031         case vVW510021_W_PLCP_LEGACY:
2032             rate = get_legacy_rate(rate_mcs_index);
2033             break;
2034
2035         case vVW510021_W_PLCP_MIXED:
2036             /*
2037              * According to section 20.3.2 "PPDU format", the HT-mixed
2038              * PLCP header has a "Non-HT SIGNAL field" (L-SIG), which
2039              * looks like an 11a SIGNAL field, followed by an HT SIGNAL
2040              * field (HT-SIG) described in section 20.3.9.4.3 "HT-SIG
2041              * definition".
2042              *
2043              * This means that the first octet of HT-SIG is at
2044              * plcp_ptr[3], skipping the 3 octets of the L-SIG field.
2045              *
2046              * 0x80 is the CBW 20/40 bit of HT-SIG.
2047              */
2048             {
2049                 /* set the appropriate flags to indicate HT mode and CB */
2050                 guint16 radioflags = FLAGS_CHAN_HT | ((plcp_ptr[3] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
2051                                    ((l1p_1 & vVW510021_W_IS_LONGGI) ? 0 : FLAGS_CHAN_SHORTGI);
2052                 rate = get_ht_rate(rate_mcs_index, radioflags);
2053             }
2054             break;
2055
2056         case vVW510021_W_PLCP_GREENFIELD:
2057             /*
2058              * According to section 20.3.2 "PPDU format", the HT-greenfield
2059              * PLCP header just has the HT SIGNAL field (HT-SIG) above, with
2060              * no L-SIG field.
2061              *
2062              * This means that the first octet of HT-SIG is at
2063              * plcp_ptr[0], as there's no L-SIG field to skip.
2064              *
2065              * 0x80 is the CBW 20/40 bit of HT-SIG.
2066              */
2067             {
2068                 /* set the appropriate flags to indicate HT mode and CB */
2069                 guint16 radioflags = FLAGS_CHAN_HT | ((plcp_ptr[0] & 0x80) ? FLAGS_CHAN_40MHZ : 0) |
2070                                    ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
2071                 rate = get_ht_rate(rate_mcs_index, radioflags);
2072             }
2073             break;
2074
2075         case vVW510021_W_PLCP_VHT_MIXED:
2076             /*
2077              * According to section 22.3.2 "VHT PPDU format" of IEEE Std
2078              * 802.11ac-2013, the VHT PLCP header has a "non-HT SIGNAL field"
2079              * (L-SIG), which looks like an 11a SIGNAL field, followed by
2080              * a VHT Signal A field (VHT-SIG-A) described in section
2081              * 22.3.8.3.3 "VHT-SIG-A definition", with training fields
2082              * between it and a VHT Signal B field (VHT-SIG-B) described
2083              * in section 22.3.8.3.6 "VHT-SIG-B definition", followed by
2084              * the PSDU.
2085              */
2086             {
2087                 guint8 SBW = vVW510021_W_BANDWIDTH_VHT(l1p_2);
2088                 guint16 radioflags = FLAGS_CHAN_VHT | ((l1p_1 & vVW510021_W_IS_LONGGI) ?  0 : FLAGS_CHAN_SHORTGI);
2089                 if (SBW == 3)
2090                     radioflags |= FLAGS_CHAN_40MHZ;
2091                 else if (SBW == 4)
2092                     radioflags |= FLAGS_CHAN_80MHZ;
2093                 rate = get_vht_rate(rate_mcs_index, radioflags, nss);
2094             }
2095             break;
2096
2097         default:
2098             rate = 0.0f;
2099             break;
2100         }
2101         phyRate = (guint16)(rate * 10);
2102         /* Calculation of Data rate ends*/
2103
2104         /* 'ver_fpga' is the 2nd Octet of each frame.
2105          * msb/lsb nibble indicates log mode/fpga version respectively.
2106          * where log mode = 0 is normal capture and 1 is reduced capture,
2107          * lsb nibble is set to 1 always as this function is applicable for only FPGA version >= 48
2108          */
2109         if (log_mode == 3) {
2110             if (frame_size >= (int) msdu_length) {
2111                 /*
2112                  * The MSDU length includes the FCS.
2113                  *
2114                  * The packet data does *not* include the FCS - it's just 4
2115                  * bytes of junk - so we have to remove it.
2116                  *
2117                  * We'll be stripping off that junk, so make sure we have at
2118                  * least 4 octets worth of packet data.
2119                  *
2120                  * XXX - is the FCS actually present here, as it appears to be
2121                  * if log_mode isn't 3?
2122                  *
2123                  * There seems to be a special case of a length of 0.
2124                  */
2125                 if (actual_octets < 4) {
2126                     if (actual_octets != 0) {
2127                         *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include 4 bytes of FCS)",
2128                                                     actual_octets);
2129                         *err = WTAP_ERR_BAD_FILE;
2130                         return FALSE;
2131                     }
2132                 } else {
2133                     actual_octets -= 4;
2134                 }
2135             }
2136             ver_fpga = 0x11;
2137         } else {
2138             ver_fpga = 0x01;
2139         }
2140
2141         /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
2142         /* 64-bit times are "Corey-endian" */
2143         s_time = pcoreytohll(&s_trail_ptr[vVW510021_W_STARTT_OFF]);
2144         e_time = pcoreytohll(&s_trail_ptr[vVW510021_W_ENDT_OFF]);
2145
2146         /* find the packet duration (difference between start and end times) */
2147         d_time = (guint32)((e_time - s_time) / NS_IN_US);  /* find diff, converting to usec */
2148
2149         /* also convert the packet start time to seconds and microseconds */
2150         start_time = s_time / NS_IN_US;                     /* convert to microseconds first */
2151         s_sec = (start_time / US_IN_SEC);                   /* get the number of seconds */
2152         s_usec = start_time - (s_sec * US_IN_SEC);          /* get the number of microseconds */
2153
2154         /* also convert the packet end time to seconds and microseconds */
2155         end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
2156
2157         /* extract the 32 LSBs of the signature timestamp field */
2158         m_ptr = &(rec[stats_offset+8+12]);
2159         pay_off = 42;         /* 24 (MAC) + 8 (SNAP) + IP */
2160         sig_off = find_signature(m_ptr, rec_size - 20, pay_off, flow_id, flow_seq);
2161         if (m_ptr[sig_off] == 0xdd)
2162             sig_ts = get_signature_ts(m_ptr, sig_off, rec_size - vVW510021_W_STATS_TRAILER_LEN);
2163         else
2164             sig_ts = 0;
2165
2166         /* Set latency based on rx/tx and signature timestamp */
2167         if (IS_TX == 0 || IS_TX == 4) {
2168             if (tsid < s_time) {
2169                 latency = s_time - tsid;
2170             } else {
2171                 /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
2172                 /* we look for a large difference between l_time and s_time. */
2173                 delta_b = tsid - s_time;
2174                 if (delta_b >  0x10000000)
2175                     latency = 0;
2176                 else
2177                     latency = delta_b;
2178             }
2179         }
2180
2181         port_type = IS_TX << 4;
2182
2183         /*
2184          * Fill up the per-packet header.
2185          *
2186          * We include the length of the metadata headers in the packet lengths.
2187          */
2188         if (IS_TX == 4) {
2189             record->rec_header.packet_header.len = OCTO_MODIFIED_RF_LEN + OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2190             record->rec_header.packet_header.caplen = OCTO_MODIFIED_RF_LEN + OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2191         } else {
2192             record->rec_header.packet_header.len = OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2193             record->rec_header.packet_header.caplen = OCTO_TIMESTAMP_FIELDS_LEN + OCTO_LAYER1TO4_LEN + actual_octets;
2194         }
2195         if (record->rec_header.packet_header.caplen > WTAP_MAX_PACKET_SIZE_STANDARD) {
2196             /*
2197              * Probably a corrupt capture file; return an error,
2198              * so that our caller doesn't blow up trying to allocate
2199              * space for an immensely-large packet.
2200              */
2201             *err_info = g_strdup_printf("vwr: File has %u-byte packet, bigger than maximum of %u",
2202                                         record->rec_header.packet_header.caplen, WTAP_MAX_PACKET_SIZE_STANDARD);
2203             *err = WTAP_ERR_BAD_FILE;
2204             return FALSE;
2205         }
2206
2207         record->ts.secs   = (time_t)s_sec;
2208         record->ts.nsecs  = (int)(s_usec * 1000);
2209         record->rec_header.packet_header.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
2210
2211         record->rec_type = REC_TYPE_PACKET;
2212         record->presence_flags = WTAP_HAS_TS;
2213
2214         ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
2215         data_ptr = ws_buffer_start_ptr(buf);
2216     }
2217
2218     /*
2219      * Generate and copy out the common metadata headers,
2220      * set the port type to port_type (XXX).
2221      *
2222      * All values are copied out in little-endian byte order.
2223      */
2224     /*** msdu_length = msdu_length + 16; ***/
2225
2226     /* 1st octet of record for port_type and other crud */
2227     phtole8(&data_ptr[bytes_written], port_type);
2228     bytes_written += 1;
2229
2230     if (IS_TX != 3) {
2231         phtole8(&data_ptr[bytes_written], ver_fpga); /* 2nd octet of record for FPGA version*/
2232         bytes_written += 1;
2233
2234         phtoles(&data_ptr[bytes_written], OCTO_TIMESTAMP_FIELDS_LEN); /* it_len */
2235         bytes_written += 2;
2236
2237     /*** Time Collapsible header started***/
2238         if (IS_TX == 1 && sig_ts != 0) {
2239             phtolel(&data_ptr[bytes_written], latency);
2240         } else {
2241             phtolel(&data_ptr[bytes_written], 0);
2242         }
2243         bytes_written += 4;
2244         phtolel(&data_ptr[bytes_written], sig_ts); /* 32 LSBs of signature timestamp (nsec) */
2245         bytes_written += 4;
2246         phtolell(&data_ptr[bytes_written], start_time); /* record start & end times of frame */
2247         bytes_written += 8;
2248         phtolell(&data_ptr[bytes_written], end_time);
2249         bytes_written += 8;
2250         phtolel(&data_ptr[bytes_written], d_time);
2251         bytes_written += 4;
2252     /*** Time Collapsible header ends ***/
2253     }
2254
2255     /*** RF Collapsable header starts***/
2256     if (IS_TX == 3 || IS_TX == 4) {
2257         phtole8(&data_ptr[bytes_written], rf_id);
2258         bytes_written += 1;
2259         data_ptr[bytes_written] = 0;
2260         bytes_written += 1;
2261         data_ptr[bytes_written] = 0;
2262         bytes_written += 1;
2263         data_ptr[bytes_written] = 0;
2264         bytes_written += 1;
2265
2266         /*** NOISE for all 4 Ports ***/
2267         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2268         {
2269             if (pntoh16(&rf_ptr[RF_PORT_1_NOISE_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2270                 phtoles(&data_ptr[bytes_written], 0);
2271                 bytes_written += 2;
2272             } else {
2273                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_NOISE_OFF+i*RF_INTER_PORT_GAP_OFF];
2274                 bytes_written += 1;
2275                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_NOISE_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2276                 bytes_written += 1;
2277             }
2278         }
2279
2280         /*** SNR for all 4 Ports ***/
2281         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2282         {
2283             if (pntoh16(&rf_ptr[RF_PORT_1_SNR_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2284                 phtoles(&data_ptr[bytes_written], 0);
2285                 bytes_written += 2;
2286             } else {
2287                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_SNR_OFF+i*RF_INTER_PORT_GAP_OFF];
2288                 bytes_written += 1;
2289                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_SNR_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2290                 bytes_written += 1;
2291             }
2292         }
2293
2294         /*** PFE for all 4 Ports ***/
2295         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2296         {
2297             if (pntoh16(&rf_ptr[RF_PORT_1_PFE_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2298                 phtoles(&data_ptr[bytes_written], 0);
2299                 bytes_written += 2;
2300             } else {
2301                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_PFE_OFF+i*RF_INTER_PORT_GAP_OFF];
2302                 bytes_written += 1;
2303                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_PFE_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2304                 bytes_written += 1;
2305             }
2306         }
2307
2308         /*** EVM SIG Data for all 4 Ports ***/
2309         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2310         {
2311             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SD_SIG_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2312                 phtoles(&data_ptr[bytes_written], 0);
2313                 bytes_written += 2;
2314             } else {
2315                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_SIG_OFF+i*RF_INTER_PORT_GAP_OFF];
2316                 bytes_written += 1;
2317                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_SIG_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2318                 bytes_written += 1;
2319             }
2320         }
2321
2322         /*** EVM SIG PILOT for all 4 Ports ***/
2323         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2324         {
2325             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SP_SIG_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2326                 phtoles(&data_ptr[bytes_written], 0);
2327                 bytes_written += 2;
2328             } else {
2329                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_SIG_OFF+i*RF_INTER_PORT_GAP_OFF];
2330                 bytes_written += 1;
2331                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_SIG_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2332                 bytes_written += 1;
2333             }
2334         }
2335
2336         /*** EVM Data Data for all 4 Ports ***/
2337         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2338         {
2339             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SD_DATA_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2340                 phtoles(&data_ptr[bytes_written], 0);
2341                 bytes_written += 2;
2342             } else {
2343                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_DATA_OFF+i*RF_INTER_PORT_GAP_OFF];
2344                 bytes_written += 1;
2345                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SD_DATA_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2346                 bytes_written += 1;
2347             }
2348         }
2349
2350         /*** EVM Data PILOT for all 4 Ports ***/
2351         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2352         {
2353             if (pntoh16(&rf_ptr[RF_PORT_1_EVM_SP_DATA_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2354                 phtoles(&data_ptr[bytes_written], 0);
2355                 bytes_written += 2;
2356             } else {
2357                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_DATA_OFF+i*RF_INTER_PORT_GAP_OFF];
2358                 bytes_written += 1;
2359                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_EVM_SP_DATA_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2360                 bytes_written += 1;
2361             }
2362         }
2363
2364         /*** EVM WORST SYMBOL for all 4 Ports ***/
2365         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2366         {
2367             if (pntoh16(&rf_ptr[RF_PORT_1_DSYMBOL_IDX_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2368                 phtoles(&data_ptr[bytes_written], 0);
2369                 bytes_written += 2;
2370             } else {
2371                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_DSYMBOL_IDX_OFF+i*RF_INTER_PORT_GAP_OFF];
2372                 bytes_written += 1;
2373                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_DSYMBOL_IDX_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2374                 bytes_written += 1;
2375             }
2376         }
2377
2378         /*** CONTEXT_P for all 4 Ports ***/
2379         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2380         {
2381             if (pntoh16(&rf_ptr[RF_PORT_1_CONTEXT_OFF+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2382                 phtoles(&data_ptr[bytes_written], 0);
2383                 bytes_written += 2;
2384             } else {
2385                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_CONTEXT_OFF+i*RF_INTER_PORT_GAP_OFF];
2386                 bytes_written += 1;
2387                 data_ptr[bytes_written] = rf_ptr[RF_PORT_1_CONTEXT_OFF+1+i*RF_INTER_PORT_GAP_OFF];
2388                 bytes_written += 1;
2389             }
2390         }
2391
2392         /*** FOR rest 24 RF data bytes are commented for future use ***/
2393 /***
2394         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2395         {
2396             if (pntoh16(&rf_ptr[20+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2397                 phtoles(&data_ptr[bytes_written], 0);
2398                 bytes_written += 2;
2399             } else {
2400                 data_ptr[bytes_written] = rf_ptr[20+i*RF_INTER_PORT_GAP_OFF];
2401                 bytes_written += 1;
2402                 data_ptr[bytes_written] = rf_ptr[21+i*RF_INTER_PORT_GAP_OFF];
2403                 bytes_written += 1;
2404             }
2405         }
2406         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2407         {
2408             if (pntoh16(&rf_ptr[24+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2409                 phtoles(&data_ptr[bytes_written], 0);
2410                 bytes_written += 2;
2411             } else {
2412                 data_ptr[bytes_written] = rf_ptr[24+i*RF_INTER_PORT_GAP_OFF];
2413                 bytes_written += 1;
2414                 data_ptr[bytes_written] = rf_ptr[25+i*RF_INTER_PORT_GAP_OFF];
2415                 bytes_written += 1;
2416             }
2417         }
2418         for (i = 0; i < RF_NUMBER_OF_PORTS; i++)
2419         {
2420             if (pntoh16(&rf_ptr[26+i*RF_INTER_PORT_GAP_OFF]) == 0) {
2421                 phtoles(&data_ptr[bytes_written], 0);
2422                 bytes_written += 2;
2423             } else {
2424                 data_ptr[bytes_written] = rf_ptr[26+i*RF_INTER_PORT_GAP_OFF];
2425                 bytes_written += 1;
2426                 data_ptr[bytes_written] = rf_ptr[27+i*RF_INTER_PORT_GAP_OFF];
2427                 bytes_written += 1;
2428             }
2429         }
2430 ***/
2431     }
2432     /*** RF Collapsable header ends***/
2433
2434     if (IS_TX != 3) {
2435         /*
2436          * Generate and copy out the WLAN metadata headers.
2437          *
2438          * All values are copied out in little-endian byte order.
2439          */
2440         phtoles(&data_ptr[bytes_written], OCTO_LAYER1TO4_LEN);
2441         bytes_written += 2;
2442
2443         /*** Layer-1 Collapsible header started***/
2444         data_ptr[bytes_written] = l1p_1;
2445         bytes_written += 1;
2446
2447         data_ptr[bytes_written] = (nss << 4) | IS_TX;
2448         bytes_written += 1;
2449
2450         phtoles(&data_ptr[bytes_written], phyRate);     /* To dosplay Data rate based on the PLCP type & MCS*/
2451         bytes_written += 2;
2452
2453         data_ptr[bytes_written] = l1p_2;
2454         bytes_written += 1;
2455
2456         data_ptr[bytes_written] = rssi[0];
2457         bytes_written += 1;
2458         data_ptr[bytes_written] = rssi[1];
2459         bytes_written += 1;
2460         data_ptr[bytes_written] = rssi[2];
2461         bytes_written += 1;
2462         data_ptr[bytes_written] = rssi[3];
2463         bytes_written += 1;
2464
2465         /* padding may not be required for S3_W*/
2466
2467         data_ptr[bytes_written] = s_start_ptr[2];    /*** For Signal Bandwidth Mask ***/
2468         bytes_written += 1;
2469         data_ptr[bytes_written] = s_start_ptr[3];    /*** For Antenna Port Energy Detect and MU_MASK ***/
2470         bytes_written += 1;
2471
2472         if (plcp_hdr_flag == 1 && (IS_TX == 0 || IS_TX == 4)) {
2473             data_ptr[bytes_written] = L1InfoC;  /*** For Other plcp type = VHT ***/
2474         } else {
2475             data_ptr[bytes_written] = 0;    /*** For Other plcp type, this offset is set to 0***/
2476         }
2477         bytes_written += 1;
2478
2479         phtoles(&data_ptr[bytes_written], msdu_length);
2480         bytes_written += 2;
2481         /*** Layer-1 Collapsible header Ends ***/
2482
2483         /*** PLCP Collapsible header Starts ***/
2484         memcpy(&data_ptr[bytes_written], &rec[stats_offset+16], 16);
2485         bytes_written += 16;
2486         /*** PLCP Collapsible header Ends ***/
2487
2488         /*** Layer 2-4 Collapsible header Starts ***/
2489
2490         phtolel(&data_ptr[bytes_written], pntoh32(&s_start_ptr[12]));   /*** This 4 bytes includes BM,BV,CV,BSSID and ClientID ***/
2491         bytes_written += 4;
2492         phtoles(&data_ptr[bytes_written], pntoh16(&s_trail_ptr[20]));   /*** 2 bytes includes FV,QT,HT,L4V,TID and WLAN type ***/
2493         bytes_written += 2;
2494         data_ptr[bytes_written] = flow_seq;
2495         bytes_written += 1;
2496         phtole24(&data_ptr[bytes_written], flow_id);
2497         bytes_written += 3;
2498         phtoles(&data_ptr[bytes_written], pntoh16(&s_trail_ptr[28]));   /*** 2 bytes for Layer 4 ID ***/
2499         bytes_written += 2;
2500         phtolel(&data_ptr[bytes_written], pntoh32(&s_trail_ptr[24]));   /*** 4 bytes for Payload Decode ***/
2501         bytes_written += 4;
2502
2503         /*** Incase of RX, Info has 3 bytes of data, whereas for TX, 2 bytes ***/
2504         if (IS_TX == 0 || IS_TX == 4) {
2505             phtoles(&data_ptr[bytes_written], info);
2506             bytes_written += 2;
2507             data_ptr[bytes_written] = info_2nd;
2508             bytes_written += 1;
2509         }
2510         else {
2511             phtoles(&data_ptr[bytes_written], info);
2512             bytes_written += 2;
2513             data_ptr[bytes_written] = 0;
2514             bytes_written += 1;
2515         }
2516
2517         phtolel(&data_ptr[bytes_written], errors);
2518         bytes_written += 4;
2519         /*** Layer 2-4 Collapsible header Ends ***/
2520
2521         /* Finally, copy the whole MAC frame to the packet buffer as-is.
2522          * This does not include the stats header or the PLCP.
2523          * This also does not include the last 4 bytes, as those don't
2524          * contain an FCS, they just contain junk.
2525          */
2526         memcpy(&data_ptr[bytes_written], &rec[stats_offset+(vwr->MPDU_OFF)], actual_octets);
2527     }
2528
2529     return TRUE;
2530 }
2531
2532 /* read an Ethernet packet */
2533 /* Copy the actual packet data from the capture file into the target data block.         */
2534 /* The packet is constructed as a 38-byte VeriWave-extended Radiotap header plus the raw */
2535 /*  MAC octets.                                                                          */
2536 static gboolean vwr_read_rec_data_ethernet(vwr_t *vwr, wtap_rec *record,
2537                                            Buffer *buf, const guint8 *rec,
2538                                            int rec_size, int IS_TX, int *err,
2539                                            gchar **err_info)
2540 {
2541     guint8           *data_ptr;
2542     int              bytes_written = 0;                   /* bytes output to buf so far */
2543     const guint8 *s_ptr, *m_ptr;                          /* stats and MPDU pointers */
2544     guint16          msdu_length, actual_octets;          /* octets in frame */
2545     guint            flow_seq;                            /* seqnum */
2546     guint64          s_time = LL_ZERO, e_time = LL_ZERO;  /* start/end */
2547                                                           /* times, nsec */
2548     guint32          latency = 0;
2549     guint64          start_time, s_sec = LL_ZERO, s_usec = LL_ZERO; /* start time, sec + usec */
2550     guint64          end_time;                            /* end time */
2551     guint            l4id;
2552     guint16          info, validityBits;                  /* INFO/ERRORS fields in stats */
2553     guint32          errors;
2554     guint16          vc_id;                               /* VC ID, total (incl of aggregates) */
2555     guint32          flow_id, d_time;                     /* packet duration */
2556     int              f_flow;                              /* flags: flow valid */
2557     guint32          frame_type;                          /* frame type field */
2558     int              mac_len, sig_off, pay_off;           /* MAC header len, signature offset */
2559     /* XXX - the code here fetched tsid, but never used it! */
2560     guint64          sig_ts/*, tsid*/;                    /* 32 LSBs of timestamp in signature */
2561     guint64          delta_b;                             /* Used for calculating latency */
2562     guint16          vw_flags;                            /* VeriWave-specific packet flags */
2563
2564     if ((guint)rec_size < vwr->STATS_LEN) {
2565         *err_info = g_strdup_printf("vwr: Invalid record length %d (must be at least %u)", rec_size, vwr->STATS_LEN);
2566         *err = WTAP_ERR_BAD_FILE;
2567         return FALSE;
2568     }
2569
2570     /* Calculate the start of the statistics block in the buffer. */
2571     /* Also get a bunch of fields from the stats block.           */
2572     m_ptr = &(rec[0]);                              /* point to the data block */
2573     s_ptr = &(rec[rec_size - vwr->STATS_LEN]);      /* point to the stats block */
2574
2575     msdu_length = pntoh16(&s_ptr[vwr->OCTET_OFF]);
2576     actual_octets = msdu_length;
2577
2578     /*
2579      * Sanity check the octets field to determine if it's greater than
2580      * the packet data available in the record - i.e., the record size
2581      * minus the length of the statistics block.
2582      *
2583      * Report an error if it is.
2584      */
2585     if (actual_octets > rec_size - vwr->STATS_LEN) {
2586         *err_info = g_strdup_printf("vwr: Invalid data length %u (runs past the end of the record)",
2587                                     actual_octets);
2588         *err = WTAP_ERR_BAD_FILE;
2589         return FALSE;
2590     }
2591
2592     vc_id = pntoh16(&s_ptr[vwr->VCID_OFF]) & vwr->VCID_MASK;
2593     flow_seq   = s_ptr[vwr->FLOWSEQ_OFF];
2594     frame_type = pntoh32(&s_ptr[vwr->FRAME_TYPE_OFF]);
2595
2596     if (vwr->FPGA_VERSION == vVW510024_E_FPGA) {
2597         validityBits = pntoh16(&s_ptr[vwr->VALID_OFF]);
2598         f_flow = validityBits & vwr->FLOW_VALID;
2599
2600         mac_len = (validityBits & vwr->IS_VLAN) ? 16 : 14;           /* MAC hdr length based on VLAN tag */
2601
2602
2603         errors = pntoh16(&s_ptr[vwr->ERRORS_OFF]);
2604     }
2605     else {
2606         f_flow  = s_ptr[vwr->VALID_OFF] & vwr->FLOW_VALID;
2607         mac_len = (frame_type & vwr->IS_VLAN) ? 16 : 14;             /* MAC hdr length based on VLAN tag */
2608
2609         /* for older fpga errors is only represented by 16 bits) */
2610         errors = pntoh16(&s_ptr[vwr->ERRORS_OFF]);
2611     }
2612
2613     info = pntoh16(&s_ptr[vwr->INFO_OFF]);
2614     /*  24 LSBs */
2615     flow_id = pntoh24(&s_ptr[vwr->FLOWID_OFF]);
2616
2617 #if 0
2618     /* For tx latency is duration, for rx latency is timestamp. */
2619     /* Get 64-bit latency value. */
2620     tsid = pcorey48tohll(&s_ptr[vwr->LATVAL_OFF]);
2621 #endif
2622
2623     l4id = pntoh16(&s_ptr[vwr->L4ID_OFF]);
2624
2625     /*
2626      * The MSDU length includes the FCS.
2627      *
2628      * The packet data does *not* include the FCS - it's just 4 bytes
2629      * of junk - so we have to remove it.
2630      *
2631      * We'll be stripping off that junk, so make sure we have at least
2632      * 4 octets worth of packet data.
2633      *
2634      * There seems to be a special case of a length of 0.
2635      */
2636     if (actual_octets < 4) {
2637         if (actual_octets != 0) {
2638             *err_info = g_strdup_printf("vwr: Invalid data length %u (too short to include 4 bytes of FCS)",
2639                                         actual_octets);
2640             *err = WTAP_ERR_BAD_FILE;
2641             return FALSE;
2642         }
2643     } else {
2644         actual_octets -= 4;
2645     }
2646
2647     /* Calculate start & end times (in sec/usec), converting 64-bit times to usec. */
2648     /* 64-bit times are "Corey-endian"                                             */
2649     s_time = pcoreytohll(&s_ptr[vwr->STARTT_OFF]);
2650     e_time = pcoreytohll(&s_ptr[vwr->ENDT_OFF]);
2651
2652     /* find the packet duration (difference between start and end times) */
2653     d_time = (guint32)((e_time - s_time));  /* find diff, leaving in nsec for Ethernet */
2654
2655     /* also convert the packet start time to seconds and microseconds */
2656     start_time = s_time / NS_IN_US;                     /* convert to microseconds first */
2657     s_sec = (start_time / US_IN_SEC);                   /* get the number of seconds */
2658     s_usec = start_time - (s_sec * US_IN_SEC);          /* get the number of microseconds */
2659
2660     /* also convert the packet end time to seconds and microseconds */
2661     end_time = e_time / NS_IN_US;                       /* convert to microseconds first */
2662
2663     if (frame_type & vwr->IS_TCP)                       /* signature offset for TCP frame */
2664     {
2665         pay_off = mac_len + 40;
2666     }
2667     else if (frame_type & vwr->IS_UDP)                  /* signature offset for UDP frame */
2668     {
2669         pay_off = mac_len + 28;
2670     }
2671     else if (frame_type & vwr->IS_ICMP)                 /* signature offset for ICMP frame */
2672     {
2673         pay_off = mac_len + 24;
2674     }
2675     else if (frame_type & vwr->IS_IGMP)                 /* signature offset for IGMPv2 frame */
2676     {
2677         pay_off = mac_len + 28;
2678     }
2679     else                                                /* signature offset for raw IP frame */
2680     {
2681         pay_off = mac_len + 20;
2682     }
2683
2684     sig_off = find_signature(m_ptr, rec_size, pay_off, flow_id, flow_seq);
2685     if ((m_ptr[sig_off] == 0xdd) && (f_flow != 0))
2686         sig_ts = get_signature_ts(m_ptr, sig_off, msdu_length);
2687     else
2688         sig_ts = 0;
2689
2690     /* Set latency based on rx/tx and signature timestamp */
2691     if (!IS_TX) {
2692         if (sig_ts < s_time) {
2693             latency = (guint32)(s_time - sig_ts);
2694         } else {
2695             /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
2696             /*  we look for a large difference between l_time and s_time.                       */
2697             delta_b = sig_ts - s_time;
2698             if (delta_b >  0x10000000) {
2699                 latency = 0;
2700             } else
2701                 latency = (guint32)delta_b;
2702         }
2703     }
2704
2705     /*
2706      * Fill up the per-packet header.
2707      *
2708      * We include the length of the metadata headers in the packet lengths.
2709      *
2710      * The maximum value of actual_octets is 65535, which, even after
2711      * adding the lengths of the metadata headers, is less than
2712      * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
2713      */
2714     record->rec_header.packet_header.len = STATS_COMMON_FIELDS_LEN + EXT_ETHERNET_FIELDS_LEN + actual_octets;
2715     record->rec_header.packet_header.caplen = STATS_COMMON_FIELDS_LEN + EXT_ETHERNET_FIELDS_LEN + actual_octets;
2716
2717     record->ts.secs   = (time_t)s_sec;
2718     record->ts.nsecs  = (int)(s_usec * 1000);
2719     record->rec_header.packet_header.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
2720
2721     record->rec_type = REC_TYPE_PACKET;
2722     record->presence_flags = WTAP_HAS_TS;
2723
2724     /*etap_hdr.vw_ip_length = (guint16)ip_len;*/
2725
2726     ws_buffer_assure_space(buf, record->rec_header.packet_header.caplen);
2727     data_ptr = ws_buffer_start_ptr(buf);
2728
2729     /*
2730      * Generate and copy out the common metadata headers,
2731      * set the port type to 1 (Ethernet).
2732      *
2733      * All values are copied out in little-endian byte order.
2734      */
2735     /* 1st octet of record for port_type and command (command is 0, hence RX) */
2736     phtole8(&data_ptr[bytes_written], ETHERNET_PORT);
2737     bytes_written += 1;
2738     /* 2nd octet of record for fpga version (Ethernet, hence non-OCTO) */
2739     phtole8(&data_ptr[bytes_written], 0);
2740     bytes_written += 1;
2741
2742     phtoles(&data_ptr[bytes_written], STATS_COMMON_FIELDS_LEN);
2743     bytes_written += 2;
2744     phtoles(&data_ptr[bytes_written], msdu_length);
2745     bytes_written += 2;
2746     phtolel(&data_ptr[bytes_written], flow_id);
2747     bytes_written += 4;
2748     phtoles(&data_ptr[bytes_written], vc_id);
2749     bytes_written += 2;
2750     phtoles(&data_ptr[bytes_written], flow_seq);
2751     bytes_written += 2;
2752     if (!IS_TX && (sig_ts != 0)) {
2753         phtolel(&data_ptr[bytes_written], latency);
2754     } else {
2755         phtolel(&data_ptr[bytes_written], 0);
2756     }
2757     bytes_written += 4;
2758     phtolel(&data_ptr[bytes_written], sig_ts);
2759     bytes_written += 4;
2760     phtolell(&data_ptr[bytes_written], start_time)                  /* record start & end times of frame */
2761     bytes_written += 8;
2762     phtolell(&data_ptr[bytes_written], end_time);
2763     bytes_written += 8;
2764     phtolel(&data_ptr[bytes_written], d_time);
2765     bytes_written += 4;
2766
2767     /*
2768      * Generate and copy out the Ethernet metadata headers.
2769      *
2770      * All values are copied out in little-endian byte order.
2771      */
2772     phtoles(&data_ptr[bytes_written], EXT_ETHERNET_FIELDS_LEN);
2773     bytes_written += 2;
2774     vw_flags = 0;
2775     if (IS_TX)
2776         vw_flags |= VW_FLAGS_TXF;
2777     if (errors & vwr->FCS_ERROR)
2778         vw_flags |= VW_FLAGS_FCSERR;
2779     phtoles(&data_ptr[bytes_written], vw_flags);
2780     bytes_written += 2;
2781     phtoles(&data_ptr[bytes_written], info);
2782     bytes_written += 2;
2783     phtolel(&data_ptr[bytes_written], errors);
2784     bytes_written += 4;
2785     phtolel(&data_ptr[bytes_written], l4id);
2786     bytes_written += 4;
2787
2788     /* Add in pad */
2789     phtolel(&data_ptr[bytes_written], 0);
2790     bytes_written += 4;
2791
2792     /*
2793      * Finally, copy the whole MAC frame to the packet buffer as-is.
2794      * This also does not include the last 4 bytes, as those don't
2795      * contain an FCS, they just contain junk.
2796      */
2797     memcpy(&data_ptr[bytes_written], m_ptr, actual_octets);
2798
2799     return TRUE;
2800 }
2801
2802 /*--------------------------------------------------------------------------------------*/
2803 /* utility to split up and decode a 16-byte message record */
2804
2805 static int decode_msg(vwr_t *vwr, guint8 *rec, int *v_type, int *IS_TX, int *log_mode)
2806 {
2807     guint8  cmd,fpga_log_mode;          /* components of message */
2808     guint32 wd2, wd3;
2809     int     v_size;                     /* size of var-len message */
2810
2811     /* break up the message record into its pieces */
2812     cmd = rec[0];
2813     fpga_log_mode = rec[1];
2814     fpga_log_mode = ((fpga_log_mode & 0x30) >> 4);
2815
2816     wd2 = pntoh32(&rec[8]);
2817     wd3 = pntoh32(&rec[12]);
2818
2819     if (vwr != NULL)
2820         *log_mode = fpga_log_mode;          /* Log mode = 3, when MPDU data is reduced */
2821
2822     /* now decode based on the command byte */
2823     switch (cmd) {
2824         case COMMAND_RX:
2825             if (vwr != NULL) {
2826                 *IS_TX = 0;
2827             }
2828             v_size  = (int)(wd2 & 0xffff);
2829             *v_type = VT_FRAME;
2830             break;
2831
2832         case COMMAND_TX:
2833             if (vwr != NULL) {
2834                 *IS_TX = 1;
2835             }
2836             v_size  = (int)(wd2 & 0xffff);
2837             *v_type = VT_FRAME;
2838             break;
2839
2840 /*
2841         case COMMAND_RFN:
2842             if (vwr != NULL) {
2843                 *IS_TX = 3;
2844             }
2845             v_size  = (int)(wd2 & 0xffff);
2846             *v_type = VT_FRAME;
2847             break;
2848 */
2849
2850         case COMMAND_RF:   /* For RF Modified only */
2851             if (vwr != NULL) {
2852                 *IS_TX = 3;
2853             }
2854             v_size  = (int)(wd2 & 0xffff);
2855             *v_type = VT_FRAME;
2856             break;
2857
2858         case COMMAND_RFRX: /* For RF_RX Modified only */
2859             if (vwr != NULL) {
2860                 *IS_TX = 4;
2861             }
2862             v_size  = (int)(wd2 & 0xffff);
2863             *v_type = VT_FRAME;
2864             break;
2865
2866         case 0xc1:
2867         case 0x8b:
2868         case 0xbb:
2869             if (vwr != NULL) {
2870                 *IS_TX = 2;
2871             }
2872             v_size  = (int)(wd2 & 0xffff);
2873             *v_type = VT_CPMSG;
2874             break;
2875
2876         case 0xfe:
2877             if (vwr != NULL) {
2878                 *IS_TX = 2;
2879             }
2880             v_size  = (int)(wd3 & 0xffff);
2881             *v_type = VT_CPMSG;
2882             break;
2883
2884         default:
2885             if (vwr != NULL) {
2886                 *IS_TX = 2;
2887             }
2888             v_size  = 0;
2889             *v_type = VT_UNKNOWN;
2890             break;
2891     }
2892
2893     return v_size;
2894 }
2895
2896
2897 /*---------------------------------------------------------------------------------------*/
2898 /* Utilities to extract and decode the PHY bit rate from 802.11 PLCP headers (OFDM/CCK). */
2899 /* They are passed a pointer to 4 or 6 consecutive bytes of PLCP header.                 */
2900 /* The integer returned by the get_xxx_rate() functions is in units of 0.5 Mb/s.         */
2901 /* The string returned by the decode_xxx_rate() functions is 3 characters wide.          */
2902
2903 static guint8 get_ofdm_rate(const guint8 *plcp)
2904 {
2905     /* extract the RATE field (LS nibble of first byte) then convert it to the MCS index used by the L1p fields */
2906     switch (plcp[0] & 0x0f) {
2907         case 0x0b:  return  4;
2908         case 0x0f:  return  5;
2909         case 0x0a:  return  6;
2910         case 0x0e:  return  7;
2911         case 0x09:  return  8;
2912         case 0x0d:  return  9;
2913         case 0x08:  return 10;
2914         case 0x0c:  return 11;
2915         default:    return  0;
2916     }
2917 }
2918
2919 static guint8 get_cck_rate(const guint8 *plcp)
2920 {
2921     /* extract rate from the SIGNAL field then convert it to the MCS index used by the L1p fields */
2922     switch (plcp[0]) {
2923         case 0x0a:  return 0;
2924         case 0x14:  return 1;
2925         case 0x37:  return 2;
2926         case 0x6e:  return 3;
2927         default:    return 0;
2928     }
2929 }
2930
2931 /*--------------------------------------------------------------------------------------*/
2932 /* utility to set up offsets and bitmasks for decoding the stats blocks */
2933
2934 static void setup_defaults(vwr_t *vwr, guint16 fpga)
2935 {
2936     switch (fpga) {
2937         /* WLAN frames */
2938         case S2_W_FPGA:
2939             vwr->STATS_LEN          = vVW510021_W_STATS_TRAILER_LEN;
2940
2941             vwr->VALID_OFF          = vVW510021_W_VALID_OFF;
2942             vwr->MTYPE_OFF          = vVW510021_W_MTYPE_OFF;
2943             vwr->VCID_OFF           = vVW510021_W_VCID_OFF;
2944             vwr->FLOWSEQ_OFF        = vVW510021_W_FLOWSEQ_OFF;
2945             vwr->FLOWID_OFF         = vVW510021_W_FLOWID_OFF;
2946
2947             /*vwr->OCTET_OFF        = v22_W_OCTET_OFF;*/
2948
2949             vwr->ERRORS_OFF         = vVW510021_W_ERRORS_OFF;
2950             vwr->PATN_OFF           = vVW510021_W_MATCH_OFF;
2951             vwr->RSSI_OFF           = vVW510021_W_RSSI_TXPOWER_OFF;
2952             vwr->STARTT_OFF         = vVW510021_W_STARTT_OFF;
2953             vwr->ENDT_OFF           = vVW510021_W_ENDT_OFF;
2954             vwr->LATVAL_OFF         = vVW510021_W_LATVAL_OFF;
2955             vwr->INFO_OFF           = vVW510021_W_INFO_OFF;
2956             vwr->FPGA_VERSION_OFF   = S2_W_FPGA_VERSION_OFF;
2957             vwr->HEADER_VERSION_OFF = vVW510021_W_HEADER_VERSION_OFF;
2958             vwr->OCTET_OFF          = vVW510021_W_MSDU_LENGTH_OFF;
2959             vwr->L1P_1_OFF          = vVW510021_W_L1P_1_OFF;
2960             vwr->L1P_2_OFF          = vVW510021_W_L1P_2_OFF;
2961             vwr->L4ID_OFF           = vVW510021_W_L4ID_OFF;
2962             vwr->IPLEN_OFF          = vVW510021_W_IPLEN_OFF;
2963             vwr->PLCP_LENGTH_OFF    = vVW510021_W_PLCP_LENGTH_OFF;
2964
2965             vwr->MT_MASK            = vVW510021_W_SEL_MASK;
2966             vwr->MCS_INDEX_MASK     = vVW510021_W_MCS_MASK;
2967             vwr->VCID_MASK          = 0xffff;
2968             vwr->FLOW_VALID         = vVW510021_W_FLOW_VALID;
2969             vwr->STATS_START_OFF    = vVW510021_W_HEADER_LEN;
2970             vwr->FCS_ERROR          = vVW510021_W_FCS_ERROR;
2971             vwr->CRYPTO_ERR         = v22_W_CRYPTO_ERR;
2972             vwr->RETRY_ERR          = v22_W_RETRY_ERR;
2973
2974             /*vwr->STATS_START_OFF  = 0;*/
2975
2976             vwr->RXTX_OFF           = vVW510021_W_RXTX_OFF;
2977
2978             vwr->MT_10_HALF         = 0;
2979             vwr->MT_10_FULL         = 0;
2980             vwr->MT_100_HALF        = 0;
2981             vwr->MT_100_FULL        = 0;
2982             vwr->MT_1G_HALF         = 0;
2983             vwr->MT_1G_FULL         = 0;
2984             vwr->MT_CCKL            = v22_W_MT_CCKL;
2985             vwr->MT_CCKS            = v22_W_MT_CCKS;
2986             /*vwr->MT_OFDM          = vVW510021_W_MT_OFDM;*/
2987
2988             vwr->WEPTYPE            = vVW510021_W_WEPTYPE;
2989             vwr->TKIPTYPE           = vVW510021_W_TKIPTYPE;
2990             vwr->CCMPTYPE           = vVW510021_W_CCMPTYPE;
2991
2992             vwr->FRAME_TYPE_OFF     =   vVW510021_W_FRAME_TYPE_OFF;
2993             vwr->IS_TCP             =   vVW510021_W_IS_TCP;
2994             vwr->IS_UDP             =   vVW510021_W_IS_UDP;
2995             vwr->IS_ICMP            =   vVW510021_W_IS_ICMP;
2996             vwr->IS_IGMP            =   vVW510021_W_IS_IGMP;
2997             vwr->IS_QOS             =   vVW510021_W_QOS_VALID;
2998
2999             /*
3000              * vVW510021_W_STATS_HEADER_LEN = 8 is:
3001              *
3002              *    2 bytes of l1p_1/l1p_2;
3003              *    1 byte of RSSI;
3004              *    2 bytes of MSDU length + other bits
3005              *    1 byte of XXX;
3006              *    2 bytes of VCID.
3007              *
3008              * The 12 is for 11 bytes of PLCP and 1 byte of pad
3009              * before the data.
3010              */
3011             vwr->MPDU_OFF           = vVW510021_W_STATS_HEADER_LEN + 12;
3012
3013             break;
3014
3015         case S3_W_FPGA:
3016             vwr->STATS_LEN       = vVW510021_W_STATS_TRAILER_LEN;
3017             vwr->PLCP_LENGTH_OFF = 16;
3018
3019             /*
3020              * The 16 + 16 is:
3021              *
3022              *    2 bytes of l1p_1/l1p_2;
3023              *    1 byte of signal bandwidth mask;
3024              *    1 byte of antenna port energy;
3025              *    4 bytes of per-antenna RSSI;
3026              *    1 byte of L1InfoC;
3027              *    3 bytes of MSDU length;
3028              *    4 bytes of something;
3029              *   16 bytes of PLCP.
3030              */
3031             vwr->MPDU_OFF        = 16 + 16;
3032
3033             break;
3034
3035         case vVW510012_E_FPGA:
3036             vwr->STATS_LEN      = v22_E_STATS_LEN;
3037
3038             vwr->VALID_OFF      = v22_E_VALID_OFF;
3039             vwr->MTYPE_OFF      = v22_E_MTYPE_OFF;
3040             vwr->VCID_OFF       = v22_E_VCID_OFF;
3041             vwr->FLOWSEQ_OFF    = v22_E_FLOWSEQ_OFF;
3042             vwr->FLOWID_OFF     = v22_E_FLOWID_OFF;
3043             vwr->OCTET_OFF      = v22_E_OCTET_OFF;
3044             vwr->ERRORS_OFF     = v22_E_ERRORS_OFF;
3045             vwr->PATN_OFF       = v22_E_PATN_OFF;
3046             vwr->RSSI_OFF       = v22_E_RSSI_OFF;
3047             vwr->STARTT_OFF     = v22_E_STARTT_OFF;
3048             vwr->ENDT_OFF       = v22_E_ENDT_OFF;
3049             vwr->LATVAL_OFF     = v22_E_LATVAL_OFF;
3050             vwr->INFO_OFF       = v22_E_INFO_OFF;
3051             vwr->L4ID_OFF       = v22_E_L4ID_OFF;
3052
3053             vwr->IS_RX          = v22_E_IS_RX;
3054             vwr->MT_MASK        = v22_E_MT_MASK;
3055             vwr->VCID_MASK      = v22_E_VCID_MASK;
3056             vwr->FLOW_VALID     = v22_E_FLOW_VALID;
3057             vwr->FCS_ERROR      = v22_E_FCS_ERROR;
3058
3059             vwr->RX_DECRYPTS    = v22_E_RX_DECRYPTS;
3060             vwr->TX_DECRYPTS    = v22_E_TX_DECRYPTS;
3061             vwr->FC_PROT_BIT    = v22_E_FC_PROT_BIT;
3062
3063             vwr->MT_10_HALF     = v22_E_MT_10_HALF;
3064             vwr->MT_10_FULL     = v22_E_MT_10_FULL;
3065             vwr->MT_100_HALF    = v22_E_MT_100_HALF;
3066             vwr->MT_100_FULL    = v22_E_MT_100_FULL;
3067             vwr->MT_1G_HALF     = v22_E_MT_1G_HALF;
3068             vwr->MT_1G_FULL     = v22_E_MT_1G_FULL;
3069             vwr->MT_CCKL        = 0;
3070             vwr->MT_CCKS        = 0;
3071             vwr->MT_OFDM        = 0;
3072
3073             vwr->FRAME_TYPE_OFF =  v22_E_FRAME_TYPE_OFF;
3074             vwr->IS_TCP         =   v22_E_IS_TCP;
3075             vwr->IS_UDP         =   v22_E_IS_UDP;
3076             vwr->IS_ICMP        =   v22_E_IS_ICMP;
3077             vwr->IS_IGMP        =   v22_E_IS_IGMP;
3078             vwr->IS_QOS         =   v22_E_IS_QOS;
3079             vwr->IS_VLAN        =   v22_E_IS_VLAN;
3080
3081             break;
3082
3083             /* WLAN frames */
3084         case S1_W_FPGA:
3085             vwr->STATS_LEN          = v22_W_STATS_LEN;
3086
3087             vwr->MTYPE_OFF          = v22_W_MTYPE_OFF;
3088             vwr->VALID_OFF          = v22_W_VALID_OFF;
3089             vwr->VCID_OFF           = v22_W_VCID_OFF;
3090             vwr->FLOWSEQ_OFF        = v22_W_FLOWSEQ_OFF;
3091             vwr->FLOWID_OFF         = v22_W_FLOWID_OFF;
3092             vwr->OCTET_OFF          = v22_W_OCTET_OFF;
3093             vwr->ERRORS_OFF         = v22_W_ERRORS_OFF;
3094             vwr->PATN_OFF           = v22_W_PATN_OFF;
3095             vwr->RSSI_OFF           = v22_W_RSSI_OFF;
3096             vwr->STARTT_OFF         = v22_W_STARTT_OFF;
3097             vwr->ENDT_OFF           = v22_W_ENDT_OFF;
3098             vwr->LATVAL_OFF         = v22_W_LATVAL_OFF;
3099             vwr->INFO_OFF           = v22_W_INFO_OFF;
3100             vwr->L4ID_OFF           = v22_W_L4ID_OFF;
3101             vwr->IPLEN_OFF          = v22_W_IPLEN_OFF;
3102             vwr->PLCP_LENGTH_OFF    = v22_W_PLCP_LENGTH_OFF;
3103
3104             vwr->FCS_ERROR          = v22_W_FCS_ERROR;
3105             vwr->CRYPTO_ERR         = v22_W_CRYPTO_ERR;
3106             vwr->PAYCHK_ERR         = v22_W_PAYCHK_ERR;
3107             vwr->RETRY_ERR          = v22_W_RETRY_ERR;
3108             vwr->IS_RX              = v22_W_IS_RX;
3109             vwr->MT_MASK            = v22_W_MT_MASK;
3110             vwr->VCID_MASK          = v22_W_VCID_MASK;
3111             vwr->FLOW_VALID         = v22_W_FLOW_VALID;
3112
3113             vwr->RX_DECRYPTS        = v22_W_RX_DECRYPTS;
3114             vwr->TX_DECRYPTS        = v22_W_TX_DECRYPTS;
3115             vwr->FC_PROT_BIT        = v22_W_FC_PROT_BIT;
3116
3117             vwr->MT_10_HALF         = 0;
3118             vwr->MT_10_FULL         = 0;
3119             vwr->MT_100_HALF        = 0;
3120             vwr->MT_100_FULL        = 0;
3121             vwr->MT_1G_HALF         = 0;
3122             vwr->MT_1G_FULL         = 0;
3123             vwr->MT_CCKL            = v22_W_MT_CCKL;
3124             vwr->MT_CCKS            = v22_W_MT_CCKS;
3125             vwr->MT_OFDM            = v22_W_MT_OFDM;
3126
3127             vwr->WEPTYPE            = v22_W_WEPTYPE;
3128             vwr->TKIPTYPE           = v22_W_TKIPTYPE;
3129             vwr->CCMPTYPE           = v22_W_CCMPTYPE;
3130
3131             vwr->FRAME_TYPE_OFF     =   v22_W_FRAME_TYPE_OFF;
3132             vwr->IS_TCP             =   v22_W_IS_TCP;
3133             vwr->IS_UDP             =   v22_W_IS_UDP;
3134             vwr->IS_ICMP            =   v22_W_IS_ICMP;
3135             vwr->IS_IGMP            =   v22_W_IS_IGMP;
3136             vwr->IS_QOS             =   v22_W_IS_QOS;
3137
3138             break;
3139
3140         /* Ethernet frames */
3141         case vVW510024_E_FPGA:
3142             vwr->STATS_LEN          = vVW510024_E_STATS_LEN;
3143
3144             vwr->VALID_OFF          = vVW510024_E_VALID_OFF;
3145             vwr->VCID_OFF           = vVW510024_E_VCID_OFF;
3146             vwr->FLOWSEQ_OFF        = vVW510024_E_FLOWSEQ_OFF;
3147             vwr->FLOWID_OFF         = vVW510024_E_FLOWID_OFF;
3148             vwr->OCTET_OFF          = vVW510024_E_MSDU_LENGTH_OFF;
3149             vwr->ERRORS_OFF         = vVW510024_E_ERRORS_OFF;
3150             vwr->PATN_OFF           = vVW510024_E_MATCH_OFF;
3151             vwr->STARTT_OFF         = vVW510024_E_STARTT_OFF;
3152             vwr->ENDT_OFF           = vVW510024_E_ENDT_OFF;
3153             vwr->LATVAL_OFF         = vVW510024_E_LATVAL_OFF;
3154             vwr->INFO_OFF           = vVW510024_E_INFO_OFF;
3155             vwr->L4ID_OFF           = vVW510024_E_L4ID_OFF;
3156             vwr->IPLEN_OFF          = vVW510024_E_IPLEN_OFF;
3157
3158             vwr->FPGA_VERSION_OFF   = vVW510024_E_FPGA_VERSION_OFF;
3159             vwr->HEADER_VERSION_OFF = vVW510024_E_HEADER_VERSION_OFF;
3160
3161             vwr->VCID_MASK          = vVW510024_E_VCID_MASK;
3162             vwr->FLOW_VALID         = vVW510024_E_FLOW_VALID;
3163             vwr->FCS_ERROR          = v22_E_FCS_ERROR;
3164
3165             vwr->FRAME_TYPE_OFF     =   vVW510024_E_FRAME_TYPE_OFF;
3166             vwr->IS_TCP             =   vVW510024_E_IS_TCP;
3167             vwr->IS_UDP             =   vVW510024_E_IS_UDP;
3168             vwr->IS_ICMP            =   vVW510024_E_IS_ICMP;
3169             vwr->IS_IGMP            =   vVW510024_E_IS_IGMP;
3170             vwr->IS_QOS             =   vVW510024_E_QOS_VALID;
3171             vwr->IS_VLAN            =   vVW510024_E_IS_VLAN;
3172
3173             break;
3174     }
3175 }
3176 #define SIG_SCAN_RANGE  64                          /* range of signature scanning region */
3177
3178 /* Utility routine: check that signature is at specified location; scan for it if not.     */
3179 /* If we can't find a signature at all, then simply return the originally supplied offset. */
3180 int find_signature(const guint8 *m_ptr, int rec_size, int pay_off, guint32 flow_id, guint8 flow_seq)
3181 {
3182     int     tgt;                /* temps */
3183     guint32 fid;
3184
3185     /* initial check is very simple: look for a '0xdd' at the target location */
3186     if (m_ptr[pay_off] == 0xdd)                         /* if magic byte is present */
3187         return pay_off;                                 /* got right offset, return it */
3188
3189     /* Hmmm, signature magic byte is not where it is supposed to be; scan from start of     */
3190     /*  payload until maximum scan range exhausted to see if we can find it.                */
3191     /* The scanning process consists of looking for a '0xdd', then checking for the correct */
3192     /*  flow ID and sequence number at the appropriate offsets.                             */
3193     for (tgt = pay_off; tgt < (rec_size); tgt++) {
3194         if (m_ptr[tgt] == 0xdd) {                       /* found magic byte? check fields */
3195             if ((tgt + 15 < rec_size) && (m_ptr[tgt + 15] == 0xe2)) {
3196                 if (m_ptr[tgt + 4] != flow_seq)
3197                     continue;
3198
3199                 fid = pletoh24(&m_ptr[tgt + 1]);
3200
3201                 if (fid != flow_id)
3202                     continue;
3203
3204                 return (tgt);
3205             }
3206             else if (tgt + SIG_FSQ_OFF < rec_size)
3207             {                                               /* out which one... */
3208                 if (m_ptr[tgt + SIG_FSQ_OFF] != flow_seq)   /* check sequence number */
3209                     continue;                               /* if failed, keep scanning */
3210
3211                 fid = pletoh24(&m_ptr[tgt + SIG_FID_OFF]);  /* assemble flow ID from signature */
3212                 if (fid != flow_id)                         /* check flow ID against expected */
3213                     continue;                               /* if failed, keep scanning */
3214
3215                 /* matched magic byte, sequence number, flow ID; found the signature */
3216                 return (tgt);                               /* return offset of signature */
3217             }
3218         }
3219     }
3220
3221     /* failed to find the signature, return the original offset as default */
3222     return pay_off;
3223 }
3224
3225 /* utility routine: harvest the signature time stamp from the data frame */
3226 guint64 get_signature_ts(const guint8 *m_ptr,int sig_off, int sig_max)
3227 {
3228     int     ts_offset;
3229     guint64 sig_ts;
3230
3231     if (sig_off + 15 >= sig_max)
3232         return 0;
3233
3234     if (m_ptr[sig_off + 15] == 0xe2)
3235         ts_offset = 5;
3236     else
3237         ts_offset = 8;
3238
3239     sig_ts = pletoh32(&m_ptr[sig_off + ts_offset]);
3240
3241     return (sig_ts & 0xffffffff);
3242 }
3243
3244 static float
3245 get_legacy_rate(guint8 rate_index)
3246 {
3247     /* Rate conversion data */
3248     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};
3249
3250     float bitrate  = 0.0f;
3251
3252     if (rate_index < G_N_ELEMENTS(canonical_rate_legacy))
3253         bitrate =  canonical_rate_legacy[rate_index];
3254
3255     return bitrate;
3256 }
3257
3258 static float
3259 get_ht_rate(guint8 mcs_index, guint16 rflags)
3260 {
3261     /* Rate conversion data */
3262     static const int   canonical_ndbps_20_ht[8]  = {26, 52, 78, 104, 156, 208, 234, 260};
3263     static const int   canonical_ndbps_40_ht[8]  = {54, 108, 162, 216, 324, 432, 486, 540};
3264
3265     float symbol_tx_time, bitrate;
3266     int   ndbps;
3267
3268     if (rflags & FLAGS_CHAN_SHORTGI)
3269         symbol_tx_time = 3.6f;
3270     else
3271         symbol_tx_time = 4.0f;
3272
3273     if (rflags & FLAGS_CHAN_40MHZ)
3274         ndbps = canonical_ndbps_40_ht[mcs_index - 8*(int)(mcs_index/8)];
3275     else
3276         ndbps = canonical_ndbps_20_ht[mcs_index - 8*(int)(mcs_index/8)];
3277
3278     bitrate = (ndbps * (((int)(mcs_index >> 3) + 1))) / symbol_tx_time;
3279
3280     return bitrate;
3281 }
3282
3283 static float
3284 get_vht_rate(guint8 mcs_index, guint16 rflags, guint8 nss)
3285 {
3286     /* Rate conversion data */
3287     static const int   canonical_ndbps_20_vht[9] = {26, 52, 78, 104, 156, 208, 234, 260, 312};
3288     static const int   canonical_ndbps_40_vht[10] = {54, 108, 162, 216, 324, 432, 486, 540, 648, 720};
3289     static const int   canonical_ndbps_80_vht[10] = {117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560};
3290
3291     float symbol_tx_time, bitrate;
3292
3293     if (rflags & FLAGS_CHAN_SHORTGI)
3294         symbol_tx_time = 3.6f;
3295     else
3296         symbol_tx_time = 4.0f;
3297
3298     /*
3299      * Check for the out of range mcs_index.
3300      * Should never happen, but if mcs index is greater than 9 just
3301      * return 0.
3302      */
3303     if (mcs_index > 9)
3304         return 0.0f;
3305     if (rflags & FLAGS_CHAN_40MHZ)
3306         bitrate = (canonical_ndbps_40_vht[mcs_index] * nss) / symbol_tx_time;
3307     else if (rflags & FLAGS_CHAN_80MHZ)
3308         bitrate = (canonical_ndbps_80_vht[mcs_index] * nss) / symbol_tx_time;
3309     else
3310     {
3311         if (mcs_index == 9)
3312         {
3313             /* This is a special case for 20 MHz. */
3314             if (nss == 3)
3315                 bitrate = 1040 / symbol_tx_time;
3316             else if (nss == 6)
3317                 bitrate = 2080 / symbol_tx_time;
3318             else
3319                 bitrate = 0.0f;
3320         }
3321         else
3322             bitrate = (canonical_ndbps_20_vht[mcs_index] * nss) / symbol_tx_time;
3323     }
3324
3325     return bitrate;
3326 }
3327
3328 static gboolean
3329 vwr_process_rec_data(FILE_T fh, int rec_size,
3330                      wtap_rec *record, Buffer *buf, vwr_t *vwr,
3331                      int IS_TX, int log_mode, int *err, gchar **err_info)
3332 {
3333     guint8*   rec;       /* local buffer (holds input record) */
3334     gboolean  ret = FALSE;
3335
3336     rec = (guint8*)g_malloc(B_SIZE);
3337
3338     /* Read over the entire record (frame + trailer) into a local buffer.         */
3339     /* If we don't get it all, then declare an error, we can't process the frame. */
3340     if (!wtap_read_bytes(fh, rec, rec_size, err, err_info))
3341     {
3342         g_free(rec);
3343         return FALSE;
3344     }
3345
3346     /* now format up the frame data */
3347     switch (vwr->FPGA_VERSION)
3348     {
3349         case S1_W_FPGA:
3350             ret = vwr_read_s1_W_rec(vwr, record, buf, rec, rec_size, err, err_info);
3351             break;
3352         case S2_W_FPGA:
3353             ret = vwr_read_s2_W_rec(vwr, record, buf, rec, rec_size, IS_TX, err, err_info);
3354             break;
3355         case S3_W_FPGA:
3356             ret = vwr_read_s3_W_rec(vwr, record, buf, rec, rec_size, IS_TX, log_mode, err, err_info);
3357             break;
3358         case vVW510012_E_FPGA:
3359         case vVW510024_E_FPGA:
3360             ret = vwr_read_rec_data_ethernet(vwr, record, buf, rec, rec_size, IS_TX, err, err_info);
3361             break;
3362         default:
3363             g_free(rec);
3364             g_assert_not_reached();
3365             return ret;
3366     }
3367
3368     g_free(rec);
3369     return ret;
3370 }
3371
3372 /*
3373  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3374  *
3375  * Local variables:
3376  * c-basic-offset: 4
3377  * tab-width: 8
3378  * indent-tabs-mode: nil
3379  * End:
3380  *
3381  * vi: set shiftwidth=4 tabstop=8 expandtab:
3382  * :indentSize=4:tabSize=8:noTabs=true:
3383  */