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