2 * Copyright (c) 2011 by Tom Alexander <talexander@ixiacom.com>
7 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "file_wrappers.h"
35 /* platform-specific definitions for portability */
37 /* unsigned long long constants */
38 # define NS_IN_US G_GINT64_CONSTANT(1000U) /* nanoseconds-to-microseconds */
39 # define NS_IN_SEC G_GINT64_CONSTANT(1000000000U) /* nanoseconds-to-seconds */
40 # define US_IN_SEC G_GINT64_CONSTANT(1000000U) /* microseconds-to-seconds */
41 # define LL_ZERO G_GINT64_CONSTANT(0U) /* zero in unsigned long long */
44 * Fetch a 64-bit value in "Corey-endian" form.
46 #define pcoreytohll(p) ((guint64)*((const guint8 *)(p)+4)<<56| \
47 (guint64)*((const guint8 *)(p)+5)<<48| \
48 (guint64)*((const guint8 *)(p)+6)<<40| \
49 (guint64)*((const guint8 *)(p)+7)<<32| \
50 (guint64)*((const guint8 *)(p)+0)<<24| \
51 (guint64)*((const guint8 *)(p)+1)<<16| \
52 (guint64)*((const guint8 *)(p)+2)<<8| \
53 (guint64)*((const guint8 *)(p)+3)<<0)
55 /* .vwr log file defines */
56 #define B_SIZE 32768 /* max var len message = 32 kB */
57 #define VT_FRAME 0 /* varlen msg is a frame */
58 #define VT_CPMSG 1 /* varlen msg is a CP<->PP msg */
59 #define MAX_TRACKED_CLIENTS 1024 /* track 1024 clients */
60 #define MAX_TRACKED_FLOWS 65536 /* and 64K flows */
62 /* the radiotap header */
64 /* IxVeriwave common header fields */
66 guint16 vw_port_type; /* 0 for WLAN, 1 for Ethernet */
67 guint16 it_len; /* WHOLE radiotap header length (incl. */
68 guint16 vw_msdu_length; /* length of MAC SDU */
69 guint32 vw_flowid; /* VeriWave-specific flow ID for packet */
70 guint16 vw_vcid; /* VeriWave-specific vC ID (client id) */
71 guint16 vw_seqnum; /* VeriWave-specific signature seqnum */
72 guint32 vw_latency; /* VeriWave-specific packet latency, ns */
73 guint32 vw_sig_ts; /* signature timestamp, 32 LSBs, nsec */
74 guint64 vw_startt; /* frame start time (nsec) */
75 guint64 vw_endt; /* frame end time (nsec) */
76 guint32 vw_pktdur; /* VeriWave-specific pkt duration, us */
78 } stats_common_fields;
80 /* Size of those fields - regardless of how the compiler packs them */
81 #define STATS_COMMON_FIELDS_LEN (2+2+2+2+4+2+2+4+4+8+8+4+4)
83 /* Veriwave-specific extended radiotap header fields (following vwr_rtap_hdr above) */
84 /* structure elements correspond one-to-one with the RADIOTAP_PRESENT bitmask below */
85 /* NOTE: must ensure that elements are aligned to their "natural" packing */
86 /* NOTE: must ensure that "latency" precedes all other packet timing details, because it */
87 /* is used to start a subtree */
89 guint16 it_len; /* WHOLE radiotap header length (incl. */
90 guint16 flags; /* short preamble, WEP, frag */
91 guint16 chanflags; /* channel flags bitmap */
92 guint8 rate; /* PHY bit rate, 500 kb/s units */
93 gint8 signal; /* RF signal power, +/- dBm */
94 gint8 tx_power; /* transmit power, +/- dBm */
96 guint16 vw_flags; /* VeriWave-specific packet flags */
97 guint16 vw_ht_length; /* ht length (in plcp header)*/
98 guint16 vw_info; /* VeriWave-specific information */
99 guint32 vw_errors; /* VeriWave-specific errors */
103 /* Size of those fields - regardless of how the compiler packs them */
104 #define EXT_RTAP_FIELDS_LEN (2+2+2+1+1+1+1+2+2+2+4)
106 /* Veriwave-specific Ethernettap header */
108 guint16 it_len; /* WHOLE radiotap header length (incl. */
109 guint16 vw_flags; /* Veriwave-specific flags (see above) */
110 guint16 vw_info; /* VeriWave-specific information */
111 guint32 vw_errors; /* VeriWave-specific flags */
112 guint32 vw_l4id; /* layer four id*/
113 guint32 it_pad2; /* pad out header to 16-byte boundary */
114 } stats_ethernettap_fields;
116 /* Size of those fields - regardless of how the compiler packs them */
117 #define STATS_ETHERNETTAP_FIELDS_LEN (2+2+2+2+4+4+4)
119 /* the bitmap offsets of the bits in it_present, above */
120 /* also lists the expected field sizes in bytes */
121 /* MUST BE IN SAME ORDER AS THE STRUCTURE ELEMENTS ABOVE */
123 VW_RADIOTAP_FLAGS = 0, /* 2 bytes */
124 VW_RADIOTAP_RATE = 1, /* 1 byte */
125 VW_RADIOTAP_CHANNEL = 2, /* 4 bytes (mhz + chanflags) */
126 VW_RADIOTAP_DBM_ANTSIGNAL = 3, /* 1 byte */
127 VW_RADIOTAP_DBM_TX_POWER = 4, /* 1 byte */
128 /* start of veriwave addition */
129 VW_RADIOTAP_FPGA_VERSION = 5, /* 2 bytes */
130 VW_RADIOTAP_VW_FLAGS = 6, /* 2 bytes */
131 VW_RADIOTAP_MSDU_LENGTH = 7, /* 2 bytes */
132 VW_RADIOTAP_HT_LENGTH = 8, /* 2 bytes */
133 VW_RADIOTAP_INFO = 9, /* 2 bytes */
134 VW_RADIOTAP_ERRORS = 10, /* 4 bytes */
135 VW_RADIOTAP_FLOWID = 11, /* 4 bytes */
136 VW_RADIOTAP_MCID = 12, /* 2 bytes */
137 VW_RADIOTAP_SEQNUM = 13, /* 2 bytes */
138 VW_RADIOTAP_LATENCY = 14, /* 4 bytes (MUST COME BEFORE OTHER TIMES)*/
139 VW_RADIOTAP_SIG_TS = 15, /* 4 bytes */
140 VW_RADIOTAP_STARTT = 16, /* 8 bytes */
141 VW_RADIOTAP_ENDT = 17, /* 8 bytes */
142 VW_RADIOTAP_PKTDUR = 18, /* 4 bytes */
143 VW_RADIOTAP_IFG = 19, /* 4 bytes */
145 /* end of Veriwave addition 6-2007 */
150 /* standard field-present bitmap corresponding to above fixed-size set of fields */
151 /* this produces a 16-byte header */
152 #define VW_RADIOTAP_PRESENT ((1 << VW_RADIOTAP_FLAGS) | \
153 (1 << VW_RADIOTAP_RATE) | \
154 (1 << VW_RADIOTAP_CHANNEL) | \
155 (1 << VW_RADIOTAP_DBM_ANTSIGNAL) | \
156 (1 << VW_RADIOTAP_DBM_TX_POWER))
158 /* extended field-present bitmap corresponding to above fixed-size set of fields */
159 /* this produces a 32-byte header */
160 #define VW_EXT_RTAP_PRESENT ((1 << VW_RADIOTAP_FLAGS) | \
161 (1 << VW_RADIOTAP_RATE) | \
162 (1 << VW_RADIOTAP_CHANNEL) | \
163 (1 << VW_RADIOTAP_DBM_ANTSIGNAL) | \
164 (1 << VW_RADIOTAP_DBM_TX_POWER) | \
165 (1 << VW_RADIOTAP_FPGA_VERSION) | \
166 (1 << VW_RADIOTAP_VW_FLAGS) | \
167 (1 << VW_RADIOTAP_MSDU_LENGTH) | \
168 (1 << VW_RADIOTAP_HT_LENGTH) | \
169 (1 << VW_RADIOTAP_ERRORS) | \
170 (1 << VW_RADIOTAP_INFO) | \
171 (1 << VW_RADIOTAP_MCID) | \
172 (1 << VW_RADIOTAP_FLOWID) | \
173 (1 << VW_RADIOTAP_SEQNUM) | \
174 (1 << VW_RADIOTAP_LATENCY) | \
175 (1 << VW_RADIOTAP_SIG_TS) | \
176 (1 << VW_RADIOTAP_STARTT) | \
177 (1 << VW_RADIOTAP_ENDT) |\
178 (1 << VW_RADIOTAP_PKTDUR) |\
179 (1 << VW_RADIOTAP_IFG))
182 * RADIOTAP_FLAGS u_int8_t bitmap
183 * See flags definitions below
185 * RADIOTAP_RATE u_int8_t 500kb/s
188 * RADIOTAP_CHANNEL 2 x u_int16_t MHz+bitmap
189 * Tx/Rx frequency in MHz, followed by flags (see below).
191 * RADIOTAP_DBM_ANTSIGNAL int8_t dBm
192 * RF signal power at the antenna, dBm
194 * RADIOTAP_DBM_ANTNOISE int8_t dBm
195 * RF noise power at the antenna, dBm
197 * RADIOTAP_BARKER_CODE_LOCK u_int16_t unitless
198 * Quality of Barker code lock. Monotonically nondecreasing with "better" lock strength.
199 * Called "Signal Quality" in datasheets.
201 * RADIOTAP_DBM_TX_POWER int8_t dBm
202 * Transmit power expressed as dBm.
205 /* Channel flags for IEEE80211_RADIOTAP_CHANNEL */
206 #define CHAN_TURBO 0x0010 /* Turbo channel */
207 #define CHAN_CCK 0x0020 /* CCK channel */
208 #define CHAN_OFDM 0x0040 /* OFDM channel */
209 #define CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
210 #define CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
211 #define CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
213 /* For RADIOTAP_FLAGS */
214 #define RADIOTAP_F_CFP 0x001 /* sent/received during CFP */
215 #define RADIOTAP_F_SHORTPRE 0x002 /* sent/received with short preamble */
216 #define RADIOTAP_F_WEP 0x004 /* sent/received with WEP encryption */
217 #define RADIOTAP_F_FRAG 0x008 /* sent/received with fragmentation */
218 #define RADIOTAP_F_FCS 0x010 /* frame includes FCS */
219 #define RADIOTAP_F_DATAPAD 0x020 /* padding between 802.11 hdr & payload */
220 #define RADIOTAP_F_CHAN_HT 0x040 /* In HT mode */
221 #define RADIOTAP_F_CHAN_40MHZ 0x080 /* 40 Mhz CBW */
222 #define RADIOTAP_F_CHAN_SHORTGI 0x100 /* Short guard interval */
225 /* For VeriWave-specific RADIOTAP_FLAGS and ETHERNETTAP_FLAGS */
226 #define RADIOTAP_VWF_TXF 0x01 /* frame was transmitted */
227 #define RADIOTAP_VWF_FCSERR 0x02 /* FCS error detected */
228 #define RADIOTAP_VWF_RETRERR 0x04 /* excess retry error detected */
229 #define RADIOTAP_VWF_DCRERR 0x10 /* decrypt error detected (WLAN) */
230 #define RADIOTAP_VWF_ENCMSK 0x60 /* encryption type mask */
231 /* 0 = none, 1 = WEP, 2 = TKIP, 3 = CCKM */
232 #define RADIOTAP_VWF_IS_WEP 0x20 /* WEP */
233 #define RADIOTAP_VWF_IS_TKIP 0x40 /* TKIP */
234 #define RADIOTAP_VWF_IS_CCMP 0x60 /* CCMP */
235 #define RADIOTAP_VWF_SEQ_ERR 0x80 /* flow sequence error detected */
237 /* FPGA-generated frame buffer STATS block offsets and definitions */
239 /* definitions for v2.2 frames, Ethernet format */
240 #define v22_E_STATS_LEN 44 /* length of stats block trailer */
241 #define v22_E_VALID_OFF 0 /* bit 6 (0x40) is flow-is-valid flag */
242 #define v22_E_MTYPE_OFF 1 /* offset of modulation type */
243 #define v22_E_VCID_OFF 2 /* offset of VC ID */
244 #define v22_E_FLOWSEQ_OFF 4 /* offset of signature sequence number */
245 #define v22_E_FLOWID_OFF 5 /* offset of flow ID */
246 #define v22_E_OCTET_OFF 8 /* offset of octets */
247 #define v22_E_ERRORS_OFF 10 /* offset of error vector */
248 #define v22_E_PATN_OFF 12 /* offset of pattern match vector */
249 #define v22_E_L4ID_OFF 12
250 #define v22_E_IPLEN_OFF 14
251 #define v22_E_FRAME_TYPE_OFF 16 /* offset of frame type, 32 bits */
252 #define v22_E_RSSI_OFF 21 /* RSSI (NOTE: invalid for Ethernet) */
253 #define v22_E_STARTT_OFF 20 /* offset of start time, 64 bits */
254 #define v22_E_ENDT_OFF 28 /* offset of end time, 64 bits */
255 #define v22_E_LATVAL_OFF 36 /* offset of latency, 32 bits */
256 #define v22_E_INFO_OFF 40 /* NO INFO FIELD IN ETHERNET STATS! */
257 #define v22_E_DIFFERENTIATOR_OFF 0 /* offset to determine whether */
258 /* eth/802.11, 8 bits */
260 #define v22_E_MT_10_HALF 0 /* 10 Mb/s half-duplex */
261 #define v22_E_MT_10_FULL 1 /* 10 Mb/s full-duplex */
262 #define v22_E_MT_100_HALF 2 /* 100 Mb/s half-duplex */
263 #define v22_E_MT_100_FULL 3 /* 100 Mb/s full-duplex */
264 #define v22_E_MT_1G_HALF 4 /* 1 Gb/s half-duplex */
265 #define v22_E_MT_1G_FULL 5 /* 1 Gb/s full-duplex */
267 #define v22_E_FCS_ERROR 0x0002 /* FCS error flag in error vector */
268 #define v22_E_CRYPTO_ERR 0x1f00 /* RX decrypt error flags (UNUSED) */
269 #define v22_E_SIG_ERR 0x0004 /* signature magic byte mismatch */
270 #define v22_E_PAYCHK_ERR 0x0008 /* payload checksum failure */
271 #define v22_E_RETRY_ERR 0x0400 /* excessive retries on TX fail (UNUSED)*/
272 #define v22_E_IS_RX 0x08 /* TX/RX bit in STATS block */
273 #define v22_E_MT_MASK 0x07 /* modulation type mask (UNUSED) */
274 #define v22_E_VCID_MASK 0x03ff /* VC ID is only 9 bits */
275 #define v22_E_FLOW_VALID 0x40 /* flow-is-valid flag (else force to 0) */
276 #define v22_E_DIFFERENTIATOR_MASK 0X3F /* mask to differentiate ethernet from */
277 #define v22_E_IS_TCP 0x00000040 /* TCP bit in FRAME_TYPE field */
278 #define v22_E_IS_UDP 0x00000010 /* UDP bit in FRAME_TYPE field */
279 #define v22_E_IS_ICMP 0x00000020 /* ICMP bit in FRAME_TYPE field */
280 #define v22_E_IS_IGMP 0x00000080 /* IGMP bit in FRAME_TYPE field */
281 #define v22_E_IS_QOS 0x80 /* QoS bit in MTYPE field (WLAN only) */
282 #define v22_E_IS_VLAN 0x00200000
285 #define v22_E_RX_DECRYPTS 0x0007 /* RX-frame-was-decrypted (UNUSED) */
286 #define v22_E_TX_DECRYPTS 0x0007 /* TX-frame-was-decrypted (UNUSED) */
288 #define v22_E_FC_PROT_BIT 0x40 /* Protected Frame bit in FC1 of frame */
291 #define v22_E_HEADER_IS_RX 0x21
292 #define v22_E_HEADER_IS_TX 0x31
294 #define v22_E_IS_ETHERNET 0x00700000 /* bits set in frame type if ethernet */
295 #define v22_E_IS_80211 0x7F000000 /* bits set in frame type if 802.11 */
297 /* definitions for v2.2 frames, WLAN format for VW510006 FPGA*/
298 #define v22_W_STATS_LEN 64 /* length of stats block trailer */
299 #define v22_W_VALID_OFF 0 /* bit 6 (0x40) is flow-is-valid flag */
300 #define v22_W_MTYPE_OFF 1 /* offset of modulation type */
301 #define v22_W_VCID_OFF 2 /* offset of VC ID */
302 #define v22_W_FLOWSEQ_OFF 4 /* offset of signature sequence number */
303 #define v22_W_FLOWID_OFF 5 /* offset of flow ID */
304 #define v22_W_OCTET_OFF 8 /* offset of octets */
305 #define v22_W_ERRORS_OFF 10 /* offset of error vector */
306 #define v22_W_PATN_OFF 12
307 #define v22_W_L4ID_OFF 12
308 #define v22_W_IPLEN_OFF 14
309 #define v22_W_FRAME_TYPE_OFF 16 /* offset of frame type, 32 bits */
310 #define v22_W_RSSI_OFF 21 /* RSSI (NOTE: RSSI must be negated!) */
311 #define v22_W_STARTT_OFF 24 /* offset of start time, 64 bits */
312 #define v22_W_ENDT_OFF 32 /* offset of end time, 64 bits */
313 #define v22_W_LATVAL_OFF 40 /* offset of latency, 32 bits */
314 #define v22_W_INFO_OFF 54 /* offset of INFO field, 16 LSBs */
315 #define v22_W_DIFFERENTIATOR_OFF 20 /* offset to determine whether */
316 /* eth/802.11, 32 bits */
318 #define v22_W_PLCP_LENGTH_OFF 4 /* LENGTH field in the plcp header */
321 #define v22_W_MT_CCKL 0 /* CCK modulation, long preamble */
322 #define v22_W_MT_CCKS 1 /* CCK modulation, short preamble */
323 #define v22_W_MT_OFDM 2 /* OFDM modulation */
325 #define v22_W_IS_TCP 0x00000040 /* TCP bit in FRAME_TYPE field */
326 #define v22_W_IS_UDP 0x00000010 /* UDP bit in FRAME_TYPE field */
327 #define v22_W_IS_ICMP 0x00000020 /* ICMP bit in FRAME_TYPE field */
328 #define v22_W_IS_IGMP 0x00000080 /* IGMP bit in FRAME_TYPE field */
329 #define v22_W_IS_QOS 0x80 /* QoS bit in MTYPE field (WLAN only) */
332 #define v22_W_FCS_ERROR 0x0002 /* FCS error flag in error vector */
333 #define v22_W_CRYPTO_ERR 0x1f00 /* RX decrypt error flags */
334 #define v22_W_SIG_ERR 0x0004 /* signature magic byte mismatch */
335 #define v22_W_PAYCHK_ERR 0x0008 /* payload checksum failure */
336 #define v22_W_RETRY_ERR 0x0400 /* excessive retries on TX failure */
337 #define v22_W_IS_RX 0x08 /* TX/RX bit in STATS block */
338 #define v22_W_MT_MASK 0x07 /* modulation type mask */
339 #define v22_W_VCID_MASK 0x01ff /* VC ID is only 9 bits */
340 #define v22_W_FLOW_VALID 0x40 /* flow-is-valid flag (else force to 0) */
341 #define v22_W_DIFFERENTIATOR_MASK 0Xf0ff /* mask to differentiate ethernet from */
344 #define v22_W_RX_DECRYPTS 0x0007 /* RX-frame-was-decrypted bits */
345 #define v22_W_TX_DECRYPTS 0x0007 /* TX-frame-was-decrypted bits */
347 #define v22_W_WEPTYPE 0x0001 /* WEP frame */
348 #define v22_W_TKIPTYPE 0x0002 /* TKIP frame */
349 #define v22_W_CCMPTYPE 0x0004 /* CCMP frame */
351 #define v22_W_HEADER_IS_RX 0x21
352 #define v22_W_HEADER_IS_TX 0x31
354 #define v22_W_FC_PROT_BIT 0x40 /* Protected Frame bit in FC1 of frame */
356 #define v22_W_IS_ETHERNET 0x00100000 /* bits set in frame type if ethernet */
357 #define v22_W_IS_80211 0x7F000000 /* bits set in frame type if 802.11 */
359 /* definitions for VW510021 FPGA, WLAN format */
362 8 bytes of stat block
363 plcp stuff (11 bytes plcp + 1 byte pad)
365 remaining 48 bytes of stat block
367 /* offsets in the stats block */
368 #define vVW510021_W_STATS_LEN 48 /* length of stats block trailer after the plcp portion*/
369 #define vVW510021_W_STARTT_OFF 0 /* offset of start time, 64 bits */
370 #define vVW510021_W_ENDT_OFF 8 /* offset of end time, 64 bits */
371 #define vVW510021_W_ERRORS_OFF 16 /* offset of error vector */
372 #define vVW510021_W_VALID_OFF 20 /* 2 Bytes with different validity bits */
373 #define vVW510021_W_INFO_OFF 22 /* offset of INFO field, 16 LSBs */
374 #define vVW510021_W_FRAME_TYPE_OFF 24
375 #define vVW510021_W_L4ID_OFF 28
376 #define vVW510021_W_IPLEN_OFF 30 /* offset of IP Total Length field */
377 #define vVW510021_W_FLOWSEQ_OFF 32 /* offset of signature sequence number */
378 #define vVW510021_W_FLOWID_OFF 33 /* offset of flow ID */
379 #define vVW510021_W_LATVAL_OFF 36 /* offset of delay/flowtimestamp, 32b */
380 #define vVW510021_W_DEBUG_OFF 40 /* offset of debug, 16 bits */
381 #define vVW510021_W_FPGA_VERSION_OFF 44 /* offset of fpga version, 16 bits */
382 #define vVW510021_W_MATCH_OFF 47 /* offset of pattern match vector */
384 /* offsets in the header block */
385 #define vVW510021_W_HEADER_LEN 16 /* length of FRAME header */
386 #define vVW510021_W_RXTX_OFF 0 /* rxtx offset, cmd byte of header */
387 #define vVW510021_W_HEADER_VERSION_OFF 9 /* version, 2bytes */
388 #define vVW510021_MSG_LENGTH_OFF 10 /* MSG LENGTH, 2bytes */
389 #define vVW510021_W_DEVICE_TYPE_OFF 8 /* version, 2bytes */
391 /* offsets that occurs right after the header */
392 #define vVW510021_W_AFTERHEADER_LEN 8 /* length of STATs info directly after header */
393 #define vVW510021_W_L1P_1_OFF 0 /* offset of 1st byte of layer one info */
394 #define vVW510021_W_L1P_2_OFF 1 /* offset of 2nd byte of layer one info */
395 #define vVW510021_W_MTYPE_OFF vVW510021_W_L1P_2_OFF
396 #define vVW510021_W_PREAMBLE_OFF vVW510021_W_L1P_1_OFF
397 #define vVW510021_W_RSSI_TXPOWER_OFF 2 /* RSSI (NOTE: RSSI must be negated!) */
398 #define vVW510021_W_MSDU_LENGTH_OFF 3 /* 7:0 of length, next byte 11:8 in top 4 bits */
399 #define vVW510021_W_BVCV_VALID_OFF 4 /* BV,CV Determine validaity of bssid and txpower */
400 #define vVW510021_W_VCID_OFF 6 /* offset of VC (client) ID */
401 #define vVW510021_W_PLCP_LENGTH_OFF 12 /* LENGTH field in the plcp header */
403 /* Masks and defines */
404 #define vVW510021_W_IS_BV 0x04 /* BV bit in STATS block */
405 #define vVW510021_W_IS_CV 0x02 /* BV bit in STATS block */
406 #define vVW510021_W_FLOW_VALID 0x8000 /* valid_off flow-is-valid flag (else 0) */
407 #define vVW510021_W_QOS_VALID 0x4000
408 #define vVW510021_W_HT_VALID 0x2000
409 #define vVW510021_W_L4ID_VALID 0x1000
410 #define vVW510021_W_PREAMBLE_MASK 0x40 /* short/long preamble/guard(ofdm) mask */
411 #define vVW510021_W_MCS_MASK 0x3f /* mcs index (a/b) type mask */
412 #define vVW510021_W_MOD_SCHEME_MASK 0x3f /* modulation type mask */
413 #define vVW510021_W_PLCPC_MASK 0x03 /* PLPCP type mask */
414 #define vVW510021_W_SEL_MASK 0x80
415 #define vVW510021_W_WEP_MASK 0x0001
416 #define vVW510021_W_CBW_MASK 0xC0
418 #define vVW510021_W_MT_SEL_LEGACY 0x00
419 #define vVW510021_W_PLCP_LEGACY 0x00
420 #define vVW510021_W_PLCP_MIXED 0x01
421 #define vVW510021_W_PLCP_GREENFIELD 0x02
422 #define vVW510021_W_HEADER_IS_RX 0x21
423 #define vVW510021_W_HEADER_IS_TX 0x31
424 #define vVW510021_W_IS_WEP 0x0001
425 #define vVW510021_W_IS_LONGPREAMBLE 0x40
427 #define vVW510021_W_IS_TCP 0x01000000 /* TCP bit in FRAME_TYPE field */
428 #define vVW510021_W_IS_UDP 0x00100000 /* UDP bit in FRAME_TYPE field */
429 #define vVW510021_W_IS_ICMP 0x00001000 /* ICMP bit in FRAME_TYPE field */
430 #define vVW510021_W_IS_IGMP 0x00010000 /* IGMP bit in FRAME_TYPE field */
433 #define vVW510021_W_HEADER_VERSION 0x00
434 #define vVW510021_W_DEVICE_TYPE 0x15
435 #define vVW510021_W_11n_DEVICE_TYPE 0x20
436 #define vVW510021_W_FPGA_VERSION 0x000C
437 #define vVW510021_W_11n_FPGA_VERSION 0x000D
440 #define vVW510021_W_FCS_ERROR 0x10
441 #define vVW510021_W_CRYPTO_ERROR 0x50000
443 #define vVW510021_W_WEPTYPE 0x0001 /* WEP frame */
444 #define vVW510021_W_TKIPTYPE 0x0002 /* TKIP frame */
445 #define vVW510021_W_CCMPTYPE 0x0004 /* CCMP frame */
447 /* definitions for VW510024 FPGA, wired ethernet format */
450 52 bytes of stats block trailer
452 /* offsets in the stats block */
453 #define vVW510024_E_STATS_LEN 48 /* length of stats block trailer */
454 #define vVW510024_E_MSDU_LENGTH_OFF 0 /* MSDU 16 BITS */
455 #define vVW510024_E_BMCV_VALID_OFF 2 /* BM,CV Determine validITY */
456 #define vVW510024_E_VCID_OFF 2 /* offset of VC (client) ID 13:8, */
458 #define vVW510024_E_STARTT_OFF 4 /* offset of start time, 64 bits */
459 #define vVW510024_E_ENDT_OFF 12 /* offset of end time, 64 bits */
460 #define vVW510024_E_ERRORS_OFF 22 /* offset of error vector */
461 #define vVW510024_E_VALID_OFF 24 /* 2 Bytes with different validity bits */
462 #define vVW510024_E_INFO_OFF 26 /* offset of INFO field, 16 LSBs */
463 #define vVW510024_E_FRAME_TYPE_OFF 28
464 #define vVW510024_E_L4ID_OFF 32
465 #define vVW510024_E_IPLEN_OFF 34
466 #define vVW510024_E_FLOWSEQ_OFF 36 /* offset of signature sequence number */
467 #define vVW510024_E_FLOWID_OFF 37 /* offset of flow ID */
468 #define vVW510024_E_LATVAL_OFF 40 /* offset of delay/flowtimestamp, 32 bits */
469 #define vVW510024_E_FPGA_VERSION_OFF 20 /* offset of fpga version, 16 bits */
470 #define vVW510024_E_MATCH_OFF 51 /* offset of pattern match vector */
472 /* offsets in the header block */
473 #define vVW510024_E_HEADER_LEN vVW510021_W_HEADER_LEN /* length of FRAME header */
474 #define vVW510024_E_RXTX_OFF vVW510021_W_RXTX_OFF /* rxtx offset, cmd byte */
475 #define vVW510024_E_HEADER_VERSION_OFF 16 /* version, 2bytes */
476 #define vVW510024_E_MSG_LENGTH_OFF vVW510021_MSG_LENGTH_OFF /* MSG LENGTH, 2bytes */
477 #define vVW510024_E_DEVICE_TYPE_OFF vVW510021_W_DEVICE_TYPE_OFF /* Device Type, 2bytes */
479 /* Masks and defines */
480 #define vVW510024_E_IS_BV 0x80 /* Bm bit in STATS block */
481 #define vVW510024_E_IS_CV 0x40 /* cV bit in STATS block */
482 #define vVW510024_E_FLOW_VALID 0x8000 /* valid_off flow-is-valid flag (else force to 0) */
483 #define vVW510024_E_QOS_VALID 0x0000 /*not valid for ethernet*/
484 #define vVW510024_E_L4ID_VALID 0x1000
485 #define vVW510024_E_CBW_MASK 0xC0
486 #define vVW510024_E_VCID_MASK 0x3FFF
488 #define vVW510024_E_HEADER_IS_RX 0x21
489 #define vVW510024_E_HEADER_IS_TX 0x31
491 #define vVW510024_E_IS_TCP 0x01000000 /* TCP bit in FRAME_TYPE field */
492 #define vVW510024_E_IS_UDP 0x00100000 /* UDP bit in FRAME_TYPE field */
493 #define vVW510024_E_IS_ICMP 0x00001000 /* ICMP bit in FRAME_TYPE field */
494 #define vVW510024_E_IS_IGMP 0x00010000
495 #define vVW510024_E_IS_VLAN 0x4000
497 #define vVW510024_E_HEADER_VERSION 0x00
498 #define vVW510024_E_DEVICE_TYPE 0x18
499 #define vVW510024_E_FPGA_VERSION 0x0001
501 #define FPGA_VER_NOT_APPLICABLE 0
503 #define UNKNOWN_FPGA 0
504 #define vVW510021_W_FPGA 1
505 #define vVW510006_W_FPGA 2
506 #define vVW510012_E_FPGA 3
507 #define vVW510024_E_FPGA 4
509 /*the flow signature is:
511 0 Magic Number (0xDD)
512 1 Chassis Number[7:0]
518 7 Flow Sequence Number[7:0]
529 #define SIG_SIZE 16 /* size of signature field, bytes */
530 #define SIG_FID_OFF 4 /* offset of flow ID in signature */
531 #define SIG_FSQ_OFF 7 /* offset of flow seqnum in signature */
532 #define SIG_TS_OFF 8 /* offset of flow seqnum in signature */
536 /*--------------------------------------------------------------------------------------*/
537 /* Per-capture file private data structure */
540 /* offsets in stats block; these are dependent on the frame type (Ethernet/WLAN) and */
541 /* version number of .vwr file, and are set up by setup_defaults() */
542 guint32 STATS_LEN; /* length of stats block trailer */
543 guint32 STATS_START_OFF; /* STATS OFF AFTER HEADER */
544 guint32 VALID_OFF; /* bit 6 (0x40) is flow-is-valid flag */
545 guint32 MTYPE_OFF; /* offset of modulation type */
546 guint32 VCID_OFF; /* offset of VC ID */
547 guint32 FLOWSEQ_OFF; /* offset of signature sequence number */
548 guint32 FLOWID_OFF; /* offset of flow ID */
549 guint32 OCTET_OFF; /* offset of octets */
550 guint32 ERRORS_OFF; /* offset of error vector */
551 guint32 PATN_OFF; /* offset of pattern match vector */
552 guint32 RSSI_OFF; /* RSSI (NOTE: RSSI must be negated!) */
553 guint32 STARTT_OFF; /* offset of start time, 64 bits */
554 guint32 ENDT_OFF; /* offset of end time, 64 bits */
555 guint32 LATVAL_OFF; /* offset of latency, 32 bits */
556 guint32 INFO_OFF; /* offset of INFO field, 16 bits */
557 guint32 L1P_1_OFF; /* offset 1ST Byte of l1params */
558 guint32 L1P_2_OFF; /* offset 2nd Byte of l1params */
559 guint32 L4ID_OFF; /* LAYER 4 id offset*/
560 guint32 IPLEN_OFF; /* */
561 guint32 PLCP_LENGTH_OFF; /* plcp length offset*/
562 guint32 FPGA_VERSION_OFF; /* offset of fpga version field, 16 bits */
563 guint32 HEADER_VERSION_OFF; /* offset of header version, 16 bits */
564 guint32 RXTX_OFF; /* offset of CMD bit, rx or tx */
565 guint32 FRAME_TYPE_OFF;
567 /* other information about the file in question */
568 guint32 MT_10_HALF; /* 10 Mb/s half-duplex */
569 guint32 MT_10_FULL; /* 10 Mb/s full-duplex */
570 guint32 MT_100_HALF; /* 100 Mb/s half-duplex */
571 guint32 MT_100_FULL; /* 100 Mb/s full-duplex */
572 guint32 MT_1G_HALF; /* 1 Gb/s half-duplex */
573 guint32 MT_1G_FULL; /* 1 Gb/s full-duplex */
574 guint32 FCS_ERROR; /* FCS error in frame */
575 guint32 CRYPTO_ERR; /* RX decrypt error flags */
576 guint32 PAYCHK_ERR; /* payload checksum failure */
577 guint32 RETRY_ERR; /* excessive retries on TX failure */
578 guint8 IS_RX; /* TX/RX bit in STATS block */
579 guint8 MT_MASK; /* modulation type mask */
580 guint16 VCID_MASK; /* VC ID is only 9 bits */
581 guint32 FLOW_VALID; /* flow-is-valid flag (else force to 0) */
583 guint32 RX_DECRYPTS; /* RX-frame-was-decrypted bits */
584 guint32 TX_DECRYPTS; /* TX-frame-was-decrypted bits */
585 guint32 FC_PROT_BIT; /* Protected Frame bit in FC1 of frame */
586 guint32 MT_CCKL; /* CCK modulation, long preamble */
587 guint32 MT_CCKS; /* CCK modulation, short preamble */
588 guint32 MT_OFDM; /* OFDM modulation */
589 guint32 MCS_INDEX_MASK; /* mcs index type mask */
590 guint32 FPGA_VERSION;
591 guint32 HEADER_IS_RX;
592 guint32 HEADER_IS_TX;
593 guint32 WEPTYPE; /* frame is WEP */
594 guint32 TKIPTYPE; /* frame is TKIP */
595 guint32 CCMPTYPE; /* frame is CCMP */
604 /* internal utility functions */
605 static int decode_msg(vwr_t *vwr, register guint8 *, int *, int *);
606 static guint8 get_ofdm_rate(guint8 *);
607 static guint8 get_cck_rate(guint8 *plcp);
608 static void setup_defaults(vwr_t *, guint16);
610 static gboolean vwr_read(wtap *, int *, gchar **, gint64 *);
611 static gboolean vwr_seek_read(wtap *, gint64, struct wtap_pkthdr *phdr, guchar *,
612 int, int *, gchar **);
614 static gboolean vwr_read_rec_header(vwr_t *, FILE_T, int *, int *, int *, gchar **);
615 static void vwr_read_rec_data(wtap *, guint8 *, guint8 *, int);
617 static int vwr_get_fpga_version(wtap *, int *, gchar **);
620 static void vwr_read_rec_data_vVW510021(wtap *, guint8 *, guint8 *, int, int);
621 static void vwr_read_rec_data_ethernet(wtap *, guint8 *, guint8 *, int, int);
623 static int find_signature(register guint8 *, int, register guint32, register guint8);
624 static guint64 get_signature_ts(register guint8 *, int);
626 /* open a .vwr file for reading */
627 /* this does very little, except setting the wiretap header for a VWR file type */
628 /* and the timestamp precision to microseconds */
630 int vwr_open(wtap *wth, int *err, gchar **err_info)
637 fpgaVer = vwr_get_fpga_version(wth, err, err_info);
639 return -1; /* I/O error */
641 if (fpgaVer == UNKNOWN_FPGA) {
642 return 0; /* not a VWR file */
645 /* This is a vwr file */
646 vwr = (vwr_t *)g_malloc(sizeof(vwr_t));
647 wth->priv = (void *)vwr;
649 vwr->FPGA_VERSION = fpgaVer;
650 /* set the local module options first */
651 setup_defaults(vwr, fpgaVer);
653 wth->snapshot_length = 0;
654 wth->subtype_read = vwr_read;
655 wth->subtype_seek_read = vwr_seek_read;
656 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
658 if (fpgaVer == vVW510021_W_FPGA) {
659 wth->file_type = WTAP_FILE_VWR_80211;
660 wth->file_encap = WTAP_ENCAP_IXVERIWAVE;
663 else if (fpgaVer == vVW510006_W_FPGA) {
664 wth->file_type = WTAP_FILE_VWR_80211;
665 wth->file_encap = WTAP_ENCAP_IXVERIWAVE;
668 else if (fpgaVer == vVW510012_E_FPGA) {
669 wth->file_type = WTAP_FILE_VWR_ETH;
670 wth->file_encap = WTAP_ENCAP_IXVERIWAVE;
673 else if (fpgaVer == vVW510024_E_FPGA) {
674 wth->file_type = WTAP_FILE_VWR_ETH;
675 wth->file_encap = WTAP_ENCAP_IXVERIWAVE;
683 /* Read the next packet */
684 /* note that the VWR file format consists of a sequence of fixed 16-byte record headers of */
685 /* different types; some types, including frame record headers, are followed by */
686 /* variable-length data */
687 /* a frame record consists of: the above 16-byte record header, a 1-16384 byte raw PLCP */
688 /* frame, and a 64-byte statistics block trailer */
689 /* the PLCP frame consists of a 4-byte or 6-byte PLCP header, followed by the MAC frame */
691 static gboolean vwr_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
693 vwr_t *vwr = (vwr_t *)wth->priv;
694 guint8 rec[B_SIZE]; /* local buffer (holds input record) */
695 int rec_size = 0, IS_TX;
697 guint16 pkt_len; /* length of radiotap headers */
699 /* read the next frame record header in the capture file; if no more frames, return */
700 if (!vwr_read_rec_header(vwr, wth->fh, &rec_size, &IS_TX, err, err_info))
701 return(FALSE); /* Read error or EOF */
703 *data_offset = (file_tell(wth->fh) - 16); /* set offset for random seek @PLCP */
705 /* got a frame record; read over entire record (frame + trailer) into a local buffer */
706 /* if we don't get it all, then declare an error, we can't process the frame */
707 if (file_read(rec, rec_size, wth->fh) != rec_size) {
708 *err = file_error(wth->fh, err_info);
710 *err = WTAP_ERR_SHORT_READ;
716 /* before writing anything out, make sure the buffer has enough space for everything */
717 if ((vwr->FPGA_VERSION == vVW510021_W_FPGA) || (vwr->FPGA_VERSION == vVW510006_W_FPGA) )
718 /* frames are always 802.11 with an extended radiotap header */
719 pkt_len = (guint16)(rec_size + STATS_COMMON_FIELDS_LEN + EXT_RTAP_FIELDS_LEN);
721 /* frames are always ethernet with an extended ethernettap header */
722 pkt_len = (guint16)(rec_size + STATS_COMMON_FIELDS_LEN + STATS_ETHERNETTAP_FIELDS_LEN);
723 buffer_assure_space(wth->frame_buffer, pkt_len);
724 data_ptr = buffer_start_ptr(wth->frame_buffer);
726 /* now format up the frame data */
727 switch (vwr->FPGA_VERSION)
729 case vVW510006_W_FPGA:
730 vwr_read_rec_data(wth, data_ptr, rec, rec_size);
732 case vVW510021_W_FPGA:
733 vwr_read_rec_data_vVW510021(wth, data_ptr, rec, rec_size, IS_TX);
735 case vVW510012_E_FPGA:
736 vwr_read_rec_data_ethernet(wth, data_ptr, rec, rec_size, IS_TX);
738 case vVW510024_E_FPGA:
739 vwr_read_rec_data_ethernet(wth, data_ptr, rec, rec_size, IS_TX);
743 /* If the per-file encapsulation isn't known, set it to this packet's encapsulation */
744 /* If it *is* known, and it isn't this packet's encapsulation, set it to */
745 /* WTAP_ENCAP_PER_PACKET, as this file doesn't have a single encapsulation for all */
746 /* packets in the file */
747 if (wth->file_encap == WTAP_ENCAP_UNKNOWN)
748 wth->file_encap = wth->phdr.pkt_encap;
750 if (wth->file_encap != wth->phdr.pkt_encap)
751 wth->file_encap = WTAP_ENCAP_PER_PACKET;
757 /* read a random frame in the middle of a file; the start of the PLCP frame is @ seek_off */
759 static gboolean vwr_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr _U_, guchar *pd, int pkt_size _U_,
760 int *err, gchar **err_info)
762 vwr_t *vwr = (vwr_t *)wth->priv;
763 guint8 rec[B_SIZE]; /* local buffer (holds input record) */
766 /* first seek to the indicated record header */
767 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
770 /* read in the record header */
771 if (!vwr_read_rec_header(vwr, wth->random_fh, &rec_size, &IS_TX, err, err_info))
772 return(FALSE); /* Read error or EOF */
774 /* read over the entire record (frame + trailer) into a local buffer */
775 /* if we don't get it all, then declare an error, we can't process the frame */
776 if (file_read(rec, rec_size, wth->random_fh) != rec_size) {
777 *err = file_error(wth->random_fh, err_info);
779 *err = WTAP_ERR_SHORT_READ;
783 /* now format up the frame data into the passed buffer, according to the FPGA type */
784 switch (vwr->FPGA_VERSION) {
785 case vVW510006_W_FPGA:
786 vwr_read_rec_data(wth, pd, rec, rec_size);
788 case vVW510021_W_FPGA:
789 vwr_read_rec_data_vVW510021(wth, pd, rec, rec_size, IS_TX);
791 case vVW510012_E_FPGA:
792 vwr_read_rec_data_ethernet(wth, pd, rec, rec_size, IS_TX);
794 case vVW510024_E_FPGA:
795 vwr_read_rec_data_ethernet(wth, pd, rec, rec_size, IS_TX);
802 /* scan down in the input capture file to find the next frame header */
803 /* decode and skip over all non-frame messages that are in the way */
804 /* return TRUE on success, FALSE on EOF or error */
805 /* also return the frame size in bytes and the "is transmitted frame" flag */
807 static gboolean vwr_read_rec_header(vwr_t *vwr, FILE_T fh, int *rec_size, int *IS_TX, int *err, gchar **err_info)
812 errno = WTAP_ERR_CANT_READ;
815 /* read out the file data in 16-byte messages, stopping either after we find a frame, */
816 /* or if we run out of data */
817 /* each 16-byte message is decoded; if we run across a non-frame message followed by a*/
818 /* variable-length item, we read the variable length item out and discard it */
819 /* if we find a frame, we return (with the header in the passed buffer) */
821 if (file_read(header, 16, fh) != 16) {
822 *err = file_error(fh, err_info);
826 /* got a header; invoke decode-message function to parse and process it */
827 /* if the function returns a length, then a frame or variable-length message */
828 /* follows the 16-byte message */
829 /* if the variable length message is not a frame, simply skip over it */
830 if ((f_len = decode_msg(vwr, header, &v_type, IS_TX)) != 0) {
831 if (f_len > B_SIZE) {
832 *err = WTAP_ERR_BAD_FILE;
833 *err_info = g_strdup_printf("vwr: Invalid message record length %d", f_len);
836 else if (v_type != VT_FRAME) {
837 if (file_seek(fh, f_len, SEEK_CUR, err) < 0)
848 /* figure out the FPGA version (and also see whether this is a VWR file type */
849 /* return FPGA version if it's a known version, UNKNOWN_FPGA if it's not, */
850 /* and -1 on an I/O error. */
852 static int vwr_get_fpga_version(wtap *wth, int *err, gchar **err_info)
854 guint8 rec[B_SIZE]; /* local buffer (holds input record) */
858 guint8 *s_510006_ptr = NULL;
859 guint8 *s_510024_ptr = NULL;
860 guint8 *s_510012_ptr = NULL; /* stats pointers */
862 guint32 frame_type = 0;
864 guint16 data_length = 0;
865 guint16 fpga_version;
867 filePos = file_tell(wth->fh);
869 *err = file_error(wth->fh, err_info);
874 /* got a frame record; see if it is vwr */
875 /* if we don't get it all, then declare an error, we can't process the frame */
876 /* read out the file data in 16-byte messages, stopping either after we find a frame, */
877 /* or if we run out of data */
878 /* each 16-byte message is decoded; if we run across a non-frame message followed by a*/
879 /* variable-length item, we read the variable length item out and discard it */
880 /* if we find a frame, we return (with the header in the passed buffer) */
881 while ((file_read(header, 16, wth->fh)) == 16) {
882 /* got a header; invoke decode-message function to parse and process it */
883 /* if the function returns a length, then a frame or variable-length message */
884 /* follows the 16-byte message */
885 /* if the variable length message is not a frame, simply skip over it */
886 if ((f_len = decode_msg(NULL, header, &v_type, NULL)) != 0) {
887 if (f_len > B_SIZE) {
888 /* Treat this here as an indication that the file probably */
889 /* isn't an vwr file. */
890 return(UNKNOWN_FPGA);
892 else if (v_type != VT_FRAME) {
893 if (file_seek(wth->fh, f_len, SEEK_CUR, err) < 0)
898 /* got a frame record; read over entire record (frame + trailer) into a local buffer */
899 /* if we don't get it all, assume this isn't a vwr file */
900 if (file_read(rec, rec_size, wth->fh) != rec_size) {
901 *err = file_error(wth->fh, err_info);
903 return(UNKNOWN_FPGA); /* short read - not a vwr file */
908 /* I'll grab the bytes where the Ethernet "octets" field should be and the bytes where */
909 /* the 802.11 "octets" field should be. Then if I do rec_size - octets - */
910 /* size_of_stats_block and it's 0, I can select the correct type. */
911 /* octets + stats_len = rec_size only when octets have been incremented to nearest */
912 /* number divisible by 4. */
914 /* First check for series I WLAN since the check is more rigorous. */
915 if (rec_size > v22_W_STATS_LEN) {
916 s_510006_ptr = &(rec[rec_size - v22_W_STATS_LEN]); /* point to 510006 WLAN */
919 data_length = pntohs(&s_510006_ptr[v22_W_OCTET_OFF]);
921 while (((data_length + i) % 4) != 0)
924 frame_type = pntohl(&s_510006_ptr[v22_W_FRAME_TYPE_OFF]);
926 if (rec_size == (data_length + v22_W_STATS_LEN + i) && (frame_type & v22_W_IS_80211) == 0x1000000) {
927 fpga_version = vVW510006_W_FPGA;
931 /* Next for the series I Ethernet */
932 if ((rec_size > v22_E_STATS_LEN) && (fpga_version == 1000)) {
933 s_510012_ptr = &(rec[rec_size - v22_E_STATS_LEN]); /* point to 510012 enet */
935 data_length = pntohs(&s_510012_ptr[v22_E_OCTET_OFF]);
937 while (((data_length + i) % 4) != 0)
940 if (rec_size == (data_length + v22_E_STATS_LEN + i))
941 fpga_version = vVW510012_E_FPGA;
945 /* Next the series II WLAN */
946 if ((rec_size > vVW510021_W_STATS_LEN) && (fpga_version == 1000)) {
949 data_length = (256 * (rec[vVW510021_W_MSDU_LENGTH_OFF + 1] & 0x1f)) + rec[vVW510021_W_MSDU_LENGTH_OFF];
952 while (((data_length + i) % 4) != 0)
955 /*the 12 is from the 12 bytes of plcp header */
956 if (rec_size == (data_length + vVW510021_W_STATS_LEN +vVW510021_W_AFTERHEADER_LEN+12+i))
957 fpga_version = vVW510021_W_FPGA;
960 /* Finally the Series II Ethernet */
961 if ((rec_size > vVW510024_E_STATS_LEN) && (fpga_version == 1000)) {
962 s_510024_ptr = &(rec[rec_size - vVW510024_E_STATS_LEN]); /* point to 510024 ENET */
963 data_length = pntohs(&s_510024_ptr[vVW510024_E_MSDU_LENGTH_OFF]);
966 while (((data_length + i) % 4) != 0)
969 if (rec_size == (data_length + vVW510024_E_STATS_LEN + i))
970 fpga_version = vVW510024_E_FPGA;
972 if (fpga_version != 1000)
974 /* reset the file position offset */
975 if (file_seek (wth->fh, filePos, SEEK_SET, err) == -1) {
978 /* We found an FPGA that works */
979 return(fpga_version);
985 *err = file_error(wth->fh, err_info);
987 return(UNKNOWN_FPGA); /* short read - not a vwr file */
991 /* copy the actual packet data from the capture file into the target data block */
992 /* the packet is constructed as a 38-byte VeriWave-extended Radiotap header plus the raw */
995 static void vwr_read_rec_data(wtap *wth, guint8 *data_ptr, guint8 *rec, int rec_size)
997 vwr_t *vwr = (vwr_t *)wth->priv;
998 int bytes_written = 0; /* bytes output to buf so far */
999 register int i; /* temps */
1000 register guint8 *s_ptr, *m_ptr; /* stats and MPDU pointers */
1001 gint16 octets, msdu_length; /* octets in frame */
1002 guint8 m_type, flow_seq; /* mod type (CCK-L/CCK-S/OFDM), seqnum */
1003 guint64 s_time = LL_ZERO, e_time = LL_ZERO; /* start/end */
1006 guint64 start_time, s_sec, s_usec = LL_ZERO; /* start time, sec + usec */
1007 guint64 end_time; /* end time */
1008 guint16 info; /* INFO/ERRORS fields in stats blk */
1009 gint16 rssi; /* RSSI, signed 16-bit number */
1010 int f_tx; /* flag: if set, is a TX frame */
1011 int f_flow, f_qos; /* flags: flow valid, frame is QoS */
1012 guint32 frame_type; /* frame type field */
1013 int rate; /* PHY bit rate in 0.5 Mb/s units */
1014 guint16 vc_id, flow_id, ht_len=0; /* VC ID, flow ID, total ip length */
1015 guint32 d_time, errors; /* packet duration & errors */
1016 guint16 r_hdr_len; /* length of radiotap headers */
1017 ext_rtap_fields er_fields; /* extended radiotap fields */
1018 stats_common_fields common_fields; /* extended radiotap fields */
1019 int mac_snap, sig_off, pay_off; /* MAC+SNAP header len, signature offset */
1020 guint64 sig_ts; /* 32 LSBs of timestamp in signature */
1022 /* calculate the start of the statistics block in the buffer */
1023 /* also get a bunch of fields from the stats block */
1024 s_ptr = &(rec[rec_size - vwr->STATS_LEN]); /* point to it */
1025 m_type = s_ptr[vwr->MTYPE_OFF] & vwr->MT_MASK;
1026 f_tx = !(s_ptr[vwr->MTYPE_OFF] & vwr->IS_RX);
1027 octets = pntohs(&s_ptr[vwr->OCTET_OFF]);
1028 vc_id = pntohs(&s_ptr[vwr->VCID_OFF]) & vwr->VCID_MASK;
1029 flow_seq = s_ptr[vwr->FLOWSEQ_OFF];
1031 f_flow = (s_ptr[vwr->VALID_OFF] & (guint8)vwr->FLOW_VALID) != 0;
1032 f_qos = (s_ptr[vwr->MTYPE_OFF] & vwr->IS_QOS) != 0;
1033 frame_type = pntohl(&s_ptr[vwr->FRAME_TYPE_OFF]);
1035 /* XXX - this is 48 bits, in a weird byte order */
1036 latency = pntohs(&s_ptr[vwr->LATVAL_OFF + 6]); /* latency MSbytes */
1037 for (i = 0; i < 4; i++)
1038 latency = (latency << 8) | s_ptr[vwr->LATVAL_OFF + i];
1040 flow_id = pntohs(&s_ptr[vwr->FLOWID_OFF + 1]); /* only 16 LSBs kept */
1041 errors = pntohs(&s_ptr[vwr->ERRORS_OFF]);
1043 info = pntohs(&s_ptr[vwr->INFO_OFF]);
1044 rssi = (s_ptr[vwr->RSSI_OFF] & 0x80) ? (-1 * (s_ptr[vwr->RSSI_OFF] & 0x7f)) : s_ptr[vwr->RSSI_OFF];
1045 /*if ((info && AGGREGATE_MASK) != 0)*/
1046 /* this length includes the Start_Spacing + Delimiter + MPDU + Padding for each piece of the aggregate*/
1047 /*ht_len = (int)pletohs(&rec[PLCP_LENGTH_OFF]);*/
1049 /* decode OFDM or CCK PLCP header and determine rate and short preamble flag */
1050 /* the SIGNAL byte is always the first byte of the PLCP header in the frame */
1051 if (m_type == vwr->MT_OFDM)
1052 rate = get_ofdm_rate(rec);
1053 else if ((m_type == vwr->MT_CCKL) || (m_type == vwr->MT_CCKS))
1054 rate = get_cck_rate(rec);
1057 /* calculate the MPDU size/ptr stuff; MPDU starts at 4 or 6 depending on OFDM/CCK */
1058 /* note that the number of octets in the frame also varies depending on OFDM/CCK, */
1059 /* because the PLCP header is prepended to the actual MPDU */
1060 m_ptr = &(rec[((m_type == vwr->MT_OFDM) ? 4 : 6)]);
1061 octets -= (m_type == vwr->MT_OFDM) ? 4 : 6;
1063 /* sanity check the octets field to determine if it is OK (or segfaults result) */
1064 /* if it's greater, then truncate to actual record size */
1065 if (octets > (rec_size - (int)vwr->STATS_LEN))
1066 octets = (rec_size - (int)vwr->STATS_LEN);
1067 msdu_length = octets;
1070 /* calculate start & end times (in sec/usec), converting 64-bit times to usec */
1071 /* 64-bit times are "Corey-endian" */
1072 s_time = pcoreytohll(&s_ptr[vwr->STARTT_OFF]);
1073 e_time = pcoreytohll(&s_ptr[vwr->ENDT_OFF]);
1075 /* find the packet duration (difference between start and end times) */
1076 d_time = (guint32)((e_time - s_time) / NS_IN_US); /* find diff, converting to usec */
1078 /* also convert the packet start time to seconds and microseconds */
1079 start_time = s_time / NS_IN_US; /* convert to microseconds first */
1080 s_sec = (start_time / US_IN_SEC); /* get the number of seconds */
1081 s_usec = start_time - (s_sec * US_IN_SEC); /* get the number of microseconds */
1083 /* also convert the packet end time to seconds and microseconds */
1084 end_time = e_time / NS_IN_US; /* convert to microseconds first */
1086 /* extract the 32 LSBs of the signature timestamp field from the data block*/
1087 mac_snap = (f_qos ? 34 : 32); /* 24 (MAC) + 2 (QoS) + 8 (SNAP) */
1089 if (frame_type & vwr->IS_TCP) /* signature offset for TCP frame */
1091 pay_off = mac_snap + 40;
1093 else if (frame_type & vwr->IS_UDP) /* signature offset for UDP frame */
1095 pay_off = mac_snap + 28;
1097 else if (frame_type & vwr->IS_ICMP) /* signature offset for ICMP frame */
1099 pay_off = mac_snap + 24;
1101 else if (frame_type & vwr->IS_IGMP) /* signature offset for IGMPv2 frame */
1103 pay_off = mac_snap + 28;
1105 else /* signature offset for raw IP frame */
1107 pay_off = mac_snap + 20;
1110 sig_off = find_signature(m_ptr, pay_off, flow_id, flow_seq);
1111 if ((m_ptr[sig_off] == 0xdd) && (sig_off + 15 <= msdu_length) && (f_flow != 0))
1112 sig_ts = get_signature_ts(m_ptr, sig_off);
1116 /* fill up the per-packet header (amazingly like a PCAP packet header! ;-) */
1117 /* frames are always 802.11, with an extended radiotap header */
1118 /* caplen is the length that is captured into the file (i.e., the written-out frame */
1119 /* block), and should always represent the actual number of bytes in the file */
1120 /* len is the length of the original packet before truncation; */
1121 /* the FCS is NOT included */
1122 r_hdr_len = STATS_COMMON_FIELDS_LEN + EXT_RTAP_FIELDS_LEN;
1124 wth->phdr.len = (msdu_length - 4) + r_hdr_len;
1125 wth->phdr.caplen = (octets - 4) + r_hdr_len;
1127 wth->phdr.presence_flags = WTAP_HAS_TS;
1129 wth->phdr.ts.secs = (time_t)s_sec;
1130 wth->phdr.ts.nsecs = (int)(s_usec * 1000);
1131 wth->phdr.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
1133 /* generate and copy out the radiotap header, set the port type to 0 (WLAN) */
1134 common_fields.vw_port_type = 0;
1135 common_fields.it_len = STATS_COMMON_FIELDS_LEN;
1136 er_fields.it_len = EXT_RTAP_FIELDS_LEN;
1138 /* create the extended radiotap header fields */
1139 er_fields.flags = (m_type == vwr->MT_CCKS) ? RADIOTAP_F_SHORTPRE : 0;
1141 er_fields.rate = rate;
1142 er_fields.chanflags = (m_type == vwr->MT_OFDM) ? CHAN_OFDM : CHAN_CCK;
1143 er_fields.signal = f_tx ? 100 : (gint8)rssi;
1144 er_fields.tx_power = f_tx ? ((gint8)rssi) : 100;
1146 /* fill in the VeriWave flags field */
1147 er_fields.vw_flags = 0;
1149 er_fields.vw_flags |= RADIOTAP_VWF_TXF;
1150 if (errors & vwr->FCS_ERROR)
1151 er_fields.vw_flags |= RADIOTAP_VWF_FCSERR;
1152 if (!f_tx && (errors & vwr->CRYPTO_ERR))
1153 er_fields.vw_flags |= RADIOTAP_VWF_DCRERR;
1154 if (!f_tx && (errors & vwr->RETRY_ERR))
1155 er_fields.vw_flags |= RADIOTAP_VWF_RETRERR;
1156 if (info & vwr->WEPTYPE)
1157 er_fields.vw_flags |= RADIOTAP_VWF_IS_WEP;
1158 else if (info & vwr->TKIPTYPE)
1159 er_fields.vw_flags |= RADIOTAP_VWF_IS_TKIP;
1160 else if (info & vwr->CCMPTYPE)
1161 er_fields.vw_flags |= RADIOTAP_VWF_IS_CCMP;
1163 er_fields.vw_errors = (guint32)errors;
1164 common_fields.vw_vcid = (guint16)vc_id;
1165 common_fields.vw_flowid = (guint16)flow_id;
1166 common_fields.vw_seqnum = (guint16)flow_seq;
1167 if (!f_tx && sig_ts != 0)
1168 common_fields.vw_latency = (guint32)latency;
1170 common_fields.vw_latency = 0;
1171 common_fields.vw_pktdur = (guint32)d_time;
1172 er_fields.vw_info = (guint16)info;
1173 common_fields.vw_msdu_length = (guint16)msdu_length;
1174 er_fields.vw_ht_length = (guint16)ht_len;
1175 common_fields.vw_sig_ts = (guint32)sig_ts; /* 32 LSBs of signature timestamp (nsec) */
1176 common_fields.vw_startt = start_time; /* record start & end times of frame */
1177 common_fields.vw_endt = end_time;
1179 /* put common_fields into the packet buffer in little-endian byte order */
1180 phtoles(&data_ptr[bytes_written], common_fields.vw_port_type);
1182 phtoles(&data_ptr[bytes_written], common_fields.it_len);
1184 phtoles(&data_ptr[bytes_written], common_fields.vw_msdu_length);
1187 memset(&data_ptr[bytes_written], 0, 2);
1189 phtolel(&data_ptr[bytes_written], common_fields.vw_flowid);
1191 phtoles(&data_ptr[bytes_written], common_fields.vw_vcid);
1193 phtoles(&data_ptr[bytes_written], common_fields.vw_seqnum);
1195 phtolel(&data_ptr[bytes_written], common_fields.vw_latency);
1197 phtolel(&data_ptr[bytes_written], common_fields.vw_sig_ts);
1199 phtolell(&data_ptr[bytes_written], common_fields.vw_startt);
1201 phtolell(&data_ptr[bytes_written], common_fields.vw_endt);
1203 phtolel(&data_ptr[bytes_written], common_fields.vw_pktdur);
1206 memset(&data_ptr[bytes_written], 0, 4);
1209 /* put er_fields into the packet buffer in little-endian byte order */
1210 phtoles(&data_ptr[bytes_written], er_fields.it_len);
1212 phtoles(&data_ptr[bytes_written], er_fields.flags);
1214 phtoles(&data_ptr[bytes_written], er_fields.chanflags);
1216 data_ptr[bytes_written] = er_fields.rate;
1218 data_ptr[bytes_written] = er_fields.signal;
1220 data_ptr[bytes_written] = er_fields.tx_power;
1223 data_ptr[bytes_written] = 0;
1225 phtoles(&data_ptr[bytes_written], er_fields.vw_flags);
1227 phtoles(&data_ptr[bytes_written], er_fields.vw_ht_length);
1229 phtoles(&data_ptr[bytes_written], er_fields.vw_info);
1231 phtolel(&data_ptr[bytes_written], er_fields.vw_errors);
1234 /* finally, copy the whole MAC frame to the packet buffer as-is; exclude FCS */
1235 if ( rec_size < ((int)msdu_length + (int)vwr->STATS_LEN) )
1236 /*something's been truncated, DUMP AS-IS*/
1237 memcpy(&data_ptr[bytes_written], m_ptr, octets);
1238 else if (octets >= 4)
1239 memcpy(&data_ptr[bytes_written], m_ptr, octets - 4);
1241 memcpy(&data_ptr[bytes_written], m_ptr, octets);
1244 /* Read the next packet for vVW510021 FPGAs */
1245 /* note that the VWR file format consists of a sequence of fixed 16-byte record headers of */
1246 /* different types; some types, including frame record headers, are followed by */
1247 /* variable-length data */
1248 /* a frame record consists of: the above 16-byte record header, a 1-16384 byte raw PLCP */
1249 /* frame, and a 56-byte statistics block trailer */
1250 /* the PLCP frame consists of a 4-byte or 6-byte PLCP header, followed by the MAC frame */
1251 /* copy the actual packet data from the capture file into the target data block */
1252 /* the packet is constructed as a 38-byte VeriWave-extended Radiotap header plus the raw */
1255 static void vwr_read_rec_data_vVW510021(wtap *wth, guint8 *data_ptr, guint8 *rec, int rec_size, int IS_TX)
1257 vwr_t *vwr = (vwr_t *)wth->priv;
1258 int bytes_written = 0; /* bytes output to buf so far */
1260 register int i; /* temps */
1261 register guint8 *s_start_ptr,*s_trail_ptr, *m_ptr,*plcp_ptr; /* stats & MPDU ptr */
1262 gint16 msdu_length, actual_octets; /* octets in frame */
1263 guint8 l1p_1,l1p_2, flow_seq, plcp_type, mcs_index; /* mod (CCK-L/CCK-S/OFDM) */
1264 guint64 s_time = LL_ZERO, e_time = LL_ZERO; /* start/end */
1266 guint64 latency = LL_ZERO;
1267 guint64 start_time, s_sec, s_usec = LL_ZERO; /* start time, sec + usec */
1268 guint64 end_time; /* end time */
1269 guint16 info, validityBits; /* INFO/ERRORS fields in stats blk */
1271 gint16 rssi; /* RSSI, signed 16-bit number */
1272 int f_tx; /* flag: if set, is a TX frame */
1273 int f_flow, f_qos; /* flags: flow valid, frame is QoS */
1274 guint32 frame_type; /* frame type field */
1275 guint8 rate; /* PHY bit rate in 0.5 Mb/s units */
1276 guint16 vc_id, ht_len=0; /* VC ID , total ip length*/
1277 guint32 flow_id, d_time; /* flow ID, packet duration*/
1278 guint16 r_hdr_len; /* length of radiotap headers */
1279 ext_rtap_fields er_fields; /* extended radiotap fields */
1280 stats_common_fields common_fields; /* extended radiotap fields */
1281 gint8 tx_power = 0; /* transmit power value in dBm */
1282 int mac_snap, sig_off, pay_off; /* MAC+SNAP header len, signature offset */
1283 guint64 sig_ts, tsid; /* 32 LSBs of timestamp in signature */
1284 guint16 chanflags = 0; /* extended radio tap channel flags */
1285 guint16 radioflags = 0; /* extended radio tap flags */
1286 guint64 delta_b; /* Used for calculating latency */
1288 /* calculate the start of the statistics block in the buffer */
1289 /* also get a bunch of fields from the stats block */
1290 s_start_ptr = &(rec[0]);
1291 s_trail_ptr = &(rec[rec_size - vwr->STATS_LEN]); /* point to it */
1293 l1p_1 = s_start_ptr[vwr->L1P_1_OFF];
1294 mcs_index = l1p_1 & (guint8)vVW510021_W_MCS_MASK;
1295 l1p_2 = s_start_ptr[vwr->L1P_2_OFF];
1296 plcp_type = l1p_2 & (guint8)vVW510021_W_PLCPC_MASK;
1297 msdu_length = (256 * (s_start_ptr[vwr->OCTET_OFF + 1] & 0x1f)) + s_start_ptr[vwr->OCTET_OFF];
1298 /* If the packet has an MSDU length of 0, then bail - malformed packet */
1299 /* if (msdu_length < 4) return; */
1300 actual_octets = msdu_length;
1304 vc_id = pntohs(&s_start_ptr[vwr->VCID_OFF]);
1305 flow_seq = s_trail_ptr[vwr->FLOWSEQ_OFF];
1306 validityBits = pntohs(&s_trail_ptr[vwr->VALID_OFF]);
1308 f_flow = (validityBits & vwr->FLOW_VALID) != 0;
1309 f_qos = (validityBits & vwr->IS_QOS) != 0;
1311 frame_type = pntohl(&s_trail_ptr[vwr->FRAME_TYPE_OFF]);
1313 latency = 0x00000000; /* clear latency */
1314 flow_id = pntoh24(&s_trail_ptr[vwr->FLOWID_OFF]); /* all 24 bits valid */
1315 /* for tx latency is duration, for rx latency is timestamp */
1316 /* get 48-bit latency value */
1317 tsid = (s_trail_ptr[vwr->LATVAL_OFF + 6] << 8) | (s_trail_ptr[vwr->LATVAL_OFF + 7]);
1319 for (i = 0; i < 4; i++)
1320 tsid = (tsid << 8) | s_trail_ptr[vwr->LATVAL_OFF + i];
1322 errors = pntohl(&s_trail_ptr[vwr->ERRORS_OFF]);
1323 info = pntohs(&s_trail_ptr[vwr->INFO_OFF]);
1324 if ((info & 0xFC00) != 0)
1325 /* this length includes the Start_Spacing + Delimiter + MPDU + Padding for each piece of the aggregate*/
1326 ht_len = pletohs(&s_start_ptr[vwr->PLCP_LENGTH_OFF]);
1328 rssi = s_start_ptr[vwr->RSSI_OFF];
1331 tx_power = -1 * (rssi & 0x7f);
1333 tx_power = rssi & 0x7f;
1335 if (rssi > 128) rssi = rssi - 256; /* Signed 2's complement */
1338 /* decode OFDM or CCK PLCP header and determine rate and short preamble flag */
1339 /* the SIGNAL byte is always the first byte of the PLCP header in the frame */
1340 plcp_ptr = &(rec[PLCP_OFF]);
1341 if (plcp_type == vVW510021_W_PLCP_LEGACY){
1342 if (mcs_index < 4) {
1343 rate = get_cck_rate(plcp_ptr);
1344 chanflags |= CHAN_CCK;
1347 rate = get_ofdm_rate(plcp_ptr);
1348 chanflags |= CHAN_OFDM;
1351 else if (plcp_type == vVW510021_W_PLCP_MIXED) {
1352 /* pack the rate field with mcs index and gi */
1353 rate = (plcp_ptr[3] & 0x7f) + (plcp_ptr[6] & 0x80);
1354 /* set the appropriate flags to indicate HT mode and CB */
1355 radioflags |= RADIOTAP_F_CHAN_HT | ((plcp_ptr[3] & 0x80) ? RADIOTAP_F_CHAN_40MHZ : 0) |
1356 ((plcp_ptr[6] & 0x80) ? RADIOTAP_F_CHAN_SHORTGI : 0);
1357 chanflags |= CHAN_OFDM;
1359 else if (plcp_type == vVW510021_W_PLCP_GREENFIELD) {
1360 /* pack the rate field with mcs index and gi */
1361 rate = (plcp_ptr[0] & 0x7f) + (plcp_ptr[3] & 0x80);
1362 /* set the appropriate flags to indicate HT mode and CB */
1363 radioflags |= RADIOTAP_F_CHAN_HT | ((plcp_ptr[0] & 0x80) ? RADIOTAP_F_CHAN_40MHZ : 0) |
1364 ((plcp_ptr[3] & 0x80) ? RADIOTAP_F_CHAN_SHORTGI : 0);
1365 chanflags |= CHAN_OFDM;
1371 /* calculate the MPDU size/ptr stuff; MPDU starts at 4 or 6 depending on OFDM/CCK */
1372 /* note that the number of octets in the frame also varies depending on OFDM/CCK, */
1373 /* because the PLCP header is prepended to the actual MPDU */
1374 /*the 8 is from the 8 bytes of stats block that precede the plcps ,
1375 the 12 is for 11 bytes plcp and 1 byte of pad before the data*/
1376 m_ptr = &(rec[8+12]);
1378 /* sanity check the msdu_length field to determine if it is OK (or segfaults result) */
1379 /* if it's greater, then truncate to the indicated message length */
1380 /*changed the comparison
1381 if (msdu_length > (rec_size )) {
1382 msdu_length = (rec_size );
1385 if (msdu_length > (rec_size - (int)vwr->STATS_LEN)) {
1386 msdu_length = (rec_size - (int)vwr->STATS_LEN);
1389 /* calculate start & end times (in sec/usec), converting 64-bit times to usec */
1390 /* 64-bit times are "Corey-endian" */
1391 s_time = pcoreytohll(&s_trail_ptr[vwr->STARTT_OFF]);
1392 e_time = pcoreytohll(&s_trail_ptr[vwr->ENDT_OFF]);
1394 /* find the packet duration (difference between start and end times) */
1395 d_time = (guint32)((e_time - s_time) / NS_IN_US); /* find diff, converting to usec */
1397 /* also convert the packet start time to seconds and microseconds */
1398 start_time = s_time / NS_IN_US; /* convert to microseconds first */
1399 s_sec = (start_time / US_IN_SEC); /* get the number of seconds */
1400 s_usec = start_time - (s_sec * US_IN_SEC); /* get the number of microseconds */
1402 /* also convert the packet end time to seconds and microseconds */
1403 end_time = e_time / NS_IN_US; /* convert to microseconds first */
1405 /* extract the 32 LSBs of the signature timestamp field */
1406 mac_snap = (f_qos ? 34 : 32); /* 24 (MAC) + 2 (QoS) + 8 (SNAP) */
1408 if (frame_type & vwr->IS_TCP) /* signature offset for TCP frame */
1410 pay_off = mac_snap + 40;
1412 else if (frame_type & vwr->IS_UDP) /* signature offset for UDP frame */
1414 pay_off = mac_snap + 28;
1416 else if (frame_type & vwr->IS_ICMP) /* signature offset for ICMP frame */
1418 pay_off = mac_snap + 24;
1420 else if (frame_type & vwr->IS_IGMP) /* signature offset for IGMPv2 frame */
1422 pay_off = mac_snap + 28;
1424 else /* signature offset for raw IP frame */
1426 pay_off = mac_snap + 20;
1429 sig_off = find_signature(m_ptr, pay_off, flow_id, flow_seq);
1430 if ((m_ptr[sig_off] == 0xdd) && (sig_off + 15 <= msdu_length) && (f_flow != 0))
1431 sig_ts = get_signature_ts(m_ptr, sig_off);
1435 /* Set latency based on rx/tx and signature timestamp */
1437 if (tsid < s_time) {
1438 latency = s_time - tsid;
1440 /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
1441 /* we look for a large difference between l_time and s_time. */
1442 delta_b = tsid - s_time;
1443 if (delta_b > 0x10000000)
1450 /* fill up the per-packet header (amazingly like a PCAP packet header! ;-) */
1451 /* frames are always 802.11, with an extended radiotap header */
1452 /* caplen is the length that is captured into the file (i.e., the written-out frame */
1453 /* block), and should always represent the actual number of bytes in the file */
1454 /* len is the length of the original packet before truncation */
1455 /* the FCS is NOT included */
1456 r_hdr_len = STATS_COMMON_FIELDS_LEN + EXT_RTAP_FIELDS_LEN;
1457 wth->phdr.len = (actual_octets - 4) + r_hdr_len;
1458 wth->phdr.caplen = (msdu_length - 4) + r_hdr_len;
1460 wth->phdr.presence_flags = WTAP_HAS_TS;
1462 wth->phdr.ts.secs = (time_t)s_sec;
1463 wth->phdr.ts.nsecs = (int)(s_usec * 1000);
1464 wth->phdr.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
1466 /* generate and copy out the radiotap header, set the port type to 0 (WLAN) */
1467 common_fields.vw_port_type = 0;
1468 common_fields.it_len = STATS_COMMON_FIELDS_LEN;
1469 er_fields.it_len = EXT_RTAP_FIELDS_LEN;
1471 /* create the extended radiotap header fields */
1472 er_fields.flags = radioflags;
1473 if (info & vVW510021_W_IS_WEP)
1474 er_fields.flags |= RADIOTAP_F_WEP;
1475 if ((l1p_1 & vVW510021_W_PREAMBLE_MASK) != vVW510021_W_IS_LONGPREAMBLE)
1476 er_fields.flags |= RADIOTAP_F_SHORTPRE;
1478 er_fields.rate = rate;
1479 er_fields.chanflags = chanflags;
1482 er_fields.tx_power = (gint8)tx_power;
1483 er_fields.signal = 100;
1486 er_fields.tx_power = 100;
1487 er_fields.signal = (gint8)rssi;
1490 /* fill in the VeriWave flags field */
1491 er_fields.vw_flags = 0;
1493 er_fields.vw_flags |= RADIOTAP_VWF_TXF;
1494 if (errors & vwr->FCS_ERROR)
1495 er_fields.vw_flags |= RADIOTAP_VWF_FCSERR;
1496 if (!f_tx && (errors & vwr->CRYPTO_ERR))
1497 er_fields.vw_flags |= RADIOTAP_VWF_DCRERR;
1498 if (!f_tx && (errors & vwr->RETRY_ERR))
1499 er_fields.vw_flags |= RADIOTAP_VWF_RETRERR;
1500 if (info & vwr->WEPTYPE)
1501 er_fields.vw_flags |= RADIOTAP_VWF_IS_WEP;
1502 else if (info & vwr->TKIPTYPE)
1503 er_fields.vw_flags |= RADIOTAP_VWF_IS_TKIP;
1504 else if (info & vwr->CCMPTYPE)
1505 er_fields.vw_flags |= RADIOTAP_VWF_IS_CCMP;
1507 er_fields.vw_errors = (guint32)errors;
1508 common_fields.vw_vcid = (guint16)vc_id;
1510 common_fields.vw_msdu_length = (guint16)msdu_length;
1511 er_fields.vw_ht_length = (guint16)ht_len;
1513 common_fields.vw_flowid = (guint32)flow_id;
1514 common_fields.vw_seqnum = (guint16)flow_seq;
1515 if (!f_tx && (sig_ts != 0) )
1516 common_fields.vw_latency = (guint32)latency;
1518 common_fields.vw_latency = 0;
1519 common_fields.vw_pktdur = (guint32)d_time;
1520 er_fields.vw_info = (guint16)info;
1522 er_fields.vw_startt = s_time;
1523 er_fields.vw_endt = e_time;
1525 common_fields.vw_startt = start_time; /* record start & end times of frame */
1526 common_fields.vw_endt = end_time;
1527 common_fields.vw_sig_ts = (guint32)(sig_ts);/* 32 LSBs of signature */
1529 /* put common_fields into the packet buffer in little-endian byte order */
1530 phtoles(&data_ptr[bytes_written], common_fields.vw_port_type);
1532 phtoles(&data_ptr[bytes_written], common_fields.it_len);
1534 phtoles(&data_ptr[bytes_written], common_fields.vw_msdu_length);
1537 memset(&data_ptr[bytes_written], 0, 2);
1539 phtolel(&data_ptr[bytes_written], common_fields.vw_flowid);
1541 phtoles(&data_ptr[bytes_written], common_fields.vw_vcid);
1543 phtoles(&data_ptr[bytes_written], common_fields.vw_seqnum);
1545 phtolel(&data_ptr[bytes_written], common_fields.vw_latency);
1547 phtolel(&data_ptr[bytes_written], common_fields.vw_sig_ts);
1549 phtolell(&data_ptr[bytes_written], common_fields.vw_startt);
1551 phtolell(&data_ptr[bytes_written], common_fields.vw_endt);
1553 phtolel(&data_ptr[bytes_written], common_fields.vw_pktdur);
1556 memset(&data_ptr[bytes_written], 0, 4);
1559 /* put er_fields into the packet buffer in little-endian byte order */
1560 phtoles(&data_ptr[bytes_written], er_fields.it_len);
1562 phtoles(&data_ptr[bytes_written], er_fields.flags);
1564 phtoles(&data_ptr[bytes_written], er_fields.chanflags);
1566 data_ptr[bytes_written] = er_fields.rate;
1568 data_ptr[bytes_written] = er_fields.signal;
1570 data_ptr[bytes_written] = er_fields.tx_power;
1573 data_ptr[bytes_written] = 0;
1575 phtoles(&data_ptr[bytes_written], er_fields.vw_flags);
1577 phtoles(&data_ptr[bytes_written], er_fields.vw_ht_length);
1579 phtoles(&data_ptr[bytes_written], er_fields.vw_info);
1581 phtolel(&data_ptr[bytes_written], er_fields.vw_errors);
1584 /* finally, copy the whole MAC frame to the packet buffer as-is; exclude 4-byte FCS */
1585 if ( rec_size < ((int)actual_octets + (int)vwr->STATS_LEN) )
1586 /*something's been truncated, DUMP AS-IS*/
1587 memcpy(&data_ptr[bytes_written], m_ptr, msdu_length);
1588 else if (msdu_length >= 4)
1589 memcpy(&data_ptr[bytes_written], m_ptr, msdu_length - 4);
1591 memcpy(&data_ptr[bytes_written], m_ptr, msdu_length);
1594 /* read an Ethernet packet */
1595 /* copy the actual packet data from the capture file into the target data block */
1596 /* the packet is constructed as a 38-byte VeriWave-extended Radiotap header plus the raw */
1599 static void vwr_read_rec_data_ethernet(wtap *wth, guint8 *data_ptr, guint8 *rec, int rec_size, int IS_TX)
1601 vwr_t *vwr = (vwr_t *)wth->priv;
1602 int bytes_written = 0; /* bytes output to buf so far */
1603 register int i; /* temps */
1604 register guint8 *s_ptr, *m_ptr; /* stats and MPDU pointers */
1605 guint16 msdu_length,actual_octets; /* octets in frame */
1606 guint8 flow_seq; /* seqnum */
1607 guint64 s_time = LL_ZERO, e_time = LL_ZERO; /* start/end */
1609 guint32 latency = 0;
1610 guint64 start_time, s_sec, s_usec = LL_ZERO; /* start time, sec + usec */
1611 guint64 end_time; /* end time */
1612 guint16 l4id, info, validityBits; /* INFO/ERRORS fields in stats */
1614 guint16 vc_id; /* VC ID, total (incl of aggregates) */
1615 guint32 flow_id, d_time; /* packet duration */
1616 int f_flow; /* flags: flow valid */
1617 guint32 frame_type; /* frame type field */
1618 stats_ethernettap_fields etap_hdr; /* VWR ethernettap header */
1619 stats_common_fields common_hdr; /* VWR common header */
1620 guint16 e_hdr_len; /* length of ethernettap headers */
1621 int mac_len, sig_off, pay_off; /* MAC header len, signature offset */
1622 guint64 sig_ts, tsid; /* 32 LSBs of timestamp in signature */
1623 guint64 delta_b; /* Used for calculating latency */
1625 /* calculate the start of the statistics block in the buffer */
1626 /* also get a bunch of fields from the stats block */
1627 m_ptr = &(rec[0]); /* point to the data block */
1628 s_ptr = &(rec[rec_size - vwr->STATS_LEN]); /* point to the stats block */
1630 msdu_length = pntohs(&s_ptr[vwr->OCTET_OFF]);
1631 actual_octets = msdu_length;
1632 /* sanity check the msdu_length field to determine if it is OK (or segfaults result) */
1633 /* if it's greater, then truncate to the indicated message length */
1634 if (msdu_length > (rec_size - (int)vwr->STATS_LEN)) {
1635 msdu_length = (rec_size - (int)vwr->STATS_LEN);
1638 vc_id = pntohs(&s_ptr[vwr->VCID_OFF]) & vwr->VCID_MASK;
1639 flow_seq = s_ptr[vwr->FLOWSEQ_OFF];
1640 frame_type = pntohl(&s_ptr[vwr->FRAME_TYPE_OFF]);
1642 if (vwr->FPGA_VERSION == vVW510024_E_FPGA) {
1643 validityBits = pntohs(&s_ptr[vwr->VALID_OFF]);
1644 f_flow = validityBits & vwr->FLOW_VALID;
1646 mac_len = (validityBits & vwr->IS_VLAN) ? 16 : 14; /* MAC hdr length based on VLAN tag */
1649 errors = pntohs(&s_ptr[vwr->ERRORS_OFF]);
1652 f_flow = s_ptr[vwr->VALID_OFF] & vwr->FLOW_VALID;
1653 mac_len = (frame_type & vwr->IS_VLAN) ? 16 : 14; /* MAC hdr length based on VLAN tag */
1656 /*for older fpga errors is only represented by 16 bits)*/
1657 errors = pntohs(&s_ptr[vwr->ERRORS_OFF]);
1660 info = pntohs(&s_ptr[vwr->INFO_OFF]);
1662 flow_id = pntoh24(&s_ptr[vwr->FLOWID_OFF]);
1664 /* for tx latency is duration, for rx latency is timestamp */
1665 /* get 64-bit latency value */
1666 tsid = (s_ptr[vwr->LATVAL_OFF + 6] << 8) | (s_ptr[vwr->LATVAL_OFF + 7]);
1667 for (i = 0; i < 4; i++)
1668 tsid = (tsid << 8) | s_ptr[vwr->LATVAL_OFF + i];
1671 l4id = pntohs(&s_ptr[vwr->L4ID_OFF]);
1673 /* calculate start & end times (in sec/usec), converting 64-bit times to usec */
1674 /* 64-bit times are "Corey-endian" */
1675 s_time = pcoreytohll(&s_ptr[vwr->STARTT_OFF]);
1676 e_time = pcoreytohll(&s_ptr[vwr->ENDT_OFF]);
1678 /* find the packet duration (difference between start and end times) */
1679 d_time = (guint32)((e_time - s_time)); /* find diff, leaving in nsec for Ethernet */
1681 /* also convert the packet start time to seconds and microseconds */
1682 start_time = s_time / NS_IN_US; /* convert to microseconds first */
1683 s_sec = (start_time / US_IN_SEC); /* get the number of seconds */
1684 s_usec = start_time - (s_sec * US_IN_SEC); /* get the number of microseconds */
1686 /* also convert the packet end time to seconds and microseconds */
1687 end_time = e_time / NS_IN_US; /* convert to microseconds first */
1689 if (frame_type & vwr->IS_TCP) /* signature offset for TCP frame */
1691 pay_off = mac_len + 40;
1693 else if (frame_type & vwr->IS_UDP) /* signature offset for UDP frame */
1695 pay_off = mac_len + 28;
1697 else if (frame_type & vwr->IS_ICMP) /* signature offset for ICMP frame */
1699 pay_off = mac_len + 24;
1701 else if (frame_type & vwr->IS_IGMP) /* signature offset for IGMPv2 frame */
1703 pay_off = mac_len + 28;
1705 else /* signature offset for raw IP frame */
1707 pay_off = mac_len + 20;
1710 sig_off = find_signature(m_ptr, pay_off, flow_id, flow_seq);
1711 if ((m_ptr[sig_off] == 0xdd) && (sig_off + 15 <= msdu_length) && (f_flow != 0))
1712 sig_ts = get_signature_ts(m_ptr, sig_off);
1716 /* Set latency based on rx/tx and signature timestamp */
1718 if (sig_ts < s_time) {
1719 latency = (guint32)(s_time - sig_ts);
1721 /* Account for the rollover case. Since we cannot use 0x100000000 - l_time + s_time */
1722 /* we look for a large difference between l_time and s_time. */
1723 delta_b = sig_ts - s_time;
1724 if (delta_b > 0x10000000) {
1727 latency = (guint32)delta_b;
1730 /* fill up the per-packet header (amazingly like a PCAP packet header! ;-) */
1731 /* frames are always wired ethernet with a wired ethernettap header */
1732 /* caplen is the length that is captured into the file (i.e., the written-out frame */
1733 /* block), and should always represent the actual number of bytes in the file */
1734 /* len is the length of the original packet before truncation*/
1735 /* the FCS is NEVER included */
1736 e_hdr_len = STATS_COMMON_FIELDS_LEN + STATS_ETHERNETTAP_FIELDS_LEN;
1737 wth->phdr.len = (actual_octets - 4) + e_hdr_len;
1738 wth->phdr.caplen = (msdu_length - 4) + e_hdr_len;
1740 wth->phdr.presence_flags = WTAP_HAS_TS;
1742 wth->phdr.ts.secs = (time_t)s_sec;
1743 wth->phdr.ts.nsecs = (int)(s_usec * 1000);
1744 wth->phdr.pkt_encap = WTAP_ENCAP_IXVERIWAVE;
1746 /* generate and copy out the ETHERNETTAP header, set the port type to 1 (Ethernet) */
1747 common_hdr.vw_port_type = 1;
1748 common_hdr.it_len = STATS_COMMON_FIELDS_LEN;
1749 etap_hdr.it_len = STATS_ETHERNETTAP_FIELDS_LEN;
1751 etap_hdr.vw_errors = (guint32)errors;
1752 etap_hdr.vw_info = (guint16)info;
1753 common_hdr.vw_msdu_length = (guint16)msdu_length;
1754 /*etap_hdr.vw_ip_length = (guint16)ip_len;*/
1756 common_hdr.vw_flowid = (guint32)flow_id;
1757 common_hdr.vw_vcid = (guint16)vc_id;
1758 common_hdr.vw_seqnum = (guint16)flow_seq;
1760 if (!IS_TX && (sig_ts != 0))
1761 common_hdr.vw_latency = (guint32)latency;
1763 common_hdr.vw_latency = 0;
1764 common_hdr.vw_pktdur = (guint32)d_time;
1765 etap_hdr.vw_l4id = (guint32)l4id;
1766 etap_hdr.vw_flags = 0;
1768 etap_hdr.vw_flags |= RADIOTAP_VWF_TXF;
1769 if (errors & vwr->FCS_ERROR)
1770 etap_hdr.vw_flags |= RADIOTAP_VWF_FCSERR;
1771 common_hdr.vw_startt = start_time; /* record start & end times of frame */
1772 common_hdr.vw_endt = end_time;
1773 common_hdr.vw_sig_ts = (guint32)(sig_ts);
1775 etap_hdr.it_pad2 = 0;
1777 /* put common_hdr into the packet buffer in little-endian byte order */
1778 phtoles(&data_ptr[bytes_written], common_hdr.vw_port_type);
1780 phtoles(&data_ptr[bytes_written], common_hdr.it_len);
1782 phtoles(&data_ptr[bytes_written], common_hdr.vw_msdu_length);
1785 memset(&data_ptr[bytes_written], 0, 2);
1787 phtolel(&data_ptr[bytes_written], common_hdr.vw_flowid);
1789 phtoles(&data_ptr[bytes_written], common_hdr.vw_vcid);
1791 phtoles(&data_ptr[bytes_written], common_hdr.vw_seqnum);
1793 phtolel(&data_ptr[bytes_written], common_hdr.vw_latency);
1795 phtolel(&data_ptr[bytes_written], common_hdr.vw_sig_ts);
1797 phtolell(&data_ptr[bytes_written], common_hdr.vw_startt);
1799 phtolell(&data_ptr[bytes_written], common_hdr.vw_endt);
1801 phtolel(&data_ptr[bytes_written], common_hdr.vw_pktdur);
1804 memset(&data_ptr[bytes_written], 0, 4);
1807 /* put etap_hdr into the packet buffer in little-endian byte order */
1808 phtoles(&data_ptr[bytes_written], etap_hdr.it_len);
1810 phtoles(&data_ptr[bytes_written], etap_hdr.vw_flags);
1812 phtoles(&data_ptr[bytes_written], etap_hdr.vw_info);
1815 memset(&data_ptr[bytes_written], 0, 2);
1817 phtolel(&data_ptr[bytes_written], etap_hdr.vw_errors);
1819 phtolel(&data_ptr[bytes_written], etap_hdr.vw_l4id);
1822 memset(&data_ptr[bytes_written], 0, 4);
1825 /* finally, copy the whole MAC frame to the packet bufffer as-is; ALWAYS exclude 4-byte FCS */
1826 if ( rec_size < ((int)actual_octets + (int)vwr->STATS_LEN) )
1827 /*something's been truncated, DUMP AS-IS*/
1828 memcpy(&data_ptr[bytes_written], m_ptr, msdu_length);
1829 else if (msdu_length >= 4)
1830 memcpy(&data_ptr[bytes_written], m_ptr, msdu_length - 4);
1832 memcpy(&data_ptr[bytes_written], m_ptr, msdu_length);
1835 /*--------------------------------------------------------------------------------------*/
1836 /* utility to split up and decode a 16-byte message record */
1838 static int decode_msg(vwr_t *vwr, guint8 *rec, int *v_type, int *IS_TX)
1840 guint8 cmd; /* components of message */
1842 int v_size = 0; /* size of var-len message */
1843 /* assume it's zero */
1845 /* break up the message record into its pieces */
1847 wd2 = pntohl(&rec[8]);
1848 wd3 = pntohl(&rec[12]);
1851 if ((cmd & vwr->HEADER_IS_TX) == vwr->HEADER_IS_TX)
1853 else if ((cmd & vwr->HEADER_IS_RX) == vwr->HEADER_IS_RX)
1855 else *IS_TX = 2; /*NULL case*/
1857 /* now decode based on the command byte */
1861 v_size = (int)(wd2 & 0xffff);
1867 v_size = (int)(wd2 & 0xffff);
1872 v_size = (int)(wd3 & 0xffff);
1884 /*--------------------------------------------------------------------------------------*/
1885 /* utilities to extract and decode the PHY bit rate from 802.11 PLCP headers (OFDM/CCK) */
1886 /* they are passed a pointer to 4 or 6 consecutive bytes of PLCP header */
1887 /* the integer returned by the get_xxx_rate() functions is in units of 0.5 Mb/s */
1888 /* The string returned by the decode_xxx_rate() functions is 3 characters wide */
1890 static guint8 get_ofdm_rate(guint8 *plcp)
1892 /* extract the RATE field (LS nibble of first byte) then decode it */
1893 switch (plcp[0] & 0x0f) {
1894 case 0x0b: return(6 * 2);
1895 case 0x0f: return(9 * 2);
1896 case 0x0a: return(12 * 2);
1897 case 0x0e: return(18 * 2);
1898 case 0x09: return(24 * 2);
1899 case 0x0d: return(36 * 2);
1900 case 0x08: return(48 * 2);
1901 case 0x0c: return(54 * 2);
1906 static guint8 get_cck_rate(guint8 *plcp)
1908 /* extract rate from the SIGNAL field, 1 byte */
1910 case 0x0a: return(1 * 2);
1911 case 0x14: return(2 * 2);
1912 case 0x37: return(11); /* 5.5 Mb/s */
1913 case 0x6e: return(11 * 2);
1918 /*--------------------------------------------------------------------------------------*/
1919 /* utility to set up offsets and bitmasks for decoding the stats blocks */
1921 static void setup_defaults(vwr_t *vwr, guint16 fpga)
1925 case vVW510021_W_FPGA:
1926 vwr->STATS_LEN = vVW510021_W_STATS_LEN;
1928 vwr->VALID_OFF = vVW510021_W_VALID_OFF;
1929 vwr->MTYPE_OFF = vVW510021_W_MTYPE_OFF;
1930 vwr->VCID_OFF = vVW510021_W_VCID_OFF;
1931 vwr->FLOWSEQ_OFF = vVW510021_W_FLOWSEQ_OFF;
1932 vwr->FLOWID_OFF = vVW510021_W_FLOWID_OFF;
1934 /*vwr->OCTET_OFF = v22_W_OCTET_OFF;*/
1936 vwr->ERRORS_OFF = vVW510021_W_ERRORS_OFF;
1937 vwr->PATN_OFF = vVW510021_W_MATCH_OFF;
1938 vwr->RSSI_OFF = vVW510021_W_RSSI_TXPOWER_OFF;
1939 vwr->STARTT_OFF = vVW510021_W_STARTT_OFF;
1940 vwr->ENDT_OFF = vVW510021_W_ENDT_OFF;
1941 vwr->LATVAL_OFF = vVW510021_W_LATVAL_OFF;
1942 vwr->INFO_OFF = vVW510021_W_INFO_OFF;
1943 vwr->FPGA_VERSION_OFF = vVW510021_W_FPGA_VERSION_OFF;
1944 vwr->HEADER_VERSION_OFF = vVW510021_W_HEADER_VERSION_OFF;
1945 vwr->OCTET_OFF = vVW510021_W_MSDU_LENGTH_OFF;
1946 vwr->L1P_1_OFF = vVW510021_W_L1P_1_OFF;
1947 vwr->L1P_2_OFF = vVW510021_W_L1P_2_OFF;
1948 vwr->L4ID_OFF = vVW510021_W_L4ID_OFF;
1949 vwr->IPLEN_OFF = vVW510021_W_IPLEN_OFF;
1950 vwr->PLCP_LENGTH_OFF = vVW510021_W_PLCP_LENGTH_OFF;
1952 vwr->HEADER_IS_RX = vVW510021_W_HEADER_IS_RX;
1953 vwr->HEADER_IS_TX = vVW510021_W_HEADER_IS_TX;
1954 vwr->MT_MASK = vVW510021_W_SEL_MASK;
1955 vwr->MCS_INDEX_MASK = vVW510021_W_MCS_MASK;
1956 vwr->VCID_MASK = 0xffff;
1957 vwr->FLOW_VALID = vVW510021_W_FLOW_VALID;
1958 vwr->STATS_START_OFF = vVW510021_W_HEADER_LEN;
1959 vwr->FCS_ERROR = vVW510021_W_FCS_ERROR;
1960 vwr->CRYPTO_ERR = v22_W_CRYPTO_ERR;
1961 vwr->RETRY_ERR = v22_W_RETRY_ERR;
1963 /*vwr->STATS_START_OFF = 0;*/
1965 vwr->RXTX_OFF = vVW510021_W_RXTX_OFF;
1967 vwr->MT_10_HALF = 0;
1968 vwr->MT_10_FULL = 0;
1969 vwr->MT_100_HALF = 0;
1970 vwr->MT_100_FULL = 0;
1971 vwr->MT_1G_HALF = 0;
1972 vwr->MT_1G_FULL = 0;
1973 vwr->MT_CCKL = v22_W_MT_CCKL;
1974 vwr->MT_CCKS = v22_W_MT_CCKS;
1975 /*vwr->MT_OFDM = vVW510021_W_MT_OFDM;*/
1977 vwr->WEPTYPE = vVW510021_W_WEPTYPE;
1978 vwr->TKIPTYPE = vVW510021_W_TKIPTYPE;
1979 vwr->CCMPTYPE = vVW510021_W_CCMPTYPE;
1981 vwr->FRAME_TYPE_OFF = vVW510021_W_FRAME_TYPE_OFF;
1982 vwr->IS_TCP = vVW510021_W_IS_TCP;
1983 vwr->IS_UDP = vVW510021_W_IS_UDP;
1984 vwr->IS_ICMP = vVW510021_W_IS_ICMP;
1985 vwr->IS_IGMP = vVW510021_W_IS_IGMP;
1986 vwr->IS_QOS = vVW510021_W_QOS_VALID;
1990 /* Ethernet frames */
1991 case vVW510012_E_FPGA:
1992 vwr->STATS_LEN = v22_E_STATS_LEN;
1994 vwr->VALID_OFF = v22_E_VALID_OFF;
1995 vwr->MTYPE_OFF = v22_E_MTYPE_OFF;
1996 vwr->VCID_OFF = v22_E_VCID_OFF;
1997 vwr->FLOWSEQ_OFF = v22_E_FLOWSEQ_OFF;
1998 vwr->FLOWID_OFF = v22_E_FLOWID_OFF;
1999 vwr->OCTET_OFF = v22_E_OCTET_OFF;
2000 vwr->ERRORS_OFF = v22_E_ERRORS_OFF;
2001 vwr->PATN_OFF = v22_E_PATN_OFF;
2002 vwr->RSSI_OFF = v22_E_RSSI_OFF;
2003 vwr->STARTT_OFF = v22_E_STARTT_OFF;
2004 vwr->ENDT_OFF = v22_E_ENDT_OFF;
2005 vwr->LATVAL_OFF = v22_E_LATVAL_OFF;
2006 vwr->INFO_OFF = v22_E_INFO_OFF;
2007 vwr->L4ID_OFF = v22_E_L4ID_OFF;
2009 vwr->HEADER_IS_RX = v22_E_HEADER_IS_RX;
2010 vwr->HEADER_IS_TX = v22_E_HEADER_IS_TX;
2012 vwr->IS_RX = v22_E_IS_RX;
2013 vwr->MT_MASK = v22_E_MT_MASK;
2014 vwr->VCID_MASK = v22_E_VCID_MASK;
2015 vwr->FLOW_VALID = v22_E_FLOW_VALID;
2016 vwr->FCS_ERROR = v22_E_FCS_ERROR;
2018 vwr->RX_DECRYPTS = v22_E_RX_DECRYPTS;
2019 vwr->TX_DECRYPTS = v22_E_TX_DECRYPTS;
2020 vwr->FC_PROT_BIT = v22_E_FC_PROT_BIT;
2022 vwr->MT_10_HALF = v22_E_MT_10_HALF;
2023 vwr->MT_10_FULL = v22_E_MT_10_FULL;
2024 vwr->MT_100_HALF = v22_E_MT_100_HALF;
2025 vwr->MT_100_FULL = v22_E_MT_100_FULL;
2026 vwr->MT_1G_HALF = v22_E_MT_1G_HALF;
2027 vwr->MT_1G_FULL = v22_E_MT_1G_FULL;
2032 vwr->FRAME_TYPE_OFF = v22_E_FRAME_TYPE_OFF;
2033 vwr->IS_TCP = v22_E_IS_TCP;
2034 vwr->IS_UDP = v22_E_IS_UDP;
2035 vwr->IS_ICMP = v22_E_IS_ICMP;
2036 vwr->IS_IGMP = v22_E_IS_IGMP;
2037 vwr->IS_QOS = v22_E_IS_QOS;
2038 vwr->IS_VLAN = v22_E_IS_VLAN;
2043 case vVW510006_W_FPGA:
2044 vwr->STATS_LEN = v22_W_STATS_LEN;
2046 vwr->MTYPE_OFF = v22_W_MTYPE_OFF;
2047 vwr->VALID_OFF = v22_W_VALID_OFF;
2048 vwr->VCID_OFF = v22_W_VCID_OFF;
2049 vwr->FLOWSEQ_OFF = v22_W_FLOWSEQ_OFF;
2050 vwr->FLOWID_OFF = v22_W_FLOWID_OFF;
2051 vwr->OCTET_OFF = v22_W_OCTET_OFF;
2052 vwr->ERRORS_OFF = v22_W_ERRORS_OFF;
2053 vwr->PATN_OFF = v22_W_PATN_OFF;
2054 vwr->RSSI_OFF = v22_W_RSSI_OFF;
2055 vwr->STARTT_OFF = v22_W_STARTT_OFF;
2056 vwr->ENDT_OFF = v22_W_ENDT_OFF;
2057 vwr->LATVAL_OFF = v22_W_LATVAL_OFF;
2058 vwr->INFO_OFF = v22_W_INFO_OFF;
2059 vwr->L4ID_OFF = v22_W_L4ID_OFF;
2060 vwr->IPLEN_OFF = v22_W_IPLEN_OFF;
2061 vwr->PLCP_LENGTH_OFF = v22_W_PLCP_LENGTH_OFF;
2063 vwr->FCS_ERROR = v22_W_FCS_ERROR;
2064 vwr->CRYPTO_ERR = v22_W_CRYPTO_ERR;
2065 vwr->PAYCHK_ERR = v22_W_PAYCHK_ERR;
2066 vwr->RETRY_ERR = v22_W_RETRY_ERR;
2067 vwr->IS_RX = v22_W_IS_RX;
2068 vwr->MT_MASK = v22_W_MT_MASK;
2069 vwr->VCID_MASK = v22_W_VCID_MASK;
2070 vwr->FLOW_VALID = v22_W_FLOW_VALID;
2072 vwr->HEADER_IS_RX = v22_W_HEADER_IS_RX;
2073 vwr->HEADER_IS_TX = v22_W_HEADER_IS_TX;
2075 vwr->RX_DECRYPTS = v22_W_RX_DECRYPTS;
2076 vwr->TX_DECRYPTS = v22_W_TX_DECRYPTS;
2077 vwr->FC_PROT_BIT = v22_W_FC_PROT_BIT;
2079 vwr->MT_10_HALF = 0;
2080 vwr->MT_10_FULL = 0;
2081 vwr->MT_100_HALF = 0;
2082 vwr->MT_100_FULL = 0;
2083 vwr->MT_1G_HALF = 0;
2084 vwr->MT_1G_FULL = 0;
2085 vwr->MT_CCKL = v22_W_MT_CCKL;
2086 vwr->MT_CCKS = v22_W_MT_CCKS;
2087 vwr->MT_OFDM = v22_W_MT_OFDM;
2089 vwr->WEPTYPE = v22_W_WEPTYPE;
2090 vwr->TKIPTYPE = v22_W_TKIPTYPE;
2091 vwr->CCMPTYPE = v22_W_CCMPTYPE;
2093 vwr->FRAME_TYPE_OFF = v22_W_FRAME_TYPE_OFF;
2094 vwr->IS_TCP = v22_W_IS_TCP;
2095 vwr->IS_UDP = v22_W_IS_UDP;
2096 vwr->IS_ICMP = v22_W_IS_ICMP;
2097 vwr->IS_IGMP = v22_W_IS_IGMP;
2098 vwr->IS_QOS = v22_W_IS_QOS;
2102 /* Ethernet frames */
2103 case vVW510024_E_FPGA:
2104 vwr->STATS_LEN = vVW510024_E_STATS_LEN;
2106 vwr->VALID_OFF = vVW510024_E_VALID_OFF;
2107 vwr->VCID_OFF = vVW510024_E_VCID_OFF;
2108 vwr->FLOWSEQ_OFF = vVW510024_E_FLOWSEQ_OFF;
2109 vwr->FLOWID_OFF = vVW510024_E_FLOWID_OFF;
2110 vwr->OCTET_OFF = vVW510024_E_MSDU_LENGTH_OFF;
2111 vwr->ERRORS_OFF = vVW510024_E_ERRORS_OFF;
2112 vwr->PATN_OFF = vVW510024_E_MATCH_OFF;
2113 vwr->STARTT_OFF = vVW510024_E_STARTT_OFF;
2114 vwr->ENDT_OFF = vVW510024_E_ENDT_OFF;
2115 vwr->LATVAL_OFF = vVW510024_E_LATVAL_OFF;
2116 vwr->INFO_OFF = vVW510024_E_INFO_OFF;
2117 vwr->L4ID_OFF = vVW510024_E_L4ID_OFF;
2118 vwr->IPLEN_OFF = vVW510024_E_IPLEN_OFF;
2120 vwr->FPGA_VERSION_OFF = vVW510024_E_FPGA_VERSION_OFF;
2121 vwr->HEADER_VERSION_OFF = vVW510024_E_HEADER_VERSION_OFF;
2123 vwr->HEADER_IS_RX = vVW510024_E_HEADER_IS_RX;
2124 vwr->HEADER_IS_TX = vVW510024_E_HEADER_IS_TX;
2126 vwr->VCID_MASK = vVW510024_E_VCID_MASK;
2127 vwr->FLOW_VALID = vVW510024_E_FLOW_VALID;
2128 vwr->FCS_ERROR = v22_E_FCS_ERROR;
2130 vwr->FRAME_TYPE_OFF = vVW510024_E_FRAME_TYPE_OFF;
2131 vwr->IS_TCP = vVW510024_E_IS_TCP;
2132 vwr->IS_UDP = vVW510024_E_IS_UDP;
2133 vwr->IS_ICMP = vVW510024_E_IS_ICMP;
2134 vwr->IS_IGMP = vVW510024_E_IS_IGMP;
2135 vwr->IS_QOS = vVW510024_E_QOS_VALID;
2136 vwr->IS_VLAN = vVW510024_E_IS_VLAN;
2141 #define SIG_SCAN_RANGE 64 /* range of signature scanning region */
2143 /* utility routine: check that signature is at specified location; scan for it if not */
2144 /* if we can't find a signature at all, then simply return the originally supplied offset */
2145 int find_signature(guint8 *m_ptr, int pay_off, guint32 flow_id, guint8 flow_seq)
2147 int tgt; /* temps */
2150 /* initial check is very simple: look for a '0xdd' at the target location */
2151 if (m_ptr[pay_off] == 0xdd) /* if magic byte is present */
2152 return(pay_off); /* got right offset, return it */
2154 /* hmmm, signature magic byte is not where it is supposed to be; scan from start of */
2155 /* payload until maximum scan range exhausted to see if we can find it */
2156 /* the scanning process consists of looking for a '0xdd', then checking for the correct */
2157 /* flow ID and sequence number at the appropriate offsets */
2158 for (tgt = pay_off; tgt < (pay_off + SIG_SCAN_RANGE); tgt++) {
2159 if (m_ptr[tgt] == 0xdd) { /* found magic byte? check fields */
2160 if (m_ptr[tgt + 15] == 0xe2) {
2161 if (m_ptr[tgt + 4] != flow_seq)
2164 fid = pletoh24(&m_ptr[tgt + 1]);
2172 { /* out which one... */
2173 if (m_ptr[tgt + SIG_FSQ_OFF] != flow_seq) /* check sequence number */
2174 continue; /* if failed, keep scanning */
2176 fid = pletoh24(&m_ptr[tgt + SIG_FID_OFF]); /* assemble flow ID from signature */
2177 if (fid != flow_id) /* check flow ID against expected */
2178 continue; /* if failed, keep scanning */
2180 /* matched magic byte, sequence number, flow ID; found the signature */
2181 return (tgt); /* return offset of signature */
2186 /* failed to find the signature, return the original offset as default */
2190 /* utility routine: harvest the signature time stamp from the data frame */
2191 guint64 get_signature_ts(guint8 *m_ptr,int sig_off)
2196 if (m_ptr[sig_off + 15] == 0xe2)
2201 sig_ts = pletohl(&m_ptr[sig_off + ts_offset]);
2203 return(sig_ts & 0xffffffff);