1 /*
2  * packet-ppi.c
3  * Routines for PPI Packet Header dissection
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 2007 Gerald Combs
8  *
9  * Copyright (c) 2006 CACE Technologies, Davis (California)
10  * All rights reserved.
11  *
12  * SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
13  *
14  *
15  * Dustin Johnson - Dustin@Dustinj.us, Dustin.Johnson@cacetech.com
16  *     May 7, 2008 - Added 'Aggregation Extension' and '802.3 Extension'
17  */
18 
19 
20 #include "config.h"
21 
22 #include <epan/packet.h>
23 #include <epan/capture_dissectors.h>
24 #include <epan/exceptions.h>
25 #include <epan/ptvcursor.h>
26 #include <epan/prefs.h>
27 #include <epan/expert.h>
28 #include <epan/reassemble.h>
29 #include <wsutil/802_11-utils.h>
30 #include <wsutil/pint.h>
31 #include <wsutil/str_util.h>
32 
33 /*
34  * Per-Packet Information (PPI) header.
35  * See the PPI Packet Header documentation at
36  *
37  *     https://wayback.archive.org/web/20120525190041/https://www.cacetech.com/documents/PPI%20Header%20format%201.0.10.pdf
38  *
39  * for details.
40  */
41 
42 /*
43  * PPI headers have the following format:
44  *
45  * ,---------------------------------------------------------.
46  * | PPH | PFH 1 | Field data 1 | PFH 2 | Field data 2 | ... |
47  * `---------------------------------------------------------'
48  *
49  * The PPH struct has the following format:
50  *
51  * typedef struct ppi_packetheader {
52  *     guint8  pph_version;     // Version.  Currently 0
53  *     guint8  pph_flags;       // Flags.
54  *     guint16 pph_len; // Length of entire message, including this header and TLV payload.
55  *     guint32 pph_dlt; // libpcap Data Link Type of the captured packet data.
56  * } ppi_packetheader_t;
57  *
58  * The PFH struct has the following format:
59  *
60  * typedef struct ppi_fieldheader {
61  *     guint16 pfh_type;        // Type
62  *     guint16 pfh_datalen;     // Length of data
63  * } ppi_fieldheader_t;
64  *
65  * Anyone looking to add their own PPI dissector would probably do well to imitate the GPS
66  * ones separation into a distinct file.  Here is a step by step guide:
67  * 1) add the number you received to the enum ppi_field_type declaration.
68  * 2) Add a value string for your number into vs_ppi_field_type
69  * 3) declare a dissector handle by the ppi_gps_handle, and initialize it inside proto_reg_handoff
70  * 4) add  case inside dissect_ppi to call your new handle.
71  * 5) Write your parser, and get it loaded.
72  * Following these steps will result in less churn inside the ppi proper parser, and avoid namespace issues.
73  */
74 
75 
76 #define PPI_PADDED (1 << 0)
77 
78 #define PPI_V0_HEADER_LEN 8
79 #define PPI_80211_COMMON_LEN 20
80 #define PPI_80211N_MAC_LEN 12
81 #define PPI_80211N_MAC_PHY_OFF 9
82 #define PPI_80211N_MAC_PHY_LEN 48
83 #define PPI_AGGREGATION_EXTENSION_LEN 4
84 #define PPI_8023_EXTENSION_LEN 8
85 
86 #define PPI_FLAG_ALIGN 0x01
87 #define IS_PPI_FLAG_ALIGN(x) ((x) & PPI_FLAG_ALIGN)
88 
89 #define DOT11_FLAG_HAVE_FCS     0x0001
90 #define DOT11_FLAG_TSF_TIMER_MS 0x0002
91 #define DOT11_FLAG_FCS_INVALID  0x0004
92 #define DOT11_FLAG_PHY_ERROR    0x0008
93 
94 #define DOT11N_FLAG_GREENFIELD      0x0001
95 #define DOT11N_FLAG_HT40            0x0002
96 #define DOT11N_FLAG_SHORT_GI        0x0004
97 #define DOT11N_FLAG_DUPLICATE_RX    0x0008
98 #define DOT11N_FLAG_IS_AGGREGATE    0x0010
99 #define DOT11N_FLAG_MORE_AGGREGATES 0x0020
100 #define DOT11N_FLAG_AGG_CRC_ERROR   0x0040
101 
102 #define DOT11N_IS_AGGREGATE(flags)      (flags & DOT11N_FLAG_IS_AGGREGATE)
103 #define DOT11N_MORE_AGGREGATES(flags)   ( \
104     (flags & DOT11N_FLAG_MORE_AGGREGATES) && \
105     !(flags & DOT11N_FLAG_AGG_CRC_ERROR))
106 #define AGGREGATE_MAX 65535
107 #define AMPDU_MAX 16383
108 
109 /* XXX - Start - Copied from packet-radiotap.c */
110 /* Channel flags. */
111 #define IEEE80211_CHAN_TURBO    0x0010  /* Turbo channel */
112 #define IEEE80211_CHAN_CCK      0x0020  /* CCK channel */
113 #define IEEE80211_CHAN_OFDM     0x0040  /* OFDM channel */
114 #define IEEE80211_CHAN_2GHZ     0x0080  /* 2 GHz spectrum channel. */
115 #define IEEE80211_CHAN_5GHZ     0x0100  /* 5 GHz spectrum channel */
116 #define IEEE80211_CHAN_PASSIVE  0x0200  /* Only passive scan allowed */
117 #define IEEE80211_CHAN_DYN      0x0400  /* Dynamic CCK-OFDM channel */
118 #define IEEE80211_CHAN_GFSK     0x0800  /* GFSK channel (FHSS PHY) */
119 
120 #define	IEEE80211_CHAN_ALL \
121 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_GFSK | \
122          IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)
123 #define	IEEE80211_CHAN_ALLTURBO \
124 	(IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO)
125 
126 /*
127  * Useful combinations of channel characteristics.
128  */
129 #define IEEE80211_CHAN_FHSS \
130         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
131 #define	IEEE80211_CHAN_DSSS \
132 	(IEEE80211_CHAN_2GHZ)
133 #define IEEE80211_CHAN_A \
134         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
135 #define IEEE80211_CHAN_B \
136         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
137 #define IEEE80211_CHAN_PUREG \
138         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
139 #define IEEE80211_CHAN_G \
140         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
141 #define	IEEE80211_CHAN_108A \
142 	(IEEE80211_CHAN_A | IEEE80211_CHAN_TURBO)
143 #define IEEE80211_CHAN_108G \
144         (IEEE80211_CHAN_G | IEEE80211_CHAN_TURBO)
145 #define IEEE80211_CHAN_108PUREG \
146         (IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO)
147 /* XXX - End - Copied from packet-radiotap.c */
148 
149 void proto_register_ppi(void);
150 void proto_reg_handoff_ppi(void);
151 
152 typedef enum {
153     /* 0 - 29999: Public types */
154     PPI_80211_COMMON          =  2,
155     PPI_80211N_MAC            =  3,
156     PPI_80211N_MAC_PHY        =  4,
157     PPI_SPECTRUM_MAP          =  5,
158     PPI_PROCESS_INFO          =  6,
159     PPI_CAPTURE_INFO          =  7,
160     PPI_AGGREGATION_EXTENSION =  8,
161     PPI_8023_EXTENSION        =  9,
162     /* 11 - 29999: RESERVED */
163 
164     /* 30000 - 65535: Private types */
165     INTEL_CORP_PRIVATE           = 30000,
166     MOHAMED_THAGA_PRIVATE        = 30001,
167     PPI_GPS_INFO                 = 30002, /* 30002 - 30005 described in PPI-GEOLOCATION specifcation */
168     PPI_VECTOR_INFO              = 30003, /* currently available in draft from. jellch@harris.com */
169     PPI_SENSOR_INFO              = 30004,
170     PPI_ANTENNA_INFO             = 30005,
171     FNET_PRIVATE                 = 0xC017,
172     CACE_PRIVATE                 = 0xCACE
173     /* All others RESERVED.  Contact the WinPcap team for an assignment */
174 } ppi_field_type;
175 
176 /* Protocol */
177 static int proto_ppi = -1;
178 
179 /* Packet header */
180 static int hf_ppi_head_version = -1;
181 static int hf_ppi_head_flags = -1;
182 static int hf_ppi_head_flag_alignment = -1;
183 static int hf_ppi_head_flag_reserved = -1;
184 static int hf_ppi_head_len = -1;
185 static int hf_ppi_head_dlt = -1;
186 
187 /* Field header */
188 static int hf_ppi_field_type = -1;
189 static int hf_ppi_field_len = -1;
190 
191 /* 802.11 Common */
192 static int hf_80211_common_tsft = -1;
193 static int hf_80211_common_flags = -1;
194 static int hf_80211_common_flags_fcs = -1;
195 static int hf_80211_common_flags_tsft = -1;
196 static int hf_80211_common_flags_fcs_valid = -1;
197 static int hf_80211_common_flags_phy_err = -1;
198 static int hf_80211_common_rate = -1;
199 static int hf_80211_common_chan_freq = -1;
200 static int hf_80211_common_chan_flags = -1;
201 
202 static int hf_80211_common_chan_flags_turbo = -1;
203 static int hf_80211_common_chan_flags_cck = -1;
204 static int hf_80211_common_chan_flags_ofdm = -1;
205 static int hf_80211_common_chan_flags_2ghz = -1;
206 static int hf_80211_common_chan_flags_5ghz = -1;
207 static int hf_80211_common_chan_flags_passive = -1;
208 static int hf_80211_common_chan_flags_dynamic = -1;
209 static int hf_80211_common_chan_flags_gfsk = -1;
210 
211 static int hf_80211_common_fhss_hopset = -1;
212 static int hf_80211_common_fhss_pattern = -1;
213 static int hf_80211_common_dbm_antsignal = -1;
214 static int hf_80211_common_dbm_antnoise = -1;
215 
216 /* 802.11n MAC */
217 static int hf_80211n_mac_flags = -1;
218 static int hf_80211n_mac_flags_greenfield = -1;
219 static int hf_80211n_mac_flags_ht20_40 = -1;
220 static int hf_80211n_mac_flags_rx_guard_interval = -1;
221 static int hf_80211n_mac_flags_duplicate_rx = -1;
222 static int hf_80211n_mac_flags_more_aggregates = -1;
223 static int hf_80211n_mac_flags_aggregate = -1;
224 static int hf_80211n_mac_flags_delimiter_crc_after = -1;
225 static int hf_80211n_mac_ampdu_id = -1;
226 static int hf_80211n_mac_num_delimiters = -1;
227 static int hf_80211n_mac_reserved = -1;
228 
229 /* 802.11n MAC+PHY */
230 static int hf_80211n_mac_phy_mcs = -1;
231 static int hf_80211n_mac_phy_num_streams = -1;
232 static int hf_80211n_mac_phy_rssi_combined = -1;
233 static int hf_80211n_mac_phy_rssi_ant0_ctl = -1;
234 static int hf_80211n_mac_phy_rssi_ant1_ctl = -1;
235 static int hf_80211n_mac_phy_rssi_ant2_ctl = -1;
236 static int hf_80211n_mac_phy_rssi_ant3_ctl = -1;
237 static int hf_80211n_mac_phy_rssi_ant0_ext = -1;
238 static int hf_80211n_mac_phy_rssi_ant1_ext = -1;
239 static int hf_80211n_mac_phy_rssi_ant2_ext = -1;
240 static int hf_80211n_mac_phy_rssi_ant3_ext = -1;
241 static int hf_80211n_mac_phy_ext_chan_freq = -1;
242 static int hf_80211n_mac_phy_ext_chan_flags = -1;
243 static int hf_80211n_mac_phy_ext_chan_flags_turbo = -1;
244 static int hf_80211n_mac_phy_ext_chan_flags_cck = -1;
245 static int hf_80211n_mac_phy_ext_chan_flags_ofdm = -1;
246 static int hf_80211n_mac_phy_ext_chan_flags_2ghz = -1;
247 static int hf_80211n_mac_phy_ext_chan_flags_5ghz = -1;
248 static int hf_80211n_mac_phy_ext_chan_flags_passive = -1;
249 static int hf_80211n_mac_phy_ext_chan_flags_dynamic = -1;
250 static int hf_80211n_mac_phy_ext_chan_flags_gfsk = -1;
251 static int hf_80211n_mac_phy_dbm_ant0signal = -1;
252 static int hf_80211n_mac_phy_dbm_ant0noise = -1;
253 static int hf_80211n_mac_phy_dbm_ant1signal = -1;
254 static int hf_80211n_mac_phy_dbm_ant1noise = -1;
255 static int hf_80211n_mac_phy_dbm_ant2signal = -1;
256 static int hf_80211n_mac_phy_dbm_ant2noise = -1;
257 static int hf_80211n_mac_phy_dbm_ant3signal = -1;
258 static int hf_80211n_mac_phy_dbm_ant3noise = -1;
259 static int hf_80211n_mac_phy_evm0 = -1;
260 static int hf_80211n_mac_phy_evm1 = -1;
261 static int hf_80211n_mac_phy_evm2 = -1;
262 static int hf_80211n_mac_phy_evm3 = -1;
263 
264 /* 802.11n-Extensions A-MPDU fragments */
265 static int hf_ampdu_reassembled_in = -1;
266 /* static int hf_ampdu_segments = -1; */
267 static int hf_ampdu_segment = -1;
268 static int hf_ampdu_count  = -1;
269 
270 /* Spectrum-Map */
271 static int hf_spectrum_map = -1;
272 
273 /* Process-Info */
274 static int hf_process_info = -1;
275 
276 /* Capture-Info */
277 static int hf_capture_info = -1;
278 
279 /* Aggregation Extension */
280 static int hf_aggregation_extension_interface_id = -1;
281 
282 /* 802.3 Extension */
283 static int hf_8023_extension_flags = -1;
284 static int hf_8023_extension_flags_fcs_present = -1;
285 static int hf_8023_extension_errors = -1;
286 static int hf_8023_extension_errors_fcs = -1;
287 static int hf_8023_extension_errors_sequence = -1;
288 static int hf_8023_extension_errors_symbol = -1;
289 static int hf_8023_extension_errors_data = -1;
290 
291 /* Generated from convert_proto_tree_add_text.pl */
292 static int hf_ppi_antenna = -1;
293 static int hf_ppi_harris = -1;
294 static int hf_ppi_reserved = -1;
295 static int hf_ppi_vector = -1;
296 static int hf_ppi_fnet = -1;
297 static int hf_ppi_gps = -1;
298 
299 static gint ett_ppi_pph = -1;
300 static gint ett_ppi_flags = -1;
301 static gint ett_dot11_common = -1;
302 static gint ett_dot11_common_flags = -1;
303 static gint ett_dot11_common_channel_flags = -1;
304 static gint ett_dot11n_mac = -1;
305 static gint ett_dot11n_mac_flags = -1;
306 static gint ett_dot11n_mac_phy = -1;
307 static gint ett_dot11n_mac_phy_ext_channel_flags = -1;
308 static gint ett_ampdu_segments = -1;
309 static gint ett_ampdu = -1;
310 static gint ett_ampdu_segment  = -1;
311 static gint ett_aggregation_extension = -1;
312 static gint ett_8023_extension = -1;
313 static gint ett_8023_extension_flags = -1;
314 static gint ett_8023_extension_errors = -1;
315 
316 /* Generated from convert_proto_tree_add_text.pl */
317 static expert_field ei_ppi_invalid_length = EI_INIT;
318 
319 static dissector_handle_t ppi_handle;
320 
321 static dissector_handle_t ieee80211_radio_handle;
322 static dissector_handle_t pcap_pktdata_handle;
323 static dissector_handle_t ppi_gps_handle, ppi_vector_handle, ppi_sensor_handle, ppi_antenna_handle;
324 static dissector_handle_t ppi_fnet_handle;
325 
326 static const true_false_string tfs_ppi_head_flag_alignment = { "32-bit aligned", "Not aligned" };
327 static const true_false_string tfs_tsft_ms = { "milliseconds", "microseconds" };
328 static const true_false_string tfs_ht20_40 = { "HT40", "HT20" };
329 static const true_false_string tfs_phy_error = { "PHY error", "No errors"};
330 
331 static const value_string vs_ppi_field_type[] = {
332     {PPI_80211_COMMON,          "802.11-Common"},
333     {PPI_80211N_MAC,            "802.11n MAC Extensions"},
334     {PPI_80211N_MAC_PHY,        "802.11n MAC+PHY Extensions"},
335     {PPI_SPECTRUM_MAP,          "Spectrum-Map"},
336     {PPI_PROCESS_INFO,          "Process-Info"},
337     {PPI_CAPTURE_INFO,          "Capture-Info"},
338     {PPI_AGGREGATION_EXTENSION, "Aggregation Extension"},
339     {PPI_8023_EXTENSION,        "802.3 Extension"},
340 
341     {INTEL_CORP_PRIVATE,        "Intel Corporation (private)"},
342     {MOHAMED_THAGA_PRIVATE,     "Mohamed Thaga (private)"},
343     {PPI_GPS_INFO,              "GPS Tagging"},
344     {PPI_VECTOR_INFO,           "Vector Tagging"},
345     {PPI_SENSOR_INFO,           "Sensor tagging"},
346     {PPI_ANTENNA_INFO,          "Antenna Tagging"},
347     {FNET_PRIVATE,              "FlukeNetworks (private)"},
348     {CACE_PRIVATE,              "CACE Technologies (private)"},
349     {0, NULL}
350 };
351 
352 /* Table for A-MPDU reassembly */
353 static reassembly_table ampdu_reassembly_table;
354 
355 /* Reassemble A-MPDUs? */
356 static gboolean ppi_ampdu_reassemble = TRUE;
357 
358 
359 static gboolean
capture_ppi(const guchar * pd,int offset _U_,int len,capture_packet_info_t * cpinfo,const union wtap_pseudo_header * pseudo_header _U_)360 capture_ppi(const guchar *pd, int offset _U_, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
361 {
362     guint32  dlt;
363     guint    ppi_len;
364 
365     ppi_len = pletoh16(pd+2);
366     if(ppi_len < PPI_V0_HEADER_LEN || !BYTES_ARE_IN_FRAME(0, len, ppi_len))
367         return FALSE;
368 
369     dlt = pletoh32(pd+4);
370 
371     return try_capture_dissector("ppi", dlt, pd, ppi_len, len, cpinfo, pseudo_header);
372 }
373 
374 static void
ptvcursor_add_invalid_check(ptvcursor_t * csr,int hf,gint len,guint64 invalid_val)375 ptvcursor_add_invalid_check(ptvcursor_t *csr, int hf, gint len, guint64 invalid_val) {
376     proto_item *ti;
377     guint64     val = invalid_val;
378 
379     switch (len) {
380         case 8:
381             val = tvb_get_letoh64(ptvcursor_tvbuff(csr),
382                 ptvcursor_current_offset(csr));
383             break;
384         case 4:
385             val = tvb_get_letohl(ptvcursor_tvbuff(csr),
386                 ptvcursor_current_offset(csr));
387             break;
388         case 2:
389             val = tvb_get_letohs(ptvcursor_tvbuff(csr),
390                 ptvcursor_current_offset(csr));
391             break;
392         case 1:
393             val = tvb_get_guint8(ptvcursor_tvbuff(csr),
394                 ptvcursor_current_offset(csr));
395             break;
396         default:
397             DISSECTOR_ASSERT_NOT_REACHED();
398     }
399 
400     ti = ptvcursor_add(csr, hf, len, ENC_LITTLE_ENDIAN);
401     if (val == invalid_val)
402         proto_item_append_text(ti, " [invalid]");
403 }
404 
405 static void
add_ppi_field_header(tvbuff_t * tvb,proto_tree * tree,int * offset)406 add_ppi_field_header(tvbuff_t *tvb, proto_tree *tree, int *offset)
407 {
408     ptvcursor_t *csr;
409 
410     csr = ptvcursor_new(wmem_packet_scope(), tree, tvb, *offset);
411     ptvcursor_add(csr, hf_ppi_field_type, 2, ENC_LITTLE_ENDIAN);
412     ptvcursor_add(csr, hf_ppi_field_len, 2, ENC_LITTLE_ENDIAN);
413     ptvcursor_free(csr);
414     *offset=ptvcursor_current_offset(csr);
415 }
416 
417 /* XXX - The main dissection function in the 802.11 dissector has the same name. */
418 static void
dissect_80211_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,int data_len,struct ieee_802_11_phdr * phdr)419 dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int data_len, struct ieee_802_11_phdr *phdr)
420 {
421     proto_tree  *ftree;
422     proto_item  *ti;
423     ptvcursor_t *csr;
424     guint64      tsft_raw;
425     guint        rate_raw;
426     guint        rate_kbps;
427     guint32      common_flags;
428     guint16      common_frequency;
429     guint16      chan_flags;
430     gint8        dbm_value;
431     gchar       *chan_str;
432 
433     ftree = proto_tree_add_subtree(tree, tvb, offset, data_len, ett_dot11_common, NULL, "802.11-Common");
434     add_ppi_field_header(tvb, ftree, &offset);
435     data_len -= 4; /* Subtract field header length */
436 
437     if (data_len != PPI_80211_COMMON_LEN) {
438         proto_tree_add_expert_format(ftree, pinfo, &ei_ppi_invalid_length, tvb, offset, data_len, "Invalid length: %u", data_len);
439         return;
440     }
441 
442     common_flags = tvb_get_letohs(tvb, offset + 8);
443     if (common_flags & DOT11_FLAG_HAVE_FCS)
444         phdr->fcs_len = 4;
445     else
446         phdr->fcs_len = 0;
447 
448     csr = ptvcursor_new(pinfo->pool, ftree, tvb, offset);
449 
450     tsft_raw = tvb_get_letoh64(tvb, offset);
451     if (tsft_raw != 0) {
452         phdr->has_tsf_timestamp = TRUE;
453         if (common_flags & DOT11_FLAG_TSF_TIMER_MS)
454             phdr->tsf_timestamp = tsft_raw * 1000;
455         else
456             phdr->tsf_timestamp = tsft_raw;
457     }
458 
459     ptvcursor_add_invalid_check(csr, hf_80211_common_tsft, 8, 0);
460 
461     ptvcursor_add_with_subtree(csr, hf_80211_common_flags, 2, ENC_LITTLE_ENDIAN,
462                                ett_dot11_common_flags);
463     ptvcursor_add_no_advance(csr, hf_80211_common_flags_fcs, 2, ENC_LITTLE_ENDIAN);
464     ptvcursor_add_no_advance(csr, hf_80211_common_flags_tsft, 2, ENC_LITTLE_ENDIAN);
465     ptvcursor_add_no_advance(csr, hf_80211_common_flags_fcs_valid, 2, ENC_LITTLE_ENDIAN);
466     ptvcursor_add(csr, hf_80211_common_flags_phy_err, 2, ENC_LITTLE_ENDIAN);
467     ptvcursor_pop_subtree(csr);
468 
469     rate_raw = tvb_get_letohs(tvb, ptvcursor_current_offset(csr));
470     if (rate_raw != 0) {
471         phdr->has_data_rate = TRUE;
472         phdr->data_rate = rate_raw;
473     }
474     rate_kbps = rate_raw * 500;
475     ti = proto_tree_add_uint_format(ftree, hf_80211_common_rate, tvb,
476                                     ptvcursor_current_offset(csr), 2, rate_kbps, "Rate: %.1f Mbps",
477                                     rate_kbps / 1000.0);
478     if (rate_kbps == 0)
479         proto_item_append_text(ti, " [invalid]");
480     col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f Mbps", rate_kbps / 1000.0);
481     ptvcursor_advance(csr, 2);
482 
483     common_frequency = tvb_get_letohs(ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr));
484     if (common_frequency != 0) {
485         gint calc_channel;
486 
487         phdr->has_frequency = TRUE;
488         phdr->frequency = common_frequency;
489         calc_channel = ieee80211_mhz_to_chan(common_frequency);
490         if (calc_channel != -1) {
491             phdr->has_channel = TRUE;
492             phdr->channel = calc_channel;
493         }
494     }
495     chan_str = ieee80211_mhz_to_str(common_frequency);
496     proto_tree_add_uint_format_value(ptvcursor_tree(csr), hf_80211_common_chan_freq, ptvcursor_tvbuff(csr),
497                                ptvcursor_current_offset(csr), 2, common_frequency, "%s", chan_str);
498     col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%s", chan_str);
499     g_free(chan_str);
500     ptvcursor_advance(csr, 2);
501 
502     memset(&phdr->phy_info, 0, sizeof(phdr->phy_info));
503     chan_flags = tvb_get_letohs(ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr));
504     switch (chan_flags & IEEE80211_CHAN_ALLTURBO) {
505 
506     case IEEE80211_CHAN_FHSS:
507         phdr->phy = PHDR_802_11_PHY_11_FHSS;
508         break;
509 
510     case IEEE80211_CHAN_DSSS:
511         phdr->phy = PHDR_802_11_PHY_11_DSSS;
512         break;
513 
514     case IEEE80211_CHAN_A:
515         phdr->phy = PHDR_802_11_PHY_11A;
516         phdr->phy_info.info_11a.has_turbo_type = TRUE;
517         phdr->phy_info.info_11a.turbo_type = PHDR_802_11A_TURBO_TYPE_NORMAL;
518         break;
519 
520     case IEEE80211_CHAN_B:
521         phdr->phy = PHDR_802_11_PHY_11B;
522         break;
523 
524     case IEEE80211_CHAN_PUREG:
525         phdr->phy = PHDR_802_11_PHY_11G;
526         phdr->phy_info.info_11g.has_mode = TRUE;
527         phdr->phy_info.info_11g.mode = PHDR_802_11G_MODE_NORMAL;
528         break;
529 
530     case IEEE80211_CHAN_G:
531         phdr->phy = PHDR_802_11_PHY_11G;
532         phdr->phy_info.info_11g.has_mode = TRUE;
533         phdr->phy_info.info_11g.mode = PHDR_802_11G_MODE_NORMAL;
534         break;
535 
536     case IEEE80211_CHAN_108A:
537         phdr->phy = PHDR_802_11_PHY_11A;
538         phdr->phy_info.info_11a.has_turbo_type = TRUE;
539         /* We assume non-STURBO is dynamic turbo */
540         phdr->phy_info.info_11a.turbo_type = PHDR_802_11A_TURBO_TYPE_DYNAMIC_TURBO;
541         break;
542 
543     case IEEE80211_CHAN_108PUREG:
544         phdr->phy = PHDR_802_11_PHY_11G;
545         phdr->phy_info.info_11g.has_mode = TRUE;
546         phdr->phy_info.info_11g.mode = PHDR_802_11G_MODE_SUPER_G;
547         break;
548     }
549     ptvcursor_add_with_subtree(csr, hf_80211_common_chan_flags, 2, ENC_LITTLE_ENDIAN,
550                                ett_dot11_common_channel_flags);
551     ptvcursor_add_no_advance(csr, hf_80211_common_chan_flags_turbo, 2, ENC_LITTLE_ENDIAN);
552     ptvcursor_add_no_advance(csr, hf_80211_common_chan_flags_cck, 2, ENC_LITTLE_ENDIAN);
553     ptvcursor_add_no_advance(csr, hf_80211_common_chan_flags_ofdm, 2, ENC_LITTLE_ENDIAN);
554     ptvcursor_add_no_advance(csr, hf_80211_common_chan_flags_2ghz, 2, ENC_LITTLE_ENDIAN);
555     ptvcursor_add_no_advance(csr, hf_80211_common_chan_flags_5ghz, 2, ENC_LITTLE_ENDIAN);
556     ptvcursor_add_no_advance(csr, hf_80211_common_chan_flags_passive, 2, ENC_LITTLE_ENDIAN);
557     ptvcursor_add_no_advance(csr, hf_80211_common_chan_flags_dynamic, 2, ENC_LITTLE_ENDIAN);
558     ptvcursor_add(csr, hf_80211_common_chan_flags_gfsk, 2, ENC_LITTLE_ENDIAN);
559     ptvcursor_pop_subtree(csr);
560 
561 
562     if (phdr->phy == PHDR_802_11_PHY_11_FHSS) {
563         phdr->phy_info.info_11_fhss.has_hop_set = TRUE;
564         phdr->phy_info.info_11_fhss.hop_set = tvb_get_guint8(ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr));
565     }
566     ptvcursor_add(csr, hf_80211_common_fhss_hopset, 1, ENC_LITTLE_ENDIAN);
567     if (phdr->phy == PHDR_802_11_PHY_11_FHSS) {
568         phdr->phy_info.info_11_fhss.has_hop_pattern = TRUE;
569         phdr->phy_info.info_11_fhss.hop_pattern = tvb_get_guint8(ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr));
570     }
571     ptvcursor_add(csr, hf_80211_common_fhss_pattern, 1, ENC_LITTLE_ENDIAN);
572 
573     dbm_value = tvb_get_gint8(tvb, ptvcursor_current_offset(csr));
574     if (dbm_value != -128 && dbm_value != 0) {
575         /*
576          * XXX - the spec says -128 is invalid, presumably meaning "use
577          * -128 if you don't have the signal strength", but some captures
578          * have 0 for noise, presumably meaning it's incorrectly being
579          * used for "don't have it", so we check for it as well.
580          */
581         col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm_value);
582         phdr->has_signal_dbm = TRUE;
583         phdr->signal_dbm = dbm_value;
584     }
585     ptvcursor_add_invalid_check(csr, hf_80211_common_dbm_antsignal, 1, 0x80); /* -128 */
586 
587     dbm_value = tvb_get_gint8(tvb, ptvcursor_current_offset(csr));
588     if (dbm_value != -128 && dbm_value != 0) {
589         /*
590          * XXX - the spec says -128 is invalid, presumably meaning "use
591          * -128 if you don't have the noise level", but some captures
592          * have 0, presumably meaning it's incorrectly being used for
593          * "don't have it", so we check for it as well.
594          */
595         phdr->has_noise_dbm = TRUE;
596         phdr->noise_dbm = dbm_value;
597     }
598     ptvcursor_add_invalid_check(csr, hf_80211_common_dbm_antnoise, 1, 0x80);
599 
600     ptvcursor_free(csr);
601 }
602 
603 static void
dissect_80211n_mac(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,int data_len,gboolean add_subtree,guint32 * n_mac_flags,guint32 * ampdu_id,struct ieee_802_11_phdr * phdr)604 dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int data_len, gboolean add_subtree, guint32 *n_mac_flags, guint32 *ampdu_id, struct ieee_802_11_phdr *phdr)
605 {
606     proto_tree  *ftree       = tree;
607     ptvcursor_t *csr;
608     guint32      flags;
609 
610     phdr->phy = PHDR_802_11_PHY_11N;
611 
612     if (add_subtree) {
613         ftree = proto_tree_add_subtree(tree, tvb, offset, data_len, ett_dot11n_mac, NULL, "802.11n MAC");
614         add_ppi_field_header(tvb, ftree, &offset);
615         data_len -= 4; /* Subtract field header length */
616     }
617 
618     if (data_len != PPI_80211N_MAC_LEN) {
619         proto_tree_add_expert_format(ftree, pinfo, &ei_ppi_invalid_length, tvb, offset, data_len, "Invalid length: %u", data_len);
620         return;
621     }
622 
623     csr = ptvcursor_new(pinfo->pool, ftree, tvb, offset);
624 
625     flags = tvb_get_letohl(tvb, ptvcursor_current_offset(csr));
626     *n_mac_flags = flags;
627     phdr->phy_info.info_11n.has_bandwidth = TRUE;
628     phdr->phy_info.info_11n.has_short_gi = TRUE;
629     phdr->phy_info.info_11n.has_greenfield = TRUE;
630     phdr->phy_info.info_11n.bandwidth = ((flags & DOT11N_FLAG_HT40) != 0);
631     phdr->phy_info.info_11n.short_gi = ((flags & DOT11N_FLAG_SHORT_GI) != 0);
632     phdr->phy_info.info_11n.greenfield = ((flags & DOT11N_FLAG_GREENFIELD) != 0);
633     if (DOT11N_IS_AGGREGATE(flags)) {
634         phdr->has_aggregate_info = 1;
635         phdr->aggregate_flags = 0;
636         if (!(flags & DOT11N_FLAG_MORE_AGGREGATES))
637             phdr->aggregate_flags |= PHDR_802_11_LAST_PART_OF_A_MPDU;
638         if (flags & DOT11N_FLAG_AGG_CRC_ERROR)
639             phdr->aggregate_flags |= PHDR_802_11_A_MPDU_DELIM_CRC_ERROR;
640     }
641     ptvcursor_add_with_subtree(csr, hf_80211n_mac_flags, 4, ENC_LITTLE_ENDIAN,
642                                ett_dot11n_mac_flags);
643     ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_greenfield, 4, ENC_LITTLE_ENDIAN);
644     ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_ht20_40, 4, ENC_LITTLE_ENDIAN);
645     ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_rx_guard_interval, 4, ENC_LITTLE_ENDIAN);
646     ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_duplicate_rx, 4, ENC_LITTLE_ENDIAN);
647     ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_aggregate, 4, ENC_LITTLE_ENDIAN);
648     ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_more_aggregates, 4, ENC_LITTLE_ENDIAN);
649     ptvcursor_add(csr, hf_80211n_mac_flags_delimiter_crc_after, 4, ENC_LITTLE_ENDIAN); /* Last */
650     ptvcursor_pop_subtree(csr);
651 
652     if (DOT11N_IS_AGGREGATE(flags)) {
653         *ampdu_id = tvb_get_letohl(tvb, ptvcursor_current_offset(csr));
654         phdr->aggregate_id = *ampdu_id;
655     }
656     ptvcursor_add(csr, hf_80211n_mac_ampdu_id, 4, ENC_LITTLE_ENDIAN);
657     ptvcursor_add(csr, hf_80211n_mac_num_delimiters, 1, ENC_LITTLE_ENDIAN);
658 
659     if (add_subtree) {
660         ptvcursor_add(csr, hf_80211n_mac_reserved, 3, ENC_LITTLE_ENDIAN);
661     }
662 
663     ptvcursor_free(csr);
664 }
665 
666 static void
dissect_80211n_mac_phy(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,int data_len,guint32 * n_mac_flags,guint32 * ampdu_id,struct ieee_802_11_phdr * phdr)667 dissect_80211n_mac_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int data_len, guint32 *n_mac_flags, guint32 *ampdu_id, struct ieee_802_11_phdr *phdr)
668 {
669     proto_tree  *ftree;
670     proto_item  *ti;
671     ptvcursor_t *csr;
672     guint8       mcs;
673     guint8       ness;
674     guint16      ext_frequency;
675     gchar       *chan_str;
676 
677     ftree = proto_tree_add_subtree(tree, tvb, offset, data_len, ett_dot11n_mac_phy, NULL, "802.11n MAC+PHY");
678     add_ppi_field_header(tvb, ftree, &offset);
679     data_len -= 4; /* Subtract field header length */
680 
681     if (data_len != PPI_80211N_MAC_PHY_LEN) {
682         proto_tree_add_expert_format(ftree, pinfo, &ei_ppi_invalid_length, tvb, offset, data_len, "Invalid length: %u", data_len);
683         return;
684     }
685 
686     dissect_80211n_mac(tvb, pinfo, ftree, offset, PPI_80211N_MAC_LEN,
687                        FALSE, n_mac_flags, ampdu_id, phdr);
688     offset += PPI_80211N_MAC_PHY_OFF;
689 
690     csr = ptvcursor_new(pinfo->pool, ftree, tvb, offset);
691 
692     mcs = tvb_get_guint8(tvb, ptvcursor_current_offset(csr));
693     if (mcs != 255) {
694         phdr->phy_info.info_11n.has_mcs_index = TRUE;
695         phdr->phy_info.info_11n.mcs_index = mcs;
696     }
697     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_mcs, 1, 255);
698 
699     ness = tvb_get_guint8(tvb, ptvcursor_current_offset(csr));
700     phdr->phy_info.info_11n.has_ness = TRUE;
701     phdr->phy_info.info_11n.ness = ness;
702     ti = ptvcursor_add(csr, hf_80211n_mac_phy_num_streams, 1, ENC_LITTLE_ENDIAN);
703     if (tvb_get_guint8(tvb, ptvcursor_current_offset(csr) - 1) == 0)
704         proto_item_append_text(ti, " (unknown)");
705     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_combined, 1, 255);
706     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant0_ctl, 1, 255);
707     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant1_ctl, 1, 255);
708     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant2_ctl, 1, 255);
709     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant3_ctl, 1, 255);
710     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant0_ext, 1, 255);
711     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant1_ext, 1, 255);
712     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant2_ext, 1, 255);
713     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_rssi_ant3_ext, 1, 255);
714 
715     ext_frequency = tvb_get_letohs(ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr));
716     chan_str = ieee80211_mhz_to_str(ext_frequency);
717     proto_tree_add_uint_format(ptvcursor_tree(csr), hf_80211n_mac_phy_ext_chan_freq, ptvcursor_tvbuff(csr),
718                                ptvcursor_current_offset(csr), 2, ext_frequency, "Ext. Channel frequency: %s", chan_str);
719     g_free(chan_str);
720     ptvcursor_advance(csr, 2);
721 
722     ptvcursor_add_with_subtree(csr, hf_80211n_mac_phy_ext_chan_flags, 2, ENC_LITTLE_ENDIAN,
723                                ett_dot11n_mac_phy_ext_channel_flags);
724     ptvcursor_add_no_advance(csr, hf_80211n_mac_phy_ext_chan_flags_turbo, 2, ENC_LITTLE_ENDIAN);
725     ptvcursor_add_no_advance(csr, hf_80211n_mac_phy_ext_chan_flags_cck, 2, ENC_LITTLE_ENDIAN);
726     ptvcursor_add_no_advance(csr, hf_80211n_mac_phy_ext_chan_flags_ofdm, 2, ENC_LITTLE_ENDIAN);
727     ptvcursor_add_no_advance(csr, hf_80211n_mac_phy_ext_chan_flags_2ghz, 2, ENC_LITTLE_ENDIAN);
728     ptvcursor_add_no_advance(csr, hf_80211n_mac_phy_ext_chan_flags_5ghz, 2, ENC_LITTLE_ENDIAN);
729     ptvcursor_add_no_advance(csr, hf_80211n_mac_phy_ext_chan_flags_passive, 2, ENC_LITTLE_ENDIAN);
730     ptvcursor_add_no_advance(csr, hf_80211n_mac_phy_ext_chan_flags_dynamic, 2, ENC_LITTLE_ENDIAN);
731     ptvcursor_add(csr, hf_80211n_mac_phy_ext_chan_flags_gfsk, 2, ENC_LITTLE_ENDIAN);
732     ptvcursor_pop_subtree(csr);
733 
734     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant0signal, 1, 0x80); /* -128 */
735     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant0noise, 1, 0x80);
736     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant1signal, 1, 0x80);
737     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant1noise, 1, 0x80);
738     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant2signal, 1, 0x80);
739     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant2noise, 1, 0x80);
740     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant3signal, 1, 0x80);
741     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_dbm_ant3noise, 1, 0x80);
742     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_evm0, 4, 0);
743     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_evm1, 4, 0);
744     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_evm2, 4, 0);
745     ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_evm3, 4, 0);
746 
747     ptvcursor_free(csr);
748 }
749 
750 static void
dissect_aggregation_extension(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,int data_len)751 dissect_aggregation_extension(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int data_len)
752 {
753     proto_tree *ftree;
754     ptvcursor_t *csr;
755 
756     ftree = proto_tree_add_subtree(tree, tvb, offset, data_len, ett_aggregation_extension, NULL, "Aggregation Extension");
757     add_ppi_field_header(tvb, ftree, &offset);
758     data_len -= 4; /* Subtract field header length */
759 
760     if (data_len != PPI_AGGREGATION_EXTENSION_LEN) {
761         proto_tree_add_expert_format(ftree, pinfo, &ei_ppi_invalid_length, tvb, offset, data_len, "Invalid length: %u", data_len);
762         return;
763     }
764 
765     csr = ptvcursor_new(pinfo->pool, ftree, tvb, offset);
766 
767     ptvcursor_add(csr, hf_aggregation_extension_interface_id, 4, ENC_LITTLE_ENDIAN); /* Last */
768     ptvcursor_free(csr);
769 }
770 
771 static void
dissect_8023_extension(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,int data_len)772 dissect_8023_extension(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int data_len)
773 {
774     proto_tree  *ftree;
775     ptvcursor_t *csr;
776 
777     ftree = proto_tree_add_subtree(tree, tvb, offset, data_len, ett_8023_extension, NULL, "802.3 Extension");
778     add_ppi_field_header(tvb, ftree, &offset);
779     data_len -= 4; /* Subtract field header length */
780 
781     if (data_len != PPI_8023_EXTENSION_LEN) {
782         proto_tree_add_expert_format(ftree, pinfo, &ei_ppi_invalid_length, tvb, offset, data_len, "Invalid length: %u", data_len);
783         return;
784     }
785 
786     csr = ptvcursor_new(pinfo->pool, ftree, tvb, offset);
787 
788     ptvcursor_add_with_subtree(csr, hf_8023_extension_flags, 4, ENC_LITTLE_ENDIAN, ett_8023_extension_flags);
789     ptvcursor_add(csr, hf_8023_extension_flags_fcs_present, 4, ENC_LITTLE_ENDIAN);
790     ptvcursor_pop_subtree(csr);
791 
792     ptvcursor_add_with_subtree(csr, hf_8023_extension_errors, 4, ENC_LITTLE_ENDIAN, ett_8023_extension_errors);
793     ptvcursor_add_no_advance(csr, hf_8023_extension_errors_fcs, 4, ENC_LITTLE_ENDIAN);
794     ptvcursor_add_no_advance(csr, hf_8023_extension_errors_sequence, 4, ENC_LITTLE_ENDIAN);
795     ptvcursor_add_no_advance(csr, hf_8023_extension_errors_symbol, 4, ENC_LITTLE_ENDIAN);
796     ptvcursor_add(csr, hf_8023_extension_errors_data, 4, ENC_LITTLE_ENDIAN);
797     ptvcursor_pop_subtree(csr);
798 
799     ptvcursor_free(csr);
800 }
801 
802 
803 #define PADDING4(x) ((((x + 3) >> 2) << 2) - x)
804 #define ADD_BASIC_TAG(hf_tag) \
805     if (tree)   \
806         proto_tree_add_item(ppi_tree, hf_tag, tvb, offset, data_len, ENC_NA)
807 
808 static int
dissect_ppi(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)809 dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
810 {
811     proto_tree    *ppi_tree    = NULL, *ppi_flags_tree = NULL, *seg_tree = NULL, *ampdu_tree = NULL;
812     proto_tree    *agg_tree    = NULL;
813     proto_item    *ti          = NULL;
814     tvbuff_t      *next_tvb;
815     int            offset      = 0;
816     guint          version, flags;
817     gint           tot_len, data_len;
818     guint          data_type;
819     guint32        dlt;
820     guint32        n_ext_flags = 0;
821     guint32        ampdu_id    = 0;
822     fragment_head *fd_head     = NULL;
823     fragment_item *ft_fdh      = NULL;
824     gint           mpdu_count  = 0;
825     gchar         *mpdu_str;
826     gboolean       first_mpdu  = TRUE;
827     guint          last_frame  = 0;
828     gint len_remain, /*pad_len = 0,*/ ampdu_len = 0;
829     struct ieee_802_11_phdr phdr;
830 
831     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPI");
832     col_clear(pinfo->cinfo, COL_INFO);
833 
834     version = tvb_get_guint8(tvb, offset);
835     flags = tvb_get_guint8(tvb, offset + 1);
836 
837     tot_len = tvb_get_letohs(tvb, offset+2);
838     dlt = tvb_get_letohl(tvb, offset+4);
839 
840     col_add_fstr(pinfo->cinfo, COL_INFO, "PPI version %u, %u bytes",
841                  version, tot_len);
842 
843     /* Dissect the packet */
844     if (tree) {
845         ti = proto_tree_add_protocol_format(tree, proto_ppi,
846                                             tvb, 0, tot_len, "PPI version %u, %u bytes", version, tot_len);
847         ppi_tree = proto_item_add_subtree(ti, ett_ppi_pph);
848         proto_tree_add_item(ppi_tree, hf_ppi_head_version,
849                             tvb, offset, 1, ENC_LITTLE_ENDIAN);
850 
851         ti = proto_tree_add_item(ppi_tree, hf_ppi_head_flags,
852                                  tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
853         ppi_flags_tree = proto_item_add_subtree(ti, ett_ppi_flags);
854         proto_tree_add_item(ppi_flags_tree, hf_ppi_head_flag_alignment,
855                             tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
856         proto_tree_add_item(ppi_flags_tree, hf_ppi_head_flag_reserved,
857                             tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
858 
859         proto_tree_add_item(ppi_tree, hf_ppi_head_len,
860                                  tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
861         proto_tree_add_item(ppi_tree, hf_ppi_head_dlt,
862                                  tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
863     }
864 
865     tot_len -= PPI_V0_HEADER_LEN;
866     offset += 8;
867 
868     /* We don't have any 802.11 metadata yet. */
869     memset(&phdr, 0, sizeof(phdr));
870     phdr.fcs_len = -1;
871     phdr.decrypted = FALSE;
872     phdr.datapad = FALSE;
873     phdr.phy = PHDR_802_11_PHY_UNKNOWN;
874 
875     while (tot_len > 0) {
876         data_type = tvb_get_letohs(tvb, offset);
877         data_len = tvb_get_letohs(tvb, offset + 2) + 4;
878         tot_len -= data_len;
879 
880         switch (data_type) {
881 
882         case PPI_80211_COMMON:
883             dissect_80211_common(tvb, pinfo, ppi_tree, offset, data_len, &phdr);
884             break;
885 
886         case PPI_80211N_MAC:
887             dissect_80211n_mac(tvb, pinfo, ppi_tree, offset, data_len,
888                 TRUE, &n_ext_flags, &ampdu_id, &phdr);
889             break;
890 
891         case PPI_80211N_MAC_PHY:
892             dissect_80211n_mac_phy(tvb, pinfo, ppi_tree, offset,
893                 data_len, &n_ext_flags, &ampdu_id, &phdr);
894             break;
895 
896         case PPI_SPECTRUM_MAP:
897             ADD_BASIC_TAG(hf_spectrum_map);
898             break;
899 
900         case PPI_PROCESS_INFO:
901             ADD_BASIC_TAG(hf_process_info);
902             break;
903 
904         case PPI_CAPTURE_INFO:
905             ADD_BASIC_TAG(hf_capture_info);
906             break;
907 
908         case PPI_AGGREGATION_EXTENSION:
909             dissect_aggregation_extension(tvb, pinfo, ppi_tree, offset, data_len);
910             break;
911 
912         case PPI_8023_EXTENSION:
913             dissect_8023_extension(tvb, pinfo, ppi_tree, offset, data_len);
914             break;
915 
916         case PPI_GPS_INFO:
917             if (ppi_gps_handle == NULL)
918             {
919                 proto_tree_add_item(ppi_tree, hf_ppi_gps, tvb, offset, data_len, ENC_NA);
920             }
921             else /* we found a suitable dissector */
922             {
923                 /* skip over the ppi_fieldheader, and pass it off to the dedicated GPS dissetor */
924                 next_tvb = tvb_new_subset_length_caplen(tvb, offset + 4, data_len - 4 , -1);
925                 call_dissector(ppi_gps_handle, next_tvb, pinfo, ppi_tree);
926             }
927             break;
928 
929         case PPI_VECTOR_INFO:
930             if (ppi_vector_handle == NULL)
931             {
932                 proto_tree_add_item(ppi_tree, hf_ppi_vector, tvb, offset, data_len, ENC_NA);
933             }
934             else /* we found a suitable dissector */
935             {
936                 /* skip over the ppi_fieldheader, and pass it off to the dedicated VECTOR dissetor */
937                 next_tvb = tvb_new_subset_length_caplen(tvb, offset + 4, data_len - 4 , -1);
938                 call_dissector(ppi_vector_handle, next_tvb, pinfo, ppi_tree);
939             }
940             break;
941 
942         case PPI_SENSOR_INFO:
943             if (ppi_sensor_handle == NULL)
944             {
945                 proto_tree_add_item(ppi_tree, hf_ppi_harris, tvb, offset, data_len, ENC_NA);
946             }
947             else /* we found a suitable dissector */
948             {
949                 /* skip over the ppi_fieldheader, and pass it off to the dedicated SENSOR dissetor */
950                 next_tvb = tvb_new_subset_length_caplen(tvb, offset + 4, data_len - 4 , -1);
951                 call_dissector(ppi_sensor_handle, next_tvb, pinfo, ppi_tree);
952             }
953             break;
954 
955         case PPI_ANTENNA_INFO:
956             if (ppi_antenna_handle == NULL)
957             {
958                 proto_tree_add_item(ppi_tree, hf_ppi_antenna, tvb, offset, data_len, ENC_NA);
959             }
960             else /* we found a suitable dissector */
961             {
962                 /* skip over the ppi_fieldheader, and pass it off to the dedicated ANTENNA dissetor */
963                 next_tvb = tvb_new_subset_length_caplen(tvb, offset + 4, data_len - 4 , -1);
964                 call_dissector(ppi_antenna_handle, next_tvb, pinfo, ppi_tree);
965             }
966             break;
967 
968         case FNET_PRIVATE:
969             if (ppi_fnet_handle == NULL)
970             {
971                 proto_tree_add_item(ppi_tree, hf_ppi_fnet, tvb, offset, data_len, ENC_NA);
972             }
973             else /* we found a suitable dissector */
974             {
975                 /* skip over the ppi_fieldheader, and pass it off to the dedicated FNET dissetor */
976                 next_tvb = tvb_new_subset_length_caplen(tvb, offset + 4, data_len - 4 , -1);
977                 call_dissector(ppi_fnet_handle, next_tvb, pinfo, ppi_tree);
978             }
979             break;
980 
981         default:
982             proto_tree_add_item(ppi_tree, hf_ppi_reserved, tvb, offset, data_len, ENC_NA);
983         }
984 
985         offset += data_len;
986         if (IS_PPI_FLAG_ALIGN(flags)){
987             offset += PADDING4(offset);
988         }
989     }
990 
991     /*
992      * The Channel-Flags field is described as "Radiotap-formatted
993      * channel flags".  The comment in the radiotap.org page about
994      * the suggested xchannel field says:
995      *
996      *  As used, this field conflates channel properties (which
997      *  need not be stored per packet but are more or less fixed)
998      *  with packet properties (like the modulation).
999      *
1000      * The radiotap channel field, in practice, seems to be used,
1001      * in some cases, to indicate channel properties (from which
1002      * the packet modulation cannot be inferred) and, in other
1003      * cases, to indicate the packet's modulation.
1004      *
1005      * The same applies to the Channel-Flags field.  There is a capture
1006      * in which the Channel-Flags field indicates that the channel is
1007      * an OFDM-only channel with a center frequency of 2422 MHz, and
1008      * the data rate field indicates a 2 Mb/s rate, which means you can't
1009      * rely on the CCK/OFDM/dynamic CCK/OFDM bits in the channel field
1010      * to indicate anything.
1011      *
1012      * That makes the Channel-Flags field unusable either for determining
1013      * the channel type or for determining the packet modulation,
1014      * as it cannot be determined how it's being used.
1015      *
1016      * Fortunately, there are other ways to determine the packet
1017      * modulation:
1018      *
1019      *  if there's an FHSS flag, the packet was transmitted
1020      *  using the 802.11 legacy FHSS modulation;
1021      *
1022      *  otherwise:
1023      *
1024      *    if there's an 802.11n MAC Extension header or an 802.11n
1025      *    MAC+PHY Extension header, the packet was transmitted using
1026      *    one of the 11n HT PHY's specified modulations;
1027      *
1028      *    otherwise:
1029      *
1030      *      if the data rate is 1 Mb/s or 2 Mb/s, the packet was
1031      *      transmitted using the 802.11 legacy DSSS modulation
1032      *      (we ignore the IR PHY - was it ever implemented?);
1033      *
1034      *      if the data rate is 5 Mb/s or 11 Mb/s, the packet
1035      *      was transmitted using the 802.11b DSSS/CCK modulation
1036      *      (or the now-obsolete DSSS/PBCC modulation; *if* we can
1037      *      rely on the channel/xchannel field's "CCK channel" and
1038      *      "Dynamic CCK-OFDM channel" flags, the absence of either
1039      *      flag would presumably indicate DSSS/PBCC);
1040      *
1041      *      if the data rate is 22 Mb/s or 33 Mb/s, the packet was
1042      *      transmitted using the 802.11b DSSS/PBCC modulation (as
1043      *      those speeds aren't supported by DSSS/CCK);
1044      *
1045      *      if the data rate is one of the OFDM rates for the 11a
1046      *      OFDM PHY and the OFDM part of the 11g ERP PHY, the
1047      *      packet was transmitted with the 11g/11a OFDM modulation.
1048      *
1049      * We've already handled the 11n headers, and may have attempted
1050      * to use the Channel-Flags field to guess the modulation.  That
1051      * guess might get the wrong answer for 11g "Dynamic CCK-OFDM"
1052      * channels.
1053      *
1054      * If we have the data rate, we use it to:
1055      *
1056      *  fix up the 11g channels;
1057      *
1058      *  determine the modulation if we haven't been able to
1059      *  determine it any other way.
1060      */
1061     if (phdr.has_data_rate) {
1062         if (phdr.phy == PHDR_802_11_PHY_UNKNOWN) {
1063             /*
1064              * We don't know they PHY, but we do have the
1065              * data rate; try to guess it based on the
1066              * data rate and channel/center frequency.
1067              */
1068             if (RATE_IS_DSSS(phdr.data_rate)) {
1069                 /* 11b */
1070                 phdr.phy = PHDR_802_11_PHY_11B;
1071             } else if (RATE_IS_OFDM(phdr.data_rate)) {
1072                 /* 11a or 11g, depending on the band. */
1073                 if (phdr.has_frequency) {
1074                     if (FREQ_IS_BG(phdr.frequency)) {
1075                         /* 11g */
1076                         phdr.phy = PHDR_802_11_PHY_11G;
1077                     } else {
1078                         /* 11a */
1079                         phdr.phy = PHDR_802_11_PHY_11A;
1080                     }
1081                 }
1082             }
1083         } else if (phdr.phy == PHDR_802_11_PHY_11G) {
1084             if (RATE_IS_DSSS(phdr.data_rate)) {
1085                 /* DSSS, so 11b. */
1086                 phdr.phy = PHDR_802_11_PHY_11B;
1087             }
1088         }
1089     }
1090 
1091     /*
1092      * There is no indication, for HR/DSSS (11b/11g), whether
1093      * the packet had a long or short preamble.
1094      */
1095     if (phdr.phy == PHDR_802_11_PHY_11B)
1096         phdr.phy_info.info_11b.has_short_preamble = FALSE;
1097 
1098     if (ppi_ampdu_reassemble && DOT11N_IS_AGGREGATE(n_ext_flags)) {
1099         len_remain = tvb_captured_length_remaining(tvb, offset);
1100 #if 0 /* XXX: pad_len never actually used ?? */
1101         if (DOT11N_MORE_AGGREGATES(n_ext_flags)) {
1102             pad_len = PADDING4(len_remain);
1103         }
1104 #endif
1105         pinfo->fragmented = TRUE;
1106 
1107         /* Make sure we aren't going to go past AGGREGATE_MAX
1108          * and caclulate our full A-MPDU length */
1109         fd_head = fragment_get(&ampdu_reassembly_table, pinfo, ampdu_id, NULL);
1110         while (fd_head) {
1111             ampdu_len += fd_head->len + PADDING4(fd_head->len) + 4;
1112             fd_head = fd_head->next;
1113         }
1114         if (ampdu_len > AGGREGATE_MAX) {
1115             proto_tree_add_expert_format(ppi_tree, pinfo, &ei_ppi_invalid_length, tvb, offset, -1, "Aggregate length greater than maximum (%u)", AGGREGATE_MAX);
1116             return offset;
1117         }
1118 
1119         /*
1120          * Note that we never actually reassemble our A-MPDUs.  Doing
1121          * so would require prepending each MPDU with an A-MPDU delimiter
1122          * and appending it with padding, only to hand it off to some
1123          * routine which would un-do the work we just did.  We're using
1124          * the reassembly code to track MPDU sizes and frame numbers.
1125          */
1126         /*??fd_head = */fragment_add_seq_next(&ampdu_reassembly_table,
1127             tvb, offset, pinfo, ampdu_id, NULL, len_remain, TRUE);
1128         pinfo->fragmented = TRUE;
1129 
1130         /* Do reassembly? */
1131         fd_head = fragment_get(&ampdu_reassembly_table, pinfo, ampdu_id, NULL);
1132 
1133         /* Show our fragments */
1134         if (fd_head && tree) {
1135             ft_fdh = fd_head;
1136             /* List our fragments */
1137             seg_tree = proto_tree_add_subtree_format(ppi_tree, tvb, offset, -1,
1138                     ett_ampdu_segments, &ti, "A-MPDU (%u bytes w/hdrs):", ampdu_len);
1139             proto_item_set_generated(ti);
1140 
1141             while (ft_fdh) {
1142                 if (ft_fdh->tvb_data && ft_fdh->len) {
1143                     last_frame = ft_fdh->frame;
1144                     if (!first_mpdu)
1145                         proto_item_append_text(ti, ",");
1146                     first_mpdu = FALSE;
1147                     proto_item_append_text(ti, " #%u(%u)",
1148                         ft_fdh->frame, ft_fdh->len);
1149                     proto_tree_add_uint_format(seg_tree, hf_ampdu_segment,
1150                         tvb, 0, 0, last_frame,
1151                         "Frame: %u (%u byte%s)",
1152                         last_frame,
1153                         ft_fdh->len,
1154                         plurality(ft_fdh->len, "", "s"));
1155                 }
1156                 ft_fdh = ft_fdh->next;
1157             }
1158             if (last_frame && last_frame != pinfo->num)
1159                 proto_tree_add_uint(seg_tree, hf_ampdu_reassembled_in,
1160                     tvb, 0, 0, last_frame);
1161         }
1162 
1163         if (fd_head && !DOT11N_MORE_AGGREGATES(n_ext_flags)) {
1164             if (tree) {
1165                 ti = proto_tree_add_protocol_format(tree,
1166                     proto_get_id_by_filter_name("wlan_aggregate"),
1167                     tvb, 0, tot_len, "IEEE 802.11 Aggregate MPDU");
1168                 agg_tree = proto_item_add_subtree(ti, ett_ampdu);
1169             }
1170 
1171             while (fd_head) {
1172                 if (fd_head->tvb_data && fd_head->len) {
1173                     mpdu_count++;
1174                     mpdu_str = wmem_strdup_printf(pinfo->pool, "MPDU #%d", mpdu_count);
1175 
1176                     next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
1177                     add_new_data_source(pinfo, next_tvb, mpdu_str);
1178 
1179                     ampdu_tree = proto_tree_add_subtree(agg_tree, next_tvb, 0, -1, ett_ampdu_segment, NULL, mpdu_str);
1180                     call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, ampdu_tree, &phdr);
1181                 }
1182                 fd_head = fd_head->next;
1183             }
1184             proto_tree_add_uint(seg_tree, hf_ampdu_count, tvb, 0, 0, mpdu_count);
1185             pinfo->fragmented=FALSE;
1186         } else {
1187             next_tvb = tvb_new_subset_remaining(tvb, offset);
1188             col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.11n");
1189             col_set_str(pinfo->cinfo, COL_INFO, "Unreassembled A-MPDU data");
1190             call_data_dissector(next_tvb, pinfo, tree);
1191         }
1192         return tvb_captured_length(tvb);
1193     }
1194 
1195     next_tvb = tvb_new_subset_remaining(tvb, offset);
1196     /*
1197      * Handle LINKTYPE_IEEE802_11, which is 105, specially; call the
1198      * "802.11 with radio information" dissector, and pass it a pointer
1199      * to the struct ieee_802_11_phdr we've constructed from the PPI data,
1200      * so that it can display that information.
1201      *
1202      * Handle everything else with the pcap_pktdata dissector, letting
1203      * it do whatever needs to be done about pseudo-headers.
1204      */
1205     if (dlt == 105) {
1206         /* LINKTYPE_IEEE802_11 */
1207         call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr);
1208     } else {
1209         /* Everything else. */
1210         call_dissector_with_data(pcap_pktdata_handle, next_tvb, pinfo, tree, &dlt);
1211     }
1212     return tvb_captured_length(tvb);
1213 }
1214 
1215 /* Establish our beachead */
1216 
1217 void
proto_register_ppi(void)1218 proto_register_ppi(void)
1219 {
1220     static hf_register_info hf[] = {
1221     { &hf_ppi_head_version,
1222       { "Version", "ppi.version",
1223         FT_UINT8, BASE_DEC, NULL, 0x0,
1224         "PPI header format version", HFILL } },
1225     { &hf_ppi_head_flags,
1226       { "Flags", "ppi.flags",
1227         FT_UINT8, BASE_HEX, NULL, 0x0,
1228         "PPI header flags", HFILL } },
1229     { &hf_ppi_head_flag_alignment,
1230       { "Alignment", "ppi.flags.alignment",
1231         FT_BOOLEAN, 8, TFS(&tfs_ppi_head_flag_alignment), 0x01,
1232         "PPI header flags - 32bit Alignment", HFILL } },
1233     { &hf_ppi_head_flag_reserved,
1234       { "Reserved", "ppi.flags.reserved",
1235         FT_UINT8, BASE_HEX, NULL, 0xFE,
1236         "PPI header flags - Reserved Flags", HFILL } },
1237     { &hf_ppi_head_len,
1238        { "Header length", "ppi.length",
1239          FT_UINT16, BASE_DEC, NULL, 0x0,
1240          "Length of header including payload", HFILL } },
1241     { &hf_ppi_head_dlt,
1242        { "DLT", "ppi.dlt",
1243          FT_UINT32, BASE_DEC, NULL, 0x0, "libpcap Data Link Type (DLT) of the payload", HFILL } },
1244 
1245     { &hf_ppi_field_type,
1246        { "Field type", "ppi.field_type",
1247          FT_UINT16, BASE_DEC, VALS(vs_ppi_field_type), 0x0, "PPI data field type", HFILL } },
1248     { &hf_ppi_field_len,
1249        { "Field length", "ppi.field_len",
1250          FT_UINT16, BASE_DEC, NULL, 0x0, "PPI data field length", HFILL } },
1251 
1252     { &hf_80211_common_tsft,
1253        { "TSFT", "ppi.80211-common.tsft",
1254          FT_UINT64, BASE_DEC, NULL, 0x0, "PPI 802.11-Common Timing Synchronization Function Timer (TSFT)", HFILL } },
1255     { &hf_80211_common_flags,
1256        { "Flags", "ppi.80211-common.flags",
1257          FT_UINT16, BASE_HEX, NULL, 0x0, "PPI 802.11-Common Flags", HFILL } },
1258     { &hf_80211_common_flags_fcs,
1259        { "FCS present flag", "ppi.80211-common.flags.fcs",
1260          FT_BOOLEAN, 16, TFS(&tfs_present_absent), DOT11_FLAG_HAVE_FCS, "PPI 802.11-Common Frame Check Sequence (FCS) Present Flag", HFILL } },
1261     { &hf_80211_common_flags_tsft,
1262        { "TSFT flag", "ppi.80211-common.flags.tsft",
1263          FT_BOOLEAN, 16, TFS(&tfs_tsft_ms), DOT11_FLAG_TSF_TIMER_MS, "PPI 802.11-Common Timing Synchronization Function Timer (TSFT) msec/usec flag", HFILL } },
1264     { &hf_80211_common_flags_fcs_valid,
1265        { "FCS validity", "ppi.80211-common.flags.fcs-invalid",
1266          FT_BOOLEAN, 16, TFS(&tfs_invalid_valid), DOT11_FLAG_FCS_INVALID, "PPI 802.11-Common Frame Check Sequence (FCS) Validity flag", HFILL } },
1267     { &hf_80211_common_flags_phy_err,
1268        { "PHY error flag", "ppi.80211-common.flags.phy-err",
1269          FT_BOOLEAN, 16, TFS(&tfs_phy_error), DOT11_FLAG_PHY_ERROR, "PPI 802.11-Common Physical level (PHY) Error", HFILL } },
1270     { &hf_80211_common_rate,
1271        { "Data rate", "ppi.80211-common.rate",
1272          FT_UINT16, BASE_DEC, NULL, 0x0, "PPI 802.11-Common Data Rate (x 500 Kbps)", HFILL } },
1273     { &hf_80211_common_chan_freq,
1274        { "Channel frequency", "ppi.80211-common.chan.freq",
1275          FT_UINT16, BASE_DEC, NULL, 0x0,
1276         "PPI 802.11-Common Channel Frequency", HFILL } },
1277     { &hf_80211_common_chan_flags,
1278        { "Channel flags", "ppi.80211-common.chan.flags",
1279          FT_UINT16, BASE_HEX, NULL, 0x0, "PPI 802.11-Common Channel Flags", HFILL } },
1280 
1281     { &hf_80211_common_chan_flags_turbo,
1282        { "Turbo", "ppi.80211-common.chan.flags.turbo",
1283          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_TURBO, "PPI 802.11-Common Channel Flags Turbo", HFILL } },
1284     { &hf_80211_common_chan_flags_cck,
1285        { "Complementary Code Keying (CCK)", "ppi.80211-common.chan.flags.cck",
1286          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_CCK, "PPI 802.11-Common Channel Flags Complementary Code Keying (CCK) Modulation", HFILL } },
1287     { &hf_80211_common_chan_flags_ofdm,
1288        { "Orthogonal Frequency-Division Multiplexing (OFDM)", "ppi.80211-common.chan.flags.ofdm",
1289          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_OFDM, "PPI 802.11-Common Channel Flags Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL } },
1290     { &hf_80211_common_chan_flags_2ghz,
1291        { "2 GHz spectrum", "ppi.80211-common.chan.flags.2ghz",
1292          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_2GHZ, "PPI 802.11-Common Channel Flags 2 GHz spectrum", HFILL } },
1293     { &hf_80211_common_chan_flags_5ghz,
1294        { "5 GHz spectrum", "ppi.80211-common.chan.flags.5ghz",
1295          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_5GHZ, "PPI 802.11-Common Channel Flags 5 GHz spectrum", HFILL } },
1296     { &hf_80211_common_chan_flags_passive,
1297        { "Passive", "ppi.80211-common.chan.flags.passive",
1298          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_PASSIVE, "PPI 802.11-Common Channel Flags Passive", HFILL } },
1299     { &hf_80211_common_chan_flags_dynamic,
1300        { "Dynamic CCK-OFDM", "ppi.80211-common.chan.flags.dynamic",
1301          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_DYN, "PPI 802.11-Common Channel Flags Dynamic CCK-OFDM Channel", HFILL } },
1302     { &hf_80211_common_chan_flags_gfsk,
1303        { "Gaussian Frequency Shift Keying (GFSK)", "ppi.80211-common.chan.flags.gfsk",
1304          FT_BOOLEAN, 16, NULL, IEEE80211_CHAN_GFSK, "PPI 802.11-Common Channel Flags Gaussian Frequency Shift Keying (GFSK) Modulation", HFILL } },
1305 
1306     { &hf_80211_common_fhss_hopset,
1307        { "FHSS hopset", "ppi.80211-common.fhss.hopset",
1308          FT_UINT8, BASE_HEX, NULL, 0x0, "PPI 802.11-Common Frequency-Hopping Spread Spectrum (FHSS) Hopset", HFILL } },
1309     { &hf_80211_common_fhss_pattern,
1310        { "FHSS pattern", "ppi.80211-common.fhss.pattern",
1311          FT_UINT8, BASE_HEX, NULL, 0x0, "PPI 802.11-Common Frequency-Hopping Spread Spectrum (FHSS) Pattern", HFILL } },
1312     { &hf_80211_common_dbm_antsignal,
1313        { "dBm antenna signal", "ppi.80211-common.dbm.antsignal",
1314          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11-Common dBm Antenna Signal", HFILL } },
1315     { &hf_80211_common_dbm_antnoise,
1316        { "dBm antenna noise", "ppi.80211-common.dbm.antnoise",
1317          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11-Common dBm Antenna Noise", HFILL } },
1318 
1319     /* 802.11n MAC */
1320     { &hf_80211n_mac_flags,
1321        { "MAC flags", "ppi.80211n-mac.flags",
1322          FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC flags", HFILL } },
1323     { &hf_80211n_mac_flags_greenfield,
1324        { "Greenfield flag", "ppi.80211n-mac.flags.greenfield",
1325          FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_GREENFIELD, "PPI 802.11n MAC Greenfield Flag", HFILL } },
1326     { &hf_80211n_mac_flags_ht20_40,
1327        { "HT20/HT40 flag", "ppi.80211n-mac.flags.ht20_40",
1328          FT_BOOLEAN, 32, TFS(&tfs_ht20_40), DOT11N_FLAG_HT40, "PPI 802.11n MAC HT20/HT40 Flag", HFILL } },
1329     { &hf_80211n_mac_flags_rx_guard_interval,
1330        { "RX Short Guard Interval (SGI) flag", "ppi.80211n-mac.flags.rx.short_guard_interval",
1331          FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_SHORT_GI, "PPI 802.11n MAC RX Short Guard Interval (SGI) Flag", HFILL } },
1332     { &hf_80211n_mac_flags_duplicate_rx,
1333        { "Duplicate RX flag", "ppi.80211n-mac.flags.rx.duplicate",
1334          FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_DUPLICATE_RX, "PPI 802.11n MAC Duplicate RX Flag", HFILL } },
1335     { &hf_80211n_mac_flags_aggregate,
1336        { "Aggregate flag", "ppi.80211n-mac.flags.agg",
1337          FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_IS_AGGREGATE, "PPI 802.11 MAC Aggregate Flag", HFILL } },
1338     { &hf_80211n_mac_flags_more_aggregates,
1339        { "More aggregates flag", "ppi.80211n-mac.flags.more_agg",
1340          FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_MORE_AGGREGATES, "PPI 802.11n MAC More Aggregates Flag", HFILL } },
1341     { &hf_80211n_mac_flags_delimiter_crc_after,
1342        { "A-MPDU Delimiter CRC error after this frame flag", "ppi.80211n-mac.flags.delim_crc_error_after",
1343          FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_AGG_CRC_ERROR, "PPI 802.11n MAC A-MPDU Delimiter CRC Error After This Frame Flag", HFILL } },
1344     { &hf_80211n_mac_ampdu_id,
1345        { "AMPDU-ID", "ppi.80211n-mac.ampdu_id",
1346          FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC AMPDU-ID", HFILL } },
1347     { &hf_80211n_mac_num_delimiters,
1348        { "Num-Delimiters", "ppi.80211n-mac.num_delimiters",
1349          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC number of zero-length pad delimiters", HFILL } },
1350     { &hf_80211n_mac_reserved,
1351        { "Reserved", "ppi.80211n-mac.reserved",
1352          FT_UINT24, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC Reserved", HFILL } },
1353 
1354 
1355     /* 802.11n MAC+PHY */
1356     { &hf_80211n_mac_phy_mcs,
1357        { "MCS", "ppi.80211n-mac-phy.mcs",
1358          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Modulation Coding Scheme (MCS)", HFILL } },
1359     { &hf_80211n_mac_phy_num_streams,
1360        { "Number of spatial streams", "ppi.80211n-mac-phy.num_streams",
1361          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY number of spatial streams", HFILL } },
1362     { &hf_80211n_mac_phy_rssi_combined,
1363        { "RSSI combined", "ppi.80211n-mac-phy.rssi.combined",
1364          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Received Signal Strength Indication (RSSI) Combined", HFILL } },
1365     { &hf_80211n_mac_phy_rssi_ant0_ctl,
1366        { "Antenna 0 control RSSI", "ppi.80211n-mac-phy.rssi.ant0ctl",
1367          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 0 Control Channel Received Signal Strength Indication (RSSI)", HFILL } },
1368     { &hf_80211n_mac_phy_rssi_ant1_ctl,
1369        { "Antenna 1 control RSSI", "ppi.80211n-mac-phy.rssi.ant1ctl",
1370          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 1 Control Channel Received Signal Strength Indication (RSSI)", HFILL } },
1371     { &hf_80211n_mac_phy_rssi_ant2_ctl,
1372        { "Antenna 2 control RSSI", "ppi.80211n-mac-phy.rssi.ant2ctl",
1373          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 2 Control Channel Received Signal Strength Indication (RSSI)", HFILL } },
1374     { &hf_80211n_mac_phy_rssi_ant3_ctl,
1375        { "Antenna 3 control RSSI", "ppi.80211n-mac-phy.rssi.ant3ctl",
1376          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 3 Control Channel Received Signal Strength Indication (RSSI)", HFILL } },
1377     { &hf_80211n_mac_phy_rssi_ant0_ext,
1378        { "Antenna 0 extension RSSI", "ppi.80211n-mac-phy.rssi.ant0ext",
1379          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 0 Extension Channel Received Signal Strength Indication (RSSI)", HFILL } },
1380     { &hf_80211n_mac_phy_rssi_ant1_ext,
1381        { "Antenna 1 extension RSSI", "ppi.80211n-mac-phy.rssi.ant1ext",
1382          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 1 Extension Channel Received Signal Strength Indication (RSSI)", HFILL } },
1383     { &hf_80211n_mac_phy_rssi_ant2_ext,
1384        { "Antenna 2 extension RSSI", "ppi.80211n-mac-phy.rssi.ant2ext",
1385          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 2 Extension Channel Received Signal Strength Indication (RSSI)", HFILL } },
1386     { &hf_80211n_mac_phy_rssi_ant3_ext,
1387        { "Antenna 3 extension RSSI", "ppi.80211n-mac-phy.rssi.ant3ext",
1388          FT_UINT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Antenna 3 Extension Channel Received Signal Strength Indication (RSSI)", HFILL } },
1389     { &hf_80211n_mac_phy_ext_chan_freq,
1390        { "Extended channel frequency", "ppi.80211-mac-phy.ext-chan.freq",
1391          FT_UINT16, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Extended Channel Frequency", HFILL } },
1392     { &hf_80211n_mac_phy_ext_chan_flags,
1393        { "Channel flags", "ppi.80211-mac-phy.ext-chan.flags",
1394          FT_UINT16, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC+PHY Channel Flags", HFILL } },
1395     { &hf_80211n_mac_phy_ext_chan_flags_turbo,
1396        { "Turbo", "ppi.80211-mac-phy.ext-chan.flags.turbo",
1397          FT_BOOLEAN, 16, NULL, 0x0010, "PPI 802.11n MAC+PHY Channel Flags Turbo", HFILL } },
1398     { &hf_80211n_mac_phy_ext_chan_flags_cck,
1399        { "Complementary Code Keying (CCK)", "ppi.80211-mac-phy.ext-chan.flags.cck",
1400          FT_BOOLEAN, 16, NULL, 0x0020, "PPI 802.11n MAC+PHY Channel Flags Complementary Code Keying (CCK) Modulation", HFILL } },
1401     { &hf_80211n_mac_phy_ext_chan_flags_ofdm,
1402        { "Orthogonal Frequency-Division Multiplexing (OFDM)", "ppi.80211-mac-phy.ext-chan.flags.ofdm",
1403          FT_BOOLEAN, 16, NULL, 0x0040, "PPI 802.11n MAC+PHY Channel Flags Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL } },
1404     { &hf_80211n_mac_phy_ext_chan_flags_2ghz,
1405        { "2 GHz spectrum", "ppi.80211-mac-phy.ext-chan.flags.2ghz",
1406          FT_BOOLEAN, 16, NULL, 0x0080, "PPI 802.11n MAC+PHY Channel Flags 2 GHz spectrum", HFILL } },
1407     { &hf_80211n_mac_phy_ext_chan_flags_5ghz,
1408        { "5 GHz spectrum", "ppi.80211-mac-phy.ext-chan.flags.5ghz",
1409          FT_BOOLEAN, 16, NULL, 0x0100, "PPI 802.11n MAC+PHY Channel Flags 5 GHz spectrum", HFILL } },
1410     { &hf_80211n_mac_phy_ext_chan_flags_passive,
1411        { "Passive", "ppi.80211-mac-phy.ext-chan.flags.passive",
1412          FT_BOOLEAN, 16, NULL, 0x0200, "PPI 802.11n MAC+PHY Channel Flags Passive", HFILL } },
1413     { &hf_80211n_mac_phy_ext_chan_flags_dynamic,
1414        { "Dynamic CCK-OFDM", "ppi.80211-mac-phy.ext-chan.flags.dynamic",
1415          FT_BOOLEAN, 16, NULL, 0x0400, "PPI 802.11n MAC+PHY Channel Flags Dynamic CCK-OFDM Channel", HFILL } },
1416     { &hf_80211n_mac_phy_ext_chan_flags_gfsk,
1417        { "Gaussian Frequency Shift Keying (GFSK)", "ppi.80211-mac-phy.ext-chan.flags.gfsk",
1418          FT_BOOLEAN, 16, NULL, 0x0800, "PPI 802.11n MAC+PHY Channel Flags Gaussian Frequency Shift Keying (GFSK) Modulation", HFILL } },
1419     { &hf_80211n_mac_phy_dbm_ant0signal,
1420        { "dBm antenna 0 signal", "ppi.80211n-mac-phy.dbmant0.signal",
1421          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 0 Signal", HFILL } },
1422     { &hf_80211n_mac_phy_dbm_ant0noise,
1423        { "dBm antenna 0 noise", "ppi.80211n-mac-phy.dbmant0.noise",
1424          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 0 Noise", HFILL } },
1425     { &hf_80211n_mac_phy_dbm_ant1signal,
1426        { "dBm antenna 1 signal", "ppi.80211n-mac-phy.dbmant1.signal",
1427          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 1 Signal", HFILL } },
1428     { &hf_80211n_mac_phy_dbm_ant1noise,
1429        { "dBm antenna 1 noise", "ppi.80211n-mac-phy.dbmant1.noise",
1430          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 1 Noise", HFILL } },
1431     { &hf_80211n_mac_phy_dbm_ant2signal,
1432        { "dBm antenna 2 signal", "ppi.80211n-mac-phy.dbmant2.signal",
1433          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 2 Signal", HFILL } },
1434     { &hf_80211n_mac_phy_dbm_ant2noise,
1435        { "dBm antenna 2 noise", "ppi.80211n-mac-phy.dbmant2.noise",
1436          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 2 Noise", HFILL } },
1437     { &hf_80211n_mac_phy_dbm_ant3signal,
1438        { "dBm antenna 3 signal", "ppi.80211n-mac-phy.dbmant3.signal",
1439          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 3 Signal", HFILL } },
1440     { &hf_80211n_mac_phy_dbm_ant3noise,
1441        { "dBm antenna 3 noise", "ppi.80211n-mac-phy.dbmant3.noise",
1442          FT_INT8, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY dBm Antenna 3 Noise", HFILL } },
1443     { &hf_80211n_mac_phy_evm0,
1444        { "EVM-0", "ppi.80211n-mac-phy.evm0",
1445          FT_UINT32, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Error Vector Magnitude (EVM) for chain 0", HFILL } },
1446     { &hf_80211n_mac_phy_evm1,
1447        { "EVM-1", "ppi.80211n-mac-phy.evm1",
1448          FT_UINT32, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Error Vector Magnitude (EVM) for chain 1", HFILL } },
1449     { &hf_80211n_mac_phy_evm2,
1450        { "EVM-2", "ppi.80211n-mac-phy.evm2",
1451          FT_UINT32, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Error Vector Magnitude (EVM) for chain 2", HFILL } },
1452     { &hf_80211n_mac_phy_evm3,
1453        { "EVM-3", "ppi.80211n-mac-phy.evm3",
1454          FT_UINT32, BASE_DEC, NULL, 0x0, "PPI 802.11n MAC+PHY Error Vector Magnitude (EVM) for chain 3", HFILL } },
1455 
1456     { &hf_ampdu_segment,
1457         { "A-MPDU", "ppi.80211n-mac.ampdu",
1458             FT_FRAMENUM, BASE_NONE, NULL, 0x0, "802.11n Aggregated MAC Protocol Data Unit (A-MPDU)", HFILL }},
1459 #if 0
1460     { &hf_ampdu_segments,
1461         { "Reassembled A-MPDU", "ppi.80211n-mac.ampdu.reassembled",
1462             FT_NONE, BASE_NONE, NULL, 0x0, "Reassembled Aggregated MAC Protocol Data Unit (A-MPDU)", HFILL }},
1463 #endif
1464     { &hf_ampdu_reassembled_in,
1465         { "Reassembled A-MPDU in frame", "ppi.80211n-mac.ampdu.reassembled_in",
1466             FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1467             "The A-MPDU that doesn't end in this segment is reassembled in this frame",
1468             HFILL }},
1469     { &hf_ampdu_count,
1470         { "MPDU count", "ppi.80211n-mac.ampdu.count",
1471             FT_UINT16, BASE_DEC, NULL, 0x0, "The number of aggregated MAC Protocol Data Units (MPDUs)", HFILL }},
1472 
1473     { &hf_spectrum_map,
1474        { "Radio spectrum map", "ppi.spectrum-map",
1475             FT_BYTES, BASE_NONE, NULL, 0x0, "PPI Radio spectrum map", HFILL } },
1476     { &hf_process_info,
1477        { "Process information", "ppi.proc-info",
1478             FT_BYTES, BASE_NONE, NULL, 0x0, "PPI Process information", HFILL } },
1479     { &hf_capture_info,
1480        { "Capture information", "ppi.cap-info",
1481             FT_BYTES, BASE_NONE, NULL, 0x0, "PPI Capture information", HFILL } },
1482 
1483     /* Aggregtion Extension */
1484     { &hf_aggregation_extension_interface_id,
1485        { "Interface ID", "ppi.aggregation_extension.interface_id",
1486             FT_UINT32, BASE_DEC, NULL, 0x0, "Zero-based index of the physical interface the packet was captured from", HFILL } },
1487 
1488     /* 802.3 Extension */
1489     { &hf_8023_extension_flags,
1490        { "Flags", "ppi.8023_extension.flags",
1491             FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.3 Extension Flags", HFILL } },
1492     { &hf_8023_extension_flags_fcs_present,
1493        { "FCS Present Flag", "ppi.8023_extension.flags.fcs_present",
1494             FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0001, "FCS (4 bytes) is present at the end of the packet", HFILL } },
1495     { &hf_8023_extension_errors,
1496        { "Errors", "ppi.8023_extension.errors",
1497             FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.3 Extension Errors", HFILL } },
1498     { &hf_8023_extension_errors_fcs,
1499        { "FCS Error", "ppi.8023_extension.errors.fcs",
1500             FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0001,
1501             "PPI 802.3 Extension FCS Error", HFILL } },
1502     { &hf_8023_extension_errors_sequence,
1503        { "Sequence Error", "ppi.8023_extension.errors.sequence",
1504             FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0002,
1505             "PPI 802.3 Extension Sequence Error", HFILL } },
1506     { &hf_8023_extension_errors_symbol,
1507        { "Symbol Error", "ppi.8023_extension.errors.symbol",
1508             FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0004,
1509             "PPI 802.3 Extension Symbol Error", HFILL } },
1510     { &hf_8023_extension_errors_data,
1511        { "Data Error", "ppi.8023_extension.errors.data",
1512             FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0008,
1513             "PPI 802.3 Extension Data Error", HFILL } },
1514 
1515       /* Generated from convert_proto_tree_add_text.pl */
1516       { &hf_ppi_gps, { "GPS", "ppi.gps", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1517       { &hf_ppi_vector, { "VECTOR", "ppi.vector", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1518       { &hf_ppi_harris, { "HARRIS", "ppi.harris", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1519       { &hf_ppi_antenna, { "ANTENNA", "ppi.antenna", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1520       { &hf_ppi_fnet, { "FNET", "ppi.fnet", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1521       { &hf_ppi_reserved, { "Reserved", "ppi.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1522     };
1523 
1524     static gint *ett[] = {
1525         &ett_ppi_pph,
1526         &ett_ppi_flags,
1527         &ett_dot11_common,
1528         &ett_dot11_common_flags,
1529         &ett_dot11_common_channel_flags,
1530         &ett_dot11n_mac,
1531         &ett_dot11n_mac_flags,
1532         &ett_dot11n_mac_phy,
1533         &ett_dot11n_mac_phy_ext_channel_flags,
1534         &ett_ampdu_segments,
1535         &ett_ampdu,
1536         &ett_ampdu_segment,
1537         &ett_aggregation_extension,
1538         &ett_8023_extension,
1539         &ett_8023_extension_flags,
1540         &ett_8023_extension_errors
1541     };
1542 
1543     static ei_register_info ei[] = {
1544         { &ei_ppi_invalid_length, { "ppi.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
1545     };
1546 
1547     module_t *ppi_module;
1548     expert_module_t* expert_ppi;
1549 
1550     proto_ppi = proto_register_protocol("PPI Packet Header", "PPI", "ppi");
1551     proto_register_field_array(proto_ppi, hf, array_length(hf));
1552     proto_register_subtree_array(ett, array_length(ett));
1553     expert_ppi = expert_register_protocol(proto_ppi);
1554     expert_register_field_array(expert_ppi, ei, array_length(ei));
1555 
1556     ppi_handle = register_dissector("ppi", dissect_ppi, proto_ppi);
1557     register_capture_dissector_table("ppi", "PPI");
1558 
1559     reassembly_table_register(&ampdu_reassembly_table,
1560                           &addresses_reassembly_table_functions);
1561 
1562     /* Configuration options */
1563     ppi_module = prefs_register_protocol(proto_ppi, NULL);
1564     prefs_register_bool_preference(ppi_module, "reassemble",
1565                                    "Reassemble fragmented 802.11 A-MPDUs",
1566                                    "Whether fragmented 802.11 aggregated MPDUs should be reassembled",
1567                                    &ppi_ampdu_reassemble);
1568 }
1569 
1570 void
proto_reg_handoff_ppi(void)1571 proto_reg_handoff_ppi(void)
1572 {
1573     capture_dissector_handle_t ppi_cap_handle;
1574 
1575     ieee80211_radio_handle = find_dissector_add_dependency("wlan_radio", proto_ppi);
1576     pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_ppi);
1577     ppi_gps_handle = find_dissector_add_dependency("ppi_gps", proto_ppi);
1578     ppi_vector_handle = find_dissector_add_dependency("ppi_vector", proto_ppi);
1579     ppi_sensor_handle = find_dissector_add_dependency("ppi_sensor", proto_ppi);
1580     ppi_antenna_handle = find_dissector_add_dependency("ppi_antenna", proto_ppi);
1581     ppi_fnet_handle = find_dissector_add_dependency("ppi_fnet", proto_ppi);
1582 
1583     dissector_add_uint("wtap_encap", WTAP_ENCAP_PPI, ppi_handle);
1584     ppi_cap_handle = create_capture_dissector_handle(capture_ppi, proto_ppi);
1585     capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_PPI, ppi_cap_handle);
1586 }
1587 
1588 /*
1589  * Editor modelines
1590  *
1591  * Local Variables:
1592  * c-basic-offset: 4
1593  * tab-width: 8
1594  * indent-tabs-mode: nil
1595  * End:
1596  *
1597  * ex: set shiftwidth=4 tabstop=8 expandtab:
1598  * :indentSize=4:tabSize=8:noTabs=true:
1599  */
1600