/src/wireshark/epan/dissectors/packet-ieee802154.c
Line | Count | Source |
1 | | /* packet-ieee802154.c |
2 | | * |
3 | | * Multipurpose frame support |
4 | | * By Devan Lai <devanl@davisinstruments.com> |
5 | | * Copyright 2019 Davis Instruments |
6 | | * |
7 | | * IEEE 802.15.4-2015 CCM* nonce for TSCH mode |
8 | | * By Maxime Brunelle <Maxime.Brunelle@trilliant.com> |
9 | | * Copyright 2019 Trilliant Inc. |
10 | | * |
11 | | * IEEE802154 TAP link type |
12 | | * By James Ko <jck@exegin.com> |
13 | | * Copyright 2019 Exegin Technologies Limited |
14 | | * |
15 | | * 4-byte FCS support and ACK tracking |
16 | | * By Carl Levesque Imbeault <carl.levesque@trilliant.com> |
17 | | * Copyright 2018 Trilliant Inc. |
18 | | * Integrated and added FCS type enum |
19 | | * by James Ko <jck@exegin.com> |
20 | | * Copyright 2019 Exegin Technologies Limited |
21 | | * |
22 | | * Auxiliary Security Header support and |
23 | | * option to force TI CC24xx FCS format |
24 | | * By Jean-Francois Wauthy <jfw@info.fundp.ac.be> |
25 | | * Copyright 2009 The University of Namur, Belgium |
26 | | * |
27 | | * IEEE 802.15.4 Dissectors for Wireshark |
28 | | * By Owen Kirby <osk@exegin.com> |
29 | | * Copyright 2007 Exegin Technologies Limited |
30 | | * |
31 | | * Wireshark - Network traffic analyzer |
32 | | * By Gerald Combs <gerald@wireshark.org> |
33 | | * Copyright 1998 Gerald Combs |
34 | | * |
35 | | * SPDX-License-Identifier: GPL-2.0-or-later |
36 | | *------------------------------------------------------------ |
37 | | * |
38 | | * In IEEE 802.15.4 packets, all fields are little endian. And |
39 | | * Each byte is transmitted least significant bit first (reflected |
40 | | * bit ordering). |
41 | | *------------------------------------------------------------ |
42 | | * |
43 | | * Most IEEE 802.15.4 Packets have the following format: |
44 | | * | FCF |Seq No| Addressing | Data | FCS | |
45 | | * |2 bytes|1 byte|0 to 20 bytes|Length-(Overhead) bytes|2/4 Bytes| |
46 | | *------------------------------------------------------------ |
47 | | * |
48 | | * Multipurpose frame packets have the following format: |
49 | | * | FCF | Seq No | Addressing | Data | FCS | |
50 | | * |1/2 bytes|0/1 bytes|0 to 20 bytes|Length-(Overhead) bytes|2 bytes| |
51 | | *------------------------------------------------------------ |
52 | | * |
53 | | * CRC16 is calculated using the x^16 + x^12 + x^5 + 1 polynomial |
54 | | * as specified by ITU-T, and is calculated over the IEEE 802.15.4 |
55 | | * packet (excluding the FCS) as transmitted over the air. Note, |
56 | | * that because the least significant bits are transmitted first, this |
57 | | * will require reversing the bit-order in each byte. Also, unlike |
58 | | * most CRC algorithms, IEEE 802.15.4 uses an initial and final value |
59 | | * of 0x0000, instead of 0xffff (which is used by the ITU-T). |
60 | | * |
61 | | * For a 4-byte FCS, CRC32 is calculated using the ITU-T CRC32. |
62 | | * |
63 | | * (Fun fact: the reference to "a 32-bit CRC equivalent to ANSI X3.66-1979" |
64 | | * in IEEE Std 802.15.4-2015 nonwithstanding, ANSI X3.66-1979 does not |
65 | | * describe any 32-bit CRC, only a 16-bit CRC from ITU-T V.41. ITU-T |
66 | | * V.42 describes both a 16-bit and 32-bit CRC; all the 16-bit CRCs |
67 | | * floating around seem to use the same generator polynomial, |
68 | | * x^16 + x^12 + x^5 + 1, but have different initial conditions and |
69 | | * no-error final remainder; the 32-bit CRC from V.42 and the one |
70 | | * described in IEEE Std 802.15.4-2015 also use the same generator |
71 | | * polynomial.) |
72 | | *------------------------------------------------------------ |
73 | | * |
74 | | * This dissector supports both link-layer IEEE 802.15.4 captures |
75 | | * and IEEE 802.15.4 packets encapsulated within other layers. |
76 | | * Additionally, support has been provided for 16-bit and 32-bit |
77 | | * FCS, as well as for frames with no FCS but with a 16-bit |
78 | | * ChipCon/Texas Instruments CC24xx-style metadata field. |
79 | | *------------------------------------------------------------ |
80 | | */ |
81 | | |
82 | | /* Include files */ |
83 | | #include "config.h" |
84 | | #include <epan/packet.h> |
85 | | #include <epan/decode_as.h> |
86 | | #include <epan/exceptions.h> |
87 | | #include <epan/crc16-tvb.h> |
88 | | #include <epan/crc32-tvb.h> |
89 | | #include <epan/expert.h> |
90 | | #include <epan/addr_resolv.h> |
91 | | #include <epan/address_types.h> |
92 | | #include <epan/conversation.h> |
93 | | #include <epan/conversation_table.h> |
94 | | #include <epan/conversation_filter.h> |
95 | | #include <epan/prefs.h> |
96 | | #include <epan/uat.h> |
97 | | #include <epan/strutil.h> |
98 | | #include <epan/to_str.h> |
99 | | #include <epan/show_exception.h> |
100 | | #include <epan/proto_data.h> |
101 | | #include <epan/etypes.h> |
102 | | #include <epan/oui.h> |
103 | | #include <epan/tap.h> |
104 | | #include <epan/tfs.h> |
105 | | #include <epan/unit_strings.h> |
106 | | #include <wsutil/pint.h> |
107 | | |
108 | | /* Use libgcrypt for cipher libraries. */ |
109 | | #include <wsutil/wsgcrypt.h> |
110 | | |
111 | | #include <wsutil/ws_padding_to.h> |
112 | | |
113 | | #include "packet-ieee802154.h" |
114 | | #include "packet-sll.h" |
115 | | #include "packet-zbee-tlv.h" |
116 | | |
117 | | void proto_register_ieee802154(void); |
118 | | void proto_reg_handoff_ieee802154(void); |
119 | | |
120 | | /* Dissection Options for dissect_ieee802154_common */ |
121 | 539 | #define DISSECT_IEEE802154_OPTION_CC24xx 0x00000001 /* Frame has TI CC24xx metadata, not an FCS, at the end */ |
122 | 14.6k | #define DISSECT_IEEE802154_OPTION_ZBOSS 0x00000002 /* ZBOSS traffic dump */ |
123 | | |
124 | | /* ethertype for 802.15.4 tag - encapsulating an Ethernet packet */ |
125 | | static unsigned int ieee802154_ethertype = 0x809A; |
126 | | |
127 | | static int ieee802154_fcs_type = IEEE802154_FCS_16_BIT; |
128 | | |
129 | | /* 802.15.4 TAP Fields */ |
130 | | typedef enum { |
131 | | IEEE802154_TAP_FCS_TYPE = 0x0000, |
132 | | IEEE802154_TAP_RSS = 0x0001, |
133 | | IEEE802154_TAP_BIT_RATE = 0x0002, |
134 | | IEEE802154_TAP_CHANNEL_ASSIGNMENT = 0x0003, |
135 | | IEEE802154_TAP_SUN_PHY_INFO = 0x0004, |
136 | | IEEE802154_TAP_START_OF_FRAME_TS = 0x0005, |
137 | | IEEE802154_TAP_END_OF_FRAME_TS = 0x0006, |
138 | | IEEE802154_TAP_ASN = 0x0007, |
139 | | IEEE802154_TAP_SLOT_START_TS = 0x0008, |
140 | | IEEE802154_TAP_TIMESLOT_LENGTH = 0x0009, |
141 | | IEEE802154_TAP_LQI = 0x000A, |
142 | | IEEE802154_TAP_CHANNEL_FREQUENCY = 0x000B, |
143 | | IEEE802154_TAP_CHANNEL_PLAN = 0x000C, |
144 | | IEEE802154_TAP_PHY_HEADER = 0x000D, |
145 | | } ieee802154_info_type_t; |
146 | | |
147 | | typedef enum { |
148 | | PHR_RAW = 0, |
149 | | PHR_O_QPSK = 1, |
150 | | PHR_CSS = 2, |
151 | | PHR_HRP_UWB = 3, |
152 | | PHR_MSK = 4, |
153 | | PHR_LRP_UWB = 5, |
154 | | PHR_SUN_FSK = 6, |
155 | | PHR_SUN_OFDM = 7, |
156 | | PHR_SUN_O_QPSK = 8, |
157 | | PHR_LECIM_FSK = 9, |
158 | | PHR_TVWS_FSK = 10, |
159 | | PHR_TVWS_OFDM = 11, |
160 | | PHR_TVWS_NB_OFDM = 12, |
161 | | PHR_RCC_LMR = 13, |
162 | | PHR_CMB_O_QPSK = 14, |
163 | | PHR_CMB_GFSK = 15, |
164 | | PHR_TASK = 16, |
165 | | PHR_RS_GFSK = 17, |
166 | | PHR_WISUN_FSK_MS = 18, |
167 | | } ieee802154_tap_phr_type_t; |
168 | | |
169 | | typedef enum { |
170 | | IEEE802154_FCS_TYPE_NONE = 0, |
171 | | IEEE802154_FCS_TYPE_16_BIT = 1, /* ITU-T CRC16 */ |
172 | | IEEE802154_FCS_TYPE_32_BIT = 2, /* ITU-T CRC32 */ |
173 | | } ieee802154_fcs_type_t; |
174 | | |
175 | | typedef enum { |
176 | | IEEE802154_SUN_TYPE_FSK_A = 0x00, |
177 | | IEEE802154_SUN_TYPE_FSK_B = 0x01, |
178 | | IEEE802154_SUN_TYPE_OQPSK_A = 0x02, |
179 | | IEEE802154_SUN_TYPE_OQPSK_B = 0x03, |
180 | | IEEE802154_SUN_TYPE_OQPSK_C = 0x04, |
181 | | IEEE802154_SUN_TYPE_OFDM_OPT1 = 0x05, |
182 | | IEEE802154_SUN_TYPE_OFDM_OPT2 = 0x06, |
183 | | IEEE802154_SUN_TYPE_OFDM_OPT3 = 0x07, |
184 | | IEEE802154_SUN_TYPE_OFDM_OPT4 = 0x08, |
185 | | } ieee802154_sun_type_t; |
186 | | |
187 | | /* boolean value set if the FCS must be ok before payload is dissected */ |
188 | | static bool ieee802154_fcs_ok = true; |
189 | | |
190 | | /* boolean value set to enable ack tracking */ |
191 | | static bool ieee802154_ack_tracking; |
192 | | |
193 | | /* boolean value set to enable 802.15.4e dissection compatibility */ |
194 | | static bool ieee802154e_compatibility; |
195 | | |
196 | | /* TSCH ASN for nonce in decryption */ |
197 | | static uint64_t ieee802154_tsch_asn; |
198 | | |
199 | | static const char *ieee802154_user = "User"; |
200 | | |
201 | | static wmem_tree_t* mac_key_hash_handlers; |
202 | | |
203 | | /* |
204 | | * Address Hash Tables |
205 | | * |
206 | | */ |
207 | | ieee802154_map_tab_t ieee802154_map = { NULL, NULL }; |
208 | | |
209 | | /* |
210 | | * Static Address Mapping UAT |
211 | | * |
212 | | */ |
213 | | /* UAT entry structure. */ |
214 | | typedef struct { |
215 | | unsigned char *eui64; |
216 | | unsigned eui64_len; |
217 | | unsigned addr16; |
218 | | unsigned pan; |
219 | | } static_addr_t; |
220 | | |
221 | | /* UAT variables */ |
222 | | static uat_t *static_addr_uat; |
223 | | static static_addr_t *static_addrs; |
224 | | static unsigned num_static_addrs; |
225 | | |
226 | | static void* |
227 | | addr_uat_copy_cb(void *dest, const void *source, size_t len _U_) |
228 | 0 | { |
229 | 0 | const static_addr_t* o = (const static_addr_t*)source; |
230 | 0 | static_addr_t* d = (static_addr_t*)dest; |
231 | |
|
232 | 0 | d->eui64 = (unsigned char *)g_memdup2(o->eui64, o->eui64_len); |
233 | 0 | d->eui64_len = o->eui64_len; |
234 | 0 | d->addr16 = o->addr16; |
235 | 0 | d->pan = o->pan; |
236 | |
|
237 | 0 | return dest; |
238 | 0 | } |
239 | | |
240 | | /* Sanity-checks a UAT record. */ |
241 | | static bool |
242 | | addr_uat_update_cb(void *r, char **err) |
243 | 0 | { |
244 | 0 | static_addr_t *map = (static_addr_t *)r; |
245 | | /* Ensure a valid short address */ |
246 | 0 | if (map->addr16 >= IEEE802154_NO_ADDR16) { |
247 | 0 | *err = g_strdup("Invalid short address"); |
248 | 0 | return false; |
249 | 0 | } |
250 | | /* Ensure a valid PAN identifier. */ |
251 | 0 | if (map->pan >= IEEE802154_BCAST_PAN) { |
252 | 0 | *err = g_strdup("Invalid PAN identifier"); |
253 | 0 | return false; |
254 | 0 | } |
255 | | /* Ensure a valid EUI-64 length */ |
256 | 0 | if (map->eui64_len != sizeof(uint64_t)) { |
257 | 0 | *err = g_strdup("Invalid EUI-64 length"); |
258 | 0 | return false; |
259 | 0 | } |
260 | 0 | return true; |
261 | 0 | } /* ieee802154_addr_uat_update_cb */ |
262 | | |
263 | | static void |
264 | | addr_uat_free_cb(void *r) |
265 | 0 | { |
266 | 0 | static_addr_t *rec = (static_addr_t *)r; |
267 | 0 | g_free(rec->eui64); |
268 | 0 | } |
269 | | |
270 | | /* Field callbacks. */ |
271 | 0 | UAT_HEX_CB_DEF(addr_uat, addr16, static_addr_t) Unexecuted instantiation: packet-ieee802154.c:addr_uat_addr16_set_cb Unexecuted instantiation: packet-ieee802154.c:addr_uat_addr16_tostr_cb |
272 | 0 | UAT_HEX_CB_DEF(addr_uat, pan, static_addr_t) Unexecuted instantiation: packet-ieee802154.c:addr_uat_pan_set_cb Unexecuted instantiation: packet-ieee802154.c:addr_uat_pan_tostr_cb |
273 | 0 | UAT_BUFFER_CB_DEF(addr_uat, eui64, static_addr_t, eui64, eui64_len) Unexecuted instantiation: packet-ieee802154.c:addr_uat_eui64_set_cb Unexecuted instantiation: packet-ieee802154.c:addr_uat_eui64_tostr_cb |
274 | | |
275 | | /* |
276 | | * Decryption Keys UAT |
277 | | */ |
278 | | |
279 | | /* UAT variables */ |
280 | | static uat_t *ieee802154_key_uat; |
281 | | static ieee802154_key_t *ieee802154_keys; |
282 | | static unsigned num_ieee802154_keys; |
283 | | |
284 | | static void ieee802154_key_post_update_cb(void) |
285 | 16 | { |
286 | 16 | unsigned i; |
287 | 16 | GByteArray *bytes; |
288 | | |
289 | 16 | for (i = 0; i < num_ieee802154_keys; i++) |
290 | 0 | { |
291 | 0 | switch (ieee802154_keys[i].hash_type) { |
292 | 0 | case KEY_HASH_NONE: |
293 | 0 | case KEY_HASH_ZIP: |
294 | | /* Get the IEEE 802.15.4 decryption key. */ |
295 | 0 | bytes = g_byte_array_new(); |
296 | 0 | if (hex_str_to_bytes(ieee802154_keys[i].pref_key, bytes, false)) |
297 | 0 | { |
298 | 0 | if (ieee802154_keys[i].hash_type == KEY_HASH_ZIP) { |
299 | 0 | char digest[32]; |
300 | |
|
301 | 0 | if (!ws_hmac_buffer(GCRY_MD_SHA256, digest, "ZigBeeIP", 8, bytes->data, IEEE802154_CIPHER_SIZE)) { |
302 | | /* Copy upper hashed bytes to the key */ |
303 | 0 | memcpy(ieee802154_keys[i].key, &digest[IEEE802154_CIPHER_SIZE], IEEE802154_CIPHER_SIZE); |
304 | | /* Copy lower hashed bytes to the MLE key */ |
305 | 0 | memcpy(ieee802154_keys[i].mle_key, digest, IEEE802154_CIPHER_SIZE); |
306 | 0 | } else { |
307 | | /* Just copy the keys verbatim */ |
308 | 0 | memcpy(ieee802154_keys[i].key, bytes->data, IEEE802154_CIPHER_SIZE); |
309 | 0 | memcpy(ieee802154_keys[i].mle_key, bytes->data, IEEE802154_CIPHER_SIZE); |
310 | 0 | } |
311 | 0 | } else { |
312 | | /* Just copy the keys verbatim */ |
313 | 0 | memcpy(ieee802154_keys[i].key, bytes->data, IEEE802154_CIPHER_SIZE); |
314 | 0 | memcpy(ieee802154_keys[i].mle_key, bytes->data, IEEE802154_CIPHER_SIZE); |
315 | 0 | } |
316 | 0 | } |
317 | 0 | g_byte_array_free(bytes, true); |
318 | 0 | break; |
319 | 0 | case KEY_HASH_THREAD: |
320 | | /* XXX - TODO? */ |
321 | 0 | break; |
322 | 0 | } |
323 | 0 | } |
324 | 16 | } |
325 | | |
326 | | static bool ieee802154_key_update_cb(void *r, char **err) |
327 | 0 | { |
328 | 0 | ieee802154_key_t* rec = (ieee802154_key_t*)r; |
329 | 0 | GByteArray *bytes; |
330 | |
|
331 | 0 | switch (rec->hash_type) { |
332 | 0 | case KEY_HASH_NONE: |
333 | 0 | case KEY_HASH_ZIP: |
334 | 0 | bytes = g_byte_array_new(); |
335 | 0 | if (hex_str_to_bytes(rec->pref_key, bytes, false) == false) |
336 | 0 | { |
337 | 0 | *err = g_strdup("Invalid key"); |
338 | 0 | g_byte_array_free(bytes, true); |
339 | 0 | return false; |
340 | 0 | } |
341 | | |
342 | 0 | if (bytes->len < IEEE802154_CIPHER_SIZE) |
343 | 0 | { |
344 | 0 | *err = ws_strdup_printf("Key must be at least %d bytes", IEEE802154_CIPHER_SIZE); |
345 | 0 | g_byte_array_free(bytes, true); |
346 | 0 | return false; |
347 | 0 | } |
348 | 0 | g_byte_array_free(bytes, true); |
349 | 0 | break; |
350 | 0 | case KEY_HASH_THREAD: |
351 | | /* XXX - TODO? */ |
352 | 0 | break; |
353 | 0 | } |
354 | | |
355 | 0 | return true; |
356 | 0 | } |
357 | | |
358 | 0 | static void* ieee802154_key_copy_cb(void* n, const void* o, size_t siz _U_) { |
359 | 0 | ieee802154_key_t* new_record = (ieee802154_key_t*)n; |
360 | 0 | const ieee802154_key_t* old_record = (const ieee802154_key_t*)o; |
361 | |
|
362 | 0 | new_record->pref_key = g_strdup(old_record->pref_key); |
363 | 0 | new_record->key_index = old_record->key_index; |
364 | 0 | new_record->hash_type = old_record->hash_type; |
365 | |
|
366 | 0 | return new_record; |
367 | 0 | } |
368 | | |
369 | 0 | static void ieee802154_key_free_cb(void*r) { |
370 | 0 | ieee802154_key_t* rec = (ieee802154_key_t *)r; |
371 | |
|
372 | 0 | g_free(rec->pref_key); |
373 | 0 | } |
374 | | |
375 | | /* Field callbacks. */ |
376 | 0 | UAT_CSTRING_CB_DEF(key_uat, pref_key, ieee802154_key_t) |
377 | 0 | UAT_DEC_CB_DEF(key_uat, key_index, ieee802154_key_t) Unexecuted instantiation: packet-ieee802154.c:key_uat_key_index_set_cb Unexecuted instantiation: packet-ieee802154.c:key_uat_key_index_tostr_cb |
378 | 0 | UAT_VS_DEF(key_uat, hash_type, ieee802154_key_t, ieee802154_key_hash, KEY_HASH_NONE, "No hash") Unexecuted instantiation: packet-ieee802154.c:key_uat_hash_type_set_cb Unexecuted instantiation: packet-ieee802154.c:key_uat_hash_type_tostr_cb |
379 | | |
380 | | |
381 | | /*------------------------------------- |
382 | | * Dissector Function Prototypes |
383 | | *------------------------------------- |
384 | | */ |
385 | | |
386 | | /* Dissection Routines. */ |
387 | | static int dissect_ieee802154_nonask_phy (tvbuff_t *, packet_info *, proto_tree *, void *); |
388 | | static int dissect_ieee802154 (tvbuff_t *, packet_info *, proto_tree *, void *); |
389 | | static int dissect_ieee802154_nofcs (tvbuff_t *, packet_info *, proto_tree *, void *); |
390 | | static int dissect_ieee802154_cc24xx (tvbuff_t *, packet_info *, proto_tree *, void *); |
391 | | static int dissect_ieee802154_tap (tvbuff_t *, packet_info *, proto_tree *, void *); |
392 | | static tvbuff_t *dissect_zboss_specific (tvbuff_t *, packet_info *, proto_tree *); |
393 | | static void dissect_ieee802154_common (tvbuff_t *, packet_info *, proto_tree *, unsigned, unsigned); |
394 | | static void ieee802154_dissect_fcs(tvbuff_t *tvb, proto_tree *ieee802154_tree, unsigned fcs_len, bool fcs_ok); |
395 | | static void ieee802154_dissect_cc24xx_metadata(tvbuff_t *tvb, proto_tree *ieee802154_tree, bool fcs_ok); |
396 | | static ieee802154_fcs_type_t dissect_ieee802154_tap_tlvs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); |
397 | | |
398 | | /* Information Elements */ |
399 | | static int dissect_ieee802154_header_ie (tvbuff_t *, packet_info *, proto_tree *, unsigned, ieee802154_packet *); |
400 | | static int dissect_ieee802154_payload_ie (tvbuff_t *, packet_info *, proto_tree *, unsigned, ieee802154_packet *); |
401 | | static int dissect_802154_eb_filter (tvbuff_t *, packet_info *, proto_tree *, void *); |
402 | | static int dissect_802154_tsch_time_sync (tvbuff_t *, packet_info *, proto_tree *, void *); |
403 | | static int dissect_802154_tsch_timeslot (tvbuff_t *, packet_info *, proto_tree *, void *); |
404 | | static int dissect_802154_tsch_slotframe_link (tvbuff_t *, packet_info *, proto_tree *, void *); |
405 | | static int dissect_802154_channel_hopping (tvbuff_t *, packet_info *, proto_tree *, void *); |
406 | | /* Sub-dissector helpers. */ |
407 | | static void dissect_ieee802154_fcf (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *, unsigned *); |
408 | | static void dissect_ieee802154_command (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *); |
409 | | static void dissect_ieee802154_assoc_req (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *); |
410 | | static void dissect_ieee802154_assoc_rsp (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *); |
411 | | static void dissect_ieee802154_disassoc (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *); |
412 | | static void dissect_ieee802154_realign (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *); |
413 | | static void dissect_ieee802154_gtsreq (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *); |
414 | | |
415 | | /* Decryption helpers. */ |
416 | | static tvbuff_t *dissect_ieee802154_decrypt(tvbuff_t *, unsigned, packet_info *, ieee802154_packet *, ieee802154_decrypt_info_t*, unsigned char *); |
417 | | |
418 | | static unsigned ieee802154_set_mac_key(ieee802154_packet *packet, unsigned char *key, unsigned char *alt_key, ieee802154_key_t *uat_key); |
419 | | static unsigned ieee802154_set_trel_key(ieee802154_packet* packet, unsigned char* key, unsigned char* alt_key, ieee802154_key_t* uat_key); |
420 | | static void tsch_ccm_init_nonce(uint64_t addr, uint64_t asn, uint8_t* generic_nonce); |
421 | | |
422 | | /* Initialize Protocol and Registered fields */ |
423 | | static int proto_ieee802154_nonask_phy; |
424 | | static int hf_ieee802154_nonask_phy_preamble; |
425 | | static int hf_ieee802154_nonask_phy_sfd; |
426 | | static int hf_ieee802154_nonask_phy_length; |
427 | | static int hf_ieee802154_nonask_phr; |
428 | | |
429 | | static int proto_ieee802154; |
430 | | static int proto_ieee802154_tap; |
431 | | static int hf_ieee802154_frame_length; |
432 | | static int hf_ieee802154_fcf; |
433 | | static int hf_ieee802154_frame_type; |
434 | | static int hf_ieee802154_security; |
435 | | static int hf_ieee802154_pending; |
436 | | static int hf_ieee802154_ack_request; |
437 | | static int hf_ieee802154_pan_id_compression; |
438 | | static int hf_ieee802154_fcf_reserved; |
439 | | static int hf_ieee802154_seqno_suppression; |
440 | | static int hf_ieee802154_ie_present; |
441 | | static int hf_ieee802154_src_addr_mode; |
442 | | static int hf_ieee802154_version; |
443 | | static int hf_ieee802154_dst_addr_mode; |
444 | | |
445 | | static int hf_ieee802154_mpf_long_frame_control; |
446 | | static int hf_ieee802154_mpf_dst_addr_mode; |
447 | | static int hf_ieee802154_mpf_src_addr_mode; |
448 | | static int hf_ieee802154_mpf_pan_id_present; |
449 | | static int hf_ieee802154_mpf_security; |
450 | | static int hf_ieee802154_mpf_seqno_suppression; |
451 | | static int hf_ieee802154_mpf_pending; |
452 | | static int hf_ieee802154_mpf_version; |
453 | | static int hf_ieee802154_mpf_ack_request; |
454 | | static int hf_ieee802154_mpf_ie_present; |
455 | | |
456 | | static int hf_ieee802154_header_ies; |
457 | | static int hf_ieee802154_header_ie_tlv; |
458 | | static int hf_ieee802154_header_ie_type; |
459 | | static int hf_ieee802154_header_ie_id; |
460 | | static int hf_ieee802154_header_ie_length; |
461 | | static int hf_ieee802154_ie_unknown_content; |
462 | | static int hf_ieee802154_ie_unknown_content_payload; |
463 | | static int hf_ieee802154_hie_unsupported; |
464 | | static int hf_ieee802154_hie_time_correction; |
465 | | static int hf_ieee802154_hie_ht1; |
466 | | static int hf_ieee802154_hie_ht2; |
467 | | static int hf_ieee802154_hie_thread; |
468 | | static int hf_ieee802154_nack; |
469 | | static int hf_ieee802154_hie_time_correction_time_sync_info; |
470 | | static int hf_ieee802154_hie_time_correction_value; |
471 | | static int hf_ieee802154_hie_csl; |
472 | | static int hf_ieee802154_hie_csl_phase; |
473 | | static int hf_ieee802154_hie_csl_period; |
474 | | static int hf_ieee802154_hie_csl_rendezvous_time; |
475 | | static int hf_ieee802154_hie_rdv; |
476 | | static int hf_ieee802154_hie_rdv_wakeup_interval; |
477 | | static int hf_ieee802154_hie_global_time; |
478 | | static int hf_ieee802154_hie_global_time_value; |
479 | | static int hf_ieee802154_hie_vendor_specific; |
480 | | static int hf_ieee802154_hie_vendor_specific_vendor_oui; |
481 | | static int hf_ieee802154_hie_vendor_specific_content; |
482 | | static int hf_ieee802154_payload_ies; |
483 | | static int hf_ieee802154_payload_ie_tlv; |
484 | | static int hf_ieee802154_payload_ie_type; |
485 | | static int hf_ieee802154_payload_ie_id; |
486 | | static int hf_ieee802154_payload_ie_length; |
487 | | static int hf_ieee802154_pie_unsupported; |
488 | | static int hf_ieee802154_pie_termination; |
489 | | static int hf_ieee802154_pie_vendor; |
490 | | static int hf_ieee802154_pie_vendor_oui; |
491 | | static int hf_ieee802154_pie_vendor_variable; |
492 | | static int hf_ieee802154_pie_ietf; |
493 | | static int hf_ieee802154_mlme; |
494 | | static int hf_ieee802154_mlme_ie_data; |
495 | | static int hf_ieee802154_mlme_ie_unsupported; |
496 | | static int hf_ieee802154_psie; |
497 | | static int hf_ieee802154_psie_type; |
498 | | static int hf_ieee802154_psie_id_short; |
499 | | static int hf_ieee802154_psie_length_short; |
500 | | static int hf_ieee802154_psie_id_long; |
501 | | static int hf_ieee802154_psie_length_long; |
502 | | |
503 | | static int hf_ieee802154_tsch_sync; |
504 | | static int hf_ieee802154_tsch_asn; |
505 | | static int hf_ieee802154_tsch_join_metric; |
506 | | static int hf_ieee802154_tsch_slotframe; |
507 | | static int hf_ieee802154_tsch_link_info; |
508 | | static int hf_ieee802154_tsch_slotf_link_nb_slotf; |
509 | | static int hf_ieee802154_tsch_slotf_link_slotf_handle; |
510 | | static int hf_ieee802154_tsch_slotf_size; |
511 | | static int hf_ieee802154_tsch_slotf_link_nb_links; |
512 | | static int hf_ieee802154_tsch_slotf_link_timeslot; |
513 | | static int hf_ieee802154_tsch_slotf_link_channel_offset; |
514 | | static int hf_ieee802154_tsch_slotf_link_options; |
515 | | static int hf_ieee802154_tsch_slotf_link_options_tx; |
516 | | static int hf_ieee802154_tsch_slotf_link_options_rx; |
517 | | static int hf_ieee802154_tsch_slotf_link_options_shared; |
518 | | static int hf_ieee802154_tsch_slotf_link_options_timkeeping; |
519 | | static int hf_ieee802154_tsch_slotf_link_options_priority; |
520 | | static int hf_ieee802154_tsch_channel_hopping; |
521 | | static int hf_ieee802154_tsch_hopping_sequence_id; |
522 | | static int hf_ieee802154_tsch_timeslot; |
523 | | static int hf_ieee802154_tsch_timeslot_id; |
524 | | static int hf_ieee802154_tsch_timeslot_cca_offset; |
525 | | static int hf_ieee802154_tsch_timeslot_cca; |
526 | | static int hf_ieee802154_tsch_timeslot_tx_offset; |
527 | | static int hf_ieee802154_tsch_timeslot_rx_offset; |
528 | | static int hf_ieee802154_tsch_timeslot_rx_ack_delay; |
529 | | static int hf_ieee802154_tsch_timeslot_tx_ack_delay; |
530 | | static int hf_ieee802154_tsch_timeslot_rx_wait; |
531 | | static int hf_ieee802154_tsch_timeslot_ack_wait; |
532 | | static int hf_ieee802154_tsch_timeslot_turnaround; |
533 | | static int hf_ieee802154_tsch_timeslot_max_ack; |
534 | | static int hf_ieee802154_tsch_timeslot_max_tx; |
535 | | static int hf_ieee802154_tsch_timeslot_length; |
536 | | |
537 | | static int hf_ieee802154_psie_eb_filter; |
538 | | static int hf_ieee802154_psie_eb_filter_pjoin; |
539 | | static int hf_ieee802154_psie_eb_filter_lqi; |
540 | | static int hf_ieee802154_psie_eb_filter_lqi_min; |
541 | | static int hf_ieee802154_psie_eb_filter_percent; |
542 | | static int hf_ieee802154_psie_eb_filter_percent_prob; |
543 | | static int hf_ieee802154_psie_eb_filter_attr_id; |
544 | | static int hf_ieee802154_psie_eb_filter_attr_id_bitmap; |
545 | | static int hf_ieee802154_p_ie_ietf_sub_id; |
546 | | |
547 | | static int hf_ieee802154_6top; |
548 | | static int hf_ieee802154_6top_version; |
549 | | static int hf_ieee802154_6top_type; |
550 | | static int hf_ieee802154_6top_flags_reserved; |
551 | | static int hf_ieee802154_6top_code; |
552 | | static int hf_ieee802154_6top_sfid; |
553 | | static int hf_ieee802154_6top_seqnum; |
554 | | static int hf_ieee802154_6top_metadata; |
555 | | static int hf_ieee802154_6top_cell_options; |
556 | | static int hf_ieee802154_6top_cell_option_tx; |
557 | | static int hf_ieee802154_6top_cell_option_rx; |
558 | | static int hf_ieee802154_6top_cell_option_shared; |
559 | | static int hf_ieee802154_6top_cell_option_reserved; |
560 | | static int hf_ieee802154_6top_num_cells; |
561 | | static int hf_ieee802154_6top_cell_list; |
562 | | static int hf_ieee802154_6top_rel_cell_list; |
563 | | static int hf_ieee802154_6top_cand_cell_list; |
564 | | static int hf_ieee802154_6top_cell; |
565 | | static int hf_ieee802154_6top_reserved; |
566 | | static int hf_ieee802154_6top_offset; |
567 | | static int hf_ieee802154_6top_max_num_cells; |
568 | | static int hf_ieee802154_6top_slot_offset; |
569 | | static int hf_ieee802154_6top_channel_offset; |
570 | | static int hf_ieee802154_6top_total_num_cells; |
571 | | static int hf_ieee802154_6top_payload; |
572 | | |
573 | | static int hf_ieee802159_mpx; |
574 | | static int hf_ieee802159_mpx_transaction_control; |
575 | | static int hf_ieee802159_mpx_transfer_type; |
576 | | static int hf_ieee802159_mpx_transaction_id; |
577 | | static int hf_ieee802159_mpx_transaction_id_as_multiplex_id; |
578 | | static int hf_ieee802159_mpx_fragment_number; |
579 | | static int hf_ieee802159_mpx_total_frame_size; |
580 | | static int hf_ieee802159_mpx_multiplex_id; |
581 | | static int hf_ieee802159_mpx_kmp_id; |
582 | | static int hf_ieee802159_mpx_kmp_vendor_oui; |
583 | | static int hf_ieee802159_mpx_fragment; |
584 | | static int hf_ieee802159_mpx_wisun_subid; |
585 | | |
586 | | static int proto_zboss; |
587 | | static int hf_zboss_direction; |
588 | | static int hf_zboss_page; |
589 | | static int hf_zboss_channel; |
590 | | static int hf_zboss_trace_number; |
591 | | |
592 | | static int hf_ieee802154_seqno; |
593 | | static int hf_ieee802154_dst_panID; |
594 | | static int hf_ieee802154_dst16; |
595 | | static int hf_ieee802154_dst64; |
596 | | static int hf_ieee802154_src_panID; |
597 | | static int hf_ieee802154_src16; |
598 | | static int hf_ieee802154_src64; |
599 | | static int hf_ieee802154_src64_origin; |
600 | | static int hf_ieee802154_addr16; |
601 | | static int hf_ieee802154_addr64; |
602 | | static int hf_ieee802154_fcs; |
603 | | static int hf_ieee802154_fcs32; |
604 | | static int hf_ieee802154_rssi; |
605 | | static int hf_ieee802154_fcs_ok; |
606 | | static int hf_ieee802154_correlation; |
607 | | |
608 | | /* Registered fields for Command Packets */ |
609 | | static int hf_ieee802154_cmd_id; |
610 | | static int hf_ieee802154_cinfo_alt_coord; |
611 | | static int hf_ieee802154_cinfo_device_type; |
612 | | static int hf_ieee802154_cinfo_power_src; |
613 | | static int hf_ieee802154_cinfo_idle_rx; |
614 | | static int hf_ieee802154_cinfo_sec_capable; |
615 | | static int hf_ieee802154_cinfo_alloc_addr; |
616 | | static int hf_ieee802154_assoc_addr; |
617 | | static int hf_ieee802154_assoc_status; |
618 | | static int hf_ieee802154_disassoc_reason; |
619 | | static int hf_ieee802154_realign_pan; |
620 | | static int hf_ieee802154_realign_caddr; |
621 | | static int hf_ieee802154_realign_channel; |
622 | | static int hf_ieee802154_realign_addr; |
623 | | static int hf_ieee802154_realign_channel_page; |
624 | | static int hf_ieee802154_gtsreq_len; |
625 | | static int hf_ieee802154_gtsreq_dir; |
626 | | static int hf_ieee802154_gtsreq_type; |
627 | | static int hf_ieee802154_cmd_vendor_oui; |
628 | | |
629 | | /* Registered fields for Beacon Packets */ |
630 | | static int hf_ieee802154_beacon_order; |
631 | | static int hf_ieee802154_superframe_order; |
632 | | static int hf_ieee802154_cap; |
633 | | static int hf_ieee802154_superframe_battery_ext; |
634 | | static int hf_ieee802154_superframe_coord; |
635 | | static int hf_ieee802154_assoc_permit; |
636 | | static int hf_ieee802154_gts_count; |
637 | | static int hf_ieee802154_gts_permit; |
638 | | static int hf_ieee802154_gts_direction; |
639 | | static int hf_ieee802154_gts_address; |
640 | | static int hf_ieee802154_pending16; |
641 | | static int hf_ieee802154_pending64; |
642 | | |
643 | | /* Registered fields for Auxiliary Security Header */ |
644 | | static int hf_ieee802154_aux_security_header; |
645 | | static int hf_ieee802154_aux_sec_security_control; |
646 | | static int hf_ieee802154_aux_sec_security_level; |
647 | | static int hf_ieee802154_aux_sec_key_id_mode; |
648 | | static int hf_ieee802154_aux_sec_frame_counter_suppression; |
649 | | static int hf_ieee802154_aux_sec_asn_in_nonce; |
650 | | static int hf_ieee802154_aux_sec_reserved; |
651 | | static int hf_ieee802154_aux_sec_frame_counter; |
652 | | static int hf_ieee802154_aux_sec_key_source; |
653 | | static int hf_ieee802154_aux_sec_key_source_bytes; |
654 | | static int hf_ieee802154_aux_sec_key_index; |
655 | | static int hf_ieee802154_mic; |
656 | | static int hf_ieee802154_key_number; |
657 | | |
658 | | /* 802.15.4-2003 security */ |
659 | | static int hf_ieee802154_sec_frame_counter; |
660 | | static int hf_ieee802154_sec_key_sequence_counter; |
661 | | |
662 | | /* 802.15.4 ack */ |
663 | | static int hf_ieee802154_no_ack; |
664 | | static int hf_ieee802154_no_ack_request; |
665 | | static int hf_ieee802154_ack_in; |
666 | | static int hf_ieee802154_ack_to; |
667 | | static int hf_ieee802154_ack_time; |
668 | | |
669 | | /* 802.15.4 TAP */ |
670 | | static int hf_ieee802154_tap_version; |
671 | | static int hf_ieee802154_tap_reserved; |
672 | | static int hf_ieee802154_tap_length; |
673 | | static int hf_ieee802154_tap_data_length; |
674 | | static int hf_ieee802154_tap_tlv_type; |
675 | | static int hf_ieee802154_tap_tlv_length; |
676 | | static int hf_ieee802154_tap_tlv_unknown; |
677 | | static int hf_ieee802154_tap_tlv_padding; |
678 | | static int hf_ieee802154_tap_fcs_type; |
679 | | static int hf_ieee802154_tap_rss; |
680 | | static int hf_ieee802154_ch_page; |
681 | | static int hf_ieee802154_ch_num; |
682 | | static int hf_ieee802154_bit_rate; |
683 | | static int hf_ieee802154_sun_band; |
684 | | static int hf_ieee802154_sun_type; |
685 | | static int hf_ieee802154_sun_mode; |
686 | | static int hf_ieee802154_mode_fsk_a; |
687 | | static int hf_ieee802154_mode_fsk_b; |
688 | | static int hf_ieee802154_mode_oqpsk_a; |
689 | | static int hf_ieee802154_mode_oqpsk_b; |
690 | | static int hf_ieee802154_mode_oqpsk_c; |
691 | | static int hf_ieee802154_mode_ofdm; |
692 | | static int hf_ieee802154_sof_ts; |
693 | | static int hf_ieee802154_eof_ts; |
694 | | static int hf_ieee802154_slot_start_ts; |
695 | | static int hf_ieee802154_tap_timeslot_length; |
696 | | static int hf_ieee802154_tap_lqi; |
697 | | static int hf_ieee802154_chplan_start; |
698 | | static int hf_ieee802154_chplan_spacing; |
699 | | static int hf_ieee802154_chplan_channels; |
700 | | static int hf_ieee802154_ch_freq; |
701 | | static int hf_ieee802154_frame_start_offset; |
702 | | static int hf_ieee802154_frame_duration; |
703 | | static int hf_ieee802154_frame_end_offset; |
704 | | static int hf_ieee802154_asn; |
705 | | |
706 | | static int hf_ieee802154_tap_phr_type; |
707 | | static int hf_ieee802154_tap_phr_bits; |
708 | | static int hf_ieee802154_tap_phr_data; |
709 | | |
710 | | static int hf_ieee802154_tap_phr_fsk; |
711 | | static int hf_ieee802154_tap_fsk_ms_phr; |
712 | | static int hf_ieee802154_tap_wisun_ms_phr; |
713 | | |
714 | | static int hf_ieee802154_tap_phr_fsk_ms; |
715 | | static int hf_ieee802154_tap_phr_fsk_fcs; |
716 | | static int hf_ieee802154_tap_phr_fsk_dw; |
717 | | static int hf_ieee802154_tap_phr_fsk_length; |
718 | | |
719 | | static int hf_ieee802154_tap_phr_fsk_ms_param; |
720 | | static int hf_ieee802154_tap_phr_fsk_ms_fec; |
721 | | static int hf_ieee802154_tap_phr_fsk_ms_checksum; |
722 | | static int hf_ieee802154_tap_phr_fsk_ms_parity; |
723 | | |
724 | | static int hf_ieee802154_tap_phr_fsk_ms_mode_page; |
725 | | static int hf_ieee802154_tap_phr_fsk_ms_mode_scheme; |
726 | | static int hf_ieee802154_tap_phr_fsk_ms_mode_mode; |
727 | | static int hf_ieee802154_tap_phr_fsk_ms_mode_addl_mode; |
728 | | static int hf_ieee802154_tap_phr_wisun_fsk_ms_reserved; |
729 | | static int hf_ieee802154_tap_phr_wisun_fsk_ms_phymodeid; |
730 | | |
731 | | /* Bit-masks for SUN FSK PHR per IEEE 802.15.4-2020 19.2.4 */ |
732 | 16 | #define IEEE802154_TAP_PHR_FSK_MS 0x8000 |
733 | 16 | #define IEEE802154_TAP_PHR_FSK_FCS 0x0100 |
734 | 16 | #define IEEE802154_TAP_PHR_FSK_DW 0x0080 |
735 | 16 | #define IEEE802154_TAP_PHR_FSK_LENGTH 0x07ff |
736 | | |
737 | | /* Bit-masks for SUN FSK Mode Switch PHR per IEEE 802.15.4-2020 19.2.5 */ |
738 | 16 | #define IEEE802154_TAP_PHR_FSK_MS_PARAM 0x6000 |
739 | 16 | #define IEEE802154_TAP_PHR_FSK_MS_FEC 0x1000 |
740 | | #define IEEE802154_TAP_PHR_FSK_MS_MODE 0x0FE0 |
741 | 16 | #define IEEE802154_TAP_PHR_FSK_MS_MODE_PAGE 0x0800 |
742 | 16 | #define IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME 0x0600 |
743 | 32 | #define IEEE802154_TAP_PHR_FSK_MS_MODE_MODE 0x01E0 |
744 | 16 | #define IEEE802154_TAP_PHR_FSK_MS_CHECKSUM 0x001E |
745 | 16 | #define IEEE802154_TAP_PHR_FSK_MS_PARITY 0x0001 |
746 | | |
747 | 0 | #define IEEE802154_TAP_PHR_FSK_MS_SCHEME_FSK 0x0000 |
748 | 0 | #define IEEE802154_TAP_PHR_FSK_MS_SCHEME_OFDM 0x0200 |
749 | 0 | #define IEEE802154_TAP_PHR_FSK_MS_SCHEME_OQPSK 0x0400 |
750 | | #define IEEE802154_TAP_PHR_FSK_MS_SCHEME_ADDL 0x0600 |
751 | | |
752 | | /* Bit-masks for Wi-SUN FSK Mode Switch PHR */ |
753 | 16 | #define IEEE802154_TAP_PHR_WISUN_FSK_MS_RESERVED 0x6000 |
754 | 16 | #define IEEE802154_TAP_PHR_WISUN_FSK_MS_PHYMODEID 0x1FE0 |
755 | | |
756 | | typedef struct _ieee802154_transaction_t { |
757 | | uint64_t dst64; |
758 | | uint64_t src64; |
759 | | int32_t dst_addr_mode; |
760 | | int32_t src_addr_mode; |
761 | | uint16_t dst16; |
762 | | uint16_t src16; |
763 | | uint32_t rqst_frame; |
764 | | uint32_t ack_frame; |
765 | | nstime_t rqst_time; |
766 | | nstime_t ack_time; |
767 | | bool dst_pan_present; |
768 | | bool src_pan_present; |
769 | | uint16_t dst_pan; |
770 | | uint16_t src_pan; |
771 | | } ieee802154_transaction_t; |
772 | | |
773 | | static const nstime_t ieee802154_transaction_timeout = NSTIME_INIT_SECS_MSECS(1, 0); // ACKs usually arrive within milliseconds |
774 | | |
775 | | static wmem_tree_t *transaction_unmatched_pdus; |
776 | | static wmem_tree_t *transaction_matched_pdus; |
777 | | |
778 | | static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key); |
779 | | static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key); |
780 | | |
781 | | /* Initialize Subtree Pointers */ |
782 | | static int ett_ieee802154_nonask_phy; |
783 | | static int ett_ieee802154_nonask_phy_phr; |
784 | | static int ett_ieee802154_tap; |
785 | | static int ett_ieee802154_tap_header; |
786 | | static int ett_ieee802154_tap_tlv; |
787 | | static int ett_ieee802154; |
788 | | static int ett_ieee802154_fcf; |
789 | | static int ett_ieee802154_auxiliary_security; |
790 | | static int ett_ieee802154_aux_sec_control; |
791 | | static int ett_ieee802154_aux_sec_key_id; |
792 | | static int ett_ieee802154_fcs; |
793 | | static int ett_ieee802154_cmd; |
794 | | static int ett_ieee802154_superframe; |
795 | | static int ett_ieee802154_gts; |
796 | | static int ett_ieee802154_gts_direction; |
797 | | static int ett_ieee802154_gts_descriptors; |
798 | | static int ett_ieee802154_pendaddr; |
799 | | static int ett_ieee802154_header_ies; |
800 | | static int ett_ieee802154_header_ie; |
801 | | static int ett_ieee802154_header_ie_tlv; |
802 | | static int ett_ieee802154_hie_unsupported; |
803 | | static int ett_ieee802154_hie_time_correction; |
804 | | static int ett_ieee802154_hie_ht; |
805 | | static int ett_ieee802154_hie_thread; |
806 | | static int ett_ieee802154_hie_csl; |
807 | | static int ett_ieee802154_hie_rdv; |
808 | | static int ett_ieee802154_hie_global_time; |
809 | | static int ett_ieee802154_hie_vendor_specific; |
810 | | static int ett_ieee802154_payload_ie; |
811 | | static int ett_ieee802154_payload_ie_tlv; |
812 | | static int ett_ieee802154_pie_termination; |
813 | | static int ett_ieee802154_pie_vendor; |
814 | | static int ett_ieee802154_pie_ietf; |
815 | | static int ett_ieee802154_pie_unsupported; |
816 | | static int ett_ieee802154_mlme; |
817 | | static int ett_ieee802154_mlme_payload; |
818 | | static int ett_ieee802154_mlme_payload_data; |
819 | | static int ett_ieee802154_mlme_unsupported; |
820 | | static int ett_ieee802154_tsch_slotframe; |
821 | | static int ett_ieee802154_tsch_slotframe_list; |
822 | | static int ett_ieee802154_tsch_slotframe_link; |
823 | | static int ett_ieee802154_tsch_slotframe_link_options; |
824 | | static int ett_ieee802154_tsch_timeslot; |
825 | | static int ett_ieee802154_tsch_synch; |
826 | | static int ett_ieee802154_channel_hopping; |
827 | | static int ett_ieee802154_psie; |
828 | | static int ett_ieee802154_eb_filter; |
829 | | static int ett_ieee802154_eb_filter_bitmap; |
830 | | static int ett_ieee802154_zigbee; |
831 | | static int ett_ieee802154_zboss; |
832 | | static int ett_ieee802154_p_ie_6top; |
833 | | static int ett_ieee802154_p_ie_6top_cell_options; |
834 | | static int ett_ieee802154_p_ie_6top_cell_list; |
835 | | static int ett_ieee802154_p_ie_6top_cand_cell_list; |
836 | | static int ett_ieee802154_p_ie_6top_rel_cell_list; |
837 | | static int ett_ieee802154_p_ie_6top_cell; |
838 | | static int ett_ieee802159_mpx; |
839 | | static int ett_ieee802159_mpx_transaction_control; |
840 | | static int ett_ieee802154_tap_phr; |
841 | | |
842 | | static expert_field ei_ieee802154_fcs_bitmask_len; |
843 | | static expert_field ei_ieee802154_invalid_addressing; |
844 | | static expert_field ei_ieee802154_invalid_panid_compression; |
845 | | static expert_field ei_ieee802154_invalid_panid_compression2; |
846 | | static expert_field ei_ieee802154_fcs; |
847 | | static expert_field ei_ieee802154_decrypt_error; |
848 | | static expert_field ei_ieee802154_dst; |
849 | | static expert_field ei_ieee802154_src; |
850 | | static expert_field ei_ieee802154_frame_ver; |
851 | | /* static expert_field ei_ieee802154_frame_type; */ |
852 | | static expert_field ei_ieee802154_seqno_suppression; |
853 | | static expert_field ei_ieee802154_ack_not_found; |
854 | | static expert_field ei_ieee802154_ack_request_not_found; |
855 | | static expert_field ei_ieee802154_time_correction_error; |
856 | | static expert_field ei_ieee802154_6top_unsupported_type; |
857 | | static expert_field ei_ieee802154_6top_unsupported_return_code; |
858 | | static expert_field ei_ieee802154_6top_unsupported_command; |
859 | | static expert_field ei_ieee802154_ie_unsupported_id; |
860 | | static expert_field ei_ieee802154_ie_unknown_extra_content; |
861 | | static expert_field ei_ieee802154_ie_unknown_extra_content_payload; |
862 | | static expert_field ei_ieee802159_mpx_invalid_transfer_type; |
863 | | static expert_field ei_ieee802159_mpx_unsupported_kmp; |
864 | | static expert_field ei_ieee802159_mpx_unknown_kmp; |
865 | | static expert_field ei_ieee802154_missing_payload_ie; |
866 | | static expert_field ei_ieee802154_payload_ie_in_header; |
867 | | static expert_field ei_ieee802154_unsupported_cmd; |
868 | | static expert_field ei_ieee802154_unknown_cmd; |
869 | | static expert_field ei_ieee802154_tap_tlv_invalid_type; |
870 | | static expert_field ei_ieee802154_tap_tlv_invalid_length; |
871 | | static expert_field ei_ieee802154_tap_tlv_padding_not_zeros; |
872 | | static expert_field ei_ieee802154_tap_tlv_invalid_fcs_type; |
873 | | static expert_field ei_ieee802154_tap_tlv_reserved_not_zero; |
874 | | static expert_field ei_ieee802154_tap_no_payload; |
875 | | |
876 | | static int ieee802_15_4_short_address_type = -1; |
877 | | /* |
878 | | * Dissector handles |
879 | | * - beacon dissection is always heuristic. |
880 | | * - the PANID table is for stateful dissectors only (ie: Decode-As) |
881 | | * - otherwise, data dissectors fall back to the heuristic dissectors. |
882 | | */ |
883 | | static dissector_table_t panid_dissector_table; |
884 | | static heur_dissector_list_t ieee802154_beacon_subdissector_list; |
885 | | static heur_dissector_list_t ieee802154_heur_subdissector_list; |
886 | | |
887 | | /* For the IEs and the vendor specific command */ |
888 | | static dissector_table_t header_ie_dissector_table; |
889 | | static dissector_table_t payload_ie_dissector_table; |
890 | | static dissector_table_t mlme_ie_dissector_table; |
891 | | static dissector_table_t cmd_vendor_dissector_table; |
892 | | |
893 | | static dissector_handle_t zigbee_ie_handle; |
894 | | static dissector_handle_t zigbee_nwk_handle; |
895 | | static dissector_handle_t ieee802154_handle; |
896 | | static dissector_handle_t ieee802154_nonask_phy_handle; |
897 | | static dissector_handle_t ieee802154_fcs_handle; |
898 | | static dissector_handle_t ieee802154_nofcs_handle; |
899 | | static dissector_handle_t ieee802154_tap_handle; |
900 | | |
901 | | /* Thread 802.15.4 - 2015 */ |
902 | | static dissector_handle_t thread_ie_handle; |
903 | | |
904 | | static int ieee802154_tap; |
905 | | |
906 | | /* Handles for MPX-IE the Multiplex ID */ |
907 | | static dissector_table_t ethertype_table; |
908 | | static dissector_handle_t eapol_handle; |
909 | | static dissector_handle_t lowpan_handle; |
910 | | static dissector_handle_t wisun_sec_handle; |
911 | | |
912 | | /* Versions */ |
913 | | static const value_string ieee802154_frame_versions[] = { |
914 | | { IEEE802154_VERSION_2003, "IEEE Std 802.15.4-2003" }, |
915 | | { IEEE802154_VERSION_2006, "IEEE Std 802.15.4-2006" }, |
916 | | { IEEE802154_VERSION_2015, "IEEE Std 802.15.4-2015" }, |
917 | | { IEEE802154_VERSION_RESERVED, "Reserved" }, |
918 | | { 0, NULL } |
919 | | }; |
920 | | |
921 | | /* Name Strings */ |
922 | | static const value_string ieee802154_frame_types[] = { |
923 | | { IEEE802154_FCF_BEACON, "Beacon" }, |
924 | | { IEEE802154_FCF_DATA, "Data" }, |
925 | | { IEEE802154_FCF_ACK, "Ack" }, |
926 | | { IEEE802154_FCF_CMD, "Command" }, |
927 | | { IEEE802154_FCF_RESERVED, "Reserved" }, |
928 | | { IEEE802154_FCF_MULTIPURPOSE, "Multipurpose" }, |
929 | | { IEEE802154_FCF_FRAGMENT, "Fragment or Frak" }, |
930 | | { IEEE802154_FCF_EXTENDED, "Extended" }, |
931 | | { 0, NULL } |
932 | | }; |
933 | | |
934 | | static const value_string ieee802154_addr_modes[] = { |
935 | | { IEEE802154_FCF_ADDR_NONE, "None" }, |
936 | | { IEEE802154_FCF_ADDR_RESERVED, "Reserved" }, |
937 | | { IEEE802154_FCF_ADDR_SHORT, "Short/16-bit" }, |
938 | | { IEEE802154_FCF_ADDR_EXT, "Long/64-bit" }, |
939 | | { 0, NULL } |
940 | | }; |
941 | | |
942 | | static const value_string ieee802154_cmd_names[] = { |
943 | | { IEEE802154_CMD_ASSOC_REQ, "Association Request" }, |
944 | | { IEEE802154_CMD_ASSOC_RSP, "Association Response" }, |
945 | | { IEEE802154_CMD_DISASSOC_NOTIFY, "Disassociation Notification" }, |
946 | | { IEEE802154_CMD_DATA_RQ, "Data Request" }, |
947 | | { IEEE802154_CMD_PANID_CONFLICT, "PAN ID Conflict" }, |
948 | | { IEEE802154_CMD_ORPHAN_NOTIFY, "Orphan Notification" }, |
949 | | { IEEE802154_CMD_BEACON_REQ, "Beacon Request" }, |
950 | | { IEEE802154_CMD_COORD_REALIGN, "Coordinator Realignment" }, |
951 | | { IEEE802154_CMD_GTS_REQ, "GTS Request" }, |
952 | | { IEEE802154_CMD_TRLE_MGMT_REQ, "TRLE Management Request"}, |
953 | | { IEEE802154_CMD_TRLE_MGMT_RSP, "TRLE Management Response"}, |
954 | | { IEEE802154_CMD_DSME_ASSOC_REQ, "DSME Association Request"}, |
955 | | { IEEE802154_CMD_DSME_ASSOC_RSP, "DSME Association Response"}, |
956 | | { IEEE802154_CMD_DSME_GTS_REQ, "DSME GTS Request"}, |
957 | | { IEEE802154_CMD_DSME_GTS_RSP, "DSME GTS Response"}, |
958 | | { IEEE802154_CMD_DSME_GTS_NOTIFY, "DSME GTS Notify"}, |
959 | | { IEEE802154_CMD_DSME_INFO_REQ, "DSME Information Request"}, |
960 | | { IEEE802154_CMD_DSME_INFO_RSP, "DSME Information Response"}, |
961 | | { IEEE802154_CMD_DSME_BEACON_ALLOC_NOTIFY, "DSME Beacon Allocation Notification"}, |
962 | | { IEEE802154_CMD_DSME_BEACON_COLL_NOTIFY, "DSME Beacon Collision Notification"}, |
963 | | { IEEE802154_CMD_DSME_LINK_REPORT, "DSME Link Report"}, |
964 | | { IEEE802154_CMD_RIT_DATA_REQ, "RIT Data Request"}, |
965 | | { IEEE802154_CMD_DBS_REQ, "DBS Request"}, |
966 | | { IEEE802154_CMD_DBS_RSP, "DBS Response"}, |
967 | | { IEEE802154_CMD_RIT_DATA_RSP, "RIT Data Response"}, |
968 | | { IEEE802154_CMD_VENDOR_SPECIFIC, "Vendor Specific"}, |
969 | | { 0, NULL } |
970 | | }; |
971 | | |
972 | | const value_string ieee802154_sec_level_names[] = { |
973 | | { SECURITY_LEVEL_NONE, "No Security" }, |
974 | | { SECURITY_LEVEL_MIC_32, "32-bit Message Integrity Code" }, |
975 | | { SECURITY_LEVEL_MIC_64, "64-bit Message Integrity Code" }, |
976 | | { SECURITY_LEVEL_MIC_128, "128-bit Message Integrity Code" }, |
977 | | { SECURITY_LEVEL_ENC, "Encryption" }, |
978 | | { SECURITY_LEVEL_ENC_MIC_32, "Encryption with 32-bit Message Integrity Code" }, |
979 | | { SECURITY_LEVEL_ENC_MIC_64, "Encryption with 64-bit Message Integrity Code" }, |
980 | | { SECURITY_LEVEL_ENC_MIC_128, "Encryption with 128-bit Message Integrity Code" }, |
981 | | { 0, NULL } |
982 | | }; |
983 | | |
984 | | const value_string ieee802154_key_id_mode_names[] = { |
985 | | { KEY_ID_MODE_IMPLICIT, "Implicit Key" }, |
986 | | { KEY_ID_MODE_KEY_INDEX, "Indexed Key using the Default Key Source" }, |
987 | | { KEY_ID_MODE_KEY_EXPLICIT_4, "Explicit Key with 4-octet Key Source" }, |
988 | | { KEY_ID_MODE_KEY_EXPLICIT_8, "Explicit Key with 8-octet Key Source" }, |
989 | | { 0, NULL } |
990 | | }; |
991 | | |
992 | | static const true_false_string ieee802154_gts_direction_tfs = { |
993 | | "Receive Only", |
994 | | "Transmit Only" |
995 | | }; |
996 | | |
997 | | /* The 802.15.4-2003 security suites for the security preferences (only AES-CCM suites are supported). */ |
998 | | /* NOTE: The equivalent 2006 security level identifier enumerations are used to simplify 2003 & 2006 integration! */ |
999 | | static const enum_val_t ieee802154_2003_sec_suite_enums[] = { |
1000 | | { "AES-CCM-128", "AES-128 Encryption, 128-bit Integrity Protection", SECURITY_LEVEL_ENC_MIC_128 }, |
1001 | | { "AES-CCM-64", "AES-128 Encryption, 64-bit Integrity Protection", SECURITY_LEVEL_ENC_MIC_64 }, |
1002 | | { "AES-CCM-32", "AES-128 Encryption, 32-bit Integrity Protection", SECURITY_LEVEL_ENC_MIC_32 }, |
1003 | | { NULL, NULL, 0 } |
1004 | | }; |
1005 | | |
1006 | | /* Enumeration for key generation */ |
1007 | | static const value_string ieee802154_key_hash_vals[] = { |
1008 | | { KEY_HASH_NONE, "No hash"}, |
1009 | | { KEY_HASH_ZIP, "ZigBee IP hash" }, |
1010 | | { KEY_HASH_THREAD, "Thread hash" }, |
1011 | | { 0, NULL } |
1012 | | }; |
1013 | | |
1014 | | static const value_string ieee802154_ie_types[] = { |
1015 | | { 0, "Header" }, |
1016 | | { 1, "Payload" }, |
1017 | | { 0, NULL } |
1018 | | }; |
1019 | | |
1020 | | static const value_string ieee802154_psie_types[] = { |
1021 | | { 0, "Short" }, |
1022 | | { 1, "Long" }, |
1023 | | { 0, NULL } |
1024 | | }; |
1025 | | |
1026 | | static const value_string ieee802154_header_ie_names[] = { |
1027 | | { IEEE802154_HEADER_IE_VENDOR_SPECIFIC, "Vendor Specific IE" }, |
1028 | | { IEEE802154_HEADER_IE_CSL, "CSL IE" }, |
1029 | | { IEEE802154_HEADER_IE_RIT, "RIT IE" }, |
1030 | | { IEEE802154_HEADER_IE_DSME_PAN, "DSME PAN descriptor IE" }, |
1031 | | { IEEE802154_HEADER_IE_RENDEZVOUS, "Rendezvous Time IE" }, |
1032 | | { IEEE802154_HEADER_IE_TIME_CORR, "Time Correction IE" }, |
1033 | | { IEEE802154_HEADER_IE_EXT_DSME_PAN, "Extended DSME PAN descriptor IE" }, |
1034 | | { IEEE802154_HEADER_IE_FSCD, "Fragment Sequence Context Description (FSCD) IE" }, |
1035 | | { IEEE802154_HEADER_IE_SMPL_SUPER_FRM, "Simplified Superframe Specification IE" }, |
1036 | | { IEEE802154_HEADER_IE_SMPL_GTS, "Simplified GTS Specification IE" }, |
1037 | | { IEEE802154_HEADER_IE_LECIM, "LECIM Capabilities IE" }, |
1038 | | { IEEE802154_HEADER_IE_TRLE, "TRLE Descriptor" }, |
1039 | | { IEEE802154_HEADER_IE_RCC_CAP, "RCC Capabilities IE" }, |
1040 | | { IEEE802154_HEADER_IE_RCCN, "RCCN Descriptor IE" }, |
1041 | | { IEEE802154_HEADER_IE_GLOBAL_TIME, "Global Time IE" }, |
1042 | | { IEEE802154_HEADER_IE_WISUN, "Wi-SUN IE" }, |
1043 | | { IEEE802154_HEADER_IE_DA_IE, "DA IE" }, |
1044 | | { IEEE802154_HEADER_IE_HT1, "Header Termination 1 IE" }, |
1045 | | { IEEE802154_HEADER_IE_HT2, "Header Termination 2 IE" }, |
1046 | | { 0, NULL } |
1047 | | }; |
1048 | | |
1049 | | static const true_false_string hf_ieee802154_nack_tfs = { |
1050 | | "Negative Acknowledgement", |
1051 | | "Acknowledgement" |
1052 | | }; |
1053 | | |
1054 | | static const value_string ieee802154_payload_ie_names[] = { |
1055 | | { IEEE802154_PAYLOAD_IE_ESDU, "ESDU IE" }, |
1056 | | { IEEE802154_PAYLOAD_IE_MLME, "MLME IE" }, |
1057 | | { IEEE802154_PAYLOAD_IE_VENDOR, "Vendor Specific IE" }, |
1058 | | { IEEE802154_PAYLOAD_IE_MPX, "MPX IE" }, |
1059 | | { IEEE802154_PAYLOAD_IE_WISUN, "Wi-SUN IE" }, |
1060 | | { IEEE802154_PAYLOAD_IE_IETF, "IETF IE" }, |
1061 | | { IEEE802154_PAYLOAD_IE_TERMINATION, "Payload Termination IE" }, |
1062 | | { 0, NULL } |
1063 | | }; |
1064 | | |
1065 | | static const value_string ieee802154_psie_names[] = { |
1066 | | { IEEE802154_MLME_SUBIE_CHANNEL_HOPPING, "Channel Hopping IE" }, |
1067 | | { IEEE802154_MLME_SUBIE_TSCH_SYNCH, "TSCH Synchronization IE" }, |
1068 | | { IEEE802154_MLME_SUBIE_TSCH_SLOTFR_LINK, "TSCH Slotframe and Link IE" }, |
1069 | | { IEEE802154_MLME_SUBIE_TSCH_TIMESLOT, "TSCH Timeslot IE" }, |
1070 | | { IEEE802154_MLME_SUBIE_HOPPING_TIMING, "Hopping Timing IE" }, |
1071 | | { IEEE802154_MLME_SUBIE_ENHANCED_BEACON_FILTER, "Enhanced Beacon Filter IE" }, |
1072 | | { IEEE802154_MLME_SUBIE_MAC_METRICS, "MAC Metrics IE" }, |
1073 | | { IEEE802154_MLME_SUBIE_ALL_MAC_METRICS, "All MAC Metrics IE" }, |
1074 | | { IEEE802154_MLME_SUBIE_COEXISTENCE_SPEC, "Coexistence Specification IE" }, |
1075 | | { IEEE802154_MLME_SUBIE_SUN_DEVICE_CAPABILITIES, "SUN Device Capabilities IE" }, |
1076 | | { IEEE802154_MLME_SUBIE_SUN_FSK_GEN_PHY, "SUN FSK Generic PHY IE" }, |
1077 | | { IEEE802154_MLME_SUBIE_MODE_SWITCH_PARAMETER, "Mode Switch Parameter IE" }, |
1078 | | { IEEE802154_MLME_SUBIE_PHY_PARAMETER_CHANGE, "PHY Parameter Change IE" }, |
1079 | | { IEEE802154_MLME_SUBIE_O_QPSK_PHY_MODE, "O-QPSY PHY Mode IE" }, |
1080 | | { IEEE802154_MLME_SUBIE_PCA_ALLOCATION, "PCA Allocation IE" }, |
1081 | | { IEEE802154_MLME_SUBIE_DSSS_OPER_MODE, "LECIM DSSS Operating Mode IE"}, |
1082 | | { IEEE802154_MLME_SUBIE_FSK_OPER_MODE, "LECIM FSK Operating Mode IE" }, |
1083 | | { IEEE802154_MLME_SUBIE_TVWS_PHY_OPE_MODE, "TVWS PHY Operating Mode Description IE" }, |
1084 | | { IEEE802154_MLME_SUBIE_TVWS_DEVICE_CAPAB, "TVWS Device Capabilities IE" }, |
1085 | | { IEEE802154_MLME_SUBIE_TVWS_DEVICE_CATEG, "TVWS Device Category IE" }, |
1086 | | { IEEE802154_MLME_SUBIE_TVWS_DEVICE_IDENTIF, "TVWS Device Identification IE" }, |
1087 | | { IEEE802154_MLME_SUBIE_TVWS_DEVICE_LOCATION, "TVWS Device Location IE" }, |
1088 | | { IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_QUERY, "TVWS Channel Information Query IE" }, |
1089 | | { IEEE802154_MLME_SUBIE_TVWS_CH_INFOR_SOURCE, "TVWS Channel Information Source IE" }, |
1090 | | { IEEE802154_MLME_SUBIE_CTM, "CTM IE" }, |
1091 | | { IEEE802154_MLME_SUBIE_TIMESTAMP, "Timestamp IE" }, |
1092 | | { IEEE802154_MLME_SUBIE_TIMESTAMP_DIFF, "Timestamp Difference IE"}, |
1093 | | { IEEE802154_MLME_SUBIE_TMCP_SPECIFICATION, "TMCTP Specification IE" }, |
1094 | | { IEEE802154_MLME_SUBIE_RCC_PHY_OPER_MODE, "RCC PHY Operating Mode IE" }, |
1095 | | { IEEE802154_IETF_SUBIE_6TOP, "6top IE" }, |
1096 | | { IEEE802154_IETF_SUBIE_6TOP_DRAFT, "6top IE (draft)" }, |
1097 | | { 0, NULL } |
1098 | | }; |
1099 | | |
1100 | | const value_string zboss_page_names[] = { |
1101 | | { 0, "2.4 GHz" }, |
1102 | | { 28, "863-868 MHz band"}, |
1103 | | { 29, "868-870, 870-876 MHz band" }, |
1104 | | { 30, "870-876 MHz band" }, |
1105 | | { 31, "915-921 MHz band" }, |
1106 | | { 0, NULL } |
1107 | | }; |
1108 | | |
1109 | | static const value_string zboss_direction_names[] = { |
1110 | | { 0, "IN" }, |
1111 | | { 1, "OUT" }, |
1112 | | { 0, NULL } |
1113 | | }; |
1114 | | |
1115 | | static const value_string tap_tlv_types[] = { |
1116 | | { IEEE802154_TAP_FCS_TYPE, "FCS type"}, |
1117 | | { IEEE802154_TAP_RSS, "RSS"}, |
1118 | | { IEEE802154_TAP_BIT_RATE, "Bit rate"}, |
1119 | | { IEEE802154_TAP_CHANNEL_ASSIGNMENT, "Channel assignment"}, |
1120 | | { IEEE802154_TAP_SUN_PHY_INFO, "SUN PHY Information"}, |
1121 | | { IEEE802154_TAP_START_OF_FRAME_TS, "Start of frame timestamp"}, |
1122 | | { IEEE802154_TAP_END_OF_FRAME_TS, "End of frame timestamp"}, |
1123 | | { IEEE802154_TAP_ASN, "Absolute Slot Number (ASN)"}, |
1124 | | { IEEE802154_TAP_SLOT_START_TS, "Start of slot timestamp"}, |
1125 | | { IEEE802154_TAP_TIMESLOT_LENGTH, "Slot length"}, |
1126 | | { IEEE802154_TAP_LQI, "Link Quality Indicator"}, |
1127 | | { IEEE802154_TAP_CHANNEL_FREQUENCY, "Channel center frequency"}, |
1128 | | { IEEE802154_TAP_CHANNEL_PLAN, "Channel plan"}, |
1129 | | { IEEE802154_TAP_PHY_HEADER, "PHY Header"}, |
1130 | | { 0, NULL } |
1131 | | }; |
1132 | | |
1133 | | static const value_string tap_fcs_type_names[] = { |
1134 | | { IEEE802154_FCS_TYPE_NONE, "None" }, |
1135 | | { IEEE802154_FCS_TYPE_16_BIT, "ITU-T CRC16" }, |
1136 | | { IEEE802154_FCS_TYPE_32_BIT, "ITU-T CRC32" }, |
1137 | | { 0, NULL } |
1138 | | }; |
1139 | | |
1140 | | /* IEEE 802.15.4 Table 7-19 */ |
1141 | | static const value_string sun_bands[] = { |
1142 | | { 0, "169 MHz [169.400-169.475]" }, |
1143 | | { 1, "450 MHz [450-470]" }, |
1144 | | { 2, "470 MHz [470-510]" }, |
1145 | | { 3, "780 MHz [779-787]" }, |
1146 | | { 4, "863 MHz [863-870]" }, |
1147 | | { 5, "896 MHz [896-901]" }, |
1148 | | { 6, "901 MHz [901-902]" }, |
1149 | | { 7, "915 MHz [902-928]" }, |
1150 | | { 8, "917 MHz [917-923.5]" }, |
1151 | | { 9, "920 MHz [920-928]" }, |
1152 | | { 10, "928 MHz [928-960]" }, |
1153 | | { 11, "920 MHz [920-960]" }, |
1154 | | { 12, "1427 MHz [1427-1518]" }, |
1155 | | { 13, "2450 MHz [2400-2483.5]" }, |
1156 | | { 14, "866 MHz [865-867]" }, |
1157 | | { 15, "870 MHz [870-876]" }, |
1158 | | { 16, "915 MHz-a [902-928 alternate]" }, |
1159 | | { 17, "915 MHz-b [902-907.5 & 915-928]" }, |
1160 | | { 18, "915 MHz-c [915-928]" }, |
1161 | | { 19, "915 MHz-d [915-921]" }, |
1162 | | { 20, "915 MHz-e [915-918]" }, |
1163 | | { 21, "919 MHz [919-923]" }, |
1164 | | { 22, "920 MHz-a [920.5-924.5]" }, |
1165 | | { 23, "920 MHz-b [920-925]" }, |
1166 | | { 24, "867 MHz [866-869]" }, |
1167 | | /* Exegin defined numbers for bands in Table 10-1 but not in Table 7-19 */ |
1168 | | { 32, "433 MHz [433.05-434.79]" }, |
1169 | | { 33, "868 MHz [868-868.6]" }, |
1170 | | { 34, "2380 MHz [2360-2400]" }, |
1171 | | { 0, NULL } |
1172 | | }; |
1173 | | |
1174 | | /* IEEE 802.15.4 Table 7-20 */ |
1175 | | static const value_string sun_types[] = { |
1176 | | { IEEE802154_SUN_TYPE_FSK_A, "FSK-A" }, |
1177 | | { IEEE802154_SUN_TYPE_FSK_B, "FSK-B" }, |
1178 | | { IEEE802154_SUN_TYPE_OQPSK_A, "O-QPSK-A" }, |
1179 | | { IEEE802154_SUN_TYPE_OQPSK_B, "O-QPSK-B" }, |
1180 | | { IEEE802154_SUN_TYPE_OQPSK_C, "O-QPSK-C" }, |
1181 | | { IEEE802154_SUN_TYPE_OFDM_OPT1, "OFDM Option 1" }, |
1182 | | { IEEE802154_SUN_TYPE_OFDM_OPT2, "OFDM Option 2" }, |
1183 | | { IEEE802154_SUN_TYPE_OFDM_OPT3, "OFDM Option 3" }, |
1184 | | { IEEE802154_SUN_TYPE_OFDM_OPT4, "OFDM Option 4" }, |
1185 | | { 0, NULL } |
1186 | | }; |
1187 | | |
1188 | | static const value_string fsk_a_modes[] = { |
1189 | | { 0, "4.8 kb/s; 2-FSK; mod index = 1.0; channel spacing = 12.5 kHz" }, |
1190 | | { 1, "9.6 kb/s; 4-FSK; mod index = 0.33; channel spacing = 12.5 kHz" }, |
1191 | | { 2, "10 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" }, |
1192 | | { 3, "20 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" }, |
1193 | | { 4, "40 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" }, |
1194 | | { 5, "4.8 kb/s; 2-FSK; mod index = 0.5; channel spacing = 12.5 kHz" }, |
1195 | | { 6, "2.4 kb/s; 2-FSK; mod index = 2.0; channel spacing = 12.5 kHz" }, |
1196 | | { 7, "9.6 kb/s; 4-FSK; mod index = 0.33; channel spacing = 12.5 kHz" }, |
1197 | | { 0, NULL } |
1198 | | }; |
1199 | | |
1200 | | static const value_string fsk_b_modes[] = { |
1201 | | { 0, "50 kb/s; 2-FSK; mod index = 1.0; channel spacing = 200 kHz" }, |
1202 | | { 1, "100 kb/s; 2-FSK; mod index = 1.0; channel spacing = 400 kHz" }, |
1203 | | { 2, "150 kb/s; 2-FSK; mod index = 0.5; channel spacing = 400 kHz" }, |
1204 | | { 3, "200 kb/s; 2-FSK; mod index = 0.5; channel spacing = 400 kHz" }, |
1205 | | { 4, "200 kb/s; 4-FSK; mod index = 0.33; channel spacing = 400 kHz" }, |
1206 | | { 5, "200 kb/s; 2-FSK; mod index = 1.0; channel spacing = 600 kHz" }, |
1207 | | { 6, "400 kb/s; 4-FSK; mod index = 0.33; channel spacing = 600 kHz" }, |
1208 | | { 7, "100 kb/s; 2-FSK; mod index = 0.5; channel spacing = 200 kHz"}, |
1209 | | { 8, "50 kb/s; 2-FSK; mod index = 0.5; channel spacing = 100 kHz"}, |
1210 | | { 9, "150 kb/s; 2-FSK; mod index = 0.5; channel spacing = 200 kHz"}, |
1211 | | { 10, "300 kb/s; 2-FSK; mod index = 0.5; channel spacing = 400 kHz" }, |
1212 | | { 0, NULL } |
1213 | | }; |
1214 | | |
1215 | | static const value_string oqpsk_a_modes[] = { |
1216 | | { 0, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 0; data rate = 6.25 kb/s"}, |
1217 | | { 1, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 1; data rate = 12.5 kb/s"}, |
1218 | | { 2, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 2; data rate = 25 kb/s"}, |
1219 | | { 3, "chip rate = 100 kchip/s; SpreadingMode = DSSS; RateMode = 3; data rate = 50 kb/s"}, |
1220 | | { 0, NULL } |
1221 | | }; |
1222 | | |
1223 | | static const value_string oqpsk_b_modes[] = { |
1224 | | { 0, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 0; data rate = 31.25 kb/s"}, |
1225 | | { 1, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 1; data rate = 125 kb/s"}, |
1226 | | { 2, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 2; data rate = 250 kb/s"}, |
1227 | | { 3, "chip rate = 1000 kchip/s; SpreadingMode = DSSS; RateMode = 3; data rate = 500 kb/s"}, |
1228 | | { 4, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 0; data rate = 62.5 kb/s"}, |
1229 | | { 5, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 1; data rate = 125 kb/s"}, |
1230 | | { 6, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 2; data rate = 250 kb/s"}, |
1231 | | { 7, "chip rate = 1000 kchip/s; SpreadingMode = MDSSS; RateMode = 3; data rate = 500 kb/s"}, |
1232 | | { 0, NULL } |
1233 | | }; |
1234 | | |
1235 | | static const value_string oqpsk_c_modes[] = { |
1236 | | { 0, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 0; data rate = 31.25 kb/s"}, |
1237 | | { 1, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 1; data rate = 125 kb/s"}, |
1238 | | { 2, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 2; data rate = 250 kb/s"}, |
1239 | | { 3, "chip rate = 2000 kchip/s; SpreadingMode = DSSS; RateMode = 3; data rate = 500 kb/s"}, |
1240 | | { 4, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 0; data rate = 62.5 kb/s"}, |
1241 | | { 5, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 1; data rate = 125 kb/s"}, |
1242 | | { 6, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 2; data rate = 250 kb/s"}, |
1243 | | { 7, "chip rate = 2000 kchip/s; SpreadingMode = MDSSS; RateMode = 3; data rate = 500 kb/s"}, |
1244 | | { 0, NULL } |
1245 | | }; |
1246 | | |
1247 | | static const value_string ofdm_modes[] = { |
1248 | | { 0, "MCS0" }, |
1249 | | { 1, "MCS1" }, |
1250 | | { 2, "MCS2" }, |
1251 | | { 3, "MCS3" }, |
1252 | | { 4, "MCS4" }, |
1253 | | { 5, "MCS5" }, |
1254 | | { 6, "MCS6" }, |
1255 | | { 0, NULL }, |
1256 | | }; |
1257 | | |
1258 | | static const value_string channel_page_names[] = { |
1259 | | { 0, "Default" }, |
1260 | | { 1, "ASK" }, |
1261 | | { 2, "O-QPSK" }, |
1262 | | { 3, "CSS" }, |
1263 | | { 4, "HRP UWB" }, |
1264 | | { 5, "780 MHz" }, |
1265 | | { 6, "GFSK" }, |
1266 | | { 7, "MSK" }, |
1267 | | { 8, "LRP_UWB" }, |
1268 | | { 9, "SUN" }, |
1269 | | { 10, "SUN FSK" }, |
1270 | | { 11, "2380 MHz" }, |
1271 | | { 12, "LECIM" }, |
1272 | | { 13, "RCC" }, |
1273 | | { 0, NULL } |
1274 | | }; |
1275 | | |
1276 | | static const value_string ietf_6top_types[] = { |
1277 | | { IETF_6TOP_TYPE_REQUEST, "Request" }, |
1278 | | { IETF_6TOP_TYPE_RESPONSE, "Response" }, |
1279 | | { IETF_6TOP_TYPE_CONFIRMATION, "Confirmation" }, |
1280 | | { 0, NULL } |
1281 | | }; |
1282 | | |
1283 | | static const value_string ietf_6top_command_identifiers[] = { |
1284 | | { IETF_6TOP_CMD_ADD, "ADD" }, |
1285 | | { IETF_6TOP_CMD_DELETE, "DELETE" }, |
1286 | | { IETF_6TOP_CMD_RELOCATE, "RELOCATE" }, |
1287 | | { IETF_6TOP_CMD_COUNT, "COUNT" }, |
1288 | | { IETF_6TOP_CMD_LIST, "LIST" }, |
1289 | | { IETF_6TOP_CMD_SIGNAL, "SIGNAL" }, |
1290 | | { IETF_6TOP_CMD_CLEAR, "CLEAR" }, |
1291 | | { 0, NULL } |
1292 | | }; |
1293 | | |
1294 | | static const value_string ietf_6top_return_codes[] = { |
1295 | | { IETF_6TOP_RC_SUCCESS, "SUCCESS" }, |
1296 | | { IETF_6TOP_RC_EOL, "RC_EOL" }, |
1297 | | { IETF_6TOP_RC_ERR, "RC_ERR" }, |
1298 | | { IETF_6TOP_RC_RESET, "RC_RESET" }, |
1299 | | { IETF_6TOP_RC_ERR_VERSION, "RC_ERR_VERSION" }, |
1300 | | { IETF_6TOP_RC_ERR_SFID, "RC_ERR_SFID" }, |
1301 | | { IETF_6TOP_RC_ERR_SEQNUM, "RC_ERR_SEQNUM" }, |
1302 | | { IETF_6TOP_RC_ERR_CELLLIST, "RC_ERR_CELLLIST" }, |
1303 | | { IETF_6TOP_RC_ERR_BUSY, "RC_ERR_BUSY" }, |
1304 | | { IETF_6TOP_RC_ERR_LOCKED, "RC_ERR_LOCKED" }, |
1305 | | { 0, NULL } |
1306 | | }; |
1307 | | |
1308 | | static const value_string ietf_6top_cell_options[] = { |
1309 | | { 0, "ALL" }, |
1310 | | { 1, "TX" }, |
1311 | | { 2, "RX" }, |
1312 | | { 3, "TX|RX" }, |
1313 | | { 4, "SHARED" }, |
1314 | | { 5, "TX|SHARED" }, |
1315 | | { 6, "RX|SHARED" }, |
1316 | | { 7, "TX|RX|SHARED" }, |
1317 | | { 0, NULL} |
1318 | | }; |
1319 | | |
1320 | | static const value_string mpx_transfer_type_vals[] = { |
1321 | | { IEEE802159_MPX_FULL_FRAME, "Full Frame" }, |
1322 | | { IEEE802159_MPX_FULL_FRAME_NO_MUXID, "Full frame with compressed Multiplex ID" }, |
1323 | | { IEEE802159_MPX_NON_LAST_FRAGMENT, "Non-last Fragment" }, |
1324 | | { IEEE802159_MPX_LAST_FRAGMENT, "Last Fragment" }, |
1325 | | { IEEE802159_MPX_ABORT, "Abort" }, |
1326 | | { 0, NULL } |
1327 | | }; |
1328 | | |
1329 | | static const value_string mpx_multiplex_id_vals[] = { |
1330 | | { IEEE802159_MPX_MULTIPLEX_ID_KMP, "KMP" }, |
1331 | | { IEEE802159_MPX_MULTIPLEX_ID_WISUN, "Wi-SUN" }, |
1332 | | { 0, NULL } |
1333 | | }; |
1334 | | |
1335 | | // used by the Wi-SUN dissector |
1336 | | const value_string ieee802154_mpx_kmp_id_vals[] = { |
1337 | | { IEEE802159_MPX_KMP_ID_IEEE8021X, "IEEE 802.1X/MKA" }, |
1338 | | { IEEE802159_MPX_KMP_ID_HIP, "HIP" }, |
1339 | | { IEEE802159_MPX_KMP_ID_IKEV2, "IKEv2" }, |
1340 | | { IEEE802159_MPX_KMP_ID_PANA, "PANA" }, |
1341 | | { IEEE802159_MPX_KMP_ID_DRAGONFLY, "Dragonfly" }, |
1342 | | { IEEE802159_MPX_KMP_ID_IEEE80211_4WH, "IEEE 802.11/4WH" }, |
1343 | | { IEEE802159_MPX_KMP_ID_IEEE80211_GKH, "IEEE 802.11/GKH" }, |
1344 | | { IEEE802159_MPX_KMP_ID_ETSI_TS_102_887_2, "ETSI TS 102 887-2" }, |
1345 | | { IEEE802159_MPX_KMP_ID_VENDOR_SPECIFIC, "Vendor-specific" }, |
1346 | | { 0, NULL } |
1347 | | }; |
1348 | | |
1349 | | static const value_string mpx_wisun_subid_vals[] = { |
1350 | | { IEEE802159_MPX_WISUN_SUBID_MHDS, "WM-MHDS" }, |
1351 | | { IEEE802159_MPX_WISUN_SUBID_6LOWPAN, "WM-6LO" }, |
1352 | | { IEEE802159_MPX_WISUN_SUBID_SECURITY, "WM-SEC" }, |
1353 | | { 0, NULL } |
1354 | | }; |
1355 | | |
1356 | | static const value_string ieee802154_phr_type_vals[] = { |
1357 | | { PHR_RAW , "RAW" }, |
1358 | | { PHR_O_QPSK , "O-QPSK" }, |
1359 | | { PHR_CSS , "CSS" }, |
1360 | | { PHR_HRP_UWB , "HRP UWB" }, |
1361 | | { PHR_MSK , "MSK" }, |
1362 | | { PHR_LRP_UWB , "LRP UWB" }, |
1363 | | { PHR_SUN_FSK , "SUN FSK" }, |
1364 | | { PHR_SUN_OFDM , "SUN OFDM" }, |
1365 | | { PHR_SUN_O_QPSK , "SUN O-QPSK" }, |
1366 | | { PHR_LECIM_FSK , "LECIM FSK" }, |
1367 | | { PHR_TVWS_FSK , "TVWS FSK" }, |
1368 | | { PHR_TVWS_OFDM , "TVWS OFDM" }, |
1369 | | { PHR_TVWS_NB_OFDM , "TVWS-NB OFDM" }, |
1370 | | { PHR_RCC_LMR , "RCC LMR" }, |
1371 | | { PHR_CMB_O_QPSK , "CMB O-QPSK" }, |
1372 | | { PHR_CMB_GFSK , "CMB GFSK" }, |
1373 | | { PHR_TASK , "TASK" }, |
1374 | | { PHR_RS_GFSK , "RS GFSK" }, |
1375 | | { PHR_WISUN_FSK_MS , "Wi-SUN FSK MS" }, |
1376 | | { 0, NULL } |
1377 | | }; |
1378 | | |
1379 | | /* SUN FSK PHR fields - IEEE 802.15.4-2020 19.2.4 */ |
1380 | | static const true_false_string tfs_fcs_type = { "2-octet FCS", "4-octet FCS" }; |
1381 | | static const value_string vals_fsk_ms_page[] = { |
1382 | | {0, "9"}, |
1383 | | {1, "10"}, |
1384 | | {0, NULL} |
1385 | | }; |
1386 | | |
1387 | | static const value_string ieee802154_phr_fsk_ms_scheme[] = { |
1388 | | { 0, "SUN FSK" }, |
1389 | | { 1, "SUN OFDM" }, |
1390 | | { 2, "SUN O-QPSK" }, |
1391 | | { 3, "Additional" }, |
1392 | | { 0, NULL } |
1393 | | }; |
1394 | | |
1395 | | static const value_string ieee802154_phr_fsk_ms_mode[] = { |
1396 | | { 1, "SUN FSK operating mode #1" }, |
1397 | | { 2, "SUN FSK operating mode #2" }, |
1398 | | { 4, "SUN FSK operating mode #3" }, |
1399 | | { 8, "SUN FSK operating mode #4" }, |
1400 | | { 0, NULL } |
1401 | | }; |
1402 | | |
1403 | | static const value_string ieee802154_phr_fsk_ms_additional_modes[] = { |
1404 | | { 0, "SUN FSK operating mode #5" }, |
1405 | | { 1, "SUN FSK operating mode #1a" }, |
1406 | | { 2, "SUN FSK operating mode #1b" }, |
1407 | | { 0, NULL } |
1408 | | }; |
1409 | | |
1410 | | /* Wi-SUN phyModeID - Wi-SUN PHY Specification Revision 1v09 Annex F PHY Operating Mode */ |
1411 | | static const value_string ieee802154_phr_wisun_phymodeid[] = { |
1412 | | { 1, "FSK #1a 50ksym/s mod-index 0.5" }, |
1413 | | { 2, "FSK #1b 50ksym/s mod-index 1.0" }, |
1414 | | { 3, "FSK #2a 100ksym/s mod-index 0.5" }, |
1415 | | { 4, "FSK #2b 100ksym/s mod-index 1.0" }, |
1416 | | { 5, "FSK #3 150ksym/s mod-index 0.5" }, |
1417 | | { 6, "FSK #4a 200ksym/s mod-index 0.5" }, |
1418 | | { 7, "FSK #4b 200ksym/s mod-index 1.0" }, |
1419 | | { 8, "FSK #5 300ksym/s mod-index 0.5" }, |
1420 | | { 17, "FSK with FEC #1a 50ksym/s mod-index 0.5" }, |
1421 | | { 18, "FSK with FEC #1b 50ksym/s mod-index 1.0" }, |
1422 | | { 19, "FSK with FEC #2a 100ksym/s mod-index 0.5" }, |
1423 | | { 20, "FSK with FEC #2b 100ksym/s mod-index 1.0" }, |
1424 | | { 21, "FSK with FEC #3 150ksym/s mod-index 0.5" }, |
1425 | | { 22, "FSK with FEC #4a 200ksym/s mod-index 0.5" }, |
1426 | | { 23, "FSK with FEC #4b 200ksym/s mod-index 1.0" }, |
1427 | | { 24, "FSK with FEC #5 300ksym/s mod-index 0.5" }, |
1428 | | { 34, "OFDM Option 1 MCS 2 400kbps" }, |
1429 | | { 35, "OFDM Option 1 MCS 3 800kbps" }, |
1430 | | { 36, "OFDM Option 1 MCS 4 1200kbps" }, |
1431 | | { 37, "OFDM Option 1 MCS 5 1600kbps" }, |
1432 | | { 38, "OFDM Option 1 MCS 6 2400kbps" }, |
1433 | | { 51, "OFDM Option 2 MCS 3 400kbps" }, |
1434 | | { 52, "OFDM Option 2 MCS 4 600kbps" }, |
1435 | | { 53, "OFDM Option 2 MCS 5 800kbps" }, |
1436 | | { 54, "OFDM Option 2 MCS 6 1200kbps" }, |
1437 | | { 68, "OFDM Option 3 MCS 4 300kbps" }, |
1438 | | { 69, "OFDM Option 3 MCS 5 400kbps" }, |
1439 | | { 70, "OFDM Option 3 MCS 6 600kbps" }, |
1440 | | { 84, "OFDM Option 4 MCS 4 150kbps" }, |
1441 | | { 85, "OFDM Option 4 MCS 5 200kbps" }, |
1442 | | { 86, "OFDM Option 4 MCS 6 300kbps" }, |
1443 | | { 0, NULL } |
1444 | | }; |
1445 | | |
1446 | | /* Preferences for 2003 security */ |
1447 | | static int ieee802154_sec_suite = SECURITY_LEVEL_ENC_MIC_64; |
1448 | | static bool ieee802154_extend_auth = true; |
1449 | | |
1450 | | /* Macro to check addressing, and throw a warning flag if incorrect. */ |
1451 | | #define IEEE802154_CMD_ADDR_CHECK(_pinfo_, _item_, _cmdid_, _x_) \ |
1452 | 44 | if (!(_x_)) \ |
1453 | 25 | expert_add_info_format(_pinfo_, _item_, &ei_ieee802154_invalid_addressing, \ |
1454 | 24 | "Invalid Addressing for %s", \ |
1455 | 24 | val_to_str_const(_cmdid_, ieee802154_cmd_names, "Unknown Command")) |
1456 | | |
1457 | | /* CRC definitions. IEEE 802.15.4 CRCs vary from ITU-T by using an initial value of |
1458 | | * 0x0000, and no XOR out. IEEE802154_CRC_XOR is defined as 0xFFFF in order to un-XOR |
1459 | | * the output from the ITU-T (CCITT) CRC routines in Wireshark. |
1460 | | */ |
1461 | 537 | #define IEEE802154_CRC_SEED 0x0000 |
1462 | 537 | #define IEEE802154_CRC_XOROUT 0xFFFF |
1463 | 537 | #define ieee802154_crc_tvb(tvb, offset) (crc16_ccitt_tvb_seed(tvb, offset, IEEE802154_CRC_SEED) ^ IEEE802154_CRC_XOROUT) |
1464 | | |
1465 | | /* For the 32-bit CRC, IEEE 802.15.4 uses ITU-T (CCITT) CRC-32. */ |
1466 | 0 | #define ieee802154_crc32_tvb(tvb, offset) (crc32_ccitt_tvb(tvb, offset)) |
1467 | | |
1468 | | static int ieee802_15_4_short_address_to_str(const address* addr, char *buf, int buf_len) |
1469 | 20.1k | { |
1470 | 20.1k | uint16_t ieee_802_15_4_short_addr = pletohu16(addr->data); |
1471 | | |
1472 | 20.1k | if (ieee_802_15_4_short_addr == 0xffff) |
1473 | 58 | { |
1474 | 58 | (void) g_strlcpy(buf, "Broadcast", buf_len); |
1475 | 58 | return 10; |
1476 | 58 | } |
1477 | | |
1478 | 20.0k | *buf++ = '0'; |
1479 | 20.0k | *buf++ = 'x'; |
1480 | 20.0k | buf = word_to_hex(buf, ieee_802_15_4_short_addr); |
1481 | 20.0k | *buf = '\0'; /* NULL terminate */ |
1482 | | |
1483 | 20.0k | return 7; |
1484 | 20.1k | } |
1485 | | |
1486 | | static int ieee802_15_4_short_address_str_len(const address* addr _U_) |
1487 | 20.1k | { |
1488 | 20.1k | return 11; |
1489 | 20.1k | } |
1490 | | |
1491 | | static int ieee802_15_4_short_address_len(void) |
1492 | 0 | { |
1493 | 0 | return 2; |
1494 | 0 | } |
1495 | | |
1496 | | /* ======================================================================= */ |
1497 | | static conversation_t *_find_or_create_conversation(packet_info *pinfo, const address *src_addr, const address *dst_addr) |
1498 | 4.53k | { |
1499 | 4.53k | conversation_t *conv = NULL; |
1500 | | |
1501 | | /* Have we seen this conversation before? */ |
1502 | 4.53k | conv = find_conversation(pinfo->num, src_addr, dst_addr, CONVERSATION_NONE, 0, 0, 0); |
1503 | 4.53k | if (conv == NULL) { |
1504 | | /* No, this is a new conversation. */ |
1505 | 798 | conv = conversation_new(pinfo->num, src_addr, dst_addr, CONVERSATION_NONE, 0, 0, 0); |
1506 | 798 | } |
1507 | 4.53k | return conv; |
1508 | 4.53k | } |
1509 | | |
1510 | | /* ======================================================================= */ |
1511 | | static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key) |
1512 | 0 | { |
1513 | 0 | ieee802154_transaction_t *ieee802154_trans; |
1514 | 0 | wmem_tree_key_t ieee802154_key[3]; |
1515 | 0 | proto_item *it; |
1516 | |
|
1517 | 0 | if (!PINFO_FD_VISITED(pinfo)) { |
1518 | | /* |
1519 | | * This is a new request, create a new transaction structure and map it |
1520 | | * to the unmatched table. |
1521 | | */ |
1522 | 0 | ieee802154_key[0].length = 2; |
1523 | 0 | ieee802154_key[0].key = key; |
1524 | 0 | ieee802154_key[1].length = 0; |
1525 | 0 | ieee802154_key[1].key = NULL; |
1526 | |
|
1527 | 0 | ieee802154_trans = wmem_new0(wmem_file_scope(), ieee802154_transaction_t); |
1528 | |
|
1529 | 0 | if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) |
1530 | 0 | ieee802154_trans->dst16 = packet->dst16; |
1531 | 0 | else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) |
1532 | 0 | ieee802154_trans->dst64 = packet->dst64; |
1533 | 0 | ieee802154_trans->dst_addr_mode = packet->dst_addr_mode; |
1534 | |
|
1535 | 0 | if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) |
1536 | 0 | ieee802154_trans->src16 = packet->src16; |
1537 | 0 | else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) |
1538 | 0 | ieee802154_trans->src64 = packet->src64; |
1539 | 0 | ieee802154_trans->src_addr_mode = packet->src_addr_mode; |
1540 | |
|
1541 | 0 | if (packet->dst_pan_present) { |
1542 | 0 | ieee802154_trans->dst_pan_present = true; |
1543 | 0 | ieee802154_trans->dst_pan = packet->dst_pan; |
1544 | 0 | } |
1545 | 0 | if (packet->src_pan_present) { |
1546 | 0 | ieee802154_trans->src_pan_present = true; |
1547 | 0 | ieee802154_trans->src_pan = packet->src_pan; |
1548 | 0 | } |
1549 | 0 | ieee802154_trans->rqst_frame = pinfo->num; |
1550 | 0 | ieee802154_trans->ack_frame = 0; |
1551 | 0 | ieee802154_trans->rqst_time = pinfo->abs_ts; |
1552 | 0 | nstime_set_unset(&ieee802154_trans->ack_time); |
1553 | 0 | wmem_tree_insert32_array(transaction_unmatched_pdus, ieee802154_key, (void *)ieee802154_trans); |
1554 | 0 | } else { |
1555 | | /* Already visited this frame */ |
1556 | 0 | uint32_t frame_num = pinfo->num; |
1557 | |
|
1558 | 0 | ieee802154_key[0].length = 2; |
1559 | 0 | ieee802154_key[0].key = key; |
1560 | 0 | ieee802154_key[1].length = 1; |
1561 | 0 | ieee802154_key[1].key = &frame_num; |
1562 | 0 | ieee802154_key[2].length = 0; |
1563 | 0 | ieee802154_key[2].key = NULL; |
1564 | |
|
1565 | 0 | ieee802154_trans = (ieee802154_transaction_t *)wmem_tree_lookup32_array(transaction_matched_pdus, ieee802154_key); |
1566 | |
|
1567 | 0 | if (!ieee802154_trans) { |
1568 | | /* No ACK found - add field and expert info */ |
1569 | 0 | it = proto_tree_add_item(tree, hf_ieee802154_no_ack, NULL, 0, 0, ENC_NA); |
1570 | 0 | proto_item_set_generated(it); |
1571 | |
|
1572 | 0 | expert_add_info_format(pinfo, it, &ei_ieee802154_ack_not_found, "No ack found to request in frame %u", pinfo->num); |
1573 | |
|
1574 | 0 | return NULL; |
1575 | 0 | } |
1576 | 0 | } |
1577 | | |
1578 | | /* Print state tracking in the tree */ |
1579 | 0 | if (ieee802154_trans->ack_frame) { |
1580 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_ack_in, NULL, 0, 0, ieee802154_trans->ack_frame); |
1581 | 0 | proto_item_set_generated(it); |
1582 | 0 | } |
1583 | |
|
1584 | 0 | return ieee802154_trans; |
1585 | 0 | } /* transaction_start() */ |
1586 | | |
1587 | | static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key) |
1588 | 0 | { |
1589 | 0 | ieee802154_transaction_t *ieee802154_trans = NULL; |
1590 | 0 | wmem_tree_key_t ieee802154_key[3]; |
1591 | 0 | proto_item *it; |
1592 | |
|
1593 | 0 | if (!PINFO_FD_VISITED(pinfo)) { |
1594 | 0 | uint32_t frame_num; |
1595 | 0 | nstime_t ns; |
1596 | |
|
1597 | 0 | ieee802154_key[0].length = 2; |
1598 | 0 | ieee802154_key[0].key = key; |
1599 | 0 | ieee802154_key[1].length = 0; |
1600 | 0 | ieee802154_key[1].key = NULL; |
1601 | |
|
1602 | 0 | ieee802154_trans = (ieee802154_transaction_t *)wmem_tree_lookup32_array(transaction_unmatched_pdus, ieee802154_key); |
1603 | 0 | if (ieee802154_trans == NULL) |
1604 | 0 | return NULL; |
1605 | | |
1606 | | /* we have already seen this response, or an identical one */ |
1607 | 0 | if (ieee802154_trans->ack_frame != 0) |
1608 | 0 | return NULL; |
1609 | | |
1610 | | /* If addresses are present they must match */ |
1611 | 0 | if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
1612 | 0 | if (packet->src16 != ieee802154_trans->dst16) |
1613 | 0 | return NULL; |
1614 | 0 | } |
1615 | 0 | else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
1616 | 0 | if (packet->src64 != ieee802154_trans->dst64) |
1617 | 0 | return NULL; |
1618 | 0 | } |
1619 | 0 | if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
1620 | 0 | if (packet->dst16 != ieee802154_trans->src16) |
1621 | 0 | return NULL; |
1622 | 0 | } |
1623 | 0 | else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
1624 | 0 | if (packet->dst64 != ieee802154_trans->src64) |
1625 | 0 | return NULL; |
1626 | 0 | } |
1627 | | |
1628 | 0 | nstime_delta(&ns, &pinfo->abs_ts, &ieee802154_trans->rqst_time); |
1629 | 0 | if (nstime_cmp(&ns, &ieee802154_transaction_timeout) > 0) |
1630 | 0 | return NULL; |
1631 | | |
1632 | 0 | ieee802154_trans->ack_time = ns; |
1633 | 0 | ieee802154_trans->ack_frame = pinfo->num; |
1634 | | |
1635 | | /* |
1636 | | * We found a match. Add entries to the matched table for both |
1637 | | * request and ack frames |
1638 | | */ |
1639 | 0 | ieee802154_key[0].length = 2; |
1640 | 0 | ieee802154_key[0].key = key; |
1641 | 0 | ieee802154_key[1].length = 1; |
1642 | 0 | ieee802154_key[1].key = &frame_num; |
1643 | 0 | ieee802154_key[2].length = 0; |
1644 | 0 | ieee802154_key[2].key = NULL; |
1645 | |
|
1646 | 0 | frame_num = ieee802154_trans->rqst_frame; |
1647 | 0 | wmem_tree_insert32_array(transaction_matched_pdus, ieee802154_key, (void *)ieee802154_trans); |
1648 | |
|
1649 | 0 | frame_num = ieee802154_trans->ack_frame; |
1650 | 0 | wmem_tree_insert32_array(transaction_matched_pdus, ieee802154_key, (void *)ieee802154_trans); |
1651 | 0 | } else { |
1652 | | /* Already visited this frame */ |
1653 | 0 | uint32_t frame_num = pinfo->num; |
1654 | |
|
1655 | 0 | ieee802154_key[0].length = 2; |
1656 | 0 | ieee802154_key[0].key = key; |
1657 | 0 | ieee802154_key[1].length = 1; |
1658 | 0 | ieee802154_key[1].key = &frame_num; |
1659 | 0 | ieee802154_key[2].length = 0; |
1660 | 0 | ieee802154_key[2].key = NULL; |
1661 | |
|
1662 | 0 | ieee802154_trans = (ieee802154_transaction_t *)wmem_tree_lookup32_array(transaction_matched_pdus, ieee802154_key); |
1663 | |
|
1664 | 0 | if (!ieee802154_trans) { |
1665 | | /* No ack request found - add field and expert info */ |
1666 | 0 | it = proto_tree_add_item(tree, hf_ieee802154_no_ack_request, NULL, 0, 0, ENC_NA); |
1667 | 0 | proto_item_set_generated(it); |
1668 | |
|
1669 | 0 | expert_add_info_format(pinfo, it, &ei_ieee802154_ack_request_not_found, "No request found to ack in frame %u", pinfo->num); |
1670 | 0 | return NULL; |
1671 | 0 | } |
1672 | 0 | } |
1673 | | |
1674 | 0 | if (packet->dst_pan_present == false) { |
1675 | 0 | if (ieee802154_trans->src_pan_present) { |
1676 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_dst_panID, NULL, 0, 0, ieee802154_trans->src_pan); |
1677 | 0 | proto_item_set_generated(it); |
1678 | 0 | } |
1679 | 0 | else if (ieee802154_trans->dst_pan_present) { |
1680 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_dst_panID, NULL, 0, 0, ieee802154_trans->dst_pan); |
1681 | 0 | proto_item_set_generated(it); |
1682 | 0 | } |
1683 | 0 | } |
1684 | 0 | if ((packet->src_pan_present == false) && (ieee802154_trans->src_pan_present) && (ieee802154_trans->dst_pan_present)) { |
1685 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_src_panID, NULL, 0, 0, ieee802154_trans->dst_pan); |
1686 | 0 | proto_item_set_generated(it); |
1687 | 0 | } |
1688 | |
|
1689 | 0 | if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) { |
1690 | 0 | if (ieee802154_trans->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
1691 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_dst16, NULL, 0, 0, ieee802154_trans->src16); |
1692 | 0 | proto_item_set_generated(it); |
1693 | |
|
1694 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_addr16, NULL, 0, 0, ieee802154_trans->src16); |
1695 | 0 | proto_item_set_hidden(it); |
1696 | 0 | proto_item_set_generated(it); |
1697 | 0 | } |
1698 | 0 | else if (ieee802154_trans->src_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
1699 | 0 | it = proto_tree_add_eui64(tree, hf_ieee802154_dst64, NULL, 0, 0, ieee802154_trans->src64); |
1700 | 0 | proto_item_set_generated(it); |
1701 | |
|
1702 | 0 | it = proto_tree_add_eui64(tree, hf_ieee802154_addr64, NULL, 0, 0, ieee802154_trans->src64); |
1703 | 0 | proto_item_set_hidden(it); |
1704 | 0 | proto_item_set_generated(it); |
1705 | 0 | } |
1706 | 0 | } |
1707 | |
|
1708 | 0 | if (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) { |
1709 | 0 | if (ieee802154_trans->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
1710 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_src16, NULL, 0, 0, ieee802154_trans->dst16); |
1711 | 0 | proto_item_set_generated(it); |
1712 | |
|
1713 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_addr16, NULL, 0, 0, ieee802154_trans->dst16); |
1714 | 0 | proto_item_set_hidden(it); |
1715 | 0 | proto_item_set_generated(it); |
1716 | 0 | } |
1717 | 0 | else if (ieee802154_trans->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
1718 | 0 | it = proto_tree_add_eui64(tree, hf_ieee802154_src64, NULL, 0, 0, ieee802154_trans->dst64); |
1719 | 0 | proto_item_set_generated(it); |
1720 | |
|
1721 | 0 | it = proto_tree_add_eui64(tree, hf_ieee802154_addr64, NULL, 0, 0, ieee802154_trans->dst64); |
1722 | 0 | proto_item_set_hidden(it); |
1723 | 0 | proto_item_set_generated(it); |
1724 | 0 | } |
1725 | 0 | } |
1726 | | |
1727 | | /* Print state tracking in the tree */ |
1728 | 0 | it = proto_tree_add_uint(tree, hf_ieee802154_ack_to, NULL, 0, 0, ieee802154_trans->rqst_frame); |
1729 | 0 | proto_item_set_generated(it); |
1730 | |
|
1731 | 0 | it = proto_tree_add_time(tree, hf_ieee802154_ack_time, NULL, 0, 0, &ieee802154_trans->ack_time); |
1732 | 0 | proto_item_set_generated(it); |
1733 | |
|
1734 | 0 | return ieee802154_trans; |
1735 | |
|
1736 | 0 | } /* transaction_end() */ |
1737 | | |
1738 | | /** |
1739 | | * Dissector helper, parses and displays the frame control field. |
1740 | | * |
1741 | | * @param tvb pointer to buffer containing raw packet. |
1742 | | * @param pinfo pointer to packet information fields |
1743 | | * @param tree pointer to data tree wireshark uses to display packet. |
1744 | | * @param packet IEEE 802.15.4 packet information. |
1745 | | * @param offset offset into the tvb to find the FCF. |
1746 | | * |
1747 | | */ |
1748 | | static void |
1749 | | dissect_ieee802154_fcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet, unsigned *offset) |
1750 | 7.62k | { |
1751 | 7.62k | uint16_t fcf; |
1752 | 7.62k | static int * const ieee802154_fields[] = { |
1753 | 7.62k | &hf_ieee802154_frame_type, |
1754 | 7.62k | &hf_ieee802154_security, |
1755 | 7.62k | &hf_ieee802154_pending, |
1756 | 7.62k | &hf_ieee802154_ack_request, |
1757 | 7.62k | &hf_ieee802154_pan_id_compression, |
1758 | 7.62k | &hf_ieee802154_fcf_reserved, |
1759 | 7.62k | &hf_ieee802154_seqno_suppression, |
1760 | 7.62k | &hf_ieee802154_ie_present, |
1761 | 7.62k | &hf_ieee802154_dst_addr_mode, |
1762 | 7.62k | &hf_ieee802154_version, |
1763 | 7.62k | &hf_ieee802154_src_addr_mode, |
1764 | 7.62k | NULL |
1765 | 7.62k | }; |
1766 | | |
1767 | 7.62k | static int* const ieee802154_mpf_short_fields[] = { |
1768 | 7.62k | &hf_ieee802154_frame_type, |
1769 | 7.62k | &hf_ieee802154_mpf_long_frame_control, |
1770 | 7.62k | &hf_ieee802154_mpf_dst_addr_mode, |
1771 | 7.62k | &hf_ieee802154_mpf_src_addr_mode, |
1772 | 7.62k | NULL |
1773 | 7.62k | }; |
1774 | | |
1775 | 7.62k | static int* const ieee802154_mpf_long_fields[] = { |
1776 | 7.62k | &hf_ieee802154_frame_type, |
1777 | 7.62k | &hf_ieee802154_mpf_long_frame_control, |
1778 | 7.62k | &hf_ieee802154_mpf_dst_addr_mode, |
1779 | 7.62k | &hf_ieee802154_mpf_src_addr_mode, |
1780 | 7.62k | &hf_ieee802154_mpf_pan_id_present, |
1781 | 7.62k | &hf_ieee802154_mpf_security, |
1782 | 7.62k | &hf_ieee802154_mpf_seqno_suppression, |
1783 | 7.62k | &hf_ieee802154_mpf_pending, |
1784 | 7.62k | &hf_ieee802154_mpf_version, |
1785 | 7.62k | &hf_ieee802154_mpf_ack_request, |
1786 | 7.62k | &hf_ieee802154_mpf_ie_present, |
1787 | 7.62k | NULL |
1788 | 7.62k | }; |
1789 | | |
1790 | | /* Get the FCF field. */ |
1791 | 7.62k | fcf = tvb_get_letohs(tvb, *offset); |
1792 | | |
1793 | | /* Parse FCF Flags. */ |
1794 | 7.62k | packet->frame_type = (fcf & IEEE802154_FCF_TYPE_MASK); |
1795 | | |
1796 | 7.62k | if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) { |
1797 | | /* Multipurpose frames use a different 1 or 2 byte FCF */ |
1798 | 40 | packet->long_frame_control = (fcf & IEEE802154_MPF_FCF_LONG_FC) >> 3; |
1799 | 40 | packet->dst_addr_mode = (fcf & IEEE802154_MPF_FCF_DADDR_MASK) >> 4; |
1800 | 40 | packet->src_addr_mode = (fcf & IEEE802154_MPF_FCF_SADDR_MASK) >> 6; |
1801 | | |
1802 | | /* The second octet of the FCF is only present if the long frame control bit is set */ |
1803 | 40 | if (packet->long_frame_control) { |
1804 | 37 | packet->pan_id_present = (fcf & IEEE802154_MPF_FCF_PAN_ID_PRESENT) >> 8; |
1805 | 37 | packet->security_enable = (fcf & IEEE802154_MPF_FCF_SEC_EN) >> 9; |
1806 | 37 | packet->seqno_suppression = (fcf & IEEE802154_MPF_FCF_SEQNO_SUPPRESSION) >> 10; |
1807 | 37 | packet->frame_pending = (fcf & IEEE802154_MPF_FCF_FRAME_PND) >> 11; |
1808 | 37 | packet->version = (fcf & IEEE802154_MPF_FCF_VERSION) >> 12; |
1809 | 37 | packet->ack_request = (fcf & IEEE802154_MPF_FCF_ACK_REQ) >> 14; |
1810 | 37 | packet->ie_present = (fcf & IEEE802154_MPF_FCF_IE_PRESENT) >> 15; |
1811 | 37 | } |
1812 | 3 | else { |
1813 | 3 | packet->security_enable = false; |
1814 | 3 | packet->seqno_suppression = false; |
1815 | 3 | packet->frame_pending = false; |
1816 | 3 | packet->version = 0; |
1817 | 3 | packet->ack_request = false; |
1818 | 3 | packet->ie_present = false; |
1819 | 3 | } |
1820 | | |
1821 | 40 | if (ieee802154e_compatibility) { |
1822 | 0 | if (((tvb_reported_length(tvb) == IEEE802154E_LE_WUF_LEN)) && !packet->long_frame_control) { |
1823 | | /* Check if this is an IEEE 802.15.4e LE-multipurpose Wake-up Frame, which has a single-octet FCF |
1824 | | * and a static layout that cannot be inferred from the FCF alone. */ |
1825 | 0 | uint16_t ie_header = tvb_get_letohs(tvb, (*offset) + 6); |
1826 | 0 | uint16_t id = (uint16_t)((ie_header & IEEE802154_HEADER_IE_ID_MASK) >> 7); |
1827 | 0 | uint16_t length = (uint16_t)(ie_header & IEEE802154_HEADER_IE_LENGTH_MASK); |
1828 | 0 | if ((id == IEEE802154_HEADER_IE_RENDEZVOUS) && (length == 2)) { |
1829 | | /* This appears to be a WUF, as identified by containing a single |
1830 | | * Rendezvous Time Header IE with only a rendezvous time. */ |
1831 | 0 | packet->ie_present = true; |
1832 | 0 | packet->pan_id_present = true; |
1833 | 0 | } |
1834 | 0 | } |
1835 | 0 | } |
1836 | 40 | } |
1837 | 7.58k | else { |
1838 | | /* Standard 802.15.4 FCF */ |
1839 | 7.58k | packet->security_enable = (fcf & IEEE802154_FCF_SEC_EN) >> 3; |
1840 | 7.58k | packet->frame_pending = (fcf & IEEE802154_FCF_FRAME_PND) >> 4; |
1841 | 7.58k | packet->ack_request = (fcf & IEEE802154_FCF_ACK_REQ) >> 5; |
1842 | 7.58k | packet->pan_id_compression = (fcf & IEEE802154_FCF_PAN_ID_COMPRESSION) >> 6; |
1843 | | /* bit 7 reserved */ |
1844 | 7.58k | packet->seqno_suppression = (fcf & IEEE802154_FCF_SEQNO_SUPPRESSION) >> 8; |
1845 | 7.58k | packet->ie_present = (fcf & IEEE802154_FCF_IE_PRESENT) >> 9; |
1846 | 7.58k | packet->dst_addr_mode = (fcf & IEEE802154_FCF_DADDR_MASK) >> 10; |
1847 | 7.58k | packet->version = (fcf & IEEE802154_FCF_VERSION) >> 12; |
1848 | 7.58k | packet->src_addr_mode = (fcf & IEEE802154_FCF_SADDR_MASK) >> 14; |
1849 | 7.58k | } |
1850 | | |
1851 | 7.62k | if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_BEACON)) { |
1852 | 201 | proto_item_append_text(tree, " Enhanced Beacon"); |
1853 | 201 | col_set_str(pinfo->cinfo, COL_INFO, "Enhanced Beacon"); |
1854 | 201 | } |
1855 | 7.42k | else { |
1856 | 7.42k | proto_item_append_text(tree, " %s", val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved")); |
1857 | 7.42k | col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->frame_type, ieee802154_frame_types, "Reserved")); |
1858 | 7.42k | } |
1859 | | |
1860 | 7.62k | if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) { |
1861 | 40 | if (packet->long_frame_control) { |
1862 | 37 | proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf, |
1863 | 37 | ett_ieee802154_fcf, ieee802154_mpf_long_fields, ENC_LITTLE_ENDIAN); |
1864 | 37 | *offset += 2; |
1865 | 37 | } |
1866 | 3 | else { |
1867 | 3 | proto_tree_add_bitmask_len(tree, tvb, *offset, 1, hf_ieee802154_fcf, |
1868 | 3 | ett_ieee802154_fcf, ieee802154_mpf_short_fields, |
1869 | 3 | &ei_ieee802154_fcs_bitmask_len, ENC_LITTLE_ENDIAN); |
1870 | 3 | *offset += 1; |
1871 | 3 | } |
1872 | 40 | } |
1873 | 7.58k | else { |
1874 | 7.58k | proto_tree_add_bitmask(tree, tvb, *offset, hf_ieee802154_fcf, |
1875 | 7.58k | ett_ieee802154_fcf, ieee802154_fields, ENC_LITTLE_ENDIAN); |
1876 | 7.58k | *offset += 2; |
1877 | 7.58k | } |
1878 | | |
1879 | 7.62k | } /* dissect_ieee802154_fcf */ |
1880 | | |
1881 | | void register_ieee802154_mac_key_hash_handler(unsigned hash_identifier, ieee802154_set_key_func key_func) |
1882 | 16 | { |
1883 | | /* Ensure no duplication */ |
1884 | 16 | DISSECTOR_ASSERT(wmem_tree_lookup32(mac_key_hash_handlers, hash_identifier) == NULL); |
1885 | | |
1886 | 16 | wmem_tree_insert32(mac_key_hash_handlers, hash_identifier, (void*)key_func); |
1887 | 16 | } |
1888 | | |
1889 | | void dissect_ieee802154_aux_sec_header_and_key_with_hf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, ieee802154_packet *packet, unsigned *offset, const ieee802154_aux_sec_hf_t *aux_sec_hf) |
1890 | 118 | { |
1891 | 118 | proto_tree *field_tree, *header_tree; |
1892 | 118 | proto_item *ti, *hidden_item; |
1893 | 118 | uint8_t security_control; |
1894 | 118 | unsigned aux_length = 1; /* Minimum length of the auxiliary header. */ |
1895 | 118 | int hf_hdr = aux_sec_hf ? aux_sec_hf->hf_aux_security_header : hf_ieee802154_aux_security_header; |
1896 | 118 | int hf_sec_ctrl = aux_sec_hf ? aux_sec_hf->hf_aux_sec_security_control : hf_ieee802154_aux_sec_security_control; |
1897 | 118 | int hf_sec_level = aux_sec_hf ? aux_sec_hf->hf_aux_sec_security_level : hf_ieee802154_aux_sec_security_level; |
1898 | 118 | int hf_key_id_mode = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_id_mode : hf_ieee802154_aux_sec_key_id_mode; |
1899 | 118 | int hf_fc_suppress = aux_sec_hf ? aux_sec_hf->hf_aux_sec_frame_counter_suppression : hf_ieee802154_aux_sec_frame_counter_suppression; |
1900 | 118 | int hf_asn = aux_sec_hf ? aux_sec_hf->hf_aux_sec_asn_in_nonce : hf_ieee802154_aux_sec_asn_in_nonce; |
1901 | 118 | int hf_res = aux_sec_hf ? aux_sec_hf->hf_aux_sec_reserved : hf_ieee802154_aux_sec_reserved; |
1902 | 118 | int hf_fc = aux_sec_hf ? aux_sec_hf->hf_aux_sec_frame_counter : hf_ieee802154_aux_sec_frame_counter; |
1903 | 118 | int hf_ks = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_source : hf_ieee802154_aux_sec_key_source; |
1904 | 118 | int hf_ks_bytes = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_source_bytes : hf_ieee802154_aux_sec_key_source_bytes; |
1905 | 118 | int hf_ki = aux_sec_hf ? aux_sec_hf->hf_aux_sec_key_index : hf_ieee802154_aux_sec_key_index; |
1906 | 118 | int ett_aux = aux_sec_hf ? aux_sec_hf->ett_auxiliary_security : ett_ieee802154_auxiliary_security; |
1907 | 118 | int ett_ctrl = aux_sec_hf ? aux_sec_hf->ett_aux_sec_control : ett_ieee802154_aux_sec_control; |
1908 | 118 | int ett_kid = aux_sec_hf ? aux_sec_hf->ett_aux_sec_key_id : ett_ieee802154_aux_sec_key_id; |
1909 | | |
1910 | 118 | int * const security_fields[] = { |
1911 | 118 | &hf_sec_level, |
1912 | 118 | &hf_key_id_mode, |
1913 | 118 | &hf_fc_suppress, |
1914 | 118 | &hf_asn, |
1915 | 118 | &hf_res, |
1916 | 118 | NULL |
1917 | 118 | }; |
1918 | | |
1919 | | /* Parse the security control field. */ |
1920 | 118 | security_control = tvb_get_uint8(tvb, *offset); |
1921 | 118 | packet->security_level = (ieee802154_security_level)(security_control & IEEE802154_AUX_SEC_LEVEL_MASK); |
1922 | 118 | packet->key_id_mode = (ieee802154_key_id_mode)((security_control & IEEE802154_AUX_KEY_ID_MODE_MASK) >> IEEE802154_AUX_KEY_ID_MODE_SHIFT); |
1923 | 118 | if (packet->version == IEEE802154_VERSION_2015) { |
1924 | 25 | packet->frame_counter_suppression = security_control & IEEE802154_AUX_FRAME_COUNTER_SUPPRESSION_MASK ? true : false; |
1925 | 25 | } |
1926 | | |
1927 | | /* Compute the length of the auxiliary header and create a subtree. */ |
1928 | 118 | if (!packet->frame_counter_suppression) aux_length += 4; |
1929 | 118 | if (packet->key_id_mode != KEY_ID_MODE_IMPLICIT) aux_length++; |
1930 | 118 | if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_4) aux_length += 4; |
1931 | 118 | if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_8) aux_length += 8; |
1932 | | |
1933 | 118 | ti = proto_tree_add_item(tree, hf_hdr, tvb, *offset, aux_length, ENC_NA); |
1934 | 118 | header_tree = proto_item_add_subtree(ti, ett_aux); |
1935 | | |
1936 | | /* Security Control Field */ |
1937 | 118 | proto_tree_add_bitmask(header_tree, tvb, *offset, hf_sec_ctrl, ett_ctrl, security_fields, ENC_NA); |
1938 | 118 | (*offset)++; |
1939 | | |
1940 | | /* Frame Counter Field */ |
1941 | 118 | if (!packet->frame_counter_suppression) { |
1942 | 101 | proto_tree_add_item_ret_uint(header_tree, hf_fc, tvb, *offset, 4, ENC_LITTLE_ENDIAN, &packet->frame_counter); |
1943 | 101 | (*offset) += 4; |
1944 | 101 | } |
1945 | 17 | else { |
1946 | 17 | packet->asn = ieee802154_tsch_asn; |
1947 | 17 | } |
1948 | | |
1949 | | /* Key identifier field(s). */ |
1950 | 118 | if (packet->key_id_mode != KEY_ID_MODE_IMPLICIT) { |
1951 | | /* Create a subtree. */ |
1952 | 30 | field_tree = proto_tree_add_subtree(header_tree, tvb, *offset, 1, |
1953 | 30 | ett_kid, &ti, "Key Identifier Field"); /* Will fix length later. */ |
1954 | | /* Add key source, if it exists. */ |
1955 | 30 | if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_4) { |
1956 | 10 | packet->key_source.addr32 = tvb_get_ntohl(tvb, *offset); |
1957 | 10 | proto_tree_add_uint64(field_tree, hf_ks, tvb, *offset, 4, packet->key_source.addr32); |
1958 | 10 | hidden_item = proto_tree_add_item(field_tree, hf_ks_bytes, tvb, *offset, 4, ENC_NA); |
1959 | 10 | proto_item_set_hidden(hidden_item); |
1960 | 10 | proto_item_set_len(ti, 1 + 4); |
1961 | 10 | (*offset) += 4; |
1962 | 10 | } |
1963 | 30 | if (packet->key_id_mode == KEY_ID_MODE_KEY_EXPLICIT_8) { |
1964 | 8 | packet->key_source.addr64 = tvb_get_ntoh64(tvb, *offset); |
1965 | 8 | proto_tree_add_uint64(field_tree, hf_ks, tvb, *offset, 8, packet->key_source.addr64); |
1966 | 8 | hidden_item = proto_tree_add_item(field_tree, hf_ks_bytes, tvb, *offset, 8, ENC_NA); |
1967 | 8 | proto_item_set_hidden(hidden_item); |
1968 | 8 | proto_item_set_len(ti, 1 + 8); |
1969 | 8 | (*offset) += 8; |
1970 | 8 | } |
1971 | | /* Add key identifier. */ |
1972 | 30 | packet->key_index = tvb_get_uint8(tvb, *offset); |
1973 | 30 | proto_tree_add_uint(field_tree, hf_ki, tvb, *offset, 1, packet->key_index); |
1974 | 30 | (*offset)++; |
1975 | 30 | } |
1976 | 118 | } |
1977 | | |
1978 | | void dissect_ieee802154_aux_sec_header_and_key(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, ieee802154_packet *packet, unsigned *offset) |
1979 | 47 | { |
1980 | 47 | dissect_ieee802154_aux_sec_header_and_key_with_hf(tvb, pinfo, tree, packet, offset, NULL); |
1981 | 47 | } |
1982 | | |
1983 | | tvbuff_t *decrypt_ieee802154_payload(tvbuff_t * tvb, unsigned offset, packet_info * pinfo, proto_tree* key_tree, |
1984 | | ieee802154_packet * packet, ieee802154_decrypt_info_t* decrypt_info, |
1985 | | ieee802154_set_key_func set_key_func, ieee802154_decrypt_func decrypt_func) |
1986 | 36 | { |
1987 | 36 | proto_item* ti; |
1988 | 36 | unsigned char key[IEEE802154_CIPHER_SIZE]; |
1989 | 36 | unsigned char alt_key[IEEE802154_CIPHER_SIZE]; |
1990 | 36 | tvbuff_t * payload_tvb = NULL; |
1991 | | |
1992 | | /* Lookup the key. */ |
1993 | 36 | for (decrypt_info->key_number = 0; decrypt_info->key_number < num_ieee802154_keys; decrypt_info->key_number++) { |
1994 | 0 | unsigned nkeys = set_key_func(packet, key, alt_key, &ieee802154_keys[decrypt_info->key_number]); |
1995 | 0 | if (nkeys >= 1) { |
1996 | | /* Try with the initial key */ |
1997 | 0 | payload_tvb = decrypt_func(tvb, offset, pinfo, packet, decrypt_info, key); |
1998 | 0 | if (!((*decrypt_info->status == DECRYPT_PACKET_MIC_CHECK_FAILED) || (*decrypt_info->status == DECRYPT_PACKET_DECRYPT_FAILED))) { |
1999 | 0 | break; |
2000 | 0 | } |
2001 | 0 | } |
2002 | 0 | if (nkeys >= 2) { |
2003 | | /* Try also with the alternate key */ |
2004 | 0 | payload_tvb = decrypt_func(tvb, offset, pinfo, packet, decrypt_info, alt_key); |
2005 | 0 | if (!((*decrypt_info->status == DECRYPT_PACKET_MIC_CHECK_FAILED) || (*decrypt_info->status == DECRYPT_PACKET_DECRYPT_FAILED))) { |
2006 | 0 | break; |
2007 | 0 | } |
2008 | 0 | } |
2009 | 0 | } |
2010 | 36 | if (decrypt_info->key_number == num_ieee802154_keys) { |
2011 | | /* None of the stored keys seemed to work */ |
2012 | 36 | *decrypt_info->status = DECRYPT_PACKET_NO_KEY; |
2013 | 36 | } |
2014 | | |
2015 | | /* Store the key number used for retrieval */ |
2016 | 36 | ti = proto_tree_add_uint(key_tree, hf_ieee802154_key_number, tvb, 0, 0, decrypt_info->key_number); |
2017 | 36 | proto_item_set_hidden(ti); |
2018 | 36 | return payload_tvb; |
2019 | 36 | } |
2020 | | |
2021 | | |
2022 | | /** |
2023 | | * Check if the CRC-OK flag in the CC24xx metadata trailer is true |
2024 | | * @param tvb the IEEE 802.15.4 frame |
2025 | | * @return if the flag is true |
2026 | | */ |
2027 | | static bool |
2028 | | is_cc24xx_crc_ok(tvbuff_t *tvb) |
2029 | 0 | { |
2030 | 0 | return tvb_get_letohs(tvb, tvb_reported_length(tvb)-2) & IEEE802154_CC24xx_CRC_OK ? true : false; |
2031 | 0 | } |
2032 | | |
2033 | | /** |
2034 | | * Verify the 16/32 bit IEEE 802.15.4 FCS |
2035 | | * @param tvb the IEEE 802.15.4 frame from the FCF up to and including the FCS |
2036 | | * @return if the computed FCS matches the transmitted FCS |
2037 | | */ |
2038 | | static bool |
2039 | | is_fcs_ok(tvbuff_t *tvb, unsigned fcs_len) |
2040 | 396 | { |
2041 | 396 | if (fcs_len == 2) { |
2042 | | /* The FCS is in the last two bytes of the packet. */ |
2043 | 396 | uint16_t fcs = tvb_get_letohs(tvb, tvb_reported_length(tvb)-2); |
2044 | 396 | uint16_t fcs_calc = (uint16_t) ieee802154_crc_tvb(tvb, tvb_reported_length(tvb)-2); |
2045 | 396 | return fcs == fcs_calc; |
2046 | 396 | } |
2047 | 0 | else { |
2048 | | /* The FCS is in the last four bytes of the packet. */ |
2049 | 0 | uint32_t fcs = tvb_get_letohl(tvb, tvb_reported_length(tvb)-4); |
2050 | 0 | uint32_t fcs_calc = ieee802154_crc32_tvb(tvb, tvb_reported_length(tvb)-4); |
2051 | 0 | return fcs == fcs_calc; |
2052 | 0 | } |
2053 | 396 | } |
2054 | | |
2055 | | /** |
2056 | | * Dissector for IEEE 802.15.4 packets with a PHY for which there's a |
2057 | | * 4-octet preamble, a 1-octet SFD, and a 1-octet PHY header |
2058 | | * with the uppermost bit reserved and the remaining 7 bits being |
2059 | | * the frame length, and a 16-bit CRC value at the end. |
2060 | | * |
2061 | | * Currently, those are the following PHYs: |
2062 | | * |
2063 | | * O-QPSK |
2064 | | * Binary phase-shift keying (BPSK) |
2065 | | * GFSK |
2066 | | * MSK |
2067 | | * RCC DSSS BPSK |
2068 | | * |
2069 | | * @param tvb pointer to buffer containing raw packet. |
2070 | | * @param pinfo pointer to packet information fields |
2071 | | * @param tree pointer to data tree wireshark uses to display packet. |
2072 | | */ |
2073 | | static int |
2074 | | dissect_ieee802154_nonask_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
2075 | 0 | { |
2076 | 0 | proto_tree *ieee802154_tree = NULL; |
2077 | 0 | proto_item *proto_root = NULL; |
2078 | |
|
2079 | 0 | unsigned offset = 0; |
2080 | 0 | uint8_t phr; |
2081 | 0 | tvbuff_t* mac; |
2082 | | |
2083 | | /* Create the protocol tree. */ |
2084 | 0 | if (tree) { |
2085 | 0 | proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154_nonask_phy, tvb, 0, tvb_captured_length(tvb), "IEEE 802.15.4 non-ASK PHY"); |
2086 | 0 | ieee802154_tree = proto_item_add_subtree(proto_root, ett_ieee802154_nonask_phy); |
2087 | 0 | } |
2088 | | |
2089 | | /* Add the protocol name. */ |
2090 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4 non-ASK PHY"); |
2091 | |
|
2092 | 0 | phr = tvb_get_uint8(tvb,offset+4+1); |
2093 | |
|
2094 | 0 | if (tree) { |
2095 | 0 | unsigned loffset = offset; |
2096 | 0 | static int * const phr_fields[] = { |
2097 | 0 | &hf_ieee802154_nonask_phy_length, |
2098 | 0 | NULL |
2099 | 0 | }; |
2100 | |
|
2101 | 0 | proto_tree_add_item(ieee802154_tree, hf_ieee802154_nonask_phy_preamble, tvb, loffset, 4, ENC_LITTLE_ENDIAN); |
2102 | 0 | loffset +=4 ; |
2103 | 0 | proto_tree_add_item(ieee802154_tree, hf_ieee802154_nonask_phy_sfd, tvb, loffset, 1, ENC_LITTLE_ENDIAN); |
2104 | 0 | loffset +=1 ; |
2105 | |
|
2106 | 0 | proto_tree_add_bitmask(ieee802154_tree, tvb, loffset, hf_ieee802154_nonask_phr, ett_ieee802154_nonask_phy_phr, |
2107 | 0 | phr_fields, ENC_NA); |
2108 | 0 | } |
2109 | |
|
2110 | 0 | offset += 4+2*1; |
2111 | 0 | mac = tvb_new_subset_length(tvb,offset, phr & IEEE802154_PHY_LENGTH_MASK); |
2112 | | |
2113 | | /* These always have the FCS at the end. */ |
2114 | | |
2115 | | /* |
2116 | | * Call the common dissector; FCS length is 2, and no flags. |
2117 | | */ |
2118 | 0 | dissect_ieee802154_common(mac, pinfo, ieee802154_tree, 2, 0); |
2119 | 0 | return tvb_captured_length(tvb); |
2120 | 0 | } /* dissect_ieee802154_nonask_phy */ |
2121 | | |
2122 | | /* Return the length in octets for the user configured |
2123 | | * FCS/metadata following the PHY Payload */ |
2124 | | static unsigned |
2125 | | ieee802154_fcs_type_len(unsigned i) |
2126 | 402 | { |
2127 | 402 | unsigned fcs_type_lengths[] = { 2, 2, 4 }; |
2128 | 402 | if (i < array_length(fcs_type_lengths)) { |
2129 | 402 | return fcs_type_lengths[i]; |
2130 | 402 | } |
2131 | 0 | return 0; |
2132 | 402 | } |
2133 | | |
2134 | | /** |
2135 | | * Dissector for IEEE 802.15.4 packet with an FCS containing a 16/32-bit |
2136 | | * CRC value, or TI CC24xx metadata, at the end, as specified by the |
2137 | | * user preference. |
2138 | | * |
2139 | | * @param tvb pointer to buffer containing raw packet. |
2140 | | * @param pinfo pointer to packet information fields. |
2141 | | * @param tree pointer to data tree wireshark uses to display packet. |
2142 | | * @param data unused |
2143 | | */ |
2144 | | static int |
2145 | | dissect_ieee802154(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
2146 | 402 | { |
2147 | 402 | tvbuff_t *new_tvb = dissect_zboss_specific(tvb, pinfo, tree); |
2148 | 402 | unsigned options = 0; |
2149 | 402 | unsigned fcs_len; |
2150 | 402 | int fcs_type; |
2151 | | |
2152 | 402 | fcs_type = ieee802154_fcs_type; |
2153 | | |
2154 | | /* Set the default FCS length based on the FCS type in the configuration */ |
2155 | 402 | fcs_len = ieee802154_fcs_type_len(fcs_type); |
2156 | | |
2157 | 402 | if (fcs_type == IEEE802154_CC24XX_METADATA) { |
2158 | 0 | options = DISSECT_IEEE802154_OPTION_CC24xx; |
2159 | 0 | } |
2160 | | |
2161 | 402 | if (new_tvb != tvb) { |
2162 | | /* ZBOSS traffic dump: always TI metadata trailer, always ZigBee */ |
2163 | 0 | options = DISSECT_IEEE802154_OPTION_CC24xx|DISSECT_IEEE802154_OPTION_ZBOSS; |
2164 | 0 | fcs_len = 2; |
2165 | 0 | } |
2166 | | |
2167 | | /* Call the common dissector. */ |
2168 | 402 | dissect_ieee802154_common(new_tvb, pinfo, tree, fcs_len, options); |
2169 | 402 | return tvb_captured_length(tvb); |
2170 | 402 | } /* dissect_ieee802154 */ |
2171 | | |
2172 | | /** |
2173 | | * Dissector for IEEE 802.15.4 packet with an FCS containing a 16/32-bit |
2174 | | * CRC value, or TI CC24xx metadata, at the end, as specified by the |
2175 | | * data parameter. |
2176 | | * |
2177 | | * @param tvb pointer to buffer containing raw packet. |
2178 | | * @param pinfo pointer to packet information fields. |
2179 | | * @param tree pointer to data tree wireshark uses to display packet. |
2180 | | * @param data int pointer to fcs type to override user config. |
2181 | | */ |
2182 | | static int |
2183 | | dissect_ieee802154_fcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) |
2184 | 0 | { |
2185 | 0 | tvbuff_t *new_tvb = dissect_zboss_specific(tvb, pinfo, tree); |
2186 | 0 | unsigned options = 0; |
2187 | 0 | unsigned fcs_len; |
2188 | 0 | int fcs_type; |
2189 | |
|
2190 | 0 | DISSECTOR_ASSERT(data != NULL); |
2191 | 0 | fcs_type = *(int *)data; |
2192 | | |
2193 | | /* Set the default FCS length based on the FCS type in the configuration */ |
2194 | 0 | fcs_len = ieee802154_fcs_type_len(fcs_type); |
2195 | |
|
2196 | 0 | if (fcs_type == IEEE802154_CC24XX_METADATA) { |
2197 | 0 | options = DISSECT_IEEE802154_OPTION_CC24xx; |
2198 | 0 | } |
2199 | |
|
2200 | 0 | if (new_tvb != tvb) { |
2201 | | /* ZBOSS traffic dump: always TI metadata trailer, always ZigBee */ |
2202 | 0 | options = DISSECT_IEEE802154_OPTION_CC24xx|DISSECT_IEEE802154_OPTION_ZBOSS; |
2203 | 0 | fcs_len = 2; |
2204 | 0 | } |
2205 | | |
2206 | | /* Call the common dissector. */ |
2207 | 0 | dissect_ieee802154_common(new_tvb, pinfo, tree, fcs_len, options); |
2208 | 0 | return tvb_captured_length(tvb); |
2209 | 0 | } /* dissect_ieee802154_fcs */ |
2210 | | |
2211 | | /** |
2212 | | * Dissector for IEEE 802.15.4 packet with no FCS present. |
2213 | | * |
2214 | | * @param tvb pointer to buffer containing raw packet. |
2215 | | * @param pinfo pointer to packet information fields |
2216 | | * @param tree pointer to data tree wireshark uses to display packet. |
2217 | | * @return captured length. |
2218 | | */ |
2219 | | static int |
2220 | | dissect_ieee802154_nofcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_) |
2221 | 7.22k | { |
2222 | | /* |
2223 | | * Call the common dissector; FCS length is 0, and no flags. |
2224 | | */ |
2225 | 7.22k | dissect_ieee802154_common(tvb, pinfo, tree, 0, 0); |
2226 | 7.22k | return tvb_captured_length(tvb); |
2227 | 7.22k | } /* dissect_ieee802154_nofcs */ |
2228 | | |
2229 | | /** |
2230 | | * Dissector for IEEE 802.15.4 packet dump produced by ZBOSS |
2231 | | * |
2232 | | * @param tvb pointer to buffer containing raw packet. |
2233 | | * @param pinfo pointer to packet information fields |
2234 | | * @param tree pointer to data tree wireshark uses to display packet. |
2235 | | * @return new tvb subset if this is really ZBOSS dump, else original tvb. |
2236 | | */ |
2237 | | static tvbuff_t * |
2238 | | dissect_zboss_specific(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
2239 | 402 | { |
2240 | 402 | proto_tree *zboss_tree; |
2241 | 402 | proto_item *proto_root; |
2242 | 402 | unsigned off = 0; |
2243 | 402 | uint32_t direction_byte, page_byte, channel; |
2244 | | |
2245 | 402 | if (tvb_captured_length(tvb) > 5) |
2246 | 364 | { |
2247 | 364 | if (tvb_get_uint8(tvb, off++) == 'Z' |
2248 | 0 | && tvb_get_uint8(tvb, off++) == 'B' |
2249 | 0 | && tvb_get_uint8(tvb, off++) == 'O' |
2250 | 0 | && tvb_get_uint8(tvb, off++) == 'S' |
2251 | 0 | && tvb_get_uint8(tvb, off++) == 'S') |
2252 | 0 | { |
2253 | | /* Create the protocol tree. */ |
2254 | 0 | proto_root = proto_tree_add_protocol_format(tree, proto_zboss, tvb, 0, tvb_captured_length(tvb), "ZBOSS dump"); |
2255 | 0 | zboss_tree = proto_item_add_subtree(proto_root, ett_ieee802154_zboss); |
2256 | |
|
2257 | 0 | proto_tree_add_item_ret_uint(zboss_tree, hf_zboss_direction, tvb, off, 1, ENC_NA, &direction_byte); |
2258 | 0 | proto_item_append_text(proto_root, ", %s", direction_byte ? "OUT" : "IN"); |
2259 | |
|
2260 | 0 | proto_tree_add_item_ret_uint(zboss_tree, hf_zboss_page, tvb, off, 1, ENC_NA, &page_byte); |
2261 | 0 | proto_item_append_text(proto_root, ", page %u", page_byte); |
2262 | 0 | off++; |
2263 | |
|
2264 | 0 | proto_tree_add_item_ret_uint(zboss_tree, hf_zboss_channel, tvb, off, 1, ENC_NA, &channel); |
2265 | 0 | proto_item_append_text(proto_root, ", channel %u", channel); |
2266 | 0 | off++; |
2267 | |
|
2268 | 0 | proto_tree_add_item(zboss_tree, hf_zboss_trace_number, tvb, off, 4, ENC_LITTLE_ENDIAN); |
2269 | 0 | off += 4; |
2270 | |
|
2271 | 0 | return tvb_new_subset_remaining(tvb, off); |
2272 | 0 | } |
2273 | 364 | } |
2274 | 402 | return tvb; |
2275 | 402 | } /* dissect_zboss_specific */ |
2276 | | |
2277 | | /** |
2278 | | * Dissector for IEEE 802.15.4 packet with 2 bytes of ChipCon/Texas |
2279 | | * Instruments compatible metadata at the end of the frame, and no FCS. |
2280 | | * This is typically called by layers encapsulating an IEEE 802.15.4 packet. |
2281 | | * |
2282 | | * @param tvb pointer to buffer containing raw packet. |
2283 | | * @param pinfo pointer to packet information fields |
2284 | | * @param tree pointer to data tree wireshark uses to display packet. |
2285 | | */ |
2286 | | static int |
2287 | | dissect_ieee802154_cc24xx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_) |
2288 | 0 | { |
2289 | | /* |
2290 | | * Call the common dissector. |
2291 | | * 2 bytes of metadata at the end of the packet data. |
2292 | | */ |
2293 | 0 | dissect_ieee802154_common(tvb, pinfo, tree, 2, DISSECT_IEEE802154_OPTION_CC24xx); |
2294 | 0 | return tvb_captured_length(tvb); |
2295 | 0 | } /* dissect_ieee802154_cc24xx */ |
2296 | | |
2297 | | /** |
2298 | | * Dissector for IEEE 802.15.4 TAP packet |
2299 | | * |
2300 | | * Contains optional TLVs and encapsulates an IEEE 802.15.4 packet. |
2301 | | * |
2302 | | * @param tvb pointer to buffer containing raw packet. |
2303 | | * @param pinfo pointer to packet information fields |
2304 | | * @param tree pointer to data tree wireshark uses to display packet. |
2305 | | */ |
2306 | | static int |
2307 | | dissect_ieee802154_tap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_) |
2308 | 1 | { |
2309 | 1 | proto_tree *info_tree = NULL; |
2310 | 1 | proto_tree *header_tree = NULL; |
2311 | 1 | proto_item *proto_root = NULL; |
2312 | 1 | proto_item *ti = NULL; |
2313 | 1 | uint32_t version = 0; |
2314 | 1 | uint32_t length = 0; |
2315 | 1 | uint32_t data_length = 0; |
2316 | 1 | tvbuff_t* tlv_tvb; |
2317 | 1 | tvbuff_t* payload_tvb; |
2318 | 1 | ieee802154_fcs_type_t tap_fcs_type; |
2319 | 1 | unsigned fcs_len; |
2320 | | |
2321 | | /* Check the version in the TAP header */ |
2322 | 1 | version = tvb_get_uint8(tvb, 0); |
2323 | 1 | if (version != 0) { |
2324 | | /* Malformed packet. We do not understand any other version at this time */ |
2325 | 1 | return 0; |
2326 | 1 | } |
2327 | | |
2328 | | /* Get the total length of the header and TLVs */ |
2329 | 0 | length = tvb_get_letohs(tvb, 2); |
2330 | |
|
2331 | 0 | if (length > tvb_captured_length(tvb)) { |
2332 | | /* Malformed packet. The TLVs exceeds our captured packet. */ |
2333 | 0 | return 0; |
2334 | 0 | } |
2335 | | |
2336 | | /* Create the protocol tree */ |
2337 | 0 | proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154_tap, tvb, 0, length, "IEEE 802.15.4 TAP"); |
2338 | 0 | info_tree = proto_item_add_subtree(proto_root, ett_ieee802154_tap); |
2339 | |
|
2340 | 0 | header_tree = proto_tree_add_subtree(info_tree, tvb, 0, 4, ett_ieee802154_tap_header, &proto_root, "Header"); |
2341 | 0 | proto_tree_add_item(header_tree, hf_ieee802154_tap_version, tvb, 0, 1, ENC_LITTLE_ENDIAN); |
2342 | 0 | proto_tree_add_item(header_tree, hf_ieee802154_tap_reserved, tvb, 1, 1, ENC_LITTLE_ENDIAN); |
2343 | 0 | proto_tree_add_item(header_tree, hf_ieee802154_tap_length, tvb, 2, 2, ENC_LITTLE_ENDIAN); |
2344 | | |
2345 | | /* Add the protocol name. */ |
2346 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4 TAP"); |
2347 | | |
2348 | | /* Create a new tvb subset with only the TLVs to dissect */ |
2349 | 0 | tlv_tvb = tvb_new_subset_length(tvb, 4, length - 4); |
2350 | 0 | tap_fcs_type = dissect_ieee802154_tap_tlvs(tlv_tvb, pinfo, info_tree); |
2351 | | |
2352 | | /* Set the FCS length based on the FCS type */ |
2353 | 0 | switch (tap_fcs_type) { |
2354 | | |
2355 | 0 | case IEEE802154_FCS_TYPE_NONE: |
2356 | 0 | fcs_len = 0; |
2357 | 0 | break; |
2358 | | |
2359 | 0 | case IEEE802154_FCS_TYPE_16_BIT: |
2360 | 0 | fcs_len = 2; |
2361 | 0 | break; |
2362 | | |
2363 | 0 | case IEEE802154_FCS_TYPE_32_BIT: |
2364 | 0 | fcs_len = 4; |
2365 | 0 | break; |
2366 | | |
2367 | 0 | default: |
2368 | | /* Not valid */ |
2369 | 0 | return tvb_captured_length(tvb); |
2370 | 0 | } |
2371 | | |
2372 | | /* Report the remaining bytes as the IEEE 802.15.4 Data Length */ |
2373 | 0 | data_length = tvb_reported_length_remaining(tvb, length); |
2374 | 0 | ti = proto_tree_add_uint(info_tree, hf_ieee802154_tap_data_length, NULL, 0, 0, data_length); |
2375 | 0 | proto_item_set_generated(ti); |
2376 | |
|
2377 | 0 | if (data_length > 0) { |
2378 | | /* |
2379 | | * Call the common dissector with the real 802.15.4 data which follows the TLV header. |
2380 | | * Create a separate packet bytes pane for the real data. |
2381 | | * Specified FCS length, no flags. |
2382 | | */ |
2383 | 0 | payload_tvb = tvb_new_child_real_data(tvb, tvb_get_ptr(tvb, length, data_length), data_length, data_length); |
2384 | 0 | add_new_data_source(pinfo, payload_tvb, "IEEE 802.15.4 Data"); |
2385 | 0 | dissect_ieee802154_common(payload_tvb, pinfo, tree, fcs_len, 0); |
2386 | 0 | } |
2387 | 0 | else { |
2388 | 0 | expert_add_info(pinfo, ti, &ei_ieee802154_tap_no_payload); |
2389 | 0 | } |
2390 | |
|
2391 | 0 | return tvb_captured_length(tvb); |
2392 | 0 | } /* dissect_ieee802154_tap */ |
2393 | | |
2394 | | /** |
2395 | | * IEEE 802.15.4 packet dissection routine for Wireshark. |
2396 | | * |
2397 | | * This function extracts all the information first before displaying. |
2398 | | * If payload exists, that portion will be passed into another dissector |
2399 | | * for further processing. |
2400 | | * |
2401 | | * This is called after the individual dissect_ieee802154* functions |
2402 | | * have been called to determine what sort of FCS is present, if any. |
2403 | | * |
2404 | | * @param tvb pointer to buffer containing raw packet. |
2405 | | * @param pinfo pointer to packet information fields |
2406 | | * @param tree pointer to data tree Wireshark uses to display packet. |
2407 | | * @param options bitwise or of dissector options (see DISSECT_IEEE802154_OPTION_xxx). |
2408 | | */ |
2409 | | static void |
2410 | | dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned fcs_len, unsigned options) |
2411 | 7.62k | { |
2412 | 7.62k | proto_tree *ieee802154_tree; |
2413 | 7.62k | ieee802154_packet *packet; |
2414 | 7.62k | bool fcs_present; |
2415 | 7.62k | bool fcs_ok; |
2416 | 7.62k | tvbuff_t* no_fcs_tvb; |
2417 | | |
2418 | 7.62k | if (fcs_len != 0) { |
2419 | | /* |
2420 | | * Well, this packet should, in theory, have an FCS or CC24xx |
2421 | | * metadata. |
2422 | | * Do we have the entire packet, and does it have enough data for |
2423 | | * the FCS/metadata? |
2424 | | */ |
2425 | 402 | unsigned reported_len = tvb_reported_length(tvb); |
2426 | | |
2427 | 402 | if (reported_len < fcs_len) { |
2428 | | /* |
2429 | | * The packet is claimed not to even have enough data |
2430 | | * for the FCS/metadata. Pretend it doesn't have one. |
2431 | | */ |
2432 | 6 | no_fcs_tvb = tvb; |
2433 | 6 | fcs_present = false; |
2434 | 6 | fcs_ok = true; // assume OK if not present |
2435 | 396 | } else { |
2436 | | /* |
2437 | | * The packet is claimed to have enough data for the |
2438 | | * FCS/metadata. |
2439 | | * Slice it off from the reported length. |
2440 | | */ |
2441 | 396 | reported_len -= fcs_len; |
2442 | 396 | no_fcs_tvb = tvb_new_subset_length(tvb, 0, reported_len); |
2443 | | |
2444 | | /* |
2445 | | * Is the FCS/metadata present in the captured data? |
2446 | | * reported_len is now the length of the packet without the |
2447 | | * FCS/metadata, so the FCS/metadata begins at an offset of |
2448 | | * reported_len. |
2449 | | */ |
2450 | 396 | if (tvb_bytes_exist(tvb, reported_len, fcs_len)) { |
2451 | | /* |
2452 | | * Yes. Check whether the FCS was OK. |
2453 | | * |
2454 | | * If we have an FCS, check it. |
2455 | | * If we have metadata, check its "FCS OK" flag. |
2456 | | */ |
2457 | 396 | fcs_present = true; |
2458 | 396 | fcs_ok = options & DISSECT_IEEE802154_OPTION_CC24xx ? is_cc24xx_crc_ok(tvb) : is_fcs_ok(tvb, fcs_len); |
2459 | 396 | } else { |
2460 | | /* |
2461 | | * No. |
2462 | | * |
2463 | | * Either 1) this means that there was a snapshot length |
2464 | | * in effect when the capture was done, and that sliced |
2465 | | * some or all of the FCS/metadata off or 2) this is a |
2466 | | * capture with no FCS/metadata, using the same link-layer |
2467 | | * header type value as captures with the FCS/metadata, |
2468 | | * and indicating the lack of the FCS/metadata by having |
2469 | | * the captured length be the length of the packet minus |
2470 | | * the length of the FCS/metadata and the actual length |
2471 | | * being the length of the packet including the FCS/metadata, |
2472 | | * rather than by using the "no FCS" link-layer header type. |
2473 | | * |
2474 | | * We could try to distinguish between them by checking |
2475 | | * for a captured length that's exactly fcs_len bytes |
2476 | | * less than the actual length. That would allow us to |
2477 | | * report packets that are cut short just before, or in |
2478 | | * the middle of, the FCS as having been cut short by the |
2479 | | * snapshot length. |
2480 | | * |
2481 | | * However, we can't distinguish between a packet that |
2482 | | * happened to be cut fcs_len bytes short due to a |
2483 | | * snapshot length being in effect when the capture was |
2484 | | * done and a packet that *wasn't* cut short by a snapshot |
2485 | | * length but that doesn't include the FCS/metadata. |
2486 | | * Let's hope that rarely happens. |
2487 | | */ |
2488 | 0 | fcs_present = false; |
2489 | 0 | fcs_ok = true; // assume OK if not present |
2490 | 0 | } |
2491 | 396 | } |
2492 | 7.22k | } else { |
2493 | 7.22k | no_fcs_tvb = tvb; |
2494 | 7.22k | fcs_present = false; |
2495 | 7.22k | fcs_ok = true; // assume OK if not present |
2496 | 7.22k | } |
2497 | | |
2498 | 7.62k | unsigned mhr_len = ieee802154_dissect_header(no_fcs_tvb, pinfo, tree, 0, &ieee802154_tree, &packet); |
2499 | 7.62k | if (!mhr_len) { |
2500 | 25 | return; |
2501 | 25 | } |
2502 | | |
2503 | 7.60k | if ((packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE)) { |
2504 | 4.53k | _find_or_create_conversation(pinfo, &pinfo->dl_src, &pinfo->dl_dst); |
2505 | 4.53k | } |
2506 | | |
2507 | 7.60k | if (ieee802154_ack_tracking && (packet->ack_request || packet->frame_type == IEEE802154_FCF_ACK)) { |
2508 | 0 | uint32_t key[2] = {0}; |
2509 | |
|
2510 | 0 | key[0] = packet->seqno; |
2511 | 0 | if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) { |
2512 | 0 | key[1] = pinfo->rec->rec_header.packet_header.interface_id; |
2513 | 0 | } |
2514 | |
|
2515 | 0 | if (packet->ack_request) { |
2516 | 0 | transaction_start(pinfo, ieee802154_tree, packet, key); |
2517 | 0 | } |
2518 | 0 | else { |
2519 | 0 | transaction_end(pinfo, ieee802154_tree, packet, key); |
2520 | 0 | } |
2521 | 0 | } |
2522 | | |
2523 | 7.60k | tvbuff_t* payload = ieee802154_decrypt_payload(no_fcs_tvb, mhr_len, pinfo, ieee802154_tree, packet); |
2524 | 7.60k | if (payload) { |
2525 | 7.31k | unsigned pie_size = ieee802154_dissect_payload_ies(payload, pinfo, ieee802154_tree, packet); |
2526 | 7.31k | payload = tvb_new_subset_remaining(payload, pie_size); |
2527 | 7.31k | if (options & DISSECT_IEEE802154_OPTION_ZBOSS && packet->frame_type == IEEE802154_FCF_DATA) { |
2528 | 0 | if ((!fcs_ok && ieee802154_fcs_ok) || !tvb_reported_length(payload)) { |
2529 | 0 | call_data_dissector(payload, pinfo, tree); |
2530 | 0 | } else { |
2531 | 0 | call_dissector_with_data(zigbee_nwk_handle, payload, pinfo, tree, packet); |
2532 | 0 | } |
2533 | 7.31k | } else { |
2534 | 7.31k | ieee802154_dissect_frame_payload(payload, pinfo, ieee802154_tree, packet, fcs_ok); |
2535 | 7.31k | } |
2536 | 7.31k | } |
2537 | | |
2538 | 7.60k | if (fcs_present) { |
2539 | 143 | if (options & DISSECT_IEEE802154_OPTION_CC24xx) |
2540 | 0 | ieee802154_dissect_cc24xx_metadata(tvb, ieee802154_tree, fcs_ok); |
2541 | 143 | else |
2542 | 143 | ieee802154_dissect_fcs(tvb, ieee802154_tree, fcs_len, fcs_ok); |
2543 | | |
2544 | | /* If the CRC is invalid, make a note of it in the info column. */ |
2545 | 143 | if (!fcs_ok) { |
2546 | 141 | col_append_str(pinfo->cinfo, COL_INFO, ", Bad FCS"); |
2547 | 141 | proto_item_append_text(proto_tree_get_parent(ieee802154_tree), ", Bad FCS"); |
2548 | | |
2549 | | /* Flag packet as having a bad crc. */ |
2550 | 141 | expert_add_info(pinfo, proto_tree_get_parent(ieee802154_tree), &ei_ieee802154_fcs); |
2551 | 141 | } |
2552 | 7.45k | } else { |
2553 | 7.45k | if (ieee802154_tree) { |
2554 | | /* Even if the FCS isn't present, add the fcs_ok field to the tree to |
2555 | | * help with filter. Be sure not to make it visible though. |
2556 | | */ |
2557 | 6.92k | proto_item *ti = proto_tree_add_boolean_format_value(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, 0, 0, fcs_ok, "Unknown"); |
2558 | 6.92k | proto_item_set_hidden(ti); |
2559 | 6.92k | } |
2560 | 7.45k | } |
2561 | | |
2562 | 7.60k | tap_queue_packet(ieee802154_tap, pinfo, NULL); |
2563 | 7.60k | } |
2564 | | |
2565 | | unsigned |
2566 | | ieee802154_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned options, proto_tree **created_header_tree, ieee802154_packet **parsed_info) |
2567 | 7.62k | { |
2568 | 7.62k | proto_tree *ieee802154_tree = NULL; |
2569 | 7.62k | proto_item *proto_root = NULL; |
2570 | 7.62k | proto_item *hidden_item; |
2571 | 7.62k | proto_item *ti; |
2572 | 7.62k | unsigned offset = 0; |
2573 | 7.62k | ieee802154_packet *packet = wmem_new0(pinfo->pool, ieee802154_packet); |
2574 | 7.62k | ieee802154_short_addr addr16; |
2575 | 7.62k | ieee802154_hints_t *ieee_hints; |
2576 | | |
2577 | 7.62k | packet->short_table = ieee802154_map.short_table; |
2578 | | |
2579 | | /* Allocate frame data with hints for upper layers */ |
2580 | 7.62k | if (!PINFO_FD_VISITED(pinfo) || |
2581 | 7.62k | (ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0)) == NULL) { |
2582 | 7.62k | ieee_hints = wmem_new0(wmem_file_scope(), ieee802154_hints_t); |
2583 | 7.62k | p_add_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0, ieee_hints); |
2584 | 7.62k | } |
2585 | | |
2586 | | /* Save a pointer to the whole packet */ |
2587 | 7.62k | ieee_hints->packet = packet; |
2588 | | |
2589 | | /* Create the protocol tree. */ |
2590 | 7.62k | proto_root = proto_tree_add_protocol_format(tree, proto_ieee802154, tvb, 0, tvb_captured_length(tvb), "IEEE 802.15.4"); |
2591 | 7.62k | ieee802154_tree = proto_item_add_subtree(proto_root, ett_ieee802154); |
2592 | | /* Add the protocol name. */ |
2593 | 7.62k | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE 802.15.4"); |
2594 | | |
2595 | | /* Set out parameters */ |
2596 | 7.62k | *created_header_tree = ieee802154_tree; |
2597 | 7.62k | *parsed_info = packet; |
2598 | | |
2599 | | /* Add the packet length to the filter field */ |
2600 | 7.62k | hidden_item = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_frame_length, NULL, 0, 0, tvb_reported_length(tvb)); |
2601 | 7.62k | proto_item_set_hidden(hidden_item); |
2602 | | |
2603 | | /* Frame Control Field */ |
2604 | 7.62k | dissect_ieee802154_fcf(tvb, pinfo, ieee802154_tree, packet, &offset); |
2605 | | |
2606 | | /* Sequence Number */ |
2607 | 7.62k | if (packet->seqno_suppression) { |
2608 | 6.11k | if (packet->version != IEEE802154_VERSION_2015 && packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) { |
2609 | 5.38k | expert_add_info(pinfo, proto_root, &ei_ieee802154_seqno_suppression); |
2610 | 5.38k | } |
2611 | 6.11k | } else { /* IEEE 802.15.4 Sequence Number Suppression */ |
2612 | 1.51k | packet->seqno = tvb_get_uint8(tvb, offset); |
2613 | 1.51k | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_seqno, tvb, offset, 1, packet->seqno); |
2614 | | /* For Ack packets display this in the root. */ |
2615 | 1.51k | if (packet->frame_type == IEEE802154_FCF_ACK) { |
2616 | 9 | proto_item_append_text(proto_root, ", Sequence Number: %u", packet->seqno); |
2617 | 9 | } |
2618 | 1.51k | offset += 1; |
2619 | 1.51k | } |
2620 | | |
2621 | | /* |
2622 | | * ADDRESSING FIELDS |
2623 | | */ |
2624 | | /* Clear out the addressing strings. */ |
2625 | 7.62k | clear_address(&pinfo->net_dst); |
2626 | 7.62k | clear_address(&pinfo->dl_dst); |
2627 | 7.62k | clear_address(&pinfo->dst); |
2628 | 7.62k | clear_address(&pinfo->net_src); |
2629 | 7.62k | clear_address(&pinfo->dl_src); |
2630 | 7.62k | clear_address(&pinfo->src); |
2631 | | |
2632 | 7.62k | if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_RESERVED) { |
2633 | | /* Invalid Destination Address Mode. Abort Dissection. */ |
2634 | 4 | expert_add_info(pinfo, proto_root, &ei_ieee802154_dst); |
2635 | 4 | return 0; |
2636 | 4 | } |
2637 | | |
2638 | 7.62k | if (packet->src_addr_mode == IEEE802154_FCF_ADDR_RESERVED) { |
2639 | | /* Invalid Source Address Mode. Abort Dissection. */ |
2640 | 6 | expert_add_info(pinfo, proto_root, &ei_ieee802154_src); |
2641 | 6 | return 0; |
2642 | 6 | } |
2643 | | |
2644 | 7.61k | if (packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) { |
2645 | | /* Multipurpose frames have a different set of frame versions, with 0 as the only valid version */ |
2646 | 39 | if (packet->version != 0) { |
2647 | | /* Unknown Frame Version for Multipurpose frames. Abort Dissection */ |
2648 | 2 | expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver); |
2649 | 2 | return 0; |
2650 | 2 | } |
2651 | | |
2652 | | /* The source PAN ID is always omitted in multipurpose frames */ |
2653 | 37 | packet->src_pan_present = false; |
2654 | | |
2655 | 37 | if (packet->pan_id_present) { |
2656 | 31 | packet->dst_pan_present = true; |
2657 | 31 | } |
2658 | 37 | } |
2659 | 7.57k | else if (packet->version == IEEE802154_VERSION_RESERVED) { |
2660 | | /* Unknown Frame Version. Abort Dissection. */ |
2661 | 4 | expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver); |
2662 | 4 | return 0; |
2663 | 4 | } |
2664 | 7.57k | else if ((packet->version == IEEE802154_VERSION_2003) || /* For Frame Version 0b00 and */ |
2665 | 6.68k | (packet->version == IEEE802154_VERSION_2006)) { /* 0b01 effect defined in section 7.2.1.5 */ |
2666 | | |
2667 | 6.68k | if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* if both destination and source */ |
2668 | 4.83k | (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) { /* addressing information is present */ |
2669 | 4.33k | if (packet->pan_id_compression == 1) { /* PAN IDs are identical */ |
2670 | 9 | packet->dst_pan_present = true; |
2671 | 9 | packet->src_pan_present = false; /* source PAN ID is omitted */ |
2672 | 9 | } |
2673 | 4.32k | else { /* PAN IDs are different, both shall be included in the frame */ |
2674 | 4.32k | packet->dst_pan_present = true; |
2675 | 4.32k | packet->src_pan_present = true; |
2676 | 4.32k | } |
2677 | 4.33k | } |
2678 | 2.35k | else { |
2679 | 2.35k | if (packet->pan_id_compression == 1) { /* all remaining cases pan_id_compression must be zero */ |
2680 | 9 | expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_panid_compression); |
2681 | 9 | return 0; |
2682 | 9 | } |
2683 | 2.34k | else { |
2684 | | /* only either the destination or the source addressing information is present */ |
2685 | 2.34k | if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */ |
2686 | 496 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) { /* Not Present */ |
2687 | 496 | packet->dst_pan_present = true; |
2688 | 496 | packet->src_pan_present = false; |
2689 | 496 | } |
2690 | 1.84k | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2691 | 1.84k | (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE)) { /* Present */ |
2692 | 1.60k | packet->dst_pan_present = false; |
2693 | 1.60k | packet->src_pan_present = true; |
2694 | 1.60k | } |
2695 | 247 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2696 | 247 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE)) { /* Not Present */ |
2697 | 247 | packet->dst_pan_present = false; |
2698 | 247 | packet->src_pan_present = false; |
2699 | 247 | } |
2700 | 0 | else { |
2701 | 0 | expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_addressing); |
2702 | 0 | return 0; |
2703 | 0 | } |
2704 | 2.34k | } |
2705 | 2.35k | } |
2706 | 6.68k | } |
2707 | 885 | else if (packet->version == IEEE802154_VERSION_2015) { |
2708 | | /* for Frame Version 0b10 PAN Id Compression only applies to these frame types */ |
2709 | 873 | if ((packet->frame_type == IEEE802154_FCF_BEACON) || |
2710 | 672 | (packet->frame_type == IEEE802154_FCF_DATA) || |
2711 | 78 | (packet->frame_type == IEEE802154_FCF_ACK) || |
2712 | 830 | (packet->frame_type == IEEE802154_FCF_CMD) ) { |
2713 | | |
2714 | | /* Implements Table 7-6 of IEEE 802.15.4-2015 |
2715 | | * |
2716 | | * Destination Address Source Address Destination PAN ID Source PAN ID PAN ID Compression |
2717 | | *------------------------------------------------------------------------------------------------- |
2718 | | * 1. Not Present Not Present Not Present Not Present 0 |
2719 | | * 2. Not Present Not Present Present Not Present 1 |
2720 | | * 3. Present Not Present Present Not Present 0 |
2721 | | * 4. Present Not Present Not Present Not Present 1 |
2722 | | * |
2723 | | * 5. Not Present Present Not Present Present 0 |
2724 | | * 6. Not Present Present Not Present Not Present 1 |
2725 | | * |
2726 | | * 7. Extended Extended Present Not Present 0 |
2727 | | * 8. Extended Extended Not Present Not Present 1 |
2728 | | * |
2729 | | * 9. Short Short Present Present 0 |
2730 | | * 10. Short Extended Present Present 0 |
2731 | | * 11. Extended Short Present Present 0 |
2732 | | * |
2733 | | * 12. Short Extended Present Not Present 1 |
2734 | | * 13. Extended Short Present Not Present 1 |
2735 | | * 14. Short Short Present Not Present 1 |
2736 | | */ |
2737 | | |
2738 | | /* Row 1 */ |
2739 | 830 | if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2740 | 117 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2741 | 90 | (packet->pan_id_compression == 0)) { |
2742 | 84 | packet->dst_pan_present = false; |
2743 | 84 | packet->src_pan_present = false; |
2744 | 84 | } |
2745 | | /* Row 2 */ |
2746 | 746 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2747 | 33 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2748 | 6 | (packet->pan_id_compression == 1)) { |
2749 | 6 | packet->dst_pan_present = true; |
2750 | 6 | packet->src_pan_present = false; |
2751 | 6 | } |
2752 | | /* Row 3 */ |
2753 | 740 | else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */ |
2754 | 713 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2755 | 460 | (packet->pan_id_compression == 0)) { |
2756 | 453 | packet->dst_pan_present = true; |
2757 | 453 | packet->src_pan_present = false; |
2758 | 453 | } |
2759 | | /* Row 4 */ |
2760 | 287 | else if ((packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */ |
2761 | 260 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2762 | 7 | (packet->pan_id_compression == 1)) { |
2763 | 7 | packet->dst_pan_present = false; |
2764 | 7 | packet->src_pan_present = false; |
2765 | 7 | } |
2766 | | /* Row 5 */ |
2767 | 280 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2768 | 27 | (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */ |
2769 | 27 | (packet->pan_id_compression == 0)) { |
2770 | 24 | packet->dst_pan_present = false; |
2771 | 24 | packet->src_pan_present = true; |
2772 | 24 | } |
2773 | | /* Row 6 */ |
2774 | 256 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && /* Not Present */ |
2775 | 3 | (packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE) && /* Present */ |
2776 | 3 | (packet->pan_id_compression == 1)) { |
2777 | 3 | packet->dst_pan_present = false; |
2778 | 3 | packet->src_pan_present = false; |
2779 | 3 | } |
2780 | | /* Row 7 */ |
2781 | 253 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2782 | 181 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2783 | 22 | (packet->pan_id_compression == 0)) { |
2784 | 17 | packet->dst_pan_present = true; |
2785 | 17 | packet->src_pan_present = false; |
2786 | 17 | } |
2787 | | /* Row 8 */ |
2788 | 236 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2789 | 164 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2790 | 5 | (packet->pan_id_compression == 1)) { |
2791 | 5 | packet->dst_pan_present = false; |
2792 | 5 | packet->src_pan_present = false; |
2793 | 5 | } |
2794 | | /* Row 9 */ |
2795 | 231 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2796 | 72 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2797 | 60 | (packet->pan_id_compression == 0)) { |
2798 | 58 | packet->dst_pan_present = true; |
2799 | 58 | packet->src_pan_present = (ieee802154e_compatibility ? false : true); |
2800 | 58 | } |
2801 | | /* Row 10 */ |
2802 | 173 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2803 | 14 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2804 | 12 | (packet->pan_id_compression == 0)) { |
2805 | 9 | packet->dst_pan_present = true; |
2806 | 9 | packet->src_pan_present = (ieee802154e_compatibility ? false : true); |
2807 | 9 | } |
2808 | | /* Row 11 */ |
2809 | 164 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2810 | 159 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2811 | 159 | (packet->pan_id_compression == 0)) { |
2812 | 157 | packet->dst_pan_present = true; |
2813 | 157 | packet->src_pan_present = (ieee802154e_compatibility ? false : true); |
2814 | 157 | } |
2815 | | /* Row 12 */ |
2816 | 7 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2817 | 5 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2818 | 3 | (packet->pan_id_compression == 1)) { |
2819 | 3 | packet->dst_pan_present = true; |
2820 | 3 | packet->src_pan_present = false; |
2821 | 3 | } |
2822 | | /* Row 13 */ |
2823 | 4 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) && /* Extended */ |
2824 | 2 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2825 | 2 | (packet->pan_id_compression == 1)) { |
2826 | 2 | packet->dst_pan_present = true; |
2827 | 2 | packet->src_pan_present = false; |
2828 | 2 | } |
2829 | | /* Row 14 */ |
2830 | 2 | else if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2831 | 2 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && /* Short */ |
2832 | 2 | (packet->pan_id_compression == 1)) { |
2833 | 2 | packet->dst_pan_present = true; |
2834 | 2 | packet->src_pan_present = false; |
2835 | 2 | } |
2836 | 0 | else { |
2837 | 0 | expert_add_info(pinfo, proto_root, &ei_ieee802154_invalid_panid_compression2); |
2838 | 0 | return 0; |
2839 | 0 | } |
2840 | 830 | } |
2841 | 43 | else { /* Frame Type is neither Beacon, Data, Ack, nor Command: PAN ID Compression is not used */ |
2842 | 43 | packet->dst_pan_present = false; /* no PAN ID will */ |
2843 | 43 | packet->src_pan_present = false; /* be present */ |
2844 | 43 | } |
2845 | 873 | } |
2846 | 12 | else { |
2847 | | /* Unknown Frame Version. Abort Dissection. */ |
2848 | 12 | expert_add_info(pinfo, proto_root, &ei_ieee802154_frame_ver); |
2849 | 12 | return 0; |
2850 | 12 | } |
2851 | | |
2852 | | /* |
2853 | | * Addressing Fields |
2854 | | */ |
2855 | | |
2856 | | /* Destination PAN Id */ |
2857 | 7.58k | if (packet->dst_pan_present) { |
2858 | 5.56k | packet->dst_pan = tvb_get_letohs(tvb, offset); |
2859 | 5.56k | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst_panID, tvb, offset, 2, packet->dst_pan); |
2860 | 5.56k | offset += 2; |
2861 | 5.56k | } |
2862 | | |
2863 | | /* Destination Address */ |
2864 | 7.58k | if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
2865 | | /* Get the address. */ |
2866 | 4.43k | packet->dst16 = tvb_get_letohs(tvb, offset); |
2867 | | |
2868 | | /* Provide address hints to higher layers that need it. */ |
2869 | 4.43k | ieee_hints->dst16 = packet->dst16; |
2870 | | |
2871 | 4.43k | set_address_tvb(&pinfo->dl_dst, ieee802_15_4_short_address_type, 2, tvb, offset); |
2872 | 4.43k | copy_address_shallow(&pinfo->dst, &pinfo->dl_dst); |
2873 | | |
2874 | 4.43k | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_dst16, tvb, offset, 2, packet->dst16); |
2875 | 4.43k | ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_addr16, tvb, offset, 2, packet->dst16); |
2876 | 4.43k | proto_item_set_generated(ti); |
2877 | 4.43k | proto_item_set_hidden(ti); |
2878 | | |
2879 | 4.43k | offset += 2; |
2880 | 4.43k | } |
2881 | 3.15k | else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
2882 | 1.14k | uint64_t *p_addr = (uint64_t *)wmem_new(pinfo->pool, uint64_t); |
2883 | | |
2884 | | /* Get the address */ |
2885 | 1.14k | packet->dst64 = tvb_get_letoh64(tvb, offset); |
2886 | | |
2887 | | /* Copy and convert the address to network byte order. */ |
2888 | 1.14k | *p_addr = pntohu64(&(packet->dst64)); |
2889 | | |
2890 | | /* Display the destination address. */ |
2891 | | /* XXX - OUI resolution doesn't happen when displaying resolved |
2892 | | * EUI64 addresses; that should probably be fixed in |
2893 | | * epan/addr_resolv.c. |
2894 | | */ |
2895 | 1.14k | set_address(&pinfo->dl_dst, AT_EUI64, 8, p_addr); |
2896 | 1.14k | copy_address_shallow(&pinfo->dst, &pinfo->dl_dst); |
2897 | 1.14k | proto_tree_add_item(ieee802154_tree, hf_ieee802154_dst64, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
2898 | 1.14k | ti = proto_tree_add_item(ieee802154_tree, hf_ieee802154_addr64, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
2899 | 1.14k | proto_item_set_generated(ti); |
2900 | 1.14k | proto_item_set_hidden(ti); |
2901 | | |
2902 | 1.14k | offset += 8; |
2903 | 1.14k | } |
2904 | | |
2905 | | /* Source PAN Id */ |
2906 | 7.58k | if (packet->src_pan_present) { |
2907 | 6.16k | packet->src_pan = tvb_get_letohs(tvb, offset); |
2908 | 6.16k | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src_panID, tvb, offset, 2, packet->src_pan); |
2909 | 6.16k | offset += 2; |
2910 | 6.16k | } |
2911 | 1.42k | else { |
2912 | 1.42k | if (packet->dst_pan_present) { |
2913 | 986 | packet->src_pan = packet->dst_pan; |
2914 | 986 | } |
2915 | 438 | else { |
2916 | 438 | packet->src_pan = IEEE802154_BCAST_PAN; |
2917 | 438 | } |
2918 | 1.42k | } |
2919 | 7.58k | ieee_hints->src_pan = packet->src_pan; |
2920 | | |
2921 | | /* Source Address */ |
2922 | 7.58k | if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
2923 | | /* Get the address. */ |
2924 | 5.63k | packet->src16 = tvb_get_letohs(tvb, offset); |
2925 | | |
2926 | 5.63k | if (!PINFO_FD_VISITED(pinfo)) { |
2927 | | /* If we know our extended source address from previous packets, |
2928 | | * provide a pointer to it in a hint for upper layers */ |
2929 | 5.63k | addr16.addr = packet->src16; |
2930 | 5.63k | addr16.pan = packet->src_pan; |
2931 | | |
2932 | 5.63k | ieee_hints->src16 = packet->src16; |
2933 | 5.63k | ieee_hints->map_rec = (ieee802154_map_rec *) |
2934 | 5.63k | g_hash_table_lookup(ieee802154_map.short_table, &addr16); |
2935 | 5.63k | } |
2936 | | |
2937 | 5.63k | set_address_tvb(&pinfo->dl_src, ieee802_15_4_short_address_type, 2, tvb, offset); |
2938 | 5.63k | copy_address_shallow(&pinfo->src, &pinfo->dl_src); |
2939 | | |
2940 | | /* Add the addressing info to the tree. */ |
2941 | 5.63k | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src16, tvb, offset, 2, packet->src16); |
2942 | 5.63k | ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_addr16, tvb, offset, 2, packet->src16); |
2943 | 5.63k | proto_item_set_generated(ti); |
2944 | 5.63k | proto_item_set_hidden(ti); |
2945 | | |
2946 | 5.63k | if (ieee_hints->map_rec) { |
2947 | | /* Display inferred source address info */ |
2948 | 0 | ti = proto_tree_add_eui64(ieee802154_tree, hf_ieee802154_src64, tvb, offset, 0, |
2949 | 0 | ieee_hints->map_rec->addr64); |
2950 | 0 | proto_item_set_generated(ti); |
2951 | 0 | ti = proto_tree_add_eui64(ieee802154_tree, hf_ieee802154_addr64, tvb, offset, 0, ieee_hints->map_rec->addr64); |
2952 | 0 | proto_item_set_generated(ti); |
2953 | 0 | proto_item_set_hidden(ti); |
2954 | |
|
2955 | 0 | if ( ieee_hints->map_rec->start_fnum ) { |
2956 | 0 | ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_src64_origin, tvb, 0, 0, |
2957 | 0 | ieee_hints->map_rec->start_fnum); |
2958 | 0 | } |
2959 | 0 | else { |
2960 | 0 | ti = proto_tree_add_uint_format_value(ieee802154_tree, hf_ieee802154_src64_origin, tvb, 0, 0, |
2961 | 0 | ieee_hints->map_rec->start_fnum, "Pre-configured"); |
2962 | 0 | } |
2963 | 0 | proto_item_set_generated(ti); |
2964 | 0 | } |
2965 | | |
2966 | 5.63k | offset += 2; |
2967 | 5.63k | } |
2968 | 1.94k | else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
2969 | 574 | uint64_t *p_addr = (uint64_t *)wmem_new(pinfo->pool, uint64_t); |
2970 | | |
2971 | | /* Get the address. */ |
2972 | 574 | packet->src64 = tvb_get_letoh64(tvb, offset); |
2973 | | |
2974 | | /* Copy and convert the address to network byte order. */ |
2975 | 574 | *p_addr = pntohu64(&(packet->src64)); |
2976 | | |
2977 | | /* Display the source address. */ |
2978 | | /* XXX - OUI resolution doesn't happen when displaying resolved |
2979 | | * EUI64 addresses; that should probably be fixed in |
2980 | | * epan/addr_resolv.c. |
2981 | | */ |
2982 | 574 | set_address(&pinfo->dl_src, AT_EUI64, 8, p_addr); |
2983 | 574 | copy_address_shallow(&pinfo->src, &pinfo->dl_src); |
2984 | 574 | proto_tree_add_item(ieee802154_tree, hf_ieee802154_src64, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
2985 | 574 | ti = proto_tree_add_item(ieee802154_tree, hf_ieee802154_addr64, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
2986 | 574 | proto_item_set_generated(ti); |
2987 | 574 | proto_item_set_hidden(ti); |
2988 | | |
2989 | 574 | offset += 8; |
2990 | 574 | } |
2991 | | |
2992 | | /* Add the addressing info to the root of the tree. */ |
2993 | 7.58k | if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
2994 | 5.63k | proto_item_append_text(proto_root, ", Src: %s", address_to_str(pinfo->pool, &pinfo->src)); |
2995 | 5.63k | col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", address_to_str(pinfo->pool, &pinfo->src)); |
2996 | 5.63k | } |
2997 | 1.95k | else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
2998 | 573 | proto_item_append_text(proto_root, ", Src: %s", eui64_to_display(pinfo->pool, packet->src64)); |
2999 | 573 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: %s", eui64_to_display(pinfo->pool, packet->src64)); |
3000 | 573 | } |
3001 | | |
3002 | 7.58k | if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
3003 | 4.43k | proto_item_append_text(proto_root, ", Dst: %s", address_to_str(pinfo->pool, &pinfo->dst)); |
3004 | 4.43k | col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", address_to_str(pinfo->pool, &pinfo->dst)); |
3005 | 4.43k | } |
3006 | 3.15k | else if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
3007 | 1.13k | proto_item_append_text(proto_root, ", Dst: %s", eui64_to_display(pinfo->pool, packet->dst64)); |
3008 | 1.13k | col_append_fstr(pinfo->cinfo, COL_INFO, ", Dst: %s", eui64_to_display(pinfo->pool, packet->dst64)); |
3009 | 1.13k | } |
3010 | | |
3011 | | /* Existence of the Auxiliary Security Header is controlled by the Security Enabled Field */ |
3012 | 7.58k | if (packet->security_enable && |
3013 | 55 | ((packet->frame_type == IEEE802154_FCF_MULTIPURPOSE) || (packet->version != IEEE802154_VERSION_2003)) && |
3014 | 47 | !(options & IEEE802154_DISSECT_HEADER_OPTION_NO_AUX_SEC_HDR)) |
3015 | 47 | { |
3016 | 47 | dissect_ieee802154_aux_sec_header_and_key(tvb, pinfo, ieee802154_tree, packet, &offset); |
3017 | 47 | } |
3018 | | |
3019 | | /* |
3020 | | * NONPAYLOAD FIELDS |
3021 | | * |
3022 | | */ |
3023 | | /* All of the beacon fields, except the beacon payload are considered nonpayload. */ |
3024 | 7.58k | if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && ((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006))) { |
3025 | 6.63k | if (tvb_reported_length(tvb) > offset) { |
3026 | 6.62k | if (packet->frame_type == IEEE802154_FCF_BEACON) { /* Regular Beacon. Some are not present in frame version (Enhanced) Beacons */ |
3027 | 226 | dissect_ieee802154_superframe(tvb, pinfo, ieee802154_tree, &offset); /* superframe spec */ |
3028 | 226 | dissect_ieee802154_gtsinfo(tvb, pinfo, ieee802154_tree, &offset); /* GTS information fields */ |
3029 | 226 | dissect_ieee802154_pendaddr(tvb, pinfo, ieee802154_tree, &offset); /* Pending address list */ |
3030 | 226 | } |
3031 | 6.62k | } |
3032 | | |
3033 | 6.63k | if (packet->frame_type == IEEE802154_FCF_CMD) { |
3034 | | /** |
3035 | | * In IEEE802.15.4-2003 and 2006 the command identifier is considered to be part of the header |
3036 | | * and is thus not encrypted. For IEEE802.15.4-2012e and later the command id is considered to be |
3037 | | * part of the payload, is encrypted, and follows the payload IEs. Thus we only parse the command id |
3038 | | * here for 2006 and earlier frames. */ |
3039 | 34 | packet->command_id = tvb_get_uint8(tvb, offset); |
3040 | 34 | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_cmd_id, tvb, offset, 1, packet->command_id); |
3041 | 34 | offset++; |
3042 | | |
3043 | | /* Display the command identifier in the info column. */ |
3044 | 34 | col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command")); |
3045 | 34 | } |
3046 | 6.63k | } |
3047 | 950 | else { |
3048 | 950 | if (packet->ie_present) { |
3049 | 415 | offset += dissect_ieee802154_header_ie(tvb, pinfo, ieee802154_tree, offset, packet); |
3050 | 415 | } |
3051 | 950 | } |
3052 | | |
3053 | | /* IEEE 802.15.4-2003 may have security information pre-pended to payload */ |
3054 | 7.58k | if (packet->security_enable && (packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003)) |
3055 | 8 | { |
3056 | | /* Store security suite preference in the 2006 security level identifier to simplify 2003 integration! */ |
3057 | 8 | packet->security_level = (ieee802154_security_level)ieee802154_sec_suite; |
3058 | | |
3059 | | /* Frame Counter and Key Sequence Counter prepended to the payload of an encrypted frame */ |
3060 | 8 | if (IEEE802154_IS_ENCRYPTED(packet->security_level)) { |
3061 | 8 | packet->frame_counter = tvb_get_letohl (tvb, offset); |
3062 | 8 | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_sec_frame_counter, tvb, offset, (int)sizeof(uint32_t), packet->frame_counter); |
3063 | 8 | offset += (int)sizeof(uint32_t); |
3064 | | |
3065 | 8 | packet->key_sequence_counter = tvb_get_uint8 (tvb, offset); |
3066 | 8 | proto_tree_add_uint(ieee802154_tree, hf_ieee802154_sec_key_sequence_counter, tvb, offset, (int)sizeof(uint8_t), packet->key_sequence_counter); |
3067 | 8 | offset += (int)sizeof(uint8_t); |
3068 | 8 | } |
3069 | 8 | } |
3070 | | |
3071 | 7.58k | return offset; |
3072 | 7.61k | } |
3073 | | |
3074 | | /* |
3075 | | * XXX - "mhr_len" is really a general offset; this is used elsewhere. |
3076 | | */ |
3077 | | tvbuff_t* |
3078 | | ieee802154_decrypt_payload(tvbuff_t *tvb, unsigned mhr_len, packet_info *pinfo, proto_tree *ieee802154_tree, ieee802154_packet *packet) |
3079 | 7.40k | { |
3080 | 7.40k | proto_item *proto_root = proto_tree_get_parent(ieee802154_tree); |
3081 | 7.40k | proto_tree *tree = proto_tree_get_parent_tree(ieee802154_tree); |
3082 | 7.40k | unsigned char rx_mic[IEEE802154_CIPHER_SIZE]; |
3083 | 7.40k | unsigned rx_mic_len = IEEE802154_MIC_LENGTH(packet->security_level); |
3084 | 7.40k | ieee802154_decrypt_status status = DECRYPT_NOT_ENCRYPTED; |
3085 | 7.40k | tvbuff_t *payload_tvb; |
3086 | | |
3087 | 7.40k | unsigned id2 = proto_get_id_by_short_name("TREL"); |
3088 | 7.40k | wmem_list_frame_t* ptr2 = wmem_list_find(pinfo->layers, GUINT_TO_POINTER(id2)); |
3089 | | |
3090 | | /* Encrypted Payload. */ |
3091 | 7.40k | if (packet->security_enable || ptr2) { |
3092 | 35 | ieee802154_decrypt_info_t decrypt_info; |
3093 | | |
3094 | 35 | decrypt_info.rx_mic = rx_mic; |
3095 | 35 | decrypt_info.rx_mic_length = &rx_mic_len; |
3096 | 35 | decrypt_info.status = &status; |
3097 | | |
3098 | 35 | if (ptr2) // if this pointer is not null that mean we found trel |
3099 | 0 | payload_tvb = decrypt_ieee802154_payload(tvb, mhr_len, pinfo, NULL, packet, &decrypt_info, |
3100 | 0 | ieee802154_set_trel_key, dissect_ieee802154_decrypt); |
3101 | 35 | else |
3102 | | // call with NULL tree since we add the key_number below without hiding it |
3103 | 35 | payload_tvb = decrypt_ieee802154_payload(tvb, mhr_len, pinfo, NULL, packet, &decrypt_info, |
3104 | 35 | ieee802154_set_mac_key, dissect_ieee802154_decrypt); |
3105 | | |
3106 | | /* Get the unencrypted data if decryption failed. */ |
3107 | 35 | if (!payload_tvb) { |
3108 | | /* Deal with possible truncation and the MIC field at the end. */ |
3109 | 35 | int reported_len = tvb_reported_length(tvb)-mhr_len-rx_mic_len; |
3110 | 35 | payload_tvb = tvb_new_subset_length(tvb, mhr_len, reported_len); |
3111 | 35 | } |
3112 | | |
3113 | | /* Display the MIC. */ |
3114 | 35 | if (rx_mic_len) { |
3115 | 12 | if (tvb_bytes_exist(tvb, tvb_reported_length(tvb) - rx_mic_len, rx_mic_len)) { |
3116 | 9 | proto_tree_add_item(ieee802154_tree, hf_ieee802154_mic, tvb, tvb_reported_length(tvb)-rx_mic_len, rx_mic_len, ENC_NA); |
3117 | 9 | } |
3118 | 12 | } |
3119 | | |
3120 | | /* Display the reason for failure, and abort if the error was fatal. */ |
3121 | 35 | switch (status) { |
3122 | 0 | case DECRYPT_PACKET_SUCCEEDED: |
3123 | 0 | { |
3124 | 0 | proto_item *pi = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_key_number, tvb, 0, 0, decrypt_info.key_number); |
3125 | 0 | proto_item_set_generated(pi); |
3126 | 0 | break; |
3127 | 0 | } |
3128 | 0 | case DECRYPT_NOT_ENCRYPTED: |
3129 | 0 | break; // nothing to do |
3130 | | |
3131 | 0 | case DECRYPT_FRAME_COUNTER_SUPPRESSION_UNSUPPORTED: |
3132 | 0 | expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Decryption of 802.15.4-2015 with frame counter suppression is not supported"); |
3133 | 0 | call_data_dissector(payload_tvb, pinfo, tree); |
3134 | 0 | return NULL; |
3135 | | |
3136 | 0 | case DECRYPT_PACKET_TOO_SMALL: |
3137 | 0 | expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Packet was too small to include the CRC and MIC"); |
3138 | 0 | call_data_dissector(payload_tvb, pinfo, tree); |
3139 | 0 | return NULL; |
3140 | | |
3141 | 0 | case DECRYPT_PACKET_NO_EXT_SRC_ADDR: |
3142 | 0 | expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "No extended source address - can't decrypt"); |
3143 | 0 | call_data_dissector(payload_tvb, pinfo, tree); |
3144 | 0 | return NULL; |
3145 | | |
3146 | 26 | case DECRYPT_PACKET_NO_KEY: |
3147 | 26 | expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "No encryption key set - can't decrypt"); |
3148 | 26 | call_data_dissector(payload_tvb, pinfo, tree); |
3149 | 26 | return NULL; |
3150 | | |
3151 | 0 | case DECRYPT_PACKET_DECRYPT_FAILED: |
3152 | 0 | expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "Decrypt failed"); |
3153 | 0 | call_data_dissector(payload_tvb, pinfo, tree); |
3154 | 0 | return NULL; |
3155 | | |
3156 | 0 | case DECRYPT_PACKET_MIC_CHECK_FAILED: |
3157 | 0 | expert_add_info_format(pinfo, proto_root, &ei_ieee802154_decrypt_error, "MIC check failed"); |
3158 | | /* |
3159 | | * Abort only if the payload was encrypted, in which case we |
3160 | | * probably didn't decrypt the packet right (eg: wrong key). |
3161 | | */ |
3162 | 0 | if (IEEE802154_IS_ENCRYPTED(packet->security_level)) { |
3163 | 0 | call_data_dissector(payload_tvb, pinfo, tree); |
3164 | 0 | return NULL; |
3165 | 0 | } |
3166 | 0 | break; |
3167 | 35 | } |
3168 | 35 | } |
3169 | | /* Plaintext Payload. */ |
3170 | 7.36k | else { |
3171 | | /* Deal with possible truncation. */ |
3172 | 7.36k | int reported_len = tvb_reported_length(tvb)-mhr_len; |
3173 | 7.36k | payload_tvb = tvb_new_subset_length(tvb, mhr_len, reported_len); |
3174 | 7.36k | } |
3175 | | |
3176 | 7.36k | return payload_tvb; |
3177 | 7.40k | } |
3178 | | |
3179 | | |
3180 | | unsigned ieee802154_dissect_payload_ies(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ieee802154_tree, ieee802154_packet *packet) |
3181 | 7.31k | { |
3182 | | /* Presence of Payload IEs is defined by the termination of the Header IEs */ |
3183 | 7.31k | if (packet->payload_ie_present) { |
3184 | 277 | if (tvb_reported_length(tvb) > 2) { |
3185 | 275 | return (unsigned) dissect_ieee802154_payload_ie(tvb, pinfo, ieee802154_tree, 0, packet); |
3186 | 275 | } else { |
3187 | 2 | expert_add_info(pinfo, proto_tree_get_parent(ieee802154_tree), &ei_ieee802154_missing_payload_ie); |
3188 | 2 | } |
3189 | 277 | } |
3190 | 7.03k | return 0; |
3191 | 7.31k | } |
3192 | | |
3193 | | |
3194 | | unsigned ieee802154_dissect_frame_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ieee802154_tree, ieee802154_packet *packet, bool fcs_ok) |
3195 | 7.04k | { |
3196 | 7.04k | tvbuff_t *payload_tvb = tvb; |
3197 | 7.04k | proto_tree *tree = proto_tree_get_parent_tree(ieee802154_tree); |
3198 | 7.04k | heur_dtbl_entry_t *hdtbl_entry; |
3199 | | |
3200 | | /* There are commands without payload */ |
3201 | 7.04k | if (tvb_captured_length(payload_tvb) > 0 || packet->frame_type == IEEE802154_FCF_CMD) { |
3202 | | /* |
3203 | | * Wrap the sub-dissection in a try/catch block in case the payload is |
3204 | | * broken. First we store the current protocol so we can fix it if an |
3205 | | * exception is thrown by the subdissectors. |
3206 | | */ |
3207 | 7.02k | const char* saved_proto = pinfo->current_proto; |
3208 | | /* Try to dissect the payload. */ |
3209 | 7.02k | TRY { |
3210 | 7.02k | switch (packet->frame_type) { |
3211 | 170 | case IEEE802154_FCF_BEACON: |
3212 | 170 | if (!dissector_try_heuristic(ieee802154_beacon_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) { |
3213 | 153 | unsigned offset; |
3214 | 153 | offset = dissect_zbee_tlvs(payload_tvb, pinfo, tree, 0, NULL, ZBEE_TLV_SRC_TYPE_DEFAULT, 0); |
3215 | 153 | if (tvb_captured_length_remaining(payload_tvb, offset) > 0) |
3216 | 30 | { |
3217 | 30 | tvbuff_t *payload_tvb_remaining; |
3218 | 30 | payload_tvb_remaining = tvb_new_subset_remaining(payload_tvb, offset); |
3219 | | /* Could not subdissect, call the data dissector instead. */ |
3220 | 30 | call_data_dissector(payload_tvb_remaining, pinfo, tree); |
3221 | 30 | } |
3222 | 153 | } |
3223 | 170 | break; |
3224 | | |
3225 | 43 | case IEEE802154_FCF_CMD: |
3226 | 43 | dissect_ieee802154_command(payload_tvb, pinfo, ieee802154_tree, packet); |
3227 | 43 | break; |
3228 | | |
3229 | 6.80k | case IEEE802154_FCF_DATA: |
3230 | | /* Sanity-check. */ |
3231 | 6.80k | if ((!fcs_ok && ieee802154_fcs_ok) || !tvb_reported_length(payload_tvb)) { |
3232 | 16 | call_data_dissector(payload_tvb, pinfo, tree); |
3233 | 16 | break; |
3234 | 16 | } |
3235 | | /* Try the PANID dissector table for stateful dissection. */ |
3236 | 6.78k | if (dissector_try_uint_with_data(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, true, packet)) { |
3237 | 0 | break; |
3238 | 0 | } |
3239 | | /* Try again with the destination PANID (if different) */ |
3240 | 6.78k | if (((packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) || |
3241 | 2.51k | (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) && |
3242 | 5.08k | (packet->dst_pan != packet->src_pan) && |
3243 | 4.21k | dissector_try_uint_with_data(panid_dissector_table, packet->src_pan, payload_tvb, pinfo, tree, true, packet)) { |
3244 | 0 | break; |
3245 | 0 | } |
3246 | | /* Try heuristic dissection. */ |
3247 | 6.78k | if (dissector_try_heuristic(ieee802154_heur_subdissector_list, payload_tvb, pinfo, tree, &hdtbl_entry, packet)) break; |
3248 | | /* Fall-through to dump undissectable payloads. */ |
3249 | | /* FALL THROUGH */ |
3250 | 3.38k | default: |
3251 | | /* Could not subdissect, call the data dissector instead. */ |
3252 | 3.38k | call_data_dissector(payload_tvb, pinfo, tree); |
3253 | 7.02k | } /* switch */ |
3254 | 7.02k | } |
3255 | 3.59k | CATCH_ALL { |
3256 | | /* |
3257 | | * Someone encountered an error while dissecting the payload. But |
3258 | | * we haven't yet finished processing all of our layer. Catch and |
3259 | | * display the exception, then fall-through to finish displaying |
3260 | | * the FCS (which we display last so the frame is ordered correctly |
3261 | | * in the tree). |
3262 | | */ |
3263 | 3.42k | show_exception(payload_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); |
3264 | 3.42k | pinfo->current_proto = saved_proto; |
3265 | 3.42k | } |
3266 | 3.59k | ENDTRY; |
3267 | 3.59k | } |
3268 | 3.61k | return tvb_captured_length(tvb); |
3269 | 7.04k | } |
3270 | | |
3271 | | /** |
3272 | | * Dissect the FCS at the end of the frame. |
3273 | | * That is only displayed if the included length of the tvb encompasses it. |
3274 | | * |
3275 | | * @param tvb the 802.15.4 frame tvb |
3276 | | * @param ieee802154_tree the 802.15.4 protocol tree |
3277 | | * @param fcs_len length of the FCS field |
3278 | | * @param fcs_ok set to false to indicate FCS verification failed |
3279 | | */ |
3280 | | static void |
3281 | | ieee802154_dissect_fcs(tvbuff_t *tvb, proto_tree *ieee802154_tree, unsigned fcs_len, bool fcs_ok) |
3282 | 143 | { |
3283 | 143 | proto_item *ti; |
3284 | | /* The FCS should be the last bytes of the reported packet. */ |
3285 | 143 | unsigned offset = tvb_reported_length(tvb)-fcs_len; |
3286 | | /* Dissect the FCS only if it exists (captures which don't or can't get the |
3287 | | * FCS will simply truncate the packet to omit it, but should still set the |
3288 | | * reported length to cover the original packet length), so if the snapshot |
3289 | | * is too short for an FCS don't make a fuss. |
3290 | | */ |
3291 | 143 | if (ieee802154_tree) { |
3292 | 143 | if (fcs_len == 2) { |
3293 | 143 | uint16_t fcs = tvb_get_letohs(tvb, offset); |
3294 | | |
3295 | 143 | ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_fcs, tvb, offset, 2, fcs); |
3296 | 143 | if (fcs_ok) { |
3297 | 2 | proto_item_append_text(ti, " (Correct)"); |
3298 | 2 | } |
3299 | 141 | else { |
3300 | 141 | proto_item_append_text(ti, " (Incorrect, expected FCS=0x%04x)", ieee802154_crc_tvb(tvb, offset)); |
3301 | 141 | } |
3302 | | /* To Help with filtering, add the fcs_ok field to the tree. */ |
3303 | 143 | ti = proto_tree_add_boolean(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, offset, 2, (uint64_t) fcs_ok); |
3304 | 143 | proto_item_set_hidden(ti); |
3305 | 143 | } |
3306 | 0 | else { |
3307 | 0 | uint32_t fcs = tvb_get_letohl(tvb, offset); |
3308 | |
|
3309 | 0 | ti = proto_tree_add_uint(ieee802154_tree, hf_ieee802154_fcs32, tvb, offset, 4, fcs); |
3310 | 0 | if (fcs_ok) { |
3311 | 0 | proto_item_append_text(ti, " (Correct)"); |
3312 | 0 | } |
3313 | 0 | else { |
3314 | 0 | proto_item_append_text(ti, " (Incorrect, expected FCS=0x%08x)", ieee802154_crc32_tvb(tvb, offset)); |
3315 | 0 | } |
3316 | | /* To Help with filtering, add the fcs_ok field to the tree. */ |
3317 | 0 | ti = proto_tree_add_boolean(ieee802154_tree, hf_ieee802154_fcs_ok, tvb, offset, 2, (uint64_t) fcs_ok); |
3318 | 0 | proto_item_set_hidden(ti); |
3319 | 0 | } |
3320 | 143 | } |
3321 | 143 | } /* ieee802154_dissect_fcs */ |
3322 | | |
3323 | | /** |
3324 | | * Dissect the TI CC24xx metadata at the end of the frame. |
3325 | | * That is only displayed if the included length of the tvb encompasses it. |
3326 | | * |
3327 | | * @param tvb the 802.15.4 frame tvb |
3328 | | * @param ieee802154_tree the 802.15.4 protocol tree |
3329 | | * @param fcs_ok set to false to indicate FCS verification failed |
3330 | | */ |
3331 | | static void |
3332 | | ieee802154_dissect_cc24xx_metadata(tvbuff_t *tvb, proto_tree *ieee802154_tree, bool fcs_ok) |
3333 | 0 | { |
3334 | | /* The metadata should be the last 2 bytes of the reported packet. */ |
3335 | 0 | unsigned offset = tvb_reported_length(tvb)-2; |
3336 | | /* Dissect the metadata only if it exists (captures which don't or can't get the |
3337 | | * metadata will simply truncate the packet to omit it, but should still set the |
3338 | | * reported length to cover the original packet length), so if the snapshot |
3339 | | * is too short for the metadata don't make a fuss. |
3340 | | */ |
3341 | 0 | if (ieee802154_tree) { |
3342 | 0 | proto_tree *field_tree; |
3343 | 0 | uint16_t metadata = tvb_get_letohs(tvb, offset); |
3344 | | |
3345 | | /* Create a subtree for the metadata. */ |
3346 | 0 | field_tree = proto_tree_add_subtree_format(ieee802154_tree, tvb, offset, 2, ett_ieee802154_fcs, NULL, |
3347 | 0 | "TI CC24xx-format metadata: FCS %s", (fcs_ok) ? "OK" : "Bad"); |
3348 | | /* Display metadata contents. */ |
3349 | 0 | proto_tree_add_boolean(field_tree, hf_ieee802154_fcs_ok, tvb, offset, 1, (uint64_t) (metadata & IEEE802154_CC24xx_CRC_OK)); |
3350 | 0 | proto_tree_add_int(field_tree, hf_ieee802154_rssi, tvb, offset++, 1, (int8_t) (metadata & IEEE802154_CC24xx_RSSI)); |
3351 | 0 | proto_tree_add_uint(field_tree, hf_ieee802154_correlation, tvb, offset, 1, (uint8_t) ((metadata & IEEE802154_CC24xx_CORRELATION) >> 8)); |
3352 | 0 | } |
3353 | 0 | } /* ieee802154_dissect_cc24xx_metadata */ |
3354 | | |
3355 | | static void |
3356 | | dissect_ieee802154_tap_sun_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, unsigned length) |
3357 | 0 | { |
3358 | 0 | (void) pinfo; |
3359 | 0 | if (length == 3) { |
3360 | 0 | uint32_t band; |
3361 | 0 | uint32_t sun_type; |
3362 | 0 | uint32_t mode; |
3363 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_sun_band, tvb, offset, 1, ENC_LITTLE_ENDIAN, &band); |
3364 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ": Band: %s (%u)", val_to_str_const(band, sun_bands, "Unknown"), band); |
3365 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_sun_type, tvb, offset+1, 1, ENC_LITTLE_ENDIAN, &sun_type); |
3366 | 0 | if (sun_type < array_length(sun_types)) { |
3367 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ", Type: %s (%u)", val_to_str_const(sun_type, sun_types, "Unknown"), sun_type); |
3368 | 0 | } |
3369 | |
|
3370 | 0 | switch (sun_type) { |
3371 | 0 | case IEEE802154_SUN_TYPE_FSK_A: |
3372 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_fsk_a, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode); |
3373 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode); |
3374 | 0 | break; |
3375 | 0 | case IEEE802154_SUN_TYPE_FSK_B: |
3376 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_fsk_b, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode); |
3377 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode); |
3378 | 0 | break; |
3379 | 0 | case IEEE802154_SUN_TYPE_OQPSK_A: |
3380 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_oqpsk_a, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode); |
3381 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode); |
3382 | 0 | break; |
3383 | 0 | case IEEE802154_SUN_TYPE_OQPSK_B: |
3384 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_oqpsk_b, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode); |
3385 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode); |
3386 | 0 | break; |
3387 | 0 | case IEEE802154_SUN_TYPE_OQPSK_C: |
3388 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_oqpsk_c, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode); |
3389 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode); |
3390 | 0 | break; |
3391 | 0 | case IEEE802154_SUN_TYPE_OFDM_OPT1: |
3392 | 0 | case IEEE802154_SUN_TYPE_OFDM_OPT2: |
3393 | 0 | case IEEE802154_SUN_TYPE_OFDM_OPT3: |
3394 | 0 | case IEEE802154_SUN_TYPE_OFDM_OPT4: |
3395 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_mode_ofdm, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &mode); |
3396 | 0 | proto_item_append_text(proto_tree_get_parent(tree), ", Mode: %u", mode); |
3397 | 0 | break; |
3398 | 0 | default: |
3399 | 0 | proto_tree_add_item(tree, hf_ieee802154_sun_mode, tvb, offset+2, 1, ENC_LITTLE_ENDIAN); |
3400 | 0 | break; |
3401 | 0 | } /* switch (sun_type) */ |
3402 | 0 | } |
3403 | 0 | } /* dissect_ieee802154_tap_sun_phy */ |
3404 | | |
3405 | | static void |
3406 | | dissect_ieee802154_tap_phy_header(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset, unsigned length) |
3407 | 0 | { |
3408 | 0 | uint32_t phr_type; |
3409 | 0 | uint32_t phr_bits; |
3410 | |
|
3411 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_tap_phr_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, &phr_type); |
3412 | 0 | proto_tree_add_item_ret_uint(tree, hf_ieee802154_tap_phr_bits, tvb, offset+2, 2, ENC_LITTLE_ENDIAN, &phr_bits); |
3413 | |
|
3414 | 0 | switch (phr_type) { |
3415 | 0 | case PHR_WISUN_FSK_MS: { |
3416 | 0 | uint32_t phr_data = tvb_get_letohs(tvb, offset+4); |
3417 | 0 | if (phr_data & IEEE802154_TAP_PHR_FSK_MS) { |
3418 | 0 | static int* const ieee802154_tap_phr_fsk_wisun_ms_fields[] = { |
3419 | 0 | &hf_ieee802154_tap_phr_fsk_ms, |
3420 | 0 | &hf_ieee802154_tap_phr_wisun_fsk_ms_reserved, |
3421 | 0 | &hf_ieee802154_tap_phr_wisun_fsk_ms_phymodeid, |
3422 | 0 | &hf_ieee802154_tap_phr_fsk_ms_checksum, |
3423 | 0 | &hf_ieee802154_tap_phr_fsk_ms_parity, |
3424 | 0 | NULL |
3425 | 0 | }; |
3426 | 0 | proto_item *pi = proto_tree_add_bitmask_with_flags(tree, tvb, offset+4, hf_ieee802154_tap_wisun_ms_phr, |
3427 | 0 | ett_ieee802154_tap_phr, ieee802154_tap_phr_fsk_wisun_ms_fields, ENC_LITTLE_ENDIAN, BMT_NO_TFS); |
3428 | 0 | if (phr_data & IEEE802154_TAP_PHR_WISUN_FSK_MS_RESERVED) { |
3429 | 0 | expert_add_info(NULL, pi, &ei_ieee802154_tap_tlv_reserved_not_zero); |
3430 | 0 | } |
3431 | | /* TODO: expert info BCH(15,11) checksum check */ |
3432 | | /* TODO: expert info parity check */ |
3433 | 0 | } |
3434 | 0 | break; |
3435 | 0 | } |
3436 | 0 | case PHR_SUN_FSK: { |
3437 | 0 | uint32_t phr_data = tvb_get_letohs(tvb, offset+4); |
3438 | 0 | if (phr_data & IEEE802154_TAP_PHR_FSK_MS) { |
3439 | 0 | int *const *fields; |
3440 | 0 | if ((phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_FSK) { |
3441 | | /* SUN FSK */ |
3442 | 0 | static int* const ieee802154_tap_phr_fsk_ms_fields[] = { |
3443 | 0 | &hf_ieee802154_tap_phr_fsk_ms, |
3444 | 0 | &hf_ieee802154_tap_phr_fsk_ms_param, |
3445 | 0 | &hf_ieee802154_tap_phr_fsk_ms_fec, |
3446 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_page, |
3447 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_scheme, |
3448 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_mode, |
3449 | 0 | &hf_ieee802154_tap_phr_fsk_ms_checksum, |
3450 | 0 | &hf_ieee802154_tap_phr_fsk_ms_parity, |
3451 | 0 | NULL |
3452 | 0 | }; |
3453 | 0 | fields = ieee802154_tap_phr_fsk_ms_fields; |
3454 | 0 | } |
3455 | 0 | else if ((phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_OFDM || |
3456 | 0 | (phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_OQPSK) { |
3457 | | /* SUN OFDM or SUN O-QPSK */ |
3458 | 0 | static int* const ieee802154_tap_phr_fsk_ms_ofdm_fields[] = { |
3459 | 0 | &hf_ieee802154_tap_phr_fsk_ms, |
3460 | 0 | &hf_ieee802154_tap_phr_fsk_ms_param, |
3461 | 0 | &hf_ieee802154_tap_phr_fsk_ms_fec, |
3462 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_page, |
3463 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_scheme, |
3464 | 0 | &hf_ieee802154_tap_phr_fsk_ms_checksum, |
3465 | 0 | &hf_ieee802154_tap_phr_fsk_ms_parity, |
3466 | 0 | NULL |
3467 | 0 | }; |
3468 | 0 | fields = ieee802154_tap_phr_fsk_ms_ofdm_fields; |
3469 | 0 | } |
3470 | 0 | else /* if ((phr_data & IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME) == IEEE802154_TAP_PHR_FSK_MS_SCHEME_ADDL) */ { |
3471 | | /* Additional Modes */ |
3472 | 0 | static int* const ieee802154_tap_phr_fsk_ms_addl_fields[] = { |
3473 | 0 | &hf_ieee802154_tap_phr_fsk_ms, |
3474 | 0 | &hf_ieee802154_tap_phr_fsk_ms_param, |
3475 | 0 | &hf_ieee802154_tap_phr_fsk_ms_fec, |
3476 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_page, |
3477 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_scheme, |
3478 | 0 | &hf_ieee802154_tap_phr_fsk_ms_mode_addl_mode, |
3479 | 0 | &hf_ieee802154_tap_phr_fsk_ms_checksum, |
3480 | 0 | &hf_ieee802154_tap_phr_fsk_ms_parity, |
3481 | 0 | NULL |
3482 | 0 | }; |
3483 | 0 | fields = ieee802154_tap_phr_fsk_ms_addl_fields; |
3484 | 0 | } |
3485 | 0 | proto_tree_add_bitmask_with_flags(tree, tvb, offset+4, hf_ieee802154_tap_fsk_ms_phr, |
3486 | 0 | ett_ieee802154_tap_phr, fields, ENC_LITTLE_ENDIAN, BMT_NO_TFS); |
3487 | | /* TODO: expert info BCH(15,11) checksum check */ |
3488 | | /* TODO: expert info parity check */ |
3489 | 0 | } |
3490 | 0 | else { |
3491 | 0 | static int* const ieee802154_tap_phr_fsk_fields[] = { |
3492 | 0 | &hf_ieee802154_tap_phr_fsk_ms, |
3493 | 0 | &hf_ieee802154_tap_phr_fsk_fcs, |
3494 | 0 | &hf_ieee802154_tap_phr_fsk_dw, |
3495 | 0 | &hf_ieee802154_tap_phr_fsk_length, |
3496 | 0 | NULL |
3497 | 0 | }; |
3498 | 0 | proto_tree_add_bitmask_with_flags(tree, tvb, offset+4, hf_ieee802154_tap_phr_fsk, |
3499 | 0 | ett_ieee802154_tap_phr, ieee802154_tap_phr_fsk_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
3500 | 0 | } |
3501 | 0 | break; |
3502 | 0 | } |
3503 | | |
3504 | 0 | case PHR_O_QPSK: |
3505 | 0 | case PHR_CSS: |
3506 | 0 | case PHR_HRP_UWB: |
3507 | 0 | case PHR_MSK: |
3508 | 0 | case PHR_LRP_UWB: |
3509 | 0 | case PHR_SUN_OFDM: |
3510 | 0 | case PHR_SUN_O_QPSK: |
3511 | 0 | case PHR_LECIM_FSK: |
3512 | 0 | case PHR_TVWS_FSK: |
3513 | 0 | case PHR_TVWS_OFDM: |
3514 | 0 | case PHR_TVWS_NB_OFDM: |
3515 | 0 | case PHR_RCC_LMR: |
3516 | 0 | case PHR_CMB_O_QPSK: |
3517 | 0 | case PHR_CMB_GFSK: |
3518 | 0 | case PHR_TASK: |
3519 | 0 | case PHR_RS_GFSK: |
3520 | | /* TODO: write specific dissectors for these PHR types */ |
3521 | | /* fall-through with RAW dissection */ |
3522 | 0 | case PHR_RAW: |
3523 | 0 | default: { |
3524 | 0 | proto_tree_add_item(tree, hf_ieee802154_tap_phr_data, tvb, offset+4, length-4, ENC_NA); |
3525 | 0 | break; |
3526 | 0 | } |
3527 | 0 | } |
3528 | 0 | } |
3529 | | |
3530 | | /** |
3531 | | * Create a tree for a TAP TLV |
3532 | | * |
3533 | | * @param tree the tree to append this item to |
3534 | | * @param tvb the tv buffer |
3535 | | * @param offset offset into the tvbuff to begin dissection |
3536 | | * @param type TLV type |
3537 | | * @param length TLV length |
3538 | | * @returns the tree created for the Payload IE |
3539 | | */ |
3540 | | static proto_tree* |
3541 | | ieee802154_create_tap_tlv_tree(proto_tree *tree, tvbuff_t *tvb, int offset, uint32_t *type, uint32_t *length) |
3542 | 0 | { |
3543 | 0 | proto_tree *subtree = NULL; |
3544 | 0 | proto_item *ti = NULL; |
3545 | 0 | uint32_t subtree_length; |
3546 | |
|
3547 | 0 | *length = tvb_get_letohs(tvb, offset+2); |
3548 | |
|
3549 | 0 | subtree_length = 4 + *length; |
3550 | 0 | subtree_length += WS_PADDING_TO_4(*length); |
3551 | |
|
3552 | 0 | subtree = proto_tree_add_subtree(tree, tvb, offset, subtree_length, ett_ieee802154_tap_tlv, &ti, ""); |
3553 | | |
3554 | | /* Check if we have a valid TLV */ |
3555 | 0 | proto_tree_add_item_ret_uint(subtree, hf_ieee802154_tap_tlv_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, type); |
3556 | 0 | if (*type < array_length(tap_tlv_types)) { |
3557 | 0 | proto_item_append_text(ti, "%s", val_to_str_const(*type, tap_tlv_types, "Unknown")); |
3558 | 0 | } |
3559 | 0 | else { |
3560 | 0 | expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_invalid_type); |
3561 | 0 | } |
3562 | |
|
3563 | 0 | proto_tree_add_item(subtree, hf_ieee802154_tap_tlv_length, tvb, offset+2, 2, ENC_LITTLE_ENDIAN); |
3564 | 0 | if (!tvb_bytes_exist(tvb, offset+4, *length)) { |
3565 | 0 | expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_invalid_length); |
3566 | 0 | } |
3567 | 0 | return subtree; |
3568 | 0 | } /* ieee802154_create_tap_tlv_tree */ |
3569 | | |
3570 | | static ieee802154_fcs_type_t |
3571 | | dissect_ieee802154_tap_tlvs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
3572 | 0 | { |
3573 | 0 | uint32_t type; |
3574 | 0 | uint32_t length; |
3575 | 0 | unsigned offset = 0; |
3576 | 0 | proto_item *ti; |
3577 | 0 | proto_tree *tlvtree; |
3578 | 0 | uint32_t tap_fcs_type; |
3579 | 0 | const char *type_str; |
3580 | 0 | nstime_t nstime; |
3581 | 0 | uint64_t frame_start_ts = 0; |
3582 | 0 | uint64_t frame_end_ts = 0; |
3583 | 0 | uint64_t slot_start_ts = 0; |
3584 | 0 | double delta_us = 0; |
3585 | 0 | uint32_t timeslot_length = 0; |
3586 | | |
3587 | | /* Default the FCS type to NONE when parsing TAP packets */ |
3588 | 0 | tap_fcs_type = IEEE802154_FCS_TYPE_NONE; |
3589 | |
|
3590 | 0 | while (tvb_bytes_exist(tvb, offset, 4)) { |
3591 | 0 | tlvtree = ieee802154_create_tap_tlv_tree(tree, tvb, offset, &type, &length); |
3592 | 0 | offset += 4; |
3593 | |
|
3594 | 0 | switch (type) { |
3595 | 0 | case IEEE802154_TAP_FCS_TYPE: |
3596 | 0 | ti = proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_tap_fcs_type, tvb, offset, 1, |
3597 | 0 | ENC_LITTLE_ENDIAN, &tap_fcs_type); |
3598 | 0 | type_str = try_val_to_str(tap_fcs_type, tap_fcs_type_names); |
3599 | 0 | if (type_str == NULL) { |
3600 | | /* Invalid - flag it as such */ |
3601 | 0 | expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_invalid_fcs_type); |
3602 | | |
3603 | | /* Use "Unknown" for the parent */ |
3604 | 0 | type_str = "Unknown"; |
3605 | 0 | } |
3606 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s (%u)", |
3607 | 0 | type_str, tap_fcs_type); |
3608 | 0 | break; |
3609 | 0 | case IEEE802154_TAP_RSS: { |
3610 | 0 | float rss = tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN); |
3611 | 0 | proto_tree_add_float_format_value(tlvtree, hf_ieee802154_tap_rss, tvb, offset, 4, rss, "%.2f dBm", rss); |
3612 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %.2f dBm", rss); |
3613 | 0 | break; |
3614 | 0 | } |
3615 | 0 | case IEEE802154_TAP_BIT_RATE: { |
3616 | 0 | uint32_t bitrate; |
3617 | 0 | proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_bit_rate, tvb, offset, 4, ENC_LITTLE_ENDIAN, &bitrate); |
3618 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %.3f kbps", bitrate/1000.0); |
3619 | 0 | break; |
3620 | 0 | } |
3621 | 0 | case IEEE802154_TAP_CHANNEL_ASSIGNMENT: { |
3622 | 0 | uint32_t channel; |
3623 | 0 | uint32_t page; |
3624 | 0 | proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_ch_num, tvb, offset, 2, ENC_LITTLE_ENDIAN, &channel); |
3625 | 0 | proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_ch_page, tvb, offset+2, 1, ENC_LITTLE_ENDIAN, &page); |
3626 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": Page: %s (%u), Number: %u", val_to_str_const(page, channel_page_names, "Unknown"), page, channel); |
3627 | 0 | break; |
3628 | 0 | } |
3629 | 0 | case IEEE802154_TAP_SUN_PHY_INFO: |
3630 | 0 | dissect_ieee802154_tap_sun_phy(tvb, pinfo, tlvtree, offset, length); |
3631 | 0 | break; |
3632 | 0 | case IEEE802154_TAP_START_OF_FRAME_TS: |
3633 | 0 | proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_sof_ts, tvb, offset, 8, |
3634 | 0 | ENC_LITTLE_ENDIAN, &frame_start_ts); |
3635 | 0 | nstime.secs = (time_t)frame_start_ts / 1000000000L; |
3636 | 0 | nstime.nsecs = frame_start_ts % 1000000000UL; |
3637 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s s", rel_time_to_secs_str(pinfo->pool, &nstime)); |
3638 | 0 | break; |
3639 | 0 | case IEEE802154_TAP_END_OF_FRAME_TS: |
3640 | 0 | proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_eof_ts, tvb, offset, 8, |
3641 | 0 | ENC_LITTLE_ENDIAN, &frame_end_ts); |
3642 | 0 | nstime.secs = (time_t)frame_end_ts / 1000000000L; |
3643 | 0 | nstime.nsecs = frame_end_ts % 1000000000UL; |
3644 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s s", rel_time_to_secs_str(pinfo->pool, &nstime)); |
3645 | 0 | break; |
3646 | 0 | case IEEE802154_TAP_ASN: |
3647 | 0 | proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_asn, tvb, offset, 8, ENC_LITTLE_ENDIAN, &ieee802154_tsch_asn); |
3648 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %"PRIu64, ieee802154_tsch_asn); |
3649 | 0 | break; |
3650 | 0 | case IEEE802154_TAP_SLOT_START_TS: |
3651 | 0 | proto_tree_add_item_ret_uint64(tlvtree, hf_ieee802154_slot_start_ts, tvb, offset, 8, |
3652 | 0 | ENC_LITTLE_ENDIAN, &slot_start_ts); |
3653 | 0 | nstime.secs = (time_t)slot_start_ts / 1000000000L; |
3654 | 0 | nstime.nsecs = slot_start_ts % 1000000000UL; |
3655 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %s s", rel_time_to_secs_str(pinfo->pool, &nstime)); |
3656 | 0 | break; |
3657 | 0 | case IEEE802154_TAP_TIMESLOT_LENGTH: |
3658 | 0 | proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_tap_timeslot_length, tvb, offset, 4, |
3659 | 0 | ENC_LITTLE_ENDIAN, ×lot_length); |
3660 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %"PRIu32" %s", timeslot_length, units_microseconds.singular); |
3661 | 0 | break; |
3662 | 0 | case IEEE802154_TAP_LQI: { |
3663 | 0 | uint32_t lqi; |
3664 | 0 | proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_tap_lqi, tvb, offset, 1, ENC_LITTLE_ENDIAN, &lqi); |
3665 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %u", lqi); |
3666 | 0 | break; |
3667 | 0 | } |
3668 | 0 | case IEEE802154_TAP_CHANNEL_FREQUENCY: { |
3669 | 0 | float freq = tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN); |
3670 | 0 | proto_tree_add_float_format_value(tlvtree, hf_ieee802154_ch_freq, tvb, offset, 4, freq, "%.3f kHz", freq); |
3671 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": %.3f kHz", freq); |
3672 | 0 | break; |
3673 | 0 | } |
3674 | 0 | case IEEE802154_TAP_CHANNEL_PLAN: { |
3675 | 0 | uint32_t count; |
3676 | 0 | float ch0_freq = tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN); |
3677 | 0 | float spacing = tvb_get_ieee_float(tvb, offset+4, ENC_LITTLE_ENDIAN); |
3678 | 0 | proto_tree_add_float_format_value(tlvtree, hf_ieee802154_chplan_start, tvb, offset, 4, ch0_freq, "%.3f kHz", ch0_freq); |
3679 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ": Start %.3f kHz", ch0_freq); |
3680 | 0 | proto_tree_add_float_format_value(tlvtree, hf_ieee802154_chplan_spacing, tvb, offset+4, 4, spacing, "%.3f kHz", spacing); |
3681 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ", Spacing %.3f kHz", spacing); |
3682 | 0 | proto_tree_add_item_ret_uint(tlvtree, hf_ieee802154_chplan_channels, tvb, offset+8, 2, ENC_LITTLE_ENDIAN, &count); |
3683 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), ", Channels %u", count); |
3684 | 0 | break; |
3685 | 0 | } |
3686 | 0 | case IEEE802154_TAP_PHY_HEADER: |
3687 | 0 | dissect_ieee802154_tap_phy_header(tvb, pinfo, tlvtree, offset, length); |
3688 | 0 | break; |
3689 | 0 | default: |
3690 | 0 | proto_tree_add_item(tlvtree, hf_ieee802154_tap_tlv_unknown, tvb, offset, length, ENC_NA); |
3691 | 0 | proto_item_append_text(proto_tree_get_parent(tlvtree), "Unknown TLV"); |
3692 | 0 | break; |
3693 | 0 | } /* switch (tlv_type) */ |
3694 | 0 | offset += length; |
3695 | |
|
3696 | 0 | unsigned padding_len = WS_PADDING_TO_4(length); |
3697 | 0 | if (padding_len != 0) { |
3698 | 0 | uint32_t zero = 0; |
3699 | 0 | GByteArray *padding = g_byte_array_sized_new(4); |
3700 | 0 | ti = proto_tree_add_bytes_item(tlvtree, hf_ieee802154_tap_tlv_padding, tvb, offset, padding_len, ENC_NA, padding, NULL, NULL); |
3701 | 0 | if (memcmp(&zero, padding->data, padding_len)) { |
3702 | 0 | expert_add_info(NULL, ti, &ei_ieee802154_tap_tlv_padding_not_zeros); |
3703 | 0 | } |
3704 | 0 | g_byte_array_free(padding, true); |
3705 | 0 | offset += padding_len; |
3706 | 0 | } |
3707 | 0 | } /* while */ |
3708 | | |
3709 | | /* if we have both slot start and frame start timestamp, show frame start offset */ |
3710 | 0 | if (slot_start_ts && frame_start_ts) { |
3711 | 0 | delta_us = (double)(frame_start_ts - slot_start_ts) / 1000; |
3712 | 0 | ti = proto_tree_add_double_format_value(tree, hf_ieee802154_frame_start_offset, NULL, 0, 0, delta_us, "%.3f %s", delta_us, units_microseconds.singular); |
3713 | 0 | proto_item_set_generated(ti); |
3714 | 0 | } |
3715 | | |
3716 | | /* if we have both start and end frame timestamp, show frame duration */ |
3717 | 0 | if (frame_start_ts && frame_end_ts) { |
3718 | 0 | delta_us = (double)(frame_end_ts - frame_start_ts) / 1000; |
3719 | 0 | ti = proto_tree_add_double_format_value(tree, hf_ieee802154_frame_duration, NULL, 0, 0, delta_us, "%.3f %s", delta_us, units_microseconds.singular); |
3720 | 0 | proto_item_set_generated(ti); |
3721 | 0 | } |
3722 | | |
3723 | | /* if we have start of slot, timeslot length, and end of frame timestamp, show frame overflow (+ve) or underflow (-ve) */ |
3724 | 0 | if (timeslot_length && frame_end_ts && slot_start_ts) { |
3725 | | /* overflow = frame_end_ts - slot_start_ts - timeslot_length */ |
3726 | 0 | delta_us = (double)(frame_end_ts - slot_start_ts) / 1000; |
3727 | 0 | delta_us -= timeslot_length; |
3728 | 0 | ti = proto_tree_add_double_format_value(tree, hf_ieee802154_frame_end_offset, NULL, 0, 0, delta_us, "%.3f %s", delta_us, units_microseconds.singular); |
3729 | 0 | proto_item_set_generated(ti); |
3730 | 0 | } |
3731 | |
|
3732 | 0 | return (ieee802154_fcs_type_t)tap_fcs_type; |
3733 | 0 | } /* dissect_ieee802154_tap_tlvs */ |
3734 | | |
3735 | | /* |
3736 | | * Information Elements Processing (IEs) |
3737 | | */ |
3738 | | |
3739 | | /** |
3740 | | * Create a tree for a Payload IE incl. the TLV header and append the IE name to the parent item |
3741 | | * |
3742 | | * @param tvb the tv buffer |
3743 | | * @param tree the tree to append this item to |
3744 | | * @param hf field index |
3745 | | * @param ett tree index |
3746 | | * @returns the tree created for the Payload IE |
3747 | | */ |
3748 | | proto_tree* |
3749 | | ieee802154_create_pie_tree(tvbuff_t *tvb, proto_tree *tree, int hf, int ett) |
3750 | 1.41k | { |
3751 | 1.41k | proto_item *subitem; |
3752 | 1.41k | proto_tree *subtree; |
3753 | 1.41k | header_field_info *hfinfo; |
3754 | 1.41k | static int * const tlv_fields[] = { |
3755 | 1.41k | &hf_ieee802154_payload_ie_type, |
3756 | 1.41k | &hf_ieee802154_payload_ie_id, |
3757 | 1.41k | &hf_ieee802154_payload_ie_length, |
3758 | 1.41k | NULL |
3759 | 1.41k | }; |
3760 | | |
3761 | 1.41k | subitem = proto_tree_add_item(tree, hf, tvb, 0, tvb_reported_length(tvb), ENC_NA); |
3762 | 1.41k | subtree = proto_item_add_subtree(subitem, ett); |
3763 | 1.41k | proto_tree_add_bitmask_with_flags(subtree, tvb, 0, hf_ieee802154_payload_ie_tlv, ett_ieee802154_payload_ie_tlv, |
3764 | 1.41k | tlv_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
3765 | | |
3766 | 1.41k | hfinfo = proto_registrar_get_nth(hf); |
3767 | 1.41k | if (hfinfo && hfinfo->name) { |
3768 | 1.41k | proto_item_append_text(proto_tree_get_parent(tree), ", %s", hfinfo->name); |
3769 | 1.41k | } |
3770 | 1.41k | return subtree; |
3771 | 1.41k | } |
3772 | | |
3773 | | /** |
3774 | | * Create a tree for a Payload Sub-IE incl. the TLV header and append the IE name to the parent item |
3775 | | * |
3776 | | * @param tvb the tv buffer |
3777 | | * @param tree the tree to append this item to |
3778 | | * @param hf field index |
3779 | | * @param ett tree index |
3780 | | * @returns the tree created for the Payload IE |
3781 | | */ |
3782 | | static proto_tree* |
3783 | | ieee802154_create_psie_tree(tvbuff_t *tvb, proto_tree *tree, int hf, int ett) |
3784 | 1.27k | { |
3785 | 1.27k | proto_item *subitem; |
3786 | 1.27k | proto_tree *subtree; |
3787 | 1.27k | header_field_info *hfinfo; |
3788 | | |
3789 | 1.27k | subitem = proto_tree_add_item(tree, hf, tvb, 0, tvb_reported_length(tvb), ENC_NA); |
3790 | 1.27k | subtree = proto_item_add_subtree(subitem, ett); |
3791 | 1.27k | if (tvb_get_letohs(tvb, 0) & IEEE802154_PSIE_TYPE_MASK) { |
3792 | 58 | static int * const fields_long[] = { |
3793 | 58 | &hf_ieee802154_psie_type, |
3794 | 58 | &hf_ieee802154_psie_id_long, |
3795 | 58 | &hf_ieee802154_psie_length_long, |
3796 | 58 | NULL |
3797 | 58 | }; |
3798 | 58 | proto_tree_add_bitmask(subtree, tvb, 0, hf_ieee802154_psie, ett_ieee802154_psie, fields_long, ENC_LITTLE_ENDIAN); |
3799 | 58 | } |
3800 | 1.22k | else { |
3801 | 1.22k | static int * const fields_short[] = { |
3802 | 1.22k | &hf_ieee802154_psie_type, |
3803 | 1.22k | &hf_ieee802154_psie_id_short, |
3804 | 1.22k | &hf_ieee802154_psie_length_short, |
3805 | 1.22k | NULL |
3806 | 1.22k | }; |
3807 | 1.22k | proto_tree_add_bitmask(subtree, tvb, 0, hf_ieee802154_psie, ett_ieee802154_psie, fields_short, ENC_LITTLE_ENDIAN); |
3808 | 1.22k | } |
3809 | | |
3810 | 1.27k | hfinfo = proto_registrar_get_nth(hf); |
3811 | 1.27k | if (hfinfo && hfinfo->name) { |
3812 | 1.27k | proto_item_append_text(proto_tree_get_parent(tree), ", %s", hfinfo->name); |
3813 | 1.27k | } |
3814 | 1.27k | return subtree; |
3815 | 1.27k | } |
3816 | | |
3817 | | /** |
3818 | | * Subdissector for the MLME Channel Hopping Payload IE |
3819 | | */ |
3820 | | static int |
3821 | | dissect_802154_channel_hopping(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
3822 | 123 | { |
3823 | 123 | proto_tree *subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_channel_hopping, ett_ieee802154_mlme_payload); |
3824 | | |
3825 | 123 | proto_tree_add_item(subtree, hf_ieee802154_tsch_hopping_sequence_id, tvb, 2, 1, ENC_LITTLE_ENDIAN); |
3826 | | |
3827 | 123 | if (tvb_reported_length_remaining(tvb, 3) > 1) { |
3828 | | /* TODO: There's still a huge amount of optional stuff that could follow */ |
3829 | 116 | proto_tree_add_item(subtree, hf_ieee802154_mlme_ie_data, tvb, 3, tvb_reported_length_remaining(tvb, 3), ENC_NA); |
3830 | 116 | } |
3831 | 123 | return tvb_reported_length(tvb); |
3832 | 123 | } /* dissect_802154_channel_hopping */ |
3833 | | |
3834 | | /** |
3835 | | * Subdissector for the Nested MLME IE for TSCH Synchronization |
3836 | | */ |
3837 | | static int |
3838 | | dissect_802154_tsch_time_sync(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
3839 | 9 | { |
3840 | 9 | proto_tree *subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_sync, ett_ieee802154_tsch_synch); |
3841 | | |
3842 | 9 | proto_tree_add_item(subtree, hf_ieee802154_tsch_asn, tvb, 2, 5, ENC_LITTLE_ENDIAN); |
3843 | 9 | proto_tree_add_item(subtree, hf_ieee802154_tsch_join_metric, tvb, 7, 1, ENC_LITTLE_ENDIAN); |
3844 | 9 | return 8; |
3845 | 9 | }/* dissect_802154_tsch_time_sync*/ |
3846 | | |
3847 | | /** |
3848 | | * Subdissector for the Nested MLME IE for TSCH Slotframe and Link |
3849 | | */ |
3850 | | static int |
3851 | | dissect_802154_tsch_slotframe_link(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
3852 | 54 | { |
3853 | 54 | uint8_t nb_slotframes; |
3854 | 54 | uint8_t slotframe_index; |
3855 | 54 | proto_tree *subtree; |
3856 | 54 | unsigned offset = 0; |
3857 | | |
3858 | 54 | subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_slotframe, ett_ieee802154_tsch_slotframe); |
3859 | 54 | offset += 2; |
3860 | | |
3861 | 54 | nb_slotframes = tvb_get_uint8(tvb, offset); |
3862 | 54 | proto_tree_add_item(subtree, hf_ieee802154_tsch_slotf_link_nb_slotf, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
3863 | 54 | offset += 1; |
3864 | | |
3865 | 155 | for (slotframe_index = 1; slotframe_index <= nb_slotframes; slotframe_index++) { |
3866 | | /* Create a tree for the slotframe. */ |
3867 | 101 | uint8_t nb_links = tvb_get_uint8(tvb, offset + 3); |
3868 | 101 | proto_item *sf_item = proto_tree_add_subtree_format(subtree, tvb, offset, 4 + (5 * nb_links), |
3869 | 101 | ett_ieee802154_tsch_slotframe, NULL, |
3870 | 101 | "Slotframes [%u]", slotframe_index); |
3871 | 101 | proto_tree *sf_tree = proto_item_add_subtree(sf_item, ett_ieee802154_tsch_slotframe_list); |
3872 | 101 | proto_tree_add_item(sf_tree, hf_ieee802154_tsch_slotf_link_slotf_handle, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
3873 | 101 | proto_tree_add_item(sf_tree, hf_ieee802154_tsch_slotf_size, tvb, offset + 1, 2, ENC_LITTLE_ENDIAN); |
3874 | 101 | proto_tree_add_item(sf_tree, hf_ieee802154_tsch_slotf_link_nb_links, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN); |
3875 | | |
3876 | | /* Create a tree for each link in the slotframe. */ |
3877 | 101 | offset += 4; |
3878 | 295 | while (nb_links > 0) { |
3879 | 194 | static int * const fields_options[] = { |
3880 | 194 | &hf_ieee802154_tsch_slotf_link_options_tx, |
3881 | 194 | &hf_ieee802154_tsch_slotf_link_options_rx, |
3882 | 194 | &hf_ieee802154_tsch_slotf_link_options_shared, |
3883 | 194 | &hf_ieee802154_tsch_slotf_link_options_timkeeping, |
3884 | 194 | &hf_ieee802154_tsch_slotf_link_options_priority, |
3885 | 194 | NULL |
3886 | 194 | }; |
3887 | | |
3888 | 194 | proto_item *link_item = proto_tree_add_item(sf_tree, hf_ieee802154_tsch_link_info, tvb, offset, 5, ENC_NA); |
3889 | 194 | proto_tree *link_tree = proto_item_add_subtree(link_item, ett_ieee802154_tsch_slotframe_link); |
3890 | 194 | proto_tree_add_item(link_tree, hf_ieee802154_tsch_slotf_link_timeslot, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3891 | 194 | proto_tree_add_item(link_tree, hf_ieee802154_tsch_slotf_link_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN); |
3892 | 194 | proto_tree_add_bitmask(link_tree, tvb, offset + 4, hf_ieee802154_tsch_slotf_link_options, ett_ieee802154_tsch_slotframe_link_options, fields_options, ENC_LITTLE_ENDIAN); |
3893 | 194 | nb_links -= 1; |
3894 | 194 | offset += 5; |
3895 | 194 | } |
3896 | 101 | } |
3897 | | |
3898 | 54 | return offset; |
3899 | 54 | }/* dissect_802154_tsch_slotframe_link */ |
3900 | | |
3901 | | /** |
3902 | | * Subdissector for the Nested MLME IE for TSCH Timeslot Description |
3903 | | */ |
3904 | | static int |
3905 | | dissect_802154_tsch_timeslot(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
3906 | 37 | { |
3907 | 37 | proto_tree *subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_tsch_timeslot, ett_ieee802154_tsch_timeslot); |
3908 | 37 | unsigned offset = 2; |
3909 | | |
3910 | 37 | proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_id, tvb, 2, 1, ENC_LITTLE_ENDIAN); |
3911 | 37 | offset++; |
3912 | | |
3913 | 37 | if (tvb_reported_length(tvb) > offset) { |
3914 | 34 | const int timeslot_fields[] = { |
3915 | 34 | hf_ieee802154_tsch_timeslot_cca_offset, |
3916 | 34 | hf_ieee802154_tsch_timeslot_cca, |
3917 | 34 | hf_ieee802154_tsch_timeslot_tx_offset, |
3918 | 34 | hf_ieee802154_tsch_timeslot_rx_offset, |
3919 | 34 | hf_ieee802154_tsch_timeslot_rx_ack_delay, |
3920 | 34 | hf_ieee802154_tsch_timeslot_tx_ack_delay, |
3921 | 34 | hf_ieee802154_tsch_timeslot_rx_wait, |
3922 | 34 | hf_ieee802154_tsch_timeslot_ack_wait, |
3923 | 34 | hf_ieee802154_tsch_timeslot_turnaround, |
3924 | 34 | hf_ieee802154_tsch_timeslot_max_ack, |
3925 | 34 | }; |
3926 | 34 | unsigned int i; |
3927 | 369 | for (i = 0; i < array_length(timeslot_fields); i++) { |
3928 | 335 | proto_tree_add_item(subtree, timeslot_fields[i], tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3929 | 335 | offset += 2; |
3930 | 335 | } |
3931 | | |
3932 | | /* The last two fields are may have different encodings depending on the length of the IE. */ |
3933 | 34 | if (tvb_reported_length_remaining(tvb, offset) > 4) { |
3934 | 33 | proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_max_tx, tvb, offset, 3, ENC_LITTLE_ENDIAN); |
3935 | 33 | offset += 3; |
3936 | 33 | proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_length, tvb, offset, 3, ENC_LITTLE_ENDIAN); |
3937 | 33 | offset += 3; |
3938 | 33 | } |
3939 | 1 | else { |
3940 | 1 | proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_max_tx, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3941 | 1 | offset += 2; |
3942 | 1 | proto_tree_add_item(subtree, hf_ieee802154_tsch_timeslot_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3943 | 1 | offset += 2; |
3944 | 1 | } |
3945 | 34 | } |
3946 | 37 | return offset; |
3947 | 37 | } /* dissect_802154_tsch_timeslot */ |
3948 | | |
3949 | | /** |
3950 | | * Subdissector for the 6TOP Protocol contained within the Payload Information Elements. |
3951 | | */ |
3952 | | static int |
3953 | | dissect_ietf_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_) |
3954 | 36 | { |
3955 | 36 | const uint8_t supported_6p_version = 0x00; |
3956 | | |
3957 | 36 | proto_tree *p_inf_elem_tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_pie_ietf, ett_ieee802154_pie_ietf); |
3958 | 36 | unsigned offset = 2; |
3959 | 36 | unsigned pie_length = tvb_reported_length(tvb) - 2; |
3960 | 36 | uint8_t version; |
3961 | 36 | uint8_t type; |
3962 | 36 | uint8_t code; |
3963 | 36 | uint8_t num_cells = 0; |
3964 | 36 | bool have_cell_list = false; |
3965 | 36 | int i; |
3966 | 36 | proto_item *sixtop_item = NULL; |
3967 | 36 | proto_tree *sixtop_tree = NULL; |
3968 | 36 | proto_item *cell_list_item = NULL; |
3969 | 36 | proto_tree *cell_list_tree = NULL; |
3970 | 36 | proto_item *cell_item = NULL; |
3971 | 36 | proto_tree *cell_tree = NULL; |
3972 | 36 | proto_item *type_item = NULL; |
3973 | 36 | proto_item *code_item = NULL; |
3974 | 36 | const char *code_str = NULL; |
3975 | 36 | static int * const cell_options[] = { |
3976 | 36 | &hf_ieee802154_6top_cell_option_tx, |
3977 | 36 | &hf_ieee802154_6top_cell_option_rx, |
3978 | 36 | &hf_ieee802154_6top_cell_option_shared, |
3979 | 36 | &hf_ieee802154_6top_cell_option_reserved, |
3980 | 36 | NULL |
3981 | 36 | }; |
3982 | | |
3983 | 36 | if (pie_length < 5) { |
3984 | 7 | return pie_length + 2; |
3985 | 7 | } |
3986 | | |
3987 | 29 | version = tvb_get_uint8(tvb, offset + 1) & IETF_6TOP_VERSION; |
3988 | | |
3989 | 29 | if (version != supported_6p_version) { |
3990 | 10 | return pie_length + 2; |
3991 | 10 | } |
3992 | | |
3993 | 19 | type = (tvb_get_uint8(tvb, offset + 1) & IETF_6TOP_TYPE) >> 4; |
3994 | 19 | code = tvb_get_uint8(tvb, offset + 2); |
3995 | | |
3996 | 19 | proto_tree_add_item(p_inf_elem_tree, hf_ieee802154_p_ie_ietf_sub_id, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
3997 | | |
3998 | 19 | sixtop_item = proto_tree_add_item(p_inf_elem_tree, hf_ieee802154_6top, tvb, offset, pie_length, ENC_NA); |
3999 | 19 | sixtop_tree = proto_item_add_subtree(sixtop_item, ett_ieee802154_p_ie_6top); |
4000 | | |
4001 | 19 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_version, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN); |
4002 | 19 | type_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_type, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN); |
4003 | 19 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_flags_reserved, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN); |
4004 | 19 | code_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_code, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN); |
4005 | 19 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_sfid, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN); |
4006 | 19 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_seqnum, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN); |
4007 | | |
4008 | 19 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "6top"); |
4009 | 19 | if (type == IETF_6TOP_TYPE_REQUEST) { |
4010 | 12 | code_str = val_to_str_const(code, ietf_6top_command_identifiers,"Unknown"); |
4011 | 12 | col_add_fstr(pinfo->cinfo, COL_INFO, "6P %s Request", code_str); |
4012 | 12 | } else { |
4013 | 7 | code_str = val_to_str_const(code, ietf_6top_return_codes,"Unknown"); |
4014 | 7 | col_add_fstr(pinfo->cinfo, COL_INFO, "6P %s (%s)", |
4015 | 7 | val_to_str_const(type, ietf_6top_types,"Unknown"), code_str); |
4016 | 7 | } |
4017 | 19 | proto_item_append_text(code_item, " (%s)", code_str); |
4018 | | |
4019 | 19 | offset += 5; |
4020 | 19 | pie_length -= 5; |
4021 | | |
4022 | 19 | if (type == IETF_6TOP_TYPE_REQUEST) { |
4023 | 12 | switch (code) { |
4024 | 3 | case IETF_6TOP_CMD_ADD: |
4025 | 3 | case IETF_6TOP_CMD_DELETE: |
4026 | 4 | case IETF_6TOP_CMD_RELOCATE: |
4027 | 4 | if (pie_length < 4) { |
4028 | 0 | break; |
4029 | 0 | } |
4030 | 4 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4031 | 4 | proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN); |
4032 | 4 | proto_tree_add_item_ret_uint8(sixtop_tree, hf_ieee802154_6top_num_cells, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN, &num_cells); |
4033 | 4 | pie_length -= 4; |
4034 | 4 | offset += 4; |
4035 | 4 | if (pie_length > 0 && (pie_length % 4) == 0) { |
4036 | 3 | have_cell_list = true; |
4037 | 3 | } |
4038 | 4 | break; |
4039 | 0 | case IETF_6TOP_CMD_COUNT: |
4040 | 0 | if (pie_length < 3) { |
4041 | 0 | break; |
4042 | 0 | } |
4043 | 0 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4044 | 0 | proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN); |
4045 | 0 | pie_length -= 3; |
4046 | 0 | offset += 3; |
4047 | 0 | break; |
4048 | 0 | case IETF_6TOP_CMD_LIST: |
4049 | 0 | if (pie_length != 8) { |
4050 | 0 | break; |
4051 | 0 | } |
4052 | 0 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4053 | 0 | proto_tree_add_bitmask(sixtop_tree, tvb, offset + 2, hf_ieee802154_6top_cell_options, ett_ieee802154_p_ie_6top_cell_options, cell_options, ENC_LITTLE_ENDIAN); |
4054 | 0 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_reserved, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN); |
4055 | 0 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_offset, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN); |
4056 | 0 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_max_num_cells, tvb, offset + 6, 2, ENC_LITTLE_ENDIAN); |
4057 | 0 | pie_length -= 8; |
4058 | 0 | offset += 8; |
4059 | 0 | break; |
4060 | 1 | case IETF_6TOP_CMD_SIGNAL: |
4061 | 1 | if (pie_length < 2) { |
4062 | 0 | break; |
4063 | 0 | } |
4064 | 1 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4065 | 1 | if (pie_length > 2) { |
4066 | 1 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_payload, tvb, offset + 2, pie_length - 2, ENC_NA); |
4067 | 1 | } |
4068 | 1 | offset += pie_length; |
4069 | 1 | pie_length = 0; |
4070 | 1 | break; |
4071 | 0 | case IETF_6TOP_CMD_CLEAR: |
4072 | 0 | if (pie_length < 2) { |
4073 | 0 | break; |
4074 | 0 | } |
4075 | 0 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_metadata, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4076 | 0 | pie_length -= 2; |
4077 | 0 | offset += 2; |
4078 | 0 | break; |
4079 | 7 | default: |
4080 | | /* unsupported command */ |
4081 | 7 | expert_add_info(pinfo, code_item, &ei_ieee802154_6top_unsupported_command); |
4082 | 7 | break; |
4083 | 12 | } |
4084 | 12 | } else if (type == IETF_6TOP_TYPE_RESPONSE || type == IETF_6TOP_TYPE_CONFIRMATION) { |
4085 | 5 | switch(code) { |
4086 | 2 | case IETF_6TOP_RC_SUCCESS: |
4087 | 2 | if (pie_length > 0) { |
4088 | 2 | if (pie_length == 2) { |
4089 | 0 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_total_num_cells, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4090 | 0 | pie_length -= 2; |
4091 | 0 | offset += 2; |
4092 | 2 | } else if ((pie_length % 4) == 0) { |
4093 | 0 | have_cell_list = true; |
4094 | 2 | } else { |
4095 | 2 | proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_payload, tvb, offset, pie_length, ENC_NA); |
4096 | 2 | offset += pie_length; |
4097 | 2 | pie_length = 0; |
4098 | 2 | } |
4099 | 2 | } |
4100 | 2 | break; |
4101 | 0 | case IETF_6TOP_RC_EOL: |
4102 | 0 | if(pie_length > 0 && (pie_length % 4) == 0) { |
4103 | 0 | have_cell_list = true; |
4104 | 0 | } |
4105 | 0 | break; |
4106 | 0 | case IETF_6TOP_RC_ERR: |
4107 | 0 | case IETF_6TOP_RC_RESET: |
4108 | 0 | case IETF_6TOP_RC_ERR_VERSION: |
4109 | 0 | case IETF_6TOP_RC_ERR_SFID: |
4110 | 0 | case IETF_6TOP_RC_ERR_SEQNUM: |
4111 | 0 | case IETF_6TOP_RC_ERR_CELLLIST: |
4112 | 0 | case IETF_6TOP_RC_ERR_BUSY: |
4113 | 0 | case IETF_6TOP_RC_ERR_LOCKED: |
4114 | | /* They have no other field */ |
4115 | 0 | break; |
4116 | 3 | default: |
4117 | | /* unsupported return code */ |
4118 | 3 | expert_add_info(pinfo, code_item, &ei_ieee802154_6top_unsupported_return_code); |
4119 | 3 | break; |
4120 | 5 | } |
4121 | 5 | } else { |
4122 | | /* unsupported type */ |
4123 | 2 | expert_add_info(pinfo, type_item, &ei_ieee802154_6top_unsupported_type); |
4124 | 2 | } |
4125 | | |
4126 | 16 | if (have_cell_list) { |
4127 | 3 | if (type == IETF_6TOP_TYPE_REQUEST && code == IETF_6TOP_CMD_RELOCATE) { |
4128 | 1 | cell_list_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_rel_cell_list, tvb, offset, pie_length, ENC_NA); |
4129 | 1 | cell_list_tree = proto_item_add_subtree(cell_list_item, ett_ieee802154_p_ie_6top_rel_cell_list); |
4130 | | /* num_cells is expected to be set properly */ |
4131 | 70 | for (i = 0; i < num_cells; offset += 4, i++) { |
4132 | 69 | cell_item = proto_tree_add_item(cell_list_tree, hf_ieee802154_6top_cell, tvb, offset, 4, ENC_NA); |
4133 | 69 | cell_tree = proto_item_add_subtree(cell_item, ett_ieee802154_p_ie_6top_cell); |
4134 | 69 | proto_tree_add_item(cell_tree, hf_ieee802154_6top_slot_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4135 | 69 | proto_tree_add_item(cell_tree, hf_ieee802154_6top_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN); |
4136 | 69 | } |
4137 | 1 | pie_length -= num_cells * 4; |
4138 | 1 | cell_list_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_cand_cell_list, tvb, offset, pie_length, ENC_NA); |
4139 | 1 | cell_list_tree = proto_item_add_subtree(cell_list_item, ett_ieee802154_p_ie_6top_cand_cell_list); |
4140 | 35 | for (i = 0; pie_length > 0; pie_length -= 4, offset += 4, i++) { |
4141 | 34 | cell_item = proto_tree_add_item(cell_list_tree, hf_ieee802154_6top_cell, tvb, offset, 4, ENC_NA); |
4142 | 34 | cell_tree = proto_item_add_subtree(cell_item, ett_ieee802154_p_ie_6top_cell); |
4143 | 34 | proto_tree_add_item(cell_tree, hf_ieee802154_6top_slot_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4144 | 34 | proto_tree_add_item(cell_tree, hf_ieee802154_6top_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN); |
4145 | 34 | } |
4146 | 2 | } else { |
4147 | 2 | cell_list_item = proto_tree_add_item(sixtop_tree, hf_ieee802154_6top_cell_list, tvb, offset, pie_length, ENC_NA); |
4148 | 2 | cell_list_tree = proto_item_add_subtree(cell_list_item, ett_ieee802154_p_ie_6top_cell_list); |
4149 | 98 | for (i = 0; pie_length > 0; pie_length -= 4, offset += 4, i++) { |
4150 | 96 | cell_item = proto_tree_add_item(cell_list_tree, hf_ieee802154_6top_cell, tvb, offset, 4, ENC_NA); |
4151 | 96 | cell_tree = proto_item_add_subtree(cell_item, ett_ieee802154_p_ie_6top_cell); |
4152 | 96 | proto_tree_add_item(cell_tree, hf_ieee802154_6top_slot_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4153 | 96 | proto_tree_add_item(cell_tree, hf_ieee802154_6top_channel_offset, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN); |
4154 | 96 | } |
4155 | 2 | } |
4156 | 3 | } |
4157 | | |
4158 | 16 | return offset; |
4159 | 19 | } /* dissect_ieee802154_6top */ |
4160 | | |
4161 | | /** |
4162 | | * Subdissector for the Superframe specification sub-field within the beacon frame. |
4163 | | * |
4164 | | * @param tvb pointer to buffer containing raw packet. |
4165 | | * @param pinfo pointer to packet information fields (unused). |
4166 | | * @param tree pointer to command subtree. |
4167 | | * @param offset offset into the tvbuff to begin dissection. |
4168 | | */ |
4169 | | void |
4170 | | dissect_ieee802154_superframe(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset) |
4171 | 226 | { |
4172 | 226 | static int * const superframe[] = { |
4173 | 226 | &hf_ieee802154_beacon_order, |
4174 | 226 | &hf_ieee802154_superframe_order, |
4175 | 226 | &hf_ieee802154_cap, |
4176 | 226 | &hf_ieee802154_superframe_battery_ext, |
4177 | 226 | &hf_ieee802154_superframe_coord, |
4178 | 226 | &hf_ieee802154_assoc_permit, |
4179 | 226 | NULL |
4180 | 226 | }; |
4181 | | |
4182 | 226 | proto_tree_add_bitmask_text(tree, tvb, *offset, 2, "Superframe Specification: ", NULL , ett_ieee802154_superframe, superframe, ENC_LITTLE_ENDIAN, BMT_NO_INT|BMT_NO_TFS); |
4183 | 226 | (*offset) += 2; |
4184 | 226 | } /* dissect_ieee802154_superframe */ |
4185 | | |
4186 | | /** |
4187 | | * Subdissector for the GTS information fields within the beacon frame. |
4188 | | * |
4189 | | * @param tvb pointer to buffer containing raw packet. |
4190 | | * @param pinfo pointer to packet information fields (unused). |
4191 | | * @param tree pointer to command subtree. |
4192 | | * @param offset offset into the tvbuff to begin dissection. |
4193 | | */ |
4194 | | void |
4195 | | dissect_ieee802154_gtsinfo(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset) |
4196 | 223 | { |
4197 | 223 | proto_tree *field_tree = NULL; |
4198 | 223 | proto_tree *subtree = NULL; |
4199 | 223 | proto_item *ti; |
4200 | 223 | uint8_t gts_spec; |
4201 | 223 | uint8_t gts_count; |
4202 | | |
4203 | | /* Get and display the GTS specification field */ |
4204 | 223 | gts_spec = tvb_get_uint8(tvb, *offset); |
4205 | 223 | gts_count = gts_spec & IEEE802154_GTS_COUNT_MASK; |
4206 | 223 | if (tree) { |
4207 | | /* Add Subtree for GTS information. */ |
4208 | 223 | if (gts_count) { |
4209 | 136 | field_tree = proto_tree_add_subtree(tree, tvb, *offset, 2 + (gts_count * 3), ett_ieee802154_gts, NULL, "GTS"); |
4210 | 136 | } |
4211 | 87 | else { |
4212 | 87 | field_tree = proto_tree_add_subtree(tree, tvb, *offset, 1, ett_ieee802154_gts, NULL, "GTS"); |
4213 | 87 | } |
4214 | | |
4215 | 223 | proto_tree_add_uint(field_tree, hf_ieee802154_gts_count, tvb, *offset, 1, gts_count); |
4216 | 223 | proto_tree_add_boolean(field_tree, hf_ieee802154_gts_permit, tvb, *offset, 1, gts_spec & IEEE802154_GTS_PERMIT_MASK); |
4217 | 223 | } |
4218 | 223 | (*offset) += 1; |
4219 | | |
4220 | | /* If the GTS descriptor count is nonzero, then the GTS directions mask and descriptor list are present. */ |
4221 | 223 | if (gts_count) { |
4222 | 136 | uint8_t gts_directions = tvb_get_uint8(tvb, *offset); |
4223 | 136 | unsigned gts_rx = 0; |
4224 | 136 | int i; |
4225 | | |
4226 | | /* Display the directions mask. */ |
4227 | 136 | if (tree) { |
4228 | 135 | proto_tree *dir_tree; |
4229 | | |
4230 | | /* Create a subtree. */ |
4231 | 135 | dir_tree = proto_tree_add_subtree(field_tree, tvb, *offset, 1, ett_ieee802154_gts_direction, &ti, "GTS Directions"); |
4232 | | |
4233 | | /* Add the directions to the subtree. */ |
4234 | 685 | for (i=0; i<gts_count; i++) { |
4235 | 550 | bool dir = gts_directions & IEEE802154_GTS_DIRECTION_SLOT(i); |
4236 | 550 | proto_tree_add_boolean_format(dir_tree, hf_ieee802154_gts_direction, tvb, *offset, 1, dir, "GTS Slot %i: %s", i+1, dir?"Receive Only":"Transmit Only"); |
4237 | 550 | if (dir) gts_rx++; |
4238 | 550 | } /* for */ |
4239 | 135 | proto_item_append_text(ti, ": %i Receive & %i Transmit", gts_rx, gts_count - gts_rx); |
4240 | 135 | } |
4241 | 136 | (*offset) += 1; |
4242 | | |
4243 | | /* Create a subtree for the GTS descriptors. */ |
4244 | 136 | subtree = proto_tree_add_subtree(field_tree, tvb, *offset, gts_count * 3, ett_ieee802154_gts_descriptors, NULL, "GTS Descriptors"); |
4245 | | |
4246 | | /* Get and display the GTS descriptors. */ |
4247 | 597 | for (i=0; i<gts_count; i++) { |
4248 | 461 | uint16_t gts_addr = tvb_get_letohs(tvb, (*offset)); |
4249 | 461 | uint8_t gts_slot = tvb_get_uint8(tvb, (*offset)+2); |
4250 | 461 | uint8_t gts_length = (gts_slot & IEEE802154_GTS_LENGTH_MASK) >> IEEE802154_GTS_LENGTH_SHIFT; |
4251 | | |
4252 | 461 | gts_slot = (gts_slot & IEEE802154_GTS_SLOT_MASK); |
4253 | | |
4254 | 461 | if (tree) { |
4255 | | /* Add address, slot, and time length fields. */ |
4256 | 438 | ti = proto_tree_add_uint(subtree, hf_ieee802154_gts_address, tvb, (*offset), 3, gts_addr); |
4257 | 438 | proto_item_append_text(ti, ", Slot: %i", gts_slot); |
4258 | 438 | proto_item_append_text(ti, ", Length: %i", gts_length); |
4259 | 438 | } |
4260 | 461 | (*offset) += 3; |
4261 | 461 | } /* for */ |
4262 | 136 | } |
4263 | 223 | } /* dissect_ieee802154_gtsinfo */ |
4264 | | |
4265 | | /** |
4266 | | * Subdissector for the pending address list fields within the beacon frame. |
4267 | | * |
4268 | | * @param tvb pointer to buffer containing raw packet. |
4269 | | * @param pinfo pointer to packet information fields (unused). |
4270 | | * @param tree pointer to command subtree. |
4271 | | * @param offset into the tvbuff to begin dissection. |
4272 | | */ |
4273 | | void |
4274 | | dissect_ieee802154_pendaddr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned *offset) |
4275 | 189 | { |
4276 | 189 | proto_tree *subtree; |
4277 | 189 | uint8_t pend_spec; |
4278 | 189 | uint8_t pend_num16; |
4279 | 189 | uint8_t pend_num64; |
4280 | 189 | int i; |
4281 | | |
4282 | | /* Get the Pending Addresses specification fields */ |
4283 | 189 | pend_spec = tvb_get_uint8(tvb, *offset); |
4284 | 189 | pend_num16 = pend_spec & IEEE802154_PENDADDR_SHORT_MASK; |
4285 | 189 | pend_num64 = (pend_spec & IEEE802154_PENDADDR_LONG_MASK) >> IEEE802154_PENDADDR_LONG_SHIFT; |
4286 | | |
4287 | | /* Add Subtree for the addresses */ |
4288 | 189 | subtree = proto_tree_add_subtree_format(tree, tvb, *offset, 1 + 2*pend_num16 + 8*pend_num64, |
4289 | 189 | ett_ieee802154_pendaddr, NULL, "Pending Addresses: %i Short and %i Long", pend_num16, pend_num64); |
4290 | 189 | (*offset) += 1; |
4291 | | |
4292 | 466 | for (i=0; i<pend_num16; i++) { |
4293 | 277 | uint16_t addr = tvb_get_letohs(tvb, *offset); |
4294 | 277 | proto_tree_add_uint(subtree, hf_ieee802154_pending16, tvb, *offset, 2, addr); |
4295 | 277 | (*offset) += 2; |
4296 | 277 | } /* for */ |
4297 | 458 | for (i=0; i<pend_num64; i++) { |
4298 | 269 | proto_tree_add_item(subtree, hf_ieee802154_pending64, tvb, *offset, 8, ENC_LITTLE_ENDIAN); |
4299 | 269 | (*offset) += 8; |
4300 | 269 | } /* for */ |
4301 | 189 | } /* dissect_ieee802154_pendaddr */ |
4302 | | |
4303 | | /* |
4304 | | * Header IEs |
4305 | | */ |
4306 | | |
4307 | | /** |
4308 | | * Create a tree for a Header IE incl. the TLV header and append the IE name to the parent item |
4309 | | * |
4310 | | * @param tvb the tv buffer |
4311 | | * @param tree the tree to append this item to |
4312 | | * @param hf field index |
4313 | | * @param ett tree index |
4314 | | * @returns the tree created for the Header IE |
4315 | | */ |
4316 | | proto_tree* |
4317 | | ieee802154_create_hie_tree(tvbuff_t *tvb, proto_tree *tree, int hf, int ett) |
4318 | 1.79k | { |
4319 | 1.79k | proto_item *subitem; |
4320 | 1.79k | proto_tree *subtree; |
4321 | 1.79k | header_field_info *hfinfo; |
4322 | 1.79k | static int * const tlv_fields[] = { |
4323 | 1.79k | &hf_ieee802154_header_ie_type, |
4324 | 1.79k | &hf_ieee802154_header_ie_id, |
4325 | 1.79k | &hf_ieee802154_header_ie_length, |
4326 | 1.79k | NULL |
4327 | 1.79k | }; |
4328 | | |
4329 | 1.79k | subitem = proto_tree_add_item(tree, hf, tvb, 0, tvb_reported_length(tvb), ENC_NA); |
4330 | 1.79k | subtree = proto_item_add_subtree(subitem, ett); |
4331 | 1.79k | proto_tree_add_bitmask_with_flags(subtree, tvb, 0, hf_ieee802154_header_ie_tlv, ett_ieee802154_header_ie_tlv, |
4332 | 1.79k | tlv_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
4333 | | |
4334 | 1.79k | hfinfo = proto_registrar_get_nth(hf); |
4335 | 1.79k | if (hfinfo && hfinfo->name) { |
4336 | 1.79k | proto_item_append_text(proto_tree_get_parent(tree), ", %s", hfinfo->name); |
4337 | 1.79k | } |
4338 | 1.79k | return subtree; |
4339 | 1.79k | } |
4340 | | |
4341 | | /* |
4342 | | * The dissectors for the individual Header IEs |
4343 | | * They are called via call_dissector with the tvb including the IE header and data as ieee802154_packet |
4344 | | */ |
4345 | | |
4346 | | /** |
4347 | | * Dissect the CSL IE (7.4.2.3) |
4348 | | */ |
4349 | | static int |
4350 | | dissect_hie_csl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
4351 | 76 | { |
4352 | 76 | proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_csl, ett_ieee802154_hie_csl); |
4353 | 76 | proto_tree_add_item(subtree, hf_ieee802154_hie_csl_phase, tvb, 2, 2, ENC_LITTLE_ENDIAN); |
4354 | 76 | proto_tree_add_item(subtree, hf_ieee802154_hie_csl_period, tvb, 4, 2, ENC_LITTLE_ENDIAN); |
4355 | 76 | if (tvb_reported_length(tvb) >= 8) { |
4356 | 59 | proto_tree_add_item(subtree, hf_ieee802154_hie_csl_rendezvous_time, tvb, 6, 2, ENC_LITTLE_ENDIAN); |
4357 | 59 | return 2 + 6; |
4358 | 59 | } |
4359 | 17 | return 2 + 4; |
4360 | 76 | } |
4361 | | |
4362 | | /** |
4363 | | * Dissect the Rendez-Vous Time IE (7.4.2.6) |
4364 | | * The IE is made of 2 fields: |
4365 | | * - RendezVous Time: in 802.15.4-2015, this is exactly the same field as in the CSL IE |
4366 | | * - Wake-Up Interval: the spec text is unclear about the field being optional or not. This dissector assumes it is |
4367 | | */ |
4368 | | static int |
4369 | | dissect_hie_rendezvous_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
4370 | 73 | { |
4371 | 73 | proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_rdv, ett_ieee802154_hie_rdv); |
4372 | | |
4373 | | // reuse field from CSL IE |
4374 | 73 | proto_tree_add_item(subtree, hf_ieee802154_hie_csl_rendezvous_time, tvb, 2, 2, ENC_LITTLE_ENDIAN); |
4375 | | |
4376 | | // In 802.15.4-2015, Rendez-Vous Time IE is only present in CSL Wake-Up Frames |
4377 | | // Update the packet information |
4378 | 73 | col_set_str(pinfo->cinfo, COL_INFO, "CSL Wake-up Frame"); |
4379 | 73 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Rendez-Vous Time: %d", tvb_get_uint16(tvb, 2, ENC_LITTLE_ENDIAN)); |
4380 | | |
4381 | | // Assume Wake-Up Interval is optional. Spec says "only present [...] when macCslInterval is nonzero" |
4382 | 73 | if (tvb_reported_length(tvb) >= 6) { |
4383 | 72 | proto_tree_add_item(subtree, hf_ieee802154_hie_rdv_wakeup_interval, tvb, 4, 2, ENC_LITTLE_ENDIAN); |
4384 | 72 | return 2 + 4; |
4385 | 72 | } |
4386 | | |
4387 | 1 | return 2 + 2; |
4388 | 73 | } |
4389 | | |
4390 | | /** |
4391 | | * Dissect the Time Correction Header IE (7.4.2.7) |
4392 | | * |
4393 | | * This field is constructed by taking a signed 16-bit 2's complement time |
4394 | | * correction in the range of -2048 us to 2047 us, AND'ing it with 0xfff, and |
4395 | | * OR'ing again with 0x8000 to indicate a negative acknowledgment. |
4396 | | */ |
4397 | | static int |
4398 | | dissect_hie_time_correction(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_) |
4399 | 74 | { |
4400 | 74 | static int * const fields[] = { |
4401 | 74 | &hf_ieee802154_hie_time_correction_value, |
4402 | 74 | &hf_ieee802154_nack, |
4403 | 74 | NULL |
4404 | 74 | }; |
4405 | 74 | proto_tree *tree = ieee802154_create_hie_tree(tvb, ies_tree, hf_ieee802154_hie_time_correction, ett_ieee802154_hie_time_correction); |
4406 | 74 | uint16_t time_sync_value = tvb_get_letohs(tvb, 2); |
4407 | 74 | proto_tree_add_bitmask_with_flags(tree, tvb, 2, hf_ieee802154_hie_time_correction_time_sync_info, ett_ieee802154_header_ie, |
4408 | 74 | fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
4409 | | |
4410 | 74 | if (time_sync_value & ~(0x8fff)) { |
4411 | 23 | expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802154_time_correction_error); |
4412 | 23 | } |
4413 | 74 | if (time_sync_value & 0x8000) { |
4414 | 14 | proto_item_append_text(proto_tree_get_parent(ies_tree), ": NACK"); |
4415 | 14 | } |
4416 | 74 | return 2 + 2; |
4417 | 74 | } |
4418 | | |
4419 | | static int |
4420 | | dissect_hie_global_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
4421 | 21 | { |
4422 | 21 | proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_global_time, ett_ieee802154_hie_global_time); |
4423 | 21 | proto_tree_add_item(subtree, hf_ieee802154_hie_global_time_value, tvb, 2, 4, ENC_TIME_SECS|ENC_LITTLE_ENDIAN); |
4424 | 21 | return 2 + 4; |
4425 | 21 | } |
4426 | | |
4427 | | /** |
4428 | | * Dissect the Vendor Specific IE (7.4.2.2) |
4429 | | */ |
4430 | | static int |
4431 | | dissect_hie_vendor_specific(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
4432 | 0 | { |
4433 | 0 | proto_tree *subtree = ieee802154_create_hie_tree(tvb, tree, hf_ieee802154_hie_vendor_specific, |
4434 | 0 | ett_ieee802154_hie_vendor_specific); |
4435 | |
|
4436 | 0 | unsigned hie_length = tvb_reported_length(tvb) - 2; |
4437 | 0 | unsigned offset = 2; |
4438 | |
|
4439 | 0 | tvb_get_letoh24(tvb, offset); |
4440 | 0 | proto_tree_add_item(subtree, hf_ieee802154_hie_vendor_specific_vendor_oui, tvb, offset, 3, ENC_LITTLE_ENDIAN); |
4441 | 0 | offset += 3; /* adjust for vendor OUI */ |
4442 | 0 | hie_length -= 3; |
4443 | |
|
4444 | 0 | proto_tree_add_item(subtree, hf_ieee802154_hie_vendor_specific_content, tvb, offset, hie_length, ENC_NA); |
4445 | |
|
4446 | 0 | return tvb_reported_length(tvb); |
4447 | 0 | } |
4448 | | |
4449 | | /** |
4450 | | Subdissector for Vendor Specific Header IEs (Information Elements) |
4451 | | */ |
4452 | | static int |
4453 | | dissect_ie_vendor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_) |
4454 | 107 | { |
4455 | 107 | proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_pie_vendor, ett_ieee802154_pie_vendor); |
4456 | | |
4457 | 107 | unsigned offset = 2; |
4458 | 107 | unsigned pie_length = tvb_reported_length(tvb) - 2; |
4459 | 107 | tvbuff_t *next_tvb; |
4460 | 107 | uint32_t vendor_oui; |
4461 | | |
4462 | 107 | vendor_oui = tvb_get_letoh24(tvb, offset); |
4463 | 107 | proto_tree_add_item(tree, hf_ieee802154_pie_vendor_oui, tvb, offset, 3, ENC_LITTLE_ENDIAN); |
4464 | 107 | offset += 3; /* adjust for vendor OUI */ |
4465 | 107 | pie_length -= 3; |
4466 | 107 | next_tvb = tvb_new_subset_length(tvb, offset, pie_length); |
4467 | | |
4468 | 107 | switch (vendor_oui) { |
4469 | 0 | case OUI_THREAD: |
4470 | | /*Decoding vendor variable data */ |
4471 | 0 | proto_tree_add_item(tree, hf_ieee802154_pie_vendor_variable, tvb, offset, pie_length, ENC_NA); |
4472 | 0 | break; |
4473 | | |
4474 | 78 | default: |
4475 | 78 | call_data_dissector(next_tvb, pinfo, tree); |
4476 | 78 | break; |
4477 | 107 | } |
4478 | | |
4479 | 78 | return tvb_reported_length(tvb); |
4480 | 107 | } |
4481 | | |
4482 | | /** |
4483 | | * Subdissector for Header IEs (Information Elements) |
4484 | | * |
4485 | | * Since the header is never encrypted and the payload may be encrypted, |
4486 | | * we dissect header and payload IEs separately. |
4487 | | * The termination of the Header IE tells us whether there are any |
4488 | | * payload IEs to follow. |
4489 | | * |
4490 | | * @param tvb the tv buffer |
4491 | | * @param pinfo pointer to packet information fields. |
4492 | | * @param tree the tree to append this item to |
4493 | | * @param orig_offset offset into the tvbuff to begin dissection. |
4494 | | * @param packet IEEE 802.15.4 packet information. |
4495 | | */ |
4496 | | static int |
4497 | | dissect_ieee802154_header_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned orig_offset, ieee802154_packet *packet) |
4498 | 415 | { |
4499 | | // GCC emits a spurious -Wclobbered if offset is used as function parameter (even with volatile) |
4500 | 415 | volatile unsigned offset = orig_offset; |
4501 | 415 | proto_item *ies_item = proto_tree_add_item(tree, hf_ieee802154_header_ies, tvb, offset, -1, ENC_NA); |
4502 | 415 | proto_tree *ies_tree = proto_item_add_subtree(ies_item, ett_ieee802154_header_ie); |
4503 | 415 | volatile int remaining = tvb_reported_length_remaining(tvb, offset) - IEEE802154_MIC_LENGTH(packet->security_level); |
4504 | | |
4505 | | // Loop as long as we don't: |
4506 | | // |
4507 | | // 1) run out of data; |
4508 | | // 2) get a header termination IE. |
4509 | | // |
4510 | | // See Table 9-6 "Termination IE inclusion rules" of IEEE Std 802.15.4-2015; |
4511 | | // unless we have no payload IEs and no payload data, we *have* to have |
4512 | | // a header termination IE to end the list of header IEs, so the "run out |
4513 | | // of data" check needs only to check whether there's any data |
4514 | | // left in the tvbuff (which has already had the FCS removed from |
4515 | | // it), other than a MIC if present - if we have no payload IEs or |
4516 | | // payload data, there might still be a MIC to Check the Message |
4517 | | // Integrity. |
4518 | | // |
4519 | | // XXX - we should make sure we have enough data left for an IE header, |
4520 | | // and report a malformed frame if not, and if we do have enough data, |
4521 | | // make sure we have enough data for the full IE, and report a malformed |
4522 | | // frame if not. |
4523 | 1.81k | do { |
4524 | 1.81k | volatile int consumed = 0; |
4525 | 1.81k | uint16_t ie_header = tvb_get_letohs(tvb, offset); |
4526 | 1.81k | uint16_t id = (uint16_t) ((ie_header & IEEE802154_HEADER_IE_ID_MASK) >> 7); |
4527 | 1.81k | uint16_t length = (uint16_t) (ie_header & IEEE802154_HEADER_IE_LENGTH_MASK); |
4528 | 1.81k | tvbuff_t * volatile ie_tvb = tvb_new_subset_length(tvb, offset, 2 + length); |
4529 | | |
4530 | 1.81k | if (id == IEEE802154_HEADER_IE_HT1 || id == IEEE802154_HEADER_IE_HT2) { |
4531 | 283 | int hf_term_ie = (id == IEEE802154_HEADER_IE_HT1) ? hf_ieee802154_hie_ht1 : hf_ieee802154_hie_ht2; |
4532 | 283 | ieee802154_create_hie_tree(ie_tvb, ies_tree, hf_term_ie, ett_ieee802154_hie_ht); |
4533 | 283 | consumed = 2; |
4534 | 1.52k | } else if (id == IEEE802154_HEADER_IE_VENDOR_SPECIFIC) { |
4535 | 107 | ieee802154_create_hie_tree(ie_tvb, ies_tree, hf_ieee802154_hie_thread, ett_ieee802154_hie_thread); |
4536 | 107 | dissect_ie_vendor(ie_tvb, pinfo, ies_tree, packet); |
4537 | 107 | consumed = 2 + length; |
4538 | 1.42k | } else { |
4539 | 1.42k | TRY { |
4540 | 1.40k | consumed = dissector_try_uint_with_data(header_ie_dissector_table, id, ie_tvb, pinfo, ies_tree, false, packet); |
4541 | 1.40k | if (consumed == 0) { |
4542 | 1.08k | proto_tree *subtree = ieee802154_create_hie_tree(ie_tvb, ies_tree, hf_ieee802154_hie_unsupported, |
4543 | 1.08k | ett_ieee802154_hie_unsupported); |
4544 | 1.08k | proto_tree_add_item(subtree, hf_ieee802154_ie_unknown_content, ie_tvb, 2, length, ENC_NA); |
4545 | 1.08k | consumed = 2 + length; |
4546 | 1.08k | if (ie_header & IEEE802154_PAYLOAD_IE_TYPE_MASK) { |
4547 | 438 | expert_add_info(pinfo, ies_tree, &ei_ieee802154_payload_ie_in_header); |
4548 | 651 | } else { |
4549 | 651 | expert_add_info(pinfo, ies_tree, &ei_ieee802154_ie_unsupported_id); |
4550 | 651 | } |
4551 | 1.08k | } |
4552 | 1.40k | } |
4553 | 1.42k | CATCH_ALL { |
4554 | 99 | show_exception(tvb, pinfo, ies_tree, EXCEPT_CODE, GET_MESSAGE); |
4555 | 99 | consumed = 2 + length; |
4556 | 99 | } |
4557 | 1.42k | ENDTRY; |
4558 | 1.42k | } |
4559 | | |
4560 | 1.81k | if (consumed < 2 + length) { |
4561 | 465 | proto_tree_add_item(ies_tree, hf_ieee802154_ie_unknown_content, ie_tvb, consumed, 2 + length - consumed, ENC_NA); |
4562 | 465 | expert_add_info(pinfo, ies_item, &ei_ieee802154_ie_unknown_extra_content); |
4563 | 465 | } |
4564 | | |
4565 | 1.81k | offset += 2 + length; |
4566 | 1.81k | remaining -= 2 + length; |
4567 | | |
4568 | 1.81k | if (id == IEEE802154_HEADER_IE_HT1 || id == IEEE802154_HEADER_IE_HT2) { |
4569 | 281 | packet->payload_ie_present = (id == IEEE802154_HEADER_IE_HT1); |
4570 | 281 | break; |
4571 | 281 | } |
4572 | 1.81k | } while (remaining > 0); |
4573 | | |
4574 | 415 | proto_item_set_len(ies_item, offset - orig_offset); |
4575 | 415 | return offset - orig_offset; |
4576 | 415 | } |
4577 | | |
4578 | | static int |
4579 | | dissect_802154_eb_filter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
4580 | 17 | { |
4581 | 17 | uint8_t filter; |
4582 | 17 | uint8_t attr_len; |
4583 | 17 | proto_tree *subtree; |
4584 | 17 | unsigned offset = 0; |
4585 | | |
4586 | 17 | static int * const fields_eb_filter[] = { |
4587 | 17 | &hf_ieee802154_psie_eb_filter_pjoin, |
4588 | 17 | &hf_ieee802154_psie_eb_filter_lqi, |
4589 | 17 | &hf_ieee802154_psie_eb_filter_percent, |
4590 | 17 | &hf_ieee802154_psie_eb_filter_attr_id, |
4591 | | /* reserved 5-7 */ |
4592 | 17 | NULL |
4593 | 17 | }; |
4594 | | |
4595 | 17 | subtree = ieee802154_create_psie_tree(tvb, tree, hf_ieee802154_psie_eb_filter, ett_ieee802154_eb_filter); |
4596 | 17 | offset += 2; |
4597 | | |
4598 | 17 | filter = tvb_get_uint8(tvb, offset); |
4599 | 17 | proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_psie_eb_filter, |
4600 | 17 | ett_ieee802154_eb_filter_bitmap, fields_eb_filter, ENC_NA); |
4601 | 17 | offset++; |
4602 | | |
4603 | 17 | if (filter & IEEE802154_MLME_PSIE_EB_FLT_LQI) { |
4604 | 12 | proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_lqi_min, tvb, offset, 1, ENC_NA); |
4605 | 12 | offset++; |
4606 | 12 | } |
4607 | | |
4608 | 17 | if (filter & IEEE802154_MLME_PSIE_EB_FLT_PERCENT) { |
4609 | 12 | proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_percent_prob, tvb, offset, 1, ENC_NA); |
4610 | 12 | offset++; |
4611 | 12 | } |
4612 | | |
4613 | 17 | attr_len = (uint8_t) ((filter & IEEE802154_MLME_PSIE_EB_FLT_ATTR_LEN) >> 3); |
4614 | 17 | if (attr_len) { |
4615 | | /* just display in hex until we know how to decode */ |
4616 | 12 | proto_tree_add_item(subtree, hf_ieee802154_psie_eb_filter_attr_id_bitmap, tvb, offset, attr_len, ENC_LITTLE_ENDIAN); |
4617 | 12 | offset += attr_len; |
4618 | 12 | } |
4619 | | |
4620 | 17 | return offset; |
4621 | 17 | } |
4622 | | |
4623 | | /** |
4624 | | * Subdissector for MLME IEs |
4625 | | */ |
4626 | | static int |
4627 | | dissect_pie_mlme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ies_tree, void *data) |
4628 | 127 | { |
4629 | 127 | proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_mlme, ett_ieee802154_mlme); |
4630 | 127 | volatile unsigned offset = 2; |
4631 | | |
4632 | 1.40k | while (tvb_reported_length_remaining(tvb, offset) > 1) { |
4633 | 1.28k | uint16_t psie_ie = tvb_get_letohs(tvb, offset); |
4634 | 1.28k | volatile uint16_t psie_id; |
4635 | 1.28k | tvbuff_t *volatile psie_tvb; |
4636 | | |
4637 | 1.28k | if (psie_ie & IEEE802154_PSIE_TYPE_MASK) { |
4638 | | /* long format: Table 7-17-Sub-ID allocation for long format */ |
4639 | 58 | psie_id = (uint16_t) ((psie_ie & IEEE802154_PSIE_ID_MASK_LONG) >> 11); |
4640 | 58 | psie_tvb = tvb_new_subset_length(tvb, offset, (psie_ie & IEEE802154_PSIE_LENGTH_MASK_LONG) + 2); |
4641 | 58 | } |
4642 | 1.22k | else { |
4643 | | /* short format: Table 7-16-Sub-ID allocation for short format */ |
4644 | 1.22k | psie_id = (uint16_t) ((psie_ie & IEEE802154_PSIE_ID_MASK_SHORT) >> 8); |
4645 | 1.22k | psie_tvb = tvb_new_subset_length(tvb, offset, (psie_ie & IEEE802154_PSIE_LENGTH_MASK_SHORT) + 2); |
4646 | 1.22k | } |
4647 | 1.28k | offset += tvb_reported_length(psie_tvb); |
4648 | | |
4649 | | /* Pass the tvb off to a subdissector. */ |
4650 | 1.28k | TRY { |
4651 | 1.27k | unsigned consumed = dissector_try_uint_with_data(mlme_ie_dissector_table, psie_id, psie_tvb, pinfo, tree, false, data); |
4652 | 1.27k | if (consumed == 0) { |
4653 | 1.03k | proto_tree *subtree = ieee802154_create_psie_tree(psie_tvb, tree, hf_ieee802154_mlme_ie_unsupported, ett_ieee802154_mlme_unsupported); |
4654 | 1.03k | if (tvb_reported_length(psie_tvb) > 2) { |
4655 | 352 | proto_tree_add_item(subtree, hf_ieee802154_mlme_ie_data, psie_tvb, 2, -1, ENC_NA); |
4656 | 352 | } |
4657 | 1.03k | expert_add_info(pinfo, subtree, &ei_ieee802154_ie_unsupported_id); |
4658 | 1.03k | } |
4659 | 1.27k | } |
4660 | 1.28k | CATCH_ALL { |
4661 | 73 | show_exception(tvb, pinfo, ies_tree, EXCEPT_CODE, GET_MESSAGE); |
4662 | 73 | } |
4663 | 1.28k | ENDTRY; |
4664 | 1.28k | } |
4665 | 127 | return offset; |
4666 | 127 | } |
4667 | | |
4668 | | /** |
4669 | | * Subdissector for MPX IEs (IEEE 802.15.9) |
4670 | | */ |
4671 | | static int |
4672 | | dissect_mpx_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_) |
4673 | 149 | { |
4674 | 149 | static int * const fields[] = { |
4675 | 149 | &hf_ieee802159_mpx_transaction_id, |
4676 | 149 | &hf_ieee802159_mpx_transfer_type, |
4677 | 149 | NULL |
4678 | 149 | }; |
4679 | 149 | static int * const fields_compressed_multiplex_id[] = { |
4680 | 149 | &hf_ieee802159_mpx_transaction_id_as_multiplex_id, |
4681 | 149 | &hf_ieee802159_mpx_transfer_type, |
4682 | 149 | NULL |
4683 | 149 | }; |
4684 | | |
4685 | 149 | proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802159_mpx, ett_ieee802159_mpx); |
4686 | 149 | unsigned offset = 2; |
4687 | 149 | uint8_t transaction_control = tvb_get_uint8(tvb, offset); |
4688 | 149 | uint8_t transfer_type = (uint8_t) (transaction_control & IEEE802159_MPX_TRANSFER_TYPE_MASK); |
4689 | 149 | uint8_t transaction_id = (uint8_t) ((transaction_control & IEEE802159_MPX_TRANSACTION_ID_MASK) >> IEEE802159_MPX_TRANSACTION_ID_SHIFT); |
4690 | 149 | int32_t multiplex_id = -1; |
4691 | 149 | uint8_t fragment_number; |
4692 | | |
4693 | 149 | if (transfer_type == IEEE802159_MPX_FULL_FRAME_NO_MUXID) { |
4694 | 7 | proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee802159_mpx_transaction_control, ett_ieee802159_mpx_transaction_control, |
4695 | 7 | fields_compressed_multiplex_id, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
4696 | 7 | multiplex_id = transaction_id; |
4697 | 142 | } else { |
4698 | 142 | proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee802159_mpx_transaction_control, ett_ieee802159_mpx_transaction_control, |
4699 | 142 | fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); |
4700 | 142 | } |
4701 | 149 | offset += 1; |
4702 | | |
4703 | 149 | switch (transfer_type) { // cf. IEEE 802.15.9 Table 18 - Summary of different MPX IE formats |
4704 | 103 | case IEEE802159_MPX_FULL_FRAME: |
4705 | 103 | multiplex_id = tvb_get_letohs(tvb, offset); |
4706 | 103 | proto_tree_add_uint_format_value(tree, hf_ieee802159_mpx_multiplex_id, tvb, offset, 2, multiplex_id, "%s (0x%04x)", |
4707 | 103 | val_to_str_const(multiplex_id, (multiplex_id > 1500) ? etype_vals : mpx_multiplex_id_vals, "Unknown"), multiplex_id); |
4708 | 103 | offset += 2; |
4709 | 103 | break; |
4710 | 7 | case IEEE802159_MPX_FULL_FRAME_NO_MUXID: |
4711 | 7 | break; // nothing to do |
4712 | 5 | case IEEE802159_MPX_NON_LAST_FRAGMENT: |
4713 | 5 | proto_tree_add_item_ret_uint8(tree, hf_ieee802159_mpx_fragment_number, tvb, offset, 1, ENC_LITTLE_ENDIAN, &fragment_number); |
4714 | 5 | offset += 1; |
4715 | 5 | if (fragment_number == 0) { |
4716 | 3 | proto_tree_add_item(tree, hf_ieee802159_mpx_total_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4717 | 3 | offset += 2; |
4718 | 3 | multiplex_id = tvb_get_letohs(tvb, offset); |
4719 | 3 | proto_tree_add_item(tree, hf_ieee802159_mpx_multiplex_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4720 | 3 | offset += 2; |
4721 | 3 | } |
4722 | 5 | break; |
4723 | 1 | case IEEE802159_MPX_LAST_FRAGMENT: |
4724 | 1 | proto_tree_add_item(tree, hf_ieee802159_mpx_fragment_number, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
4725 | 1 | offset += 1; |
4726 | 1 | break; |
4727 | 3 | case IEEE802159_MPX_ABORT: |
4728 | 3 | if (tvb_reported_length_remaining(tvb, offset) == 2) { |
4729 | 0 | proto_tree_add_item(tree, hf_ieee802159_mpx_total_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
4730 | 0 | offset += 2; |
4731 | 0 | } |
4732 | 3 | return offset; |
4733 | 3 | default: // reserved values -> warning and return |
4734 | 3 | expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_invalid_transfer_type); |
4735 | 3 | return offset; |
4736 | 149 | } |
4737 | | |
4738 | | // TODO: reassembly |
4739 | | |
4740 | 115 | dissector_handle_t dissector = NULL; |
4741 | | |
4742 | 115 | if (multiplex_id == IEEE802159_MPX_MULTIPLEX_ID_KMP) { |
4743 | 2 | uint8_t kmp_id = tvb_get_uint8(tvb, offset); |
4744 | 2 | proto_tree_add_item(tree, hf_ieee802159_mpx_kmp_id, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
4745 | 2 | offset += 1; |
4746 | 2 | switch (kmp_id) { |
4747 | 1 | case IEEE802159_MPX_KMP_ID_IEEE8021X: |
4748 | 1 | case IEEE802159_MPX_KMP_ID_IEEE80211_4WH: |
4749 | 1 | case IEEE802159_MPX_KMP_ID_IEEE80211_GKH: |
4750 | 1 | dissector = eapol_handle; |
4751 | 1 | break; |
4752 | | |
4753 | | // TODO |
4754 | 0 | case IEEE802159_MPX_KMP_ID_HIP: |
4755 | 0 | case IEEE802159_MPX_KMP_ID_IKEV2: |
4756 | 0 | case IEEE802159_MPX_KMP_ID_PANA: |
4757 | 0 | case IEEE802159_MPX_KMP_ID_DRAGONFLY: |
4758 | 0 | case IEEE802159_MPX_KMP_ID_ETSI_TS_102_887_2: |
4759 | 0 | expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unsupported_kmp); |
4760 | 0 | break; |
4761 | | |
4762 | 0 | case IEEE802159_MPX_KMP_ID_VENDOR_SPECIFIC: |
4763 | 0 | proto_tree_add_item(tree, hf_ieee802159_mpx_kmp_vendor_oui, tvb, offset, 3, ENC_BIG_ENDIAN); |
4764 | 0 | offset += 3; |
4765 | 0 | break; |
4766 | | |
4767 | | // Unknown |
4768 | 1 | default: |
4769 | 1 | expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unknown_kmp); |
4770 | 2 | } |
4771 | 2 | } |
4772 | 113 | else if (multiplex_id == IEEE802159_MPX_MULTIPLEX_ID_WISUN) { |
4773 | 1 | uint8_t subid = tvb_get_uint8(tvb, offset); |
4774 | 1 | proto_tree_add_item(tree, hf_ieee802159_mpx_wisun_subid, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
4775 | 1 | offset += 1; |
4776 | 1 | switch (subid) { |
4777 | 0 | case IEEE802159_MPX_WISUN_SUBID_6LOWPAN: |
4778 | 0 | dissector = lowpan_handle; |
4779 | 0 | break; |
4780 | | |
4781 | 0 | case IEEE802159_MPX_WISUN_SUBID_SECURITY: |
4782 | 0 | dissector = wisun_sec_handle; |
4783 | 0 | break; |
4784 | | |
4785 | 0 | case IEEE802159_MPX_WISUN_SUBID_MHDS: |
4786 | 0 | expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unsupported_kmp); |
4787 | 0 | break; |
4788 | | |
4789 | 1 | default: |
4790 | 1 | expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unknown_kmp); |
4791 | 1 | break; |
4792 | 1 | } |
4793 | 1 | } |
4794 | 112 | else if (multiplex_id > 1500) { |
4795 | 94 | dissector = dissector_get_uint_handle(ethertype_table, (unsigned)multiplex_id); |
4796 | 94 | } |
4797 | | |
4798 | 115 | if (transfer_type == IEEE802159_MPX_FULL_FRAME || transfer_type == IEEE802159_MPX_FULL_FRAME_NO_MUXID) { |
4799 | 110 | tvbuff_t * payload = tvb_new_subset_remaining(tvb, offset); |
4800 | 110 | if (dissector) { |
4801 | 1 | call_dissector(dissector, payload, pinfo, proto_tree_get_root(tree)); // exceptions are caught in our caller |
4802 | 109 | } else { |
4803 | 109 | call_data_dissector(payload, pinfo, proto_tree_get_root(tree)); |
4804 | 109 | } |
4805 | 110 | } else { |
4806 | 5 | proto_tree_add_item(tree, hf_ieee802159_mpx_fragment, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA); |
4807 | 5 | } |
4808 | 115 | offset = tvb_reported_length(tvb); |
4809 | | |
4810 | 115 | return offset; |
4811 | 115 | } |
4812 | | |
4813 | | /** |
4814 | | * Subdissector for Vendor Specific Payload IEs (Information Elements) |
4815 | | */ |
4816 | | static int |
4817 | | dissect_pie_vendor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ies_tree, void *data _U_) |
4818 | 16 | { |
4819 | 16 | proto_tree *tree = ieee802154_create_pie_tree(tvb, ies_tree, hf_ieee802154_pie_vendor, ett_ieee802154_pie_vendor); |
4820 | | |
4821 | 16 | unsigned offset = 2; |
4822 | 16 | unsigned pie_length = tvb_reported_length(tvb) - 2; |
4823 | 16 | tvbuff_t *next_tvb; |
4824 | 16 | uint32_t vendor_oui; |
4825 | | |
4826 | 16 | vendor_oui = tvb_get_letoh24(tvb, offset); |
4827 | 16 | proto_tree_add_item(tree, hf_ieee802154_pie_vendor_oui, tvb, offset, 3, ENC_LITTLE_ENDIAN); |
4828 | 16 | offset += 3; /* adjust for vendor OUI */ |
4829 | 16 | pie_length -= 3; |
4830 | 16 | next_tvb = tvb_new_subset_length(tvb, offset, pie_length); |
4831 | | |
4832 | 16 | switch (vendor_oui) { |
4833 | 0 | case OUI_ZIGBEE: |
4834 | 0 | call_dissector_with_data(zigbee_ie_handle, next_tvb, pinfo, tree, &pie_length); |
4835 | 0 | break; |
4836 | | |
4837 | 14 | default: |
4838 | 14 | call_data_dissector(next_tvb, pinfo, tree); |
4839 | 14 | break; |
4840 | 16 | } |
4841 | | |
4842 | 14 | return tvb_reported_length(tvb); |
4843 | 16 | } |
4844 | | |
4845 | | /** |
4846 | | * Subdissector for Payload IEs (Information Elements) |
4847 | | * |
4848 | | * @param tvb the tv buffer |
4849 | | * @param pinfo pointer to packet information fields. |
4850 | | * @param tree the tree to append this item to |
4851 | | * @param orig_offset offset into the tvbuff to begin dissection. |
4852 | | * @param packet IEEE 802.15.4 packet information. |
4853 | | */ |
4854 | | static int |
4855 | | dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned orig_offset, ieee802154_packet *packet) |
4856 | 275 | { |
4857 | | // GCC emits a spurious -Wclobbered if offset is used as function parameter (even with volatile) |
4858 | 275 | volatile unsigned offset = orig_offset; |
4859 | 275 | proto_item *ies_item = proto_tree_add_item(tree, hf_ieee802154_payload_ies, tvb, offset, -1, ENC_NA); |
4860 | 275 | proto_tree *ies_tree = proto_item_add_subtree(ies_item, ett_ieee802154_payload_ie); |
4861 | | |
4862 | 1.30k | do { |
4863 | 1.30k | volatile int consumed = 0; |
4864 | 1.30k | uint16_t ie_header = tvb_get_letohs(tvb, offset); |
4865 | 1.30k | uint16_t id = (uint16_t) ((ie_header & IEEE802154_PAYLOAD_IE_ID_MASK) >> 11); |
4866 | 1.30k | volatile uint16_t length = (uint16_t) (ie_header & IEEE802154_PAYLOAD_IE_LENGTH_MASK); |
4867 | 1.30k | tvbuff_t * volatile ie_tvb = tvb_new_subset_length(tvb, offset, 2 + length); |
4868 | | |
4869 | 1.30k | if (id == IEEE802154_PAYLOAD_IE_TERMINATION) { |
4870 | 8 | ieee802154_create_pie_tree(ie_tvb, ies_tree, hf_ieee802154_pie_termination, ett_ieee802154_pie_termination); |
4871 | 8 | consumed = 2; |
4872 | 1.29k | } else { |
4873 | 1.29k | TRY { |
4874 | 1.29k | consumed = dissector_try_uint_with_data(payload_ie_dissector_table, id, ie_tvb, pinfo, ies_tree, false, packet); |
4875 | 1.29k | if (consumed == 0) { |
4876 | 807 | proto_tree *subtree = ieee802154_create_pie_tree(ie_tvb, ies_tree, hf_ieee802154_pie_unsupported, ett_ieee802154_pie_unsupported); |
4877 | 807 | proto_tree_add_item(subtree, hf_ieee802154_ie_unknown_content_payload, ie_tvb, 2, length, ENC_NA); |
4878 | 807 | consumed = 2 + length; |
4879 | 807 | expert_add_info(pinfo, proto_tree_get_parent(subtree), &ei_ieee802154_ie_unsupported_id); |
4880 | 807 | } |
4881 | 1.29k | } |
4882 | 1.29k | CATCH_ALL { |
4883 | 127 | show_exception(tvb, pinfo, ies_tree, EXCEPT_CODE, GET_MESSAGE); |
4884 | 127 | consumed = 2 + length; |
4885 | 127 | } |
4886 | 1.29k | ENDTRY; |
4887 | 1.29k | } |
4888 | | |
4889 | 1.30k | if (consumed < 2 + length) { |
4890 | 122 | proto_tree_add_item(ies_tree, hf_ieee802154_ie_unknown_content_payload, ie_tvb, consumed, 2 + length - consumed, ENC_NA); |
4891 | 122 | expert_add_info(pinfo, ies_item, &ei_ieee802154_ie_unknown_extra_content_payload); |
4892 | 122 | } |
4893 | | |
4894 | 1.30k | offset += 2 + length; |
4895 | | |
4896 | 1.30k | if (id == IEEE802154_PAYLOAD_IE_TERMINATION) { |
4897 | 3 | break; |
4898 | 3 | } |
4899 | 1.30k | } while (tvb_reported_length_remaining(tvb, offset) > 1); |
4900 | | |
4901 | 275 | proto_item_set_len(ies_item, offset - orig_offset); |
4902 | 275 | return offset - orig_offset; |
4903 | 275 | } |
4904 | | |
4905 | | static const true_false_string tfs_cinfo_device_type = { "FFD", "RFD" }; |
4906 | | static const true_false_string tfs_cinfo_power_src = { "AC/Mains Power", "Battery" }; |
4907 | | |
4908 | | /** |
4909 | | * Command subdissector routine for the Association request command. |
4910 | | * |
4911 | | * @param tvb pointer to buffer containing raw packet. |
4912 | | * @param pinfo pointer to packet information fields. |
4913 | | * @param tree pointer to protocol tree. |
4914 | | * @param packet IEEE 802.15.4 packet information. |
4915 | | */ |
4916 | | |
4917 | | static void |
4918 | | dissect_ieee802154_assoc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet) |
4919 | 5 | { |
4920 | 5 | uint8_t cap; |
4921 | 5 | proto_tree *subtree; |
4922 | 5 | static int * const capability[] = { |
4923 | 5 | &hf_ieee802154_cinfo_alt_coord, |
4924 | 5 | &hf_ieee802154_cinfo_device_type, |
4925 | 5 | &hf_ieee802154_cinfo_power_src, |
4926 | 5 | &hf_ieee802154_cinfo_idle_rx, |
4927 | 5 | &hf_ieee802154_cinfo_sec_capable, |
4928 | 5 | &hf_ieee802154_cinfo_alloc_addr, |
4929 | 5 | NULL |
4930 | 5 | }; |
4931 | | |
4932 | 5 | cap = tvb_get_uint8(tvb, 0); |
4933 | 5 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", tfs_get_string(cap & IEEE802154_CMD_CINFO_DEVICE_TYPE, &tfs_cinfo_device_type)); |
4934 | | |
4935 | | /* Create a subtree for this command frame. */ |
4936 | 5 | subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL, |
4937 | 5 | val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command")); |
4938 | | |
4939 | | /* Get and display capability info. */ |
4940 | 5 | proto_tree_add_bitmask_list(subtree, tvb, 0, 1, capability, ENC_NA); |
4941 | | |
4942 | | /* Call the data dissector for any leftover bytes. */ |
4943 | 5 | if (tvb_reported_length(tvb) > 1) { |
4944 | 4 | call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree); |
4945 | 4 | } |
4946 | 5 | } /* dissect_ieee802154_assoc_req */ |
4947 | | |
4948 | | /** |
4949 | | * Command subdissector routine for the Association response command. |
4950 | | * |
4951 | | * @param tvb pointer to buffer containing raw packet. |
4952 | | * @param pinfo pointer to packet information fields. |
4953 | | * @param tree pointer to protocol tree. |
4954 | | * @param packet IEEE 802.15.4 packet information. |
4955 | | */ |
4956 | | static void |
4957 | | dissect_ieee802154_assoc_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet) |
4958 | 7 | { |
4959 | 7 | proto_tree *subtree; |
4960 | 7 | proto_item *ti; |
4961 | 7 | uint16_t short_addr; |
4962 | 7 | uint8_t status; |
4963 | 7 | unsigned offset = 0; |
4964 | | |
4965 | | /* Create a subtree for this command frame. */ |
4966 | 7 | subtree = proto_tree_add_subtree(tree, tvb, offset, 3, ett_ieee802154_cmd, NULL, |
4967 | 7 | val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command")); |
4968 | | |
4969 | | /* Get and display the short address. */ |
4970 | 7 | short_addr = tvb_get_letohs(tvb, offset); |
4971 | 7 | proto_tree_add_uint(subtree, hf_ieee802154_assoc_addr, tvb, offset, 2, short_addr); |
4972 | 7 | offset += 2; |
4973 | | |
4974 | | /* Get and display the status. */ |
4975 | 7 | status = tvb_get_uint8(tvb, offset); |
4976 | 7 | if (tree) { |
4977 | 6 | ti = proto_tree_add_uint(subtree, hf_ieee802154_assoc_status, tvb, offset, 1, status); |
4978 | 6 | if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) proto_item_append_text(ti, " (Association Successful)"); |
4979 | 3 | else if (status == IEEE802154_CMD_ASRSP_PAN_FULL) proto_item_append_text(ti, " (PAN Full)"); |
4980 | 2 | else if (status == IEEE802154_CMD_ASRSP_PAN_DENIED) proto_item_append_text(ti, " (Association Denied)"); |
4981 | 1 | else proto_item_append_text(ti, " (Reserved)"); |
4982 | 6 | } |
4983 | 7 | offset += 1; |
4984 | | |
4985 | | /* Update the info column. */ |
4986 | 7 | if (status == IEEE802154_CMD_ASRSP_AS_SUCCESS) { |
4987 | | /* Association was successful. */ |
4988 | 3 | if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) { |
4989 | 2 | col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", packet->dst_pan); |
4990 | 2 | } |
4991 | 3 | if (short_addr != IEEE802154_NO_ADDR16) { |
4992 | 3 | col_append_fstr(pinfo->cinfo, COL_INFO, " Addr: 0x%04x", short_addr); |
4993 | 3 | } |
4994 | 3 | } |
4995 | 4 | else { |
4996 | | /* Association was unsuccessful. */ |
4997 | 4 | col_append_str(pinfo->cinfo, COL_INFO, ", Unsuccessful"); |
4998 | 4 | } |
4999 | | |
5000 | | /* Update the address table. */ |
5001 | 7 | if ((status == IEEE802154_CMD_ASRSP_AS_SUCCESS) && (short_addr != IEEE802154_NO_ADDR16)) { |
5002 | 3 | ieee802154_addr_update(&ieee802154_map, short_addr, packet->dst_pan, packet->dst64, |
5003 | 3 | pinfo->current_proto, pinfo->num); |
5004 | 3 | } |
5005 | | |
5006 | | /* Call the data dissector for any leftover bytes. */ |
5007 | 7 | if (tvb_captured_length(tvb) > offset) { |
5008 | 6 | call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree); |
5009 | 6 | } |
5010 | 7 | } /* dissect_ieee802154_assoc_rsp */ |
5011 | | |
5012 | | /** |
5013 | | * Command subdissector routine for the Disassociate command. |
5014 | | * |
5015 | | * @param tvb pointer to buffer containing raw packet. |
5016 | | * @param pinfo pointer to packet information fields. |
5017 | | * @param tree pointer to protocol tree. |
5018 | | * @param packet IEEE 802.15.4 packet information. |
5019 | | */ |
5020 | | static void |
5021 | | dissect_ieee802154_disassoc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet) |
5022 | 3 | { |
5023 | 3 | proto_tree *subtree; |
5024 | 3 | proto_item *ti; |
5025 | 3 | uint8_t reason; |
5026 | | |
5027 | | /* Create a subtree for this command frame. */ |
5028 | 3 | subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL, |
5029 | 3 | val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command")); |
5030 | | |
5031 | | /* Get and display the disassociation reason. */ |
5032 | 3 | reason = tvb_get_uint8(tvb, 0); |
5033 | 3 | if (tree) { |
5034 | 3 | ti = proto_tree_add_uint(subtree, hf_ieee802154_disassoc_reason, tvb, 0, 1, reason); |
5035 | 3 | switch (reason) { |
5036 | 0 | case 0x01: |
5037 | 0 | proto_item_append_text(ti, " (Coordinator requests device to leave)"); |
5038 | 0 | break; |
5039 | | |
5040 | 0 | case 0x02: |
5041 | 0 | proto_item_append_text(ti, " (Device wishes to leave)"); |
5042 | 0 | break; |
5043 | | |
5044 | 3 | default: |
5045 | 3 | proto_item_append_text(ti, " (Reserved)"); |
5046 | 3 | break; |
5047 | 3 | } /* switch */ |
5048 | 3 | } |
5049 | | |
5050 | 3 | if (!PINFO_FD_VISITED(pinfo)) { |
5051 | | /* Update the address tables */ |
5052 | 3 | if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT ) { |
5053 | 0 | ieee802154_long_addr_invalidate(packet->dst64, pinfo->num); |
5054 | 3 | } else if ( packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT ) { |
5055 | 2 | ieee802154_short_addr_invalidate(packet->dst16, packet->dst_pan, pinfo->num); |
5056 | 2 | } |
5057 | 3 | } |
5058 | | |
5059 | | /* Call the data dissector for any leftover bytes. */ |
5060 | 3 | if (tvb_captured_length(tvb) > 1) { |
5061 | 3 | call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree); |
5062 | 3 | } |
5063 | 3 | } /* dissect_ieee802154_disassoc */ |
5064 | | |
5065 | | /** |
5066 | | * Command subdissector routine for the Coordinator Realignment command. |
5067 | | * |
5068 | | * @param tvb pointer to buffer containing raw packet. |
5069 | | * @param pinfo pointer to packet information fields. |
5070 | | * @param tree pointer to protocol tree. |
5071 | | * @param packet IEEE 802.15.4 packet information. |
5072 | | */ |
5073 | | static void |
5074 | | dissect_ieee802154_realign(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet) |
5075 | 2 | { |
5076 | 2 | proto_tree *subtree; |
5077 | 2 | proto_item *subitem; |
5078 | 2 | uint16_t pan_id; |
5079 | 2 | uint16_t coord_addr; |
5080 | 2 | uint8_t channel; |
5081 | 2 | uint16_t short_addr; |
5082 | 2 | unsigned offset = 0; |
5083 | | |
5084 | | /* Create a subtree for this command frame. */ |
5085 | 2 | subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_ieee802154_cmd, &subitem, |
5086 | 2 | val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command")); |
5087 | | |
5088 | | /* Get and display the command PAN ID. */ |
5089 | 2 | pan_id = tvb_get_letohs(tvb, offset); |
5090 | 2 | proto_tree_add_uint(subtree, hf_ieee802154_realign_pan, tvb, offset, 2, pan_id); |
5091 | 2 | col_append_fstr(pinfo->cinfo, COL_INFO, ", PAN: 0x%04x", pan_id); |
5092 | 2 | offset += 2; |
5093 | | |
5094 | | /* Get and display the coordinator address. */ |
5095 | 2 | coord_addr = tvb_get_letohs(tvb, offset); |
5096 | 2 | proto_tree_add_uint(subtree, hf_ieee802154_realign_caddr, tvb, offset, 2, coord_addr); |
5097 | 2 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Coordinator: 0x%04x", coord_addr); |
5098 | 2 | offset += 2; |
5099 | | |
5100 | | /* Get and display the channel. */ |
5101 | 2 | channel = tvb_get_uint8(tvb, offset); |
5102 | 2 | proto_tree_add_uint(subtree, hf_ieee802154_realign_channel, tvb, offset, 1, channel); |
5103 | 2 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Channel: %u", channel); |
5104 | 2 | offset += 1; |
5105 | | |
5106 | | /* Get and display the short address. */ |
5107 | 2 | short_addr = tvb_get_letohs(tvb, offset); |
5108 | 2 | if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_addr, tvb, offset, 2, short_addr); |
5109 | 2 | if ((packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) |
5110 | 1 | && (short_addr != IEEE802154_NO_ADDR16)) { |
5111 | 1 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Addr: 0x%04x", short_addr); |
5112 | 1 | } |
5113 | 2 | offset += 2; |
5114 | | /* Update the address table. */ |
5115 | 2 | if ((short_addr != IEEE802154_NO_ADDR16) && (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)) { |
5116 | 1 | ieee802154_addr_update(&ieee802154_map, short_addr, packet->dst_pan, packet->dst64, |
5117 | 1 | pinfo->current_proto, pinfo->num); |
5118 | 1 | } |
5119 | | |
5120 | | /* Get and display the channel page, if it exists. Added in IEEE802.15.4-2006 */ |
5121 | 2 | if (tvb_bytes_exist(tvb, offset, 1)) { |
5122 | 2 | uint8_t channel_page = tvb_get_uint8(tvb, offset); |
5123 | 2 | if (tree) proto_tree_add_uint(subtree, hf_ieee802154_realign_channel_page, tvb, offset, 1, channel_page); |
5124 | 2 | offset += 1; |
5125 | 2 | } |
5126 | | |
5127 | | /* Fix the length of the command subtree. */ |
5128 | 2 | if (tree) { |
5129 | 2 | proto_item_set_len(subitem, offset); |
5130 | 2 | } |
5131 | | |
5132 | | /* Call the data dissector for any leftover bytes. */ |
5133 | 2 | if (tvb_captured_length(tvb) > offset) { |
5134 | 2 | call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree); |
5135 | 2 | } |
5136 | 2 | } /* dissect_ieee802154_realign */ |
5137 | | |
5138 | | static const true_false_string tfs_gtsreq_dir = { "Receive", "Transmit" }; |
5139 | | static const true_false_string tfs_gtsreq_type= { "Allocate GTS", "Deallocate GTS" }; |
5140 | | |
5141 | | /** |
5142 | | * Command subdissector routine for the GTS request command. |
5143 | | * |
5144 | | * Assumes that COL_INFO will be set to the command name, |
5145 | | * command name will already be appended to the command subtree |
5146 | | * and protocol root. In addition, assumes that the command ID |
5147 | | * has already been parsed. |
5148 | | * |
5149 | | * @param tvb pointer to buffer containing raw packet. |
5150 | | * @param pinfo pointer to packet information fields (unused). |
5151 | | * @param tree pointer to protocol tree. |
5152 | | * @param packet IEEE 802.15.4 packet information (unused). |
5153 | | */ |
5154 | | |
5155 | | static void |
5156 | | dissect_ieee802154_gtsreq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet) |
5157 | 2 | { |
5158 | 2 | proto_tree *subtree; |
5159 | 2 | static int * const characteristics[] = { |
5160 | 2 | &hf_ieee802154_gtsreq_len, |
5161 | 2 | &hf_ieee802154_gtsreq_dir, |
5162 | 2 | &hf_ieee802154_gtsreq_type, |
5163 | 2 | NULL |
5164 | 2 | }; |
5165 | | |
5166 | | /* Create a subtree for this command frame. */ |
5167 | 2 | subtree = proto_tree_add_subtree(tree, tvb, 0, 1, ett_ieee802154_cmd, NULL, |
5168 | 2 | val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command")); |
5169 | | |
5170 | 2 | proto_tree_add_bitmask_list(subtree, tvb, 0, 1, characteristics, ENC_NA); |
5171 | | |
5172 | | /* Call the data dissector for any leftover bytes. */ |
5173 | 2 | if (tvb_reported_length(tvb) > 1) { |
5174 | 2 | call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree); |
5175 | 2 | } |
5176 | 2 | } /* dissect_ieee802154_gtsreq */ |
5177 | | |
5178 | | /** |
5179 | | * Subdissector routine for IEEE 802.15.4 commands |
5180 | | * |
5181 | | * @param tvb pointer to buffer containing the command payload |
5182 | | * @param pinfo pointer to packet information fields |
5183 | | * @param tree pointer to the protocol tree |
5184 | | * @param packet IEEE 802.15.4 packet information |
5185 | | */ |
5186 | | static void |
5187 | | dissect_ieee802154_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet) |
5188 | 43 | { |
5189 | 43 | if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_CMD)) { |
5190 | | /* In 802.15.4e and later the Command Id follows the Payload IEs. */ |
5191 | 12 | packet->command_id = tvb_get_uint8(tvb, 0); |
5192 | 12 | proto_tree_add_uint(tree, hf_ieee802154_cmd_id, tvb, 0, 1, packet->command_id); |
5193 | 12 | tvb = tvb_new_subset_remaining(tvb, 1); |
5194 | | |
5195 | | /* Display the command identifier in the info column. */ |
5196 | 12 | if ((packet->version == IEEE802154_VERSION_2015) && (packet->command_id == IEEE802154_CMD_BEACON_REQ)) { |
5197 | 1 | col_set_str(pinfo->cinfo, COL_INFO, "Enhanced Beacon Request"); |
5198 | 1 | } |
5199 | 11 | else { |
5200 | 11 | col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet->command_id, ieee802154_cmd_names, "Unknown Command")); |
5201 | 11 | } |
5202 | 12 | } |
5203 | | |
5204 | 43 | switch (packet->command_id) { |
5205 | 5 | case IEEE802154_CMD_ASSOC_REQ: |
5206 | 5 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5207 | 5 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && |
5208 | 5 | (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE)); |
5209 | 5 | dissect_ieee802154_assoc_req(tvb, pinfo, tree, packet); |
5210 | 5 | break; |
5211 | | |
5212 | 7 | case IEEE802154_CMD_ASSOC_RSP: |
5213 | 7 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5214 | 7 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && |
5215 | 7 | (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)); |
5216 | 7 | dissect_ieee802154_assoc_rsp(tvb, pinfo, tree, packet); |
5217 | 7 | break; |
5218 | | |
5219 | 3 | case IEEE802154_CMD_DISASSOC_NOTIFY: |
5220 | 3 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5221 | 3 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && |
5222 | 3 | (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)); |
5223 | 3 | dissect_ieee802154_disassoc(tvb, pinfo, tree, packet); |
5224 | 3 | break; |
5225 | | |
5226 | 2 | case IEEE802154_CMD_DATA_RQ: |
5227 | 2 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE); |
5228 | | /* No payload expected. */ |
5229 | 2 | break; |
5230 | | |
5231 | 0 | case IEEE802154_CMD_PANID_CONFLICT: |
5232 | 0 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5233 | 0 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && |
5234 | 0 | (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT)); |
5235 | | /* No payload expected. */ |
5236 | 0 | break; |
5237 | | |
5238 | 2 | case IEEE802154_CMD_ORPHAN_NOTIFY: |
5239 | 2 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5240 | 2 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && |
5241 | 2 | (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && |
5242 | 2 | (packet->dst16 == IEEE802154_BCAST_ADDR) && |
5243 | 2 | (packet->src_pan == IEEE802154_BCAST_PAN) && |
5244 | 2 | (packet->dst_pan == IEEE802154_BCAST_PAN)); |
5245 | | /* No payload expected. */ |
5246 | 2 | break; |
5247 | | |
5248 | 2 | case IEEE802154_CMD_BEACON_REQ: |
5249 | 2 | if ((packet->version == IEEE802154_VERSION_2003) || (packet->version == IEEE802154_VERSION_2006)) { |
5250 | 1 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5251 | 1 | (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) && |
5252 | 1 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) && |
5253 | 1 | (packet->dst16 == IEEE802154_BCAST_ADDR) && |
5254 | 1 | (packet->dst_pan == IEEE802154_BCAST_PAN)); |
5255 | 1 | } |
5256 | | /* No payload expected. */ |
5257 | 2 | break; |
5258 | | |
5259 | 2 | case IEEE802154_CMD_COORD_REALIGN: |
5260 | 2 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5261 | 2 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) && |
5262 | 2 | (packet->dst_pan == IEEE802154_BCAST_PAN) && |
5263 | 2 | (packet->dst_addr_mode != IEEE802154_FCF_ADDR_NONE)); |
5264 | 2 | if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT) { |
5265 | | /* If directed to a 16-bit address, check that it is being broadcast. */ |
5266 | 1 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, packet->dst16 == IEEE802154_BCAST_ADDR); |
5267 | 1 | } |
5268 | 2 | dissect_ieee802154_realign(tvb, pinfo, tree, packet); |
5269 | 2 | break; |
5270 | | |
5271 | 2 | case IEEE802154_CMD_GTS_REQ: |
5272 | | /* Check that the addressing is correct for this command type. */ |
5273 | 2 | IEEE802154_CMD_ADDR_CHECK(pinfo, tree, packet->command_id, |
5274 | 2 | (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT) && |
5275 | 2 | (packet->dst_addr_mode == IEEE802154_FCF_ADDR_NONE) && |
5276 | 2 | (packet->src16 != IEEE802154_BCAST_ADDR) && |
5277 | 2 | (packet->src16 != IEEE802154_NO_ADDR16)); |
5278 | 2 | dissect_ieee802154_gtsreq(tvb, pinfo, tree, packet); |
5279 | 2 | break; |
5280 | | |
5281 | 2 | case IEEE802154_CMD_VENDOR_SPECIFIC: |
5282 | 2 | { |
5283 | 2 | uint32_t oui = tvb_get_letoh24(tvb, 0); |
5284 | 2 | proto_tree_add_item(tree, hf_ieee802154_cmd_vendor_oui, tvb, 0, 3, ENC_LITTLE_ENDIAN); |
5285 | 2 | if (!dissector_try_uint_with_data(cmd_vendor_dissector_table, oui, tvb_new_subset_remaining(tvb, 3), pinfo, tree, false, packet)) { |
5286 | 2 | call_data_dissector(tvb_new_subset_remaining(tvb, 3), pinfo, tree); |
5287 | 2 | } |
5288 | 2 | break; |
5289 | 0 | } |
5290 | | |
5291 | 2 | case IEEE802154_CMD_TRLE_MGMT_REQ: |
5292 | 3 | case IEEE802154_CMD_TRLE_MGMT_RSP: |
5293 | 4 | case IEEE802154_CMD_DSME_ASSOC_REQ: |
5294 | 5 | case IEEE802154_CMD_DSME_ASSOC_RSP: |
5295 | 6 | case IEEE802154_CMD_DSME_GTS_REQ: |
5296 | 6 | case IEEE802154_CMD_DSME_GTS_RSP: |
5297 | 6 | case IEEE802154_CMD_DSME_GTS_NOTIFY: |
5298 | 6 | case IEEE802154_CMD_DSME_INFO_REQ: |
5299 | 7 | case IEEE802154_CMD_DSME_INFO_RSP: |
5300 | 7 | case IEEE802154_CMD_DSME_BEACON_ALLOC_NOTIFY: |
5301 | 7 | case IEEE802154_CMD_DSME_BEACON_COLL_NOTIFY: |
5302 | 7 | case IEEE802154_CMD_DSME_LINK_REPORT: |
5303 | 7 | case IEEE802154_CMD_RIT_DATA_REQ: |
5304 | 9 | case IEEE802154_CMD_DBS_REQ: |
5305 | 9 | case IEEE802154_CMD_DBS_RSP: |
5306 | 9 | case IEEE802154_CMD_RIT_DATA_RSP: |
5307 | | /* TODO add support for these commands, for now if anything remains, dump it */ |
5308 | 9 | expert_add_info(pinfo, tree, &ei_ieee802154_unsupported_cmd); |
5309 | 9 | if (tvb_captured_length_remaining(tvb, 0) > 0) { |
5310 | 8 | call_data_dissector(tvb, pinfo, tree); |
5311 | 8 | } |
5312 | 9 | break; |
5313 | 6 | default: |
5314 | 6 | expert_add_info(pinfo, tree, &ei_ieee802154_unknown_cmd); |
5315 | 6 | if (tvb_captured_length_remaining(tvb, 0) > 0) { |
5316 | 4 | call_data_dissector(tvb, pinfo, tree); |
5317 | 4 | } |
5318 | 43 | } /* switch */ |
5319 | 43 | } /* dissect_ieee802154_command */ |
5320 | | |
5321 | | /** |
5322 | | * IEEE 802.15.4 decryption algorithm |
5323 | | * @param tvb IEEE 802.15.4 packet, not including the FCS or metadata trailer. |
5324 | | * @param pinfo Packet info structure. |
5325 | | * @param offset Offset where the ciphertext 'c' starts. |
5326 | | * @param packet IEEE 802.15.4 packet information. |
5327 | | * @return decrypted payload. |
5328 | | */ |
5329 | | static tvbuff_t * |
5330 | | dissect_ieee802154_decrypt(tvbuff_t *tvb, |
5331 | | unsigned offset, |
5332 | | packet_info *pinfo, |
5333 | | ieee802154_packet *packet, |
5334 | | ieee802154_decrypt_info_t* decrypt_info, |
5335 | | unsigned char *key) |
5336 | 0 | { |
5337 | 0 | tvbuff_t *ptext_tvb; |
5338 | 0 | bool have_mic = false; |
5339 | 0 | uint64_t srcAddr = 0; |
5340 | 0 | unsigned char tmp[IEEE802154_CIPHER_SIZE]; |
5341 | 0 | unsigned M; |
5342 | 0 | int captured_len; |
5343 | 0 | int reported_len; |
5344 | 0 | ieee802154_hints_t *ieee_hints; |
5345 | 0 | uint8_t *generic_nonce_ptr = NULL; |
5346 | 0 | uint8_t generic_nonce[13]; |
5347 | |
|
5348 | 0 | ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0); |
5349 | | |
5350 | | /* Get the captured and on-the-air length of the payload. */ |
5351 | 0 | M = IEEE802154_MIC_LENGTH(packet->security_level); |
5352 | 0 | *decrypt_info->rx_mic_length = M; |
5353 | | |
5354 | | /* Is the MIC larger than the total amount of data? */ |
5355 | 0 | reported_len = tvb_reported_length_remaining(tvb, offset) - M; |
5356 | 0 | if (reported_len < 0) { |
5357 | | /* Yes. Give up. */ |
5358 | 0 | *decrypt_info->status = DECRYPT_PACKET_TOO_SMALL; |
5359 | 0 | return NULL; |
5360 | 0 | } |
5361 | | /* Check whether the payload is truncated by a snapshot length. */ |
5362 | 0 | if (tvb_bytes_exist(tvb, offset, reported_len)) { |
5363 | | /* It's not, so we have all of the payload. */ |
5364 | 0 | captured_len = reported_len; |
5365 | 0 | } |
5366 | 0 | else { |
5367 | | /* |
5368 | | * It is, so we don't have all of the payload - and we don't |
5369 | | * have the MIC, either, as that comes after the payload. |
5370 | | * As the MIC isn't part of the captured data - the captured |
5371 | | * data was cut short before the first byte of the MIC - we |
5372 | | * don't subtract the length of the MIC from the amount of |
5373 | | * captured data. |
5374 | | */ |
5375 | 0 | captured_len = tvb_captured_length_remaining(tvb, offset); |
5376 | 0 | } |
5377 | | |
5378 | | /* Check if the MIC is present in the captured data. */ |
5379 | 0 | have_mic = tvb_bytes_exist(tvb, offset + reported_len, M); |
5380 | 0 | if (have_mic) { |
5381 | | /* It is - save a copy of it. */ |
5382 | 0 | tvb_memcpy(tvb, decrypt_info->rx_mic, offset + reported_len, M); |
5383 | 0 | } |
5384 | | |
5385 | | /* We need the extended source address. */ |
5386 | 0 | if ((packet->key_index == IEEE802154_THR_WELL_KNOWN_KEY_INDEX) && |
5387 | 0 | (packet->key_source.addr32 == IEEE802154_THR_WELL_KNOWN_KEY_SRC)) |
5388 | 0 | { |
5389 | | /* Use the well-known extended address */ |
5390 | 0 | srcAddr = IEEE802154_THR_WELL_KNOWN_EXT_ADDR; |
5391 | 0 | } else { |
5392 | 0 | if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) { |
5393 | | /* The source EUI-64 is included in the headers. */ |
5394 | 0 | srcAddr = packet->src64; |
5395 | 0 | } |
5396 | 0 | else if (packet->src_addr_mode == IEEE802154_FCF_ADDR_SHORT && packet->frame_counter_suppression) { |
5397 | | /* In TSCH mode, the source address is a combination of 802.15 CID, PAN ID and Short Address */ |
5398 | 0 | srcAddr = IEEE80215_CID << 40; |
5399 | 0 | srcAddr |= ((uint64_t)packet->src_pan & 0xffff) << 16; |
5400 | 0 | srcAddr |= packet->src16; |
5401 | 0 | } |
5402 | 0 | else if (ieee_hints && ieee_hints->map_rec && ieee_hints->map_rec->addr64) { |
5403 | | /* Use the hint */ |
5404 | 0 | srcAddr = ieee_hints->map_rec->addr64; |
5405 | 0 | } |
5406 | 0 | else { |
5407 | | /* Lookup failed. */ |
5408 | 0 | *decrypt_info->status = DECRYPT_PACKET_NO_EXT_SRC_ADDR; |
5409 | 0 | return NULL; |
5410 | 0 | } |
5411 | 0 | } |
5412 | | |
5413 | | /* |
5414 | | * CCM* - CTR mode payload encryption |
5415 | | * |
5416 | | */ |
5417 | | /* 802.15.4-2015 TSCH mode */ |
5418 | 0 | if (packet->frame_counter_suppression) { |
5419 | 0 | tsch_ccm_init_nonce(srcAddr, packet->asn, generic_nonce); |
5420 | 0 | generic_nonce_ptr = generic_nonce; |
5421 | 0 | } |
5422 | | |
5423 | | /* Create the CCM* initial block for decryption (Adata=0, M=0, counter=0). */ |
5424 | 0 | if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003)) |
5425 | 0 | ccm_init_block(tmp, false, 0, srcAddr, packet->frame_counter, packet->key_sequence_counter, 0, NULL); |
5426 | 0 | else |
5427 | 0 | ccm_init_block(tmp, false, 0, srcAddr, packet->frame_counter, packet->security_level, 0, generic_nonce_ptr); |
5428 | | |
5429 | | /* |
5430 | | * If the payload is encrypted, so that it's the ciphertext, and we |
5431 | | * have at least one byte of it in the captured data, decrypt the |
5432 | | * ciphertext, and place the plaintext in a new tvb. |
5433 | | */ |
5434 | 0 | if (IEEE802154_IS_ENCRYPTED(packet->security_level) && captured_len) { |
5435 | 0 | uint8_t *text; |
5436 | | /* |
5437 | | * Make a copy of the ciphertext in heap memory. |
5438 | | * |
5439 | | * We will decrypt the message in-place and then use the buffer as the |
5440 | | * real data for the new tvb. |
5441 | | */ |
5442 | 0 | text = (uint8_t *)tvb_memdup(pinfo->pool, tvb, offset, captured_len); |
5443 | | |
5444 | | /* Perform CTR-mode transformation. */ |
5445 | 0 | if (!ccm_ctr_encrypt(key, tmp, decrypt_info->rx_mic, text, captured_len)) { |
5446 | 0 | wmem_free(pinfo->pool, text); |
5447 | 0 | *decrypt_info->status = DECRYPT_PACKET_DECRYPT_FAILED; |
5448 | 0 | return NULL; |
5449 | 0 | } |
5450 | | |
5451 | | /* Create a tvbuff for the plaintext. */ |
5452 | 0 | ptext_tvb = tvb_new_child_real_data(tvb, text, captured_len, reported_len); |
5453 | 0 | add_new_data_source(pinfo, ptext_tvb, "Decrypted IEEE 802.15.4 payload"); |
5454 | 0 | *decrypt_info->status = DECRYPT_PACKET_SUCCEEDED; |
5455 | 0 | } |
5456 | 0 | else { |
5457 | | /* |
5458 | | * Either the payload isn't encrypted or we don't have any of it |
5459 | | * in the captured data. |
5460 | | */ |
5461 | | /* Decrypt the MIC (if present). */ |
5462 | 0 | if ((have_mic) && (!ccm_ctr_encrypt(key, tmp, decrypt_info->rx_mic, NULL, 0))) { |
5463 | 0 | *decrypt_info->status = DECRYPT_PACKET_DECRYPT_FAILED; |
5464 | 0 | return NULL; |
5465 | 0 | } |
5466 | | |
5467 | | /* Create a tvbuff for the plaintext. This might result in a zero-length tvbuff. */ |
5468 | 0 | ptext_tvb = tvb_new_subset_length(tvb, offset, reported_len); |
5469 | 0 | *decrypt_info->status = DECRYPT_PACKET_SUCCEEDED; |
5470 | 0 | } |
5471 | | |
5472 | | /* |
5473 | | * CCM* - CBC-mode message authentication |
5474 | | * |
5475 | | */ |
5476 | | /* We can only verify the message if the MIC wasn't truncated. */ |
5477 | 0 | if (have_mic) { |
5478 | 0 | unsigned char dec_mic[16]; |
5479 | 0 | unsigned l_m = captured_len; |
5480 | 0 | unsigned l_a = offset; |
5481 | | |
5482 | | /* Adjust the lengths of the plaintext and additional data if unencrypted. */ |
5483 | 0 | if (!IEEE802154_IS_ENCRYPTED(packet->security_level)) { |
5484 | 0 | l_a += l_m; |
5485 | 0 | l_m = 0; |
5486 | 0 | } |
5487 | 0 | else if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003) && !ieee802154_extend_auth) |
5488 | 0 | l_a -= 5; /* Exclude Frame Counter (4 bytes) and Key Sequence Counter (1 byte) from authentication data */ |
5489 | | |
5490 | | |
5491 | | /* Create the CCM* initial block for authentication (Adata!=0, M!=0, counter=l(m)). */ |
5492 | 0 | if ((packet->frame_type != IEEE802154_FCF_MULTIPURPOSE) && (packet->version == IEEE802154_VERSION_2003)) |
5493 | 0 | ccm_init_block(tmp, true, M, srcAddr, packet->frame_counter, packet->key_sequence_counter, l_m, NULL); |
5494 | 0 | else |
5495 | 0 | ccm_init_block(tmp, true, M, srcAddr, packet->frame_counter, packet->security_level, l_m, generic_nonce_ptr); |
5496 | | |
5497 | | /* Compute CBC-MAC authentication tag. */ |
5498 | | /* |
5499 | | * And yes, despite the warning in tvbuff.h, I think tvb_get_ptr is the |
5500 | | * right function here since either A) the payload wasn't encrypted, in |
5501 | | * which case l_m is zero, or B) the payload was encrypted, and the tvb |
5502 | | * already points to contiguous memory, since we just allocated it in |
5503 | | * decryption phase. |
5504 | | */ |
5505 | 0 | memset(dec_mic, 0, sizeof(dec_mic)); |
5506 | 0 | if (!ccm_cbc_mac(key, tmp, tvb_memdup(pinfo->pool, tvb, 0, l_a), l_a, tvb_get_ptr(ptext_tvb, 0, l_m), l_m, dec_mic)) { |
5507 | 0 | *decrypt_info->status = DECRYPT_PACKET_MIC_CHECK_FAILED; |
5508 | 0 | } |
5509 | | /* Compare the received MIC with the one we generated. */ |
5510 | 0 | else if (memcmp(decrypt_info->rx_mic, dec_mic, M) != 0) { |
5511 | 0 | *decrypt_info->status = DECRYPT_PACKET_MIC_CHECK_FAILED; |
5512 | 0 | } |
5513 | 0 | } |
5514 | | |
5515 | | /* Done! */ |
5516 | 0 | return ptext_tvb; |
5517 | 0 | } /* dissect_ieee802154_decrypt */ |
5518 | | |
5519 | | /** |
5520 | | * Creates the CCM* initial block value for IEEE 802.15.4. |
5521 | | * |
5522 | | * @param block Output pointer for the initial block. |
5523 | | * @param adata true if additional auth data is present |
5524 | | * @param M CCM* parameter M. |
5525 | | * @param addr Source extended address. |
5526 | | * @param frame_counter Packet frame counter |
5527 | | * @param level Security level or key_sequence_counter for 802.15.4-2003 |
5528 | | * @param ctr_val Value in the last L bytes of the block. |
5529 | | * @param generic_nonce 13-byte nonce to be set by non 802.15.4 calls. If set addr, frame_counter and level are ignored. |
5530 | | */ |
5531 | | void |
5532 | | ccm_init_block(uint8_t *block, bool adata, int M, uint64_t addr, uint32_t frame_counter, uint8_t level, int ctr_val, const uint8_t *generic_nonce) |
5533 | 0 | { |
5534 | 0 | int i = 0; |
5535 | | |
5536 | | /* Flags: Reserved(0) || Adata || (M-2)/2 || (L-1) */ |
5537 | 0 | block[i] = (0x2 - 1); /* (L-1) */ |
5538 | 0 | if (M > 0) block[i] |= (((M-2)/2) << 3); /* (M-2)/2 */ |
5539 | 0 | if (adata) block[i] |= (1 << 6); /* Adata */ |
5540 | 0 | i++; |
5541 | 0 | if (generic_nonce == NULL) { |
5542 | | /* 2003 CCM Nonce: Source Address || Frame Counter || Key Sequence Counter */ |
5543 | | /* 2006 CCM* Nonce: Source Address || Frame Counter || Security Level */ |
5544 | 0 | block[i++] = (uint8_t)((addr >> 56) & 0xff); |
5545 | 0 | block[i++] = (uint8_t)((addr >> 48) & 0xff); |
5546 | 0 | block[i++] = (uint8_t)((addr >> 40) & 0xff); |
5547 | 0 | block[i++] = (uint8_t)((addr >> 32) & 0xff); |
5548 | 0 | block[i++] = (uint8_t)((addr >> 24) & 0xff); |
5549 | 0 | block[i++] = (uint8_t)((addr >> 16) & 0xff); |
5550 | 0 | block[i++] = (uint8_t)((addr >> 8) & 0xff); |
5551 | 0 | block[i++] = (uint8_t)((addr >> 0) & 0xff); |
5552 | 0 | block[i++] = (uint8_t)((frame_counter >> 24) & 0xff); |
5553 | 0 | block[i++] = (uint8_t)((frame_counter >> 16) & 0xff); |
5554 | 0 | block[i++] = (uint8_t)((frame_counter >> 8) & 0xff); |
5555 | 0 | block[i++] = (uint8_t)((frame_counter >> 0) & 0xff); |
5556 | 0 | block[i++] = level; |
5557 | 0 | } else { |
5558 | 0 | memcpy(&block[i], generic_nonce, 13); |
5559 | 0 | i += 13; |
5560 | 0 | } |
5561 | | /* Plaintext length. */ |
5562 | 0 | block[i++] = (uint8_t)((ctr_val >> 8) & 0xff); |
5563 | 0 | block[i] = (uint8_t)((ctr_val >> 0) & 0xff); |
5564 | 0 | } /* ccm_init_block */ |
5565 | | |
5566 | | /** |
5567 | | * Creates the IEEE 802.15.4 TSCH nonce. |
5568 | | * |
5569 | | * @param addr Source extended address. |
5570 | | * @param asn TSCH Absolute Slot Number |
5571 | | * @param generic_nonce 13-byte nonce to returned by this function. |
5572 | | */ |
5573 | | static void |
5574 | | tsch_ccm_init_nonce(uint64_t addr, uint64_t asn, uint8_t* generic_nonce) |
5575 | 0 | { |
5576 | 0 | int i = 0; |
5577 | | |
5578 | | /* 2015 CCM* Nonce: Source Address || ASN */ |
5579 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 56) & 0xff); |
5580 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 48) & 0xff); |
5581 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 40) & 0xff); |
5582 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 32) & 0xff); |
5583 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 24) & 0xff); |
5584 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 16) & 0xff); |
5585 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 8) & 0xff); |
5586 | 0 | generic_nonce[i++] = (uint8_t)((addr >> 0) & 0xff); |
5587 | 0 | generic_nonce[i++] = (uint8_t)((asn >> 32) & 0xff); |
5588 | 0 | generic_nonce[i++] = (uint8_t)((asn >> 24) & 0xff); |
5589 | 0 | generic_nonce[i++] = (uint8_t)((asn >> 16) & 0xff); |
5590 | 0 | generic_nonce[i++] = (uint8_t)((asn >> 8) & 0xff); |
5591 | 0 | generic_nonce[i++] = (uint8_t)((asn >> 0) & 0xff); |
5592 | 0 | } /* tsch_ccm_init_nonce */ |
5593 | | |
5594 | | /** |
5595 | | * Perform an in-place CTR-mode encryption/decryption. |
5596 | | * |
5597 | | * @param key Encryption Key. |
5598 | | * @param iv Counter initial value. |
5599 | | * @param mic MIC to encrypt/decrypt. |
5600 | | * @param data Buffer to encrypt/decrypt. |
5601 | | * @param length Length of the buffer. |
5602 | | * @return true on SUCCESS, false on error. |
5603 | | */ |
5604 | | bool |
5605 | | ccm_ctr_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *mic, uint8_t *data, int length) |
5606 | 0 | { |
5607 | 0 | gcry_cipher_hd_t cipher_hd; |
5608 | | |
5609 | | /* Open the cipher. */ |
5610 | 0 | if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0)) { |
5611 | 0 | return false; |
5612 | 0 | } |
5613 | | |
5614 | | /* Set the key and initial value. */ |
5615 | 0 | if (gcry_cipher_setkey(cipher_hd, key, 16)) { |
5616 | 0 | gcry_cipher_close(cipher_hd); |
5617 | 0 | return false; |
5618 | 0 | } |
5619 | 0 | if (gcry_cipher_setctr(cipher_hd, iv, 16)) { |
5620 | 0 | gcry_cipher_close(cipher_hd); |
5621 | 0 | return false; |
5622 | 0 | } |
5623 | | |
5624 | | /* Decrypt the MIC. */ |
5625 | 0 | if (gcry_cipher_encrypt(cipher_hd, mic, 16, NULL, 0)) { |
5626 | 0 | gcry_cipher_close(cipher_hd); |
5627 | 0 | return false; |
5628 | 0 | } |
5629 | | /* Decrypt the payload. */ |
5630 | 0 | if (gcry_cipher_encrypt(cipher_hd, data, length, NULL, 0)) { |
5631 | 0 | gcry_cipher_close(cipher_hd); |
5632 | 0 | return false; |
5633 | 0 | } |
5634 | | |
5635 | | /* Done with the cipher. */ |
5636 | 0 | gcry_cipher_close(cipher_hd); |
5637 | 0 | return true; |
5638 | 0 | } /* ccm_ctr_encrypt */ |
5639 | | |
5640 | | /** |
5641 | | * Generate a CBC-MAC of the decrypted payload and additional authentication headers. |
5642 | | * @param key Encryption Key. |
5643 | | * @param iv Counter initial value. |
5644 | | * @param a Additional auth headers. |
5645 | | * @param a_len Length of the additional headers. |
5646 | | * @param m Plaintext message. |
5647 | | * @param m_len Length of plaintext message. |
5648 | | * @param mic Output for CBC-MAC. |
5649 | | * @return true on SUCCESS, false on error. |
5650 | | */ |
5651 | | bool |
5652 | | ccm_cbc_mac(const uint8_t *key, const uint8_t *iv, const uint8_t *a, int a_len, const uint8_t *m, int m_len, uint8_t *mic) |
5653 | 0 | { |
5654 | 0 | gcry_cipher_hd_t cipher_hd; |
5655 | 0 | unsigned i = 0; |
5656 | 0 | unsigned char block[IEEE802154_CIPHER_SIZE]; |
5657 | | |
5658 | | /* Open the cipher. */ |
5659 | 0 | if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC)) return false; |
5660 | | |
5661 | | /* Set the key. */ |
5662 | 0 | if (gcry_cipher_setkey(cipher_hd, key, IEEE802154_CIPHER_SIZE)) { |
5663 | 0 | gcry_cipher_close(cipher_hd); |
5664 | 0 | return false; |
5665 | 0 | } |
5666 | | |
5667 | | /* Process the initial value. */ |
5668 | 0 | if (gcry_cipher_encrypt(cipher_hd, mic, 16, iv, 16)) { |
5669 | 0 | gcry_cipher_close(cipher_hd); |
5670 | 0 | return false; |
5671 | 0 | } |
5672 | | |
5673 | | /* Encode L(a) */ |
5674 | 0 | i = 0; |
5675 | | |
5676 | | /* XXX: GINT_MAX is not defined so #if ... will always be false */ |
5677 | | #if (GINT_MAX >= (1LL << 32)) |
5678 | | if (a_len >= (1LL << 32)) { |
5679 | | block[i++] = 0xff; |
5680 | | block[i++] = 0xff; |
5681 | | block[i++] = (a_len >> 56) & 0xff; |
5682 | | block[i++] = (a_len >> 48) & 0xff; |
5683 | | block[i++] = (a_len >> 40) & 0xff; |
5684 | | block[i++] = (a_len >> 32) & 0xff; |
5685 | | block[i++] = (a_len >> 24) & 0xff; |
5686 | | block[i++] = (a_len >> 16) & 0xff; |
5687 | | block[i++] = (a_len >> 8) & 0xff; |
5688 | | block[i++] = (a_len >> 0) & 0xff; |
5689 | | } |
5690 | | else |
5691 | | #endif |
5692 | 0 | if (a_len >= ((1 << 16) - (1 << 8))) { |
5693 | 0 | block[i++] = 0xff; |
5694 | 0 | block[i++] = 0xfe; |
5695 | 0 | block[i++] = (a_len >> 24) & 0xff; |
5696 | 0 | block[i++] = (a_len >> 16) & 0xff; |
5697 | 0 | block[i++] = (a_len >> 8) & 0xff; |
5698 | 0 | block[i++] = (a_len >> 0) & 0xff; |
5699 | 0 | } |
5700 | 0 | else { |
5701 | 0 | block[i++] = (a_len >> 8) & 0xff; |
5702 | 0 | block[i++] = (a_len >> 0) & 0xff; |
5703 | 0 | } |
5704 | | /* Append a to get the first block of input (pad if we encounter the end of a). */ |
5705 | 0 | while ((i < sizeof(block)) && (a_len > 0)) { |
5706 | 0 | block[i++] = *a++; |
5707 | 0 | a_len--; |
5708 | 0 | } |
5709 | 0 | while (i < sizeof(block)) { |
5710 | 0 | block[i++] = 0; |
5711 | 0 | } |
5712 | | |
5713 | | /* Process the first block of AuthData. */ |
5714 | 0 | if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, 16)) { |
5715 | 0 | gcry_cipher_close(cipher_hd); |
5716 | 0 | return false; |
5717 | 0 | } |
5718 | | |
5719 | | /* Transform and process the remainder of a. */ |
5720 | 0 | while (a_len > 0) { |
5721 | | /* Copy and pad. */ |
5722 | 0 | if ((unsigned)a_len >= sizeof(block)) { |
5723 | 0 | memcpy(block, a, sizeof(block)); |
5724 | 0 | } |
5725 | 0 | else { |
5726 | 0 | memcpy(block, a, a_len); |
5727 | 0 | memset(&block[a_len], 0, sizeof(block)-a_len); |
5728 | 0 | } |
5729 | | /* Adjust pointers. */ |
5730 | 0 | a += sizeof(block); |
5731 | 0 | a_len -= (int)sizeof(block); |
5732 | | /* Execute the CBC-MAC algorithm. */ |
5733 | 0 | if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, sizeof(block))) { |
5734 | 0 | gcry_cipher_close(cipher_hd); |
5735 | 0 | return false; |
5736 | 0 | } |
5737 | 0 | } /* while */ |
5738 | | |
5739 | | /* Process the message, m. */ |
5740 | 0 | while (m_len > 0) { |
5741 | | /* Copy and pad. */ |
5742 | 0 | if ((unsigned)m_len >= sizeof(block)) { |
5743 | 0 | memcpy(block, m, sizeof(block)); |
5744 | 0 | } |
5745 | 0 | else { |
5746 | 0 | memcpy(block, m, m_len); |
5747 | 0 | memset(&block[m_len], 0, sizeof(block)-m_len); |
5748 | 0 | } |
5749 | | /* Adjust pointers. */ |
5750 | 0 | m += sizeof(block); |
5751 | 0 | m_len -= (int)sizeof(block); |
5752 | | /* Execute the CBC-MAC algorithm. */ |
5753 | 0 | if (gcry_cipher_encrypt(cipher_hd, mic, 16, block, sizeof(block))) { |
5754 | 0 | gcry_cipher_close(cipher_hd); |
5755 | 0 | return false; |
5756 | 0 | } |
5757 | 0 | } |
5758 | | |
5759 | | /* Done with the cipher. */ |
5760 | 0 | gcry_cipher_close(cipher_hd); |
5761 | 0 | return true; |
5762 | 0 | } /* ccm_cbc_mac */ |
5763 | | |
5764 | | /* Key hash function. */ |
5765 | | unsigned ieee802154_short_addr_hash(const void *key) |
5766 | 16.0k | { |
5767 | 16.0k | return (((const ieee802154_short_addr *)key)->addr) | (((const ieee802154_short_addr *)key)->pan << 16); |
5768 | 16.0k | } |
5769 | | |
5770 | | /* Key equal function. */ |
5771 | | gboolean ieee802154_short_addr_equal(const void *a, const void *b) |
5772 | 4.25k | { |
5773 | 4.25k | return (((const ieee802154_short_addr *)a)->pan == ((const ieee802154_short_addr *)b)->pan) && |
5774 | 4.25k | (((const ieee802154_short_addr *)a)->addr == ((const ieee802154_short_addr *)b)->addr); |
5775 | 4.25k | } |
5776 | | |
5777 | | /* Key hash function. */ |
5778 | | unsigned ieee802154_long_addr_hash(const void *key) |
5779 | 336 | { |
5780 | 336 | return (unsigned)(((const ieee802154_long_addr *)key)->addr) & 0xFFFFFFFF; |
5781 | 336 | } |
5782 | | |
5783 | | /* Key equal function. */ |
5784 | | gboolean ieee802154_long_addr_equal(const void *a, const void *b) |
5785 | 328 | { |
5786 | 328 | return (((const ieee802154_long_addr *)a)->addr == ((const ieee802154_long_addr *)b)->addr); |
5787 | 328 | } |
5788 | | |
5789 | | /* Set MAC key function. */ |
5790 | | static unsigned ieee802154_set_mac_key(ieee802154_packet *packet, unsigned char *key, unsigned char *alt_key, ieee802154_key_t *uat_key) |
5791 | 0 | { |
5792 | 0 | ieee802154_set_key_func func = (ieee802154_set_key_func)wmem_tree_lookup32(mac_key_hash_handlers, uat_key->hash_type); |
5793 | |
|
5794 | 0 | if (func != NULL) |
5795 | 0 | return func(packet, key, alt_key, uat_key); |
5796 | | |
5797 | | /* Right now, KEY_HASH_NONE and KEY_HASH_ZIP are not registered because they |
5798 | | work with this "default" behavior */ |
5799 | 0 | if (packet->key_index == uat_key->key_index) |
5800 | 0 | { |
5801 | 0 | memcpy(key, uat_key->key, IEEE802154_CIPHER_SIZE); |
5802 | 0 | return 1; |
5803 | 0 | } |
5804 | | |
5805 | 0 | return 0; |
5806 | 0 | } |
5807 | | |
5808 | | static bool trel_key_derivation_func(/*ieee802154_packet* packet*/ unsigned char* key, uint32_t seq, ieee802154_key_t* uat_key) |
5809 | 0 | { |
5810 | 0 | uint8_t prk[32]; /* GCRY_MD_SHA256 hash output. */ |
5811 | 0 | gcry_error_t err; |
5812 | 0 | uint32_t Key_sequence = seq; |
5813 | 0 | unsigned char ikm[16]; |
5814 | 0 | GByteArray* bytes; |
5815 | 0 | bytes = g_byte_array_new(); |
5816 | 0 | bool res = hex_str_to_bytes(uat_key->pref_key, bytes, false); |
5817 | 0 | if (!res) { |
5818 | 0 | g_byte_array_unref(bytes); |
5819 | 0 | return false; |
5820 | 0 | } |
5821 | | |
5822 | 0 | uint8_t saltstring[] = { 'T', 'h', 'r', 'e', 'a', 'd', 'S', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 'M', 'a', 's', 't', 'e', 'r', 'K', 'e', 'y' }; |
5823 | 0 | uint8_t info_str[] = { 'T', 'h', 'r', 'e', 'a', 'd', 'O', 'v', 'e','r', 'I', 'n', 'f', 'r', 'a', 'K', 'e', 'y' }; |
5824 | 0 | uint8_t salt[sizeof(uint32_t) + sizeof(saltstring)]; |
5825 | |
|
5826 | 0 | salt[0] = (Key_sequence >> 24) & 0xff; |
5827 | 0 | salt[1] = (Key_sequence >> 16) & 0xff; |
5828 | 0 | salt[2] = (Key_sequence >> 8) & 0xff; |
5829 | 0 | salt[3] = (Key_sequence >> 0) & 0xff; |
5830 | |
|
5831 | 0 | memcpy(ikm, bytes->data, 16); |
5832 | 0 | g_byte_array_unref(bytes); |
5833 | 0 | memcpy(salt + sizeof(uint32_t), saltstring, sizeof(saltstring)); |
5834 | |
|
5835 | 0 | err = hkdf_extract(GCRY_MD_SHA256, salt, sizeof(salt), ikm, sizeof(ikm), prk); |
5836 | 0 | DISSECTOR_ASSERT(err == 0); |
5837 | 0 | err = hkdf_expand(GCRY_MD_SHA256, prk, sizeof(prk), info_str, sizeof(info_str), key, 16); |
5838 | 0 | DISSECTOR_ASSERT(err == 0); |
5839 | |
|
5840 | 0 | return true; |
5841 | 0 | } |
5842 | | static unsigned ieee802154_set_trel_key(ieee802154_packet* packet, unsigned char* key, unsigned char* alt_key, ieee802154_key_t* uat_key) |
5843 | 0 | { |
5844 | 0 | if (packet->key_index == uat_key->key_index && alt_key) |
5845 | 0 | { |
5846 | 0 | memcpy(key, uat_key->key, IEEE802154_CIPHER_SIZE); |
5847 | 0 | } |
5848 | |
|
5849 | 0 | if(trel_key_derivation_func(key, 0, uat_key) == 1) |
5850 | 0 | return 1; |
5851 | | |
5852 | 0 | return 0; |
5853 | 0 | } |
5854 | | |
5855 | | /** |
5856 | | * Creates a record that maps the given short address and pan to a long (extended) address. |
5857 | | * @param short_addr 16-bit short address |
5858 | | * @param pan 16-bit PAN id |
5859 | | * @param long_addr 64-bit long (extended) address |
5860 | | * @param proto pointer to name of current protocol |
5861 | | * @param fnum Frame number this mapping became valid |
5862 | | * @return true Record was updated, false Couldn't find it |
5863 | | */ |
5864 | | ieee802154_map_rec *ieee802154_addr_update(ieee802154_map_tab_t *au_ieee802154_map, |
5865 | | uint16_t short_addr, uint16_t pan, uint64_t long_addr, const char *proto, unsigned fnum) |
5866 | 214 | { |
5867 | 214 | ieee802154_short_addr addr16; |
5868 | 214 | ieee802154_map_rec *p_map_rec; |
5869 | 214 | void * old_key; |
5870 | | |
5871 | | /* Look up short address hash */ |
5872 | 214 | addr16.pan = pan; |
5873 | 214 | addr16.addr = short_addr; |
5874 | 214 | p_map_rec = (ieee802154_map_rec *)g_hash_table_lookup(au_ieee802154_map->short_table, &addr16); |
5875 | | |
5876 | | /* Update mapping record */ |
5877 | 214 | if (p_map_rec) { |
5878 | | /* record already exists */ |
5879 | 109 | if ( p_map_rec->addr64 == long_addr ) { |
5880 | | /* no change */ |
5881 | 46 | return p_map_rec; |
5882 | 46 | } |
5883 | 63 | else { |
5884 | | /* mark current mapping record invalid */ |
5885 | 63 | p_map_rec->end_fnum = fnum; |
5886 | 63 | } |
5887 | 109 | } |
5888 | | |
5889 | | /* create a new mapping record */ |
5890 | 168 | p_map_rec = wmem_new(wmem_file_scope(), ieee802154_map_rec); |
5891 | 168 | p_map_rec->proto = proto; |
5892 | 168 | p_map_rec->start_fnum = fnum; |
5893 | 168 | p_map_rec->end_fnum = 0; |
5894 | 168 | p_map_rec->addr64 = long_addr; |
5895 | | |
5896 | | /* link new mapping record to addr hash tables */ |
5897 | 168 | if ( g_hash_table_lookup_extended(au_ieee802154_map->short_table, &addr16, &old_key, NULL) ) { |
5898 | | /* update short addr hash table, reusing pointer to old key */ |
5899 | 63 | g_hash_table_insert(au_ieee802154_map->short_table, old_key, p_map_rec); |
5900 | 105 | } else { |
5901 | | /* create new hash entry */ |
5902 | 105 | g_hash_table_insert(au_ieee802154_map->short_table, wmem_memdup(wmem_file_scope(), &addr16, sizeof(addr16)), p_map_rec); |
5903 | 105 | } |
5904 | | |
5905 | 168 | if ( g_hash_table_lookup_extended(au_ieee802154_map->long_table, &long_addr, &old_key, NULL) ) { |
5906 | | /* update long addr hash table, reusing pointer to old key */ |
5907 | 35 | g_hash_table_insert(au_ieee802154_map->long_table, old_key, p_map_rec); |
5908 | 133 | } else { |
5909 | | /* create new hash entry */ |
5910 | 133 | g_hash_table_insert(au_ieee802154_map->long_table, wmem_memdup(wmem_file_scope(), &long_addr, sizeof(long_addr)), p_map_rec); |
5911 | 133 | } |
5912 | | |
5913 | 168 | return p_map_rec; |
5914 | 214 | } /* ieee802154_addr_update */ |
5915 | | |
5916 | | /** |
5917 | | * Marks a mapping record associated with device with short_addr |
5918 | | * as invalid at a certain frame number, typically when a |
5919 | | * disassociation occurs. |
5920 | | * |
5921 | | * @param short_addr 16-bit short address |
5922 | | * @param pan 16-bit PAN id |
5923 | | * @param fnum Frame number when mapping became invalid |
5924 | | * @return true Record was updated, false Couldn't find it |
5925 | | */ |
5926 | | bool ieee802154_short_addr_invalidate(uint16_t short_addr, uint16_t pan, unsigned fnum) |
5927 | 2 | { |
5928 | 2 | ieee802154_short_addr addr16; |
5929 | 2 | ieee802154_map_rec *map_rec; |
5930 | | |
5931 | 2 | addr16.pan = pan; |
5932 | 2 | addr16.addr = short_addr; |
5933 | | |
5934 | 2 | map_rec = (ieee802154_map_rec *)g_hash_table_lookup(ieee802154_map.short_table, &addr16); |
5935 | 2 | if ( map_rec ) { |
5936 | | /* indicates this mapping is invalid at frame fnum */ |
5937 | 0 | map_rec->end_fnum = fnum; |
5938 | 0 | return true; |
5939 | 0 | } |
5940 | | |
5941 | 2 | return false; |
5942 | 2 | } /* ieee802154_short_addr_invalidate */ |
5943 | | |
5944 | | /** |
5945 | | * Mark a mapping record associated with device with long_addr |
5946 | | * as invalid at a certain frame number, typically when a |
5947 | | * disassociation occurs. |
5948 | | * |
5949 | | * @param long_addr 16-bit short address |
5950 | | * @param fnum Frame number when mapping became invalid |
5951 | | * @return true If record was updated, false otherwise |
5952 | | */ |
5953 | | bool ieee802154_long_addr_invalidate(uint64_t long_addr, unsigned fnum) |
5954 | 0 | { |
5955 | 0 | ieee802154_map_rec *map_rec; |
5956 | |
|
5957 | 0 | map_rec = (ieee802154_map_rec *)g_hash_table_lookup(ieee802154_map.long_table, &long_addr); |
5958 | 0 | if ( map_rec ) { |
5959 | | /* indicates this mapping is invalid at frame fnum */ |
5960 | 0 | map_rec->end_fnum = fnum; |
5961 | 0 | return true; |
5962 | 0 | } |
5963 | | |
5964 | 0 | return false; |
5965 | 0 | } /* ieee802154_long_addr_invalidate */ |
5966 | | |
5967 | | /** |
5968 | | * Init routine for the IEEE 802.15.4 dissector. Creates hash |
5969 | | * tables for mapping between 16-bit to 64-bit addresses and |
5970 | | * populates them with static address pairs from a UAT |
5971 | | * preference table. |
5972 | | */ |
5973 | | static void |
5974 | | proto_init_ieee802154(void) |
5975 | 16 | { |
5976 | 16 | unsigned i; |
5977 | | |
5978 | 16 | ieee802154_map.short_table = g_hash_table_new(ieee802154_short_addr_hash, ieee802154_short_addr_equal); |
5979 | 16 | ieee802154_map.long_table = g_hash_table_new(ieee802154_long_addr_hash, ieee802154_long_addr_equal); |
5980 | | /* Reload the hash table from the static address UAT. */ |
5981 | 16 | for (i=0; (i<num_static_addrs) && (static_addrs); i++) { |
5982 | 0 | ieee802154_addr_update(&ieee802154_map,(uint16_t)static_addrs[i].addr16, (uint16_t)static_addrs[i].pan, |
5983 | 0 | pntohu64(static_addrs[i].eui64), ieee802154_user, IEEE802154_USER_MAPPING); |
5984 | 0 | } /* for */ |
5985 | 16 | } /* proto_init_ieee802154 */ |
5986 | | |
5987 | | /** |
5988 | | * Cleanup for the IEEE 802.15.4 dissector. |
5989 | | */ |
5990 | | static void |
5991 | | proto_cleanup_ieee802154(void) |
5992 | 0 | { |
5993 | 0 | g_hash_table_destroy(ieee802154_map.short_table); |
5994 | 0 | g_hash_table_destroy(ieee802154_map.long_table); |
5995 | 0 | } |
5996 | | |
5997 | | /* Returns the prompt string for the Decode-As dialog. */ |
5998 | | static void ieee802154_da_prompt(packet_info *pinfo _U_, char* result) |
5999 | 0 | { |
6000 | 0 | ieee802154_hints_t *hints; |
6001 | 0 | hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0); |
6002 | 0 | if (hints) |
6003 | 0 | snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IEEE 802.15.4 PAN 0x%04x as", hints->src_pan); |
6004 | 0 | else |
6005 | 0 | snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "IEEE 802.15.4 PAN Unknown"); |
6006 | 0 | } /* iee802154_da_prompt */ |
6007 | | |
6008 | | /* Returns the value to index the panid decode table with (source PAN)*/ |
6009 | | static void *ieee802154_da_value(packet_info *pinfo _U_) |
6010 | 0 | { |
6011 | 0 | ieee802154_hints_t *hints; |
6012 | 0 | hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ieee802154, 0); |
6013 | 0 | if (hints) |
6014 | 0 | return GUINT_TO_POINTER((unsigned)(hints->src_pan)); |
6015 | 0 | else |
6016 | 0 | return NULL; |
6017 | 0 | } /* iee802154_da_value */ |
6018 | | |
6019 | | static const char* ieee802154_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) |
6020 | 0 | { |
6021 | 0 | if (filter == CONV_FT_SRC_ADDRESS) { |
6022 | 0 | if (conv->src_address.type == ieee802_15_4_short_address_type) |
6023 | 0 | return "wpan.src16"; |
6024 | 0 | else if (conv->src_address.type == AT_EUI64) |
6025 | 0 | return "wpan.src64"; |
6026 | 0 | } |
6027 | | |
6028 | 0 | if (filter == CONV_FT_DST_ADDRESS) { |
6029 | 0 | if (conv->dst_address.type == ieee802_15_4_short_address_type) |
6030 | 0 | return "wpan.dst16"; |
6031 | 0 | else if (conv->dst_address.type == AT_EUI64) |
6032 | 0 | return "wpan.dst64"; |
6033 | 0 | } |
6034 | | |
6035 | 0 | if (filter == CONV_FT_ANY_ADDRESS) { |
6036 | 0 | if (conv->src_address.type == ieee802_15_4_short_address_type) |
6037 | 0 | return "wpan.addr16"; |
6038 | 0 | else if (conv->src_address.type == AT_EUI64) |
6039 | 0 | return "wpan.addr64"; |
6040 | 0 | } |
6041 | | |
6042 | 0 | return CONV_FILTER_INVALID; |
6043 | 0 | } |
6044 | | |
6045 | | static ct_dissector_info_t ieee802154_ct_dissector_info = {&ieee802154_conv_get_filter_type }; |
6046 | | |
6047 | | static tap_packet_status ieee802154_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags) |
6048 | 0 | { |
6049 | 0 | conv_hash_t *hash = (conv_hash_t*)pct; |
6050 | 0 | hash->flags = flags; |
6051 | |
|
6052 | 0 | add_conversation_table_data(hash, &pinfo->dl_src, &pinfo->dl_dst, 0, 0, 1, |
6053 | 0 | pinfo->fd->pkt_len, &pinfo->rel_ts, &pinfo->abs_ts, |
6054 | 0 | &ieee802154_ct_dissector_info, CONVERSATION_NONE); |
6055 | |
|
6056 | 0 | return TAP_PACKET_REDRAW; |
6057 | 0 | } |
6058 | | |
6059 | | static const char* ieee802154_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter) |
6060 | 0 | { |
6061 | 0 | if (filter == CONV_FT_ANY_ADDRESS) { |
6062 | 0 | if (endpoint->myaddress.type == ieee802_15_4_short_address_type) |
6063 | 0 | return "wpan.addr16"; |
6064 | 0 | else if (endpoint->myaddress.type == AT_EUI64) |
6065 | 0 | return "wpan.addr64"; |
6066 | 0 | } |
6067 | | |
6068 | 0 | return CONV_FILTER_INVALID; |
6069 | 0 | } |
6070 | | |
6071 | | static et_dissector_info_t ieee802154_endpoint_dissector_info = {&ieee802154_endpoint_get_filter_type }; |
6072 | | |
6073 | | static tap_packet_status ieee802154_endpoint_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags) |
6074 | 0 | { |
6075 | 0 | conv_hash_t *hash = (conv_hash_t*)pit; |
6076 | 0 | hash->flags = flags; |
6077 | | |
6078 | | /* Take two "add" passes per packet, adding for each direction, ensures that all |
6079 | | packets are counted properly (even if address is sending to itself) |
6080 | | XXX - this could probably be done more efficiently inside endpoint_table */ |
6081 | 0 | add_endpoint_table_data(hash, &pinfo->dl_src, 0, true, 1, |
6082 | 0 | pinfo->fd->pkt_len, &ieee802154_endpoint_dissector_info, ENDPOINT_NONE); |
6083 | 0 | add_endpoint_table_data(hash, &pinfo->dl_dst, 0, false, 1, |
6084 | 0 | pinfo->fd->pkt_len, &ieee802154_endpoint_dissector_info, ENDPOINT_NONE); |
6085 | |
|
6086 | 0 | return TAP_PACKET_REDRAW; |
6087 | 0 | } |
6088 | | |
6089 | | static bool ieee802154_filter_valid(packet_info *pinfo, void *user_data _U_) |
6090 | 0 | { |
6091 | 0 | return proto_is_frame_protocol(pinfo->layers, "wpan") |
6092 | 0 | && ((pinfo->dl_src.type == ieee802_15_4_short_address_type) || (pinfo->dl_src.type == AT_EUI64)) |
6093 | 0 | && ((pinfo->dl_dst.type == ieee802_15_4_short_address_type) || (pinfo->dl_dst.type == AT_EUI64)); |
6094 | 0 | } |
6095 | | |
6096 | | static char* ieee802154_build_filter(packet_info *pinfo, void *user_data _U_) |
6097 | 0 | { |
6098 | 0 | return ws_strdup_printf("wpan.%s eq %s and wpan.%s eq %s", |
6099 | 0 | (pinfo->dl_src.type == ieee802_15_4_short_address_type) ? "addr16" : "addr64", |
6100 | 0 | address_to_str(pinfo->pool, &pinfo->dl_src), |
6101 | 0 | (pinfo->dl_dst.type == ieee802_15_4_short_address_type) ? "addr16" : "addr64", |
6102 | 0 | address_to_str(pinfo->pool, &pinfo->dl_dst)); |
6103 | 0 | } |
6104 | | |
6105 | | /** |
6106 | | * IEEE 802.15.4 protocol registration routine. |
6107 | | */ |
6108 | | void proto_register_ieee802154(void) |
6109 | 16 | { |
6110 | | /* Protocol fields */ |
6111 | 16 | static hf_register_info hf_phy[] = { |
6112 | | /* PHY level */ |
6113 | | |
6114 | 16 | { &hf_ieee802154_nonask_phy_preamble, |
6115 | 16 | { "Preamble", "wpan-nonask-phy.preamble", FT_UINT32, BASE_HEX, NULL, 0x0, |
6116 | 16 | NULL, HFILL }}, |
6117 | | |
6118 | 16 | { &hf_ieee802154_nonask_phy_sfd, |
6119 | 16 | { "Start of Frame Delimiter", "wpan-nonask-phy.sfd", FT_UINT8, BASE_HEX, NULL, 0x0, |
6120 | 16 | NULL, HFILL }}, |
6121 | | |
6122 | 16 | { &hf_ieee802154_nonask_phy_length, |
6123 | 16 | { "Frame Length", "wpan-nonask-phy.frame_length", FT_UINT8, BASE_HEX, NULL, |
6124 | 16 | IEEE802154_PHY_LENGTH_MASK, NULL, HFILL }}, |
6125 | | |
6126 | 16 | { &hf_ieee802154_nonask_phr, |
6127 | 16 | { "PHR", "wpan-nonask-phy.phr", FT_UINT8, BASE_HEX, NULL, |
6128 | 16 | 0x0, NULL, HFILL }}, |
6129 | 16 | }; |
6130 | | |
6131 | 16 | static hf_register_info hf[] = { |
6132 | | |
6133 | 16 | { &hf_ieee802154_frame_length, |
6134 | 16 | { "Frame Length", "wpan.frame_length", FT_UINT8, BASE_DEC, NULL, 0x0, |
6135 | 16 | "Frame Length as reported from lower layer", HFILL }}, |
6136 | | |
6137 | 16 | { &hf_ieee802154_fcf, |
6138 | 16 | { "Frame Control Field", "wpan.fcf", FT_UINT16, BASE_HEX, NULL, |
6139 | 16 | 0x0, NULL, HFILL }}, |
6140 | | |
6141 | 16 | { &hf_ieee802154_frame_type, |
6142 | 16 | { "Frame Type", "wpan.frame_type", FT_UINT16, BASE_HEX, VALS(ieee802154_frame_types), |
6143 | 16 | IEEE802154_FCF_TYPE_MASK, NULL, HFILL }}, |
6144 | | |
6145 | 16 | { &hf_ieee802154_security, |
6146 | 16 | { "Security Enabled", "wpan.security", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_SEC_EN, |
6147 | 16 | "Whether security operations are performed at the MAC layer or not.", HFILL }}, |
6148 | | |
6149 | 16 | { &hf_ieee802154_pending, |
6150 | 16 | { "Frame Pending", "wpan.pending", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_FRAME_PND, |
6151 | 16 | "Indication of additional packets waiting to be transferred from the source device.", HFILL }}, |
6152 | | |
6153 | 16 | { &hf_ieee802154_ack_request, |
6154 | 16 | { "Acknowledge Request", "wpan.ack_request", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_ACK_REQ, |
6155 | 16 | "Whether the sender of this packet requests acknowledgment or not.", HFILL }}, |
6156 | | |
6157 | 16 | { &hf_ieee802154_pan_id_compression, |
6158 | 16 | { "PAN ID Compression", "wpan.pan_id_compression", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_PAN_ID_COMPRESSION, |
6159 | 16 | "Whether this packet contains the PAN ID or not.", HFILL }}, |
6160 | | |
6161 | 16 | { &hf_ieee802154_fcf_reserved, |
6162 | 16 | { "Reserved", "wpan.fcf.reserved", FT_BOOLEAN, 16, NULL, 0x0080, |
6163 | 16 | NULL, HFILL }}, |
6164 | | |
6165 | 16 | { &hf_ieee802154_seqno_suppression, |
6166 | 16 | { "Sequence Number Suppression", "wpan.seqno_suppression", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_SEQNO_SUPPRESSION, |
6167 | 16 | "Whether this packet contains the Sequence Number or not.", HFILL }}, |
6168 | | |
6169 | 16 | { &hf_ieee802154_ie_present, |
6170 | 16 | { "Information Elements Present", "wpan.ie_present", FT_BOOLEAN, 16, NULL, IEEE802154_FCF_IE_PRESENT, |
6171 | 16 | "Whether this packet contains the Information Elements or not.", HFILL }}, |
6172 | | |
6173 | 16 | { &hf_ieee802154_dst_addr_mode, |
6174 | 16 | { "Destination Addressing Mode", "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes), |
6175 | 16 | IEEE802154_FCF_DADDR_MASK, NULL, HFILL }}, |
6176 | | |
6177 | 16 | { &hf_ieee802154_version, |
6178 | 16 | { "Frame Version", "wpan.version", FT_UINT16, BASE_DEC, VALS(ieee802154_frame_versions), |
6179 | 16 | IEEE802154_FCF_VERSION, NULL, HFILL }}, |
6180 | | |
6181 | 16 | { &hf_ieee802154_src_addr_mode, |
6182 | 16 | { "Source Addressing Mode", "wpan.src_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes), |
6183 | 16 | IEEE802154_FCF_SADDR_MASK, NULL, HFILL }}, |
6184 | | |
6185 | | /* 802.15.4-2015 Multipurpose frame control fields */ |
6186 | 16 | { &hf_ieee802154_mpf_long_frame_control, |
6187 | 16 | { "Long Frame Control", "wpan.long_frame_control", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_LONG_FC, |
6188 | 16 | "Whether this frame control field uses one or two octets.", HFILL }}, |
6189 | | |
6190 | 16 | { &hf_ieee802154_mpf_dst_addr_mode, |
6191 | 16 | { "Destination Addressing Mode", "wpan.dst_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes), |
6192 | 16 | IEEE802154_MPF_FCF_DADDR_MASK, NULL, HFILL }}, |
6193 | | |
6194 | 16 | { &hf_ieee802154_mpf_src_addr_mode, |
6195 | 16 | { "Source Addressing Mode", "wpan.src_addr_mode", FT_UINT16, BASE_HEX, VALS(ieee802154_addr_modes), |
6196 | 16 | IEEE802154_MPF_FCF_SADDR_MASK, NULL, HFILL }}, |
6197 | | |
6198 | 16 | { &hf_ieee802154_mpf_pan_id_present, |
6199 | 16 | { "PAN ID Present", "wpan.pan_id_present", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_PAN_ID_PRESENT, |
6200 | 16 | "Whether this packet contains the destination PAN ID or not", HFILL }}, |
6201 | | |
6202 | 16 | { &hf_ieee802154_mpf_security, |
6203 | 16 | { "Security Enabled", "wpan.security", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_SEC_EN, |
6204 | 16 | "Whether security operations are performed at the MAC layer or not.", HFILL }}, |
6205 | | |
6206 | 16 | { &hf_ieee802154_mpf_seqno_suppression, |
6207 | 16 | { "Sequence Number Suppression", "wpan.seqno_suppression", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_SEQNO_SUPPRESSION, |
6208 | 16 | "Whether this packet contains the Sequence Number or not.", HFILL }}, |
6209 | | |
6210 | 16 | { &hf_ieee802154_mpf_pending, |
6211 | 16 | { "Frame Pending", "wpan.pending", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_FRAME_PND, |
6212 | 16 | "Indication of additional packets waiting to be transferred from the source device.", HFILL }}, |
6213 | | |
6214 | 16 | { &hf_ieee802154_mpf_version, |
6215 | 16 | { "Multipurpose Frame Version", "wpan.mpf_version", FT_UINT16, BASE_DEC, NULL, |
6216 | 16 | IEEE802154_MPF_FCF_VERSION, NULL, HFILL }}, |
6217 | | |
6218 | 16 | { &hf_ieee802154_mpf_ack_request, |
6219 | 16 | { "Acknowledge Request", "wpan.ack_request", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_ACK_REQ, |
6220 | 16 | "Whether the sender of this packet requests acknowledgment or not.", HFILL }}, |
6221 | | |
6222 | 16 | { &hf_ieee802154_mpf_ie_present, |
6223 | 16 | { "Information Elements Present", "wpan.ie_present", FT_BOOLEAN, 16, NULL, IEEE802154_MPF_FCF_IE_PRESENT, |
6224 | 16 | "Whether this packet contains the Information Elements or not.", HFILL }}, |
6225 | | |
6226 | 16 | { &hf_ieee802154_seqno, |
6227 | 16 | { "Sequence Number", "wpan.seq_no", FT_UINT8, BASE_DEC, NULL, 0x0, |
6228 | 16 | NULL, HFILL }}, |
6229 | | |
6230 | 16 | { &hf_ieee802154_dst_panID, |
6231 | 16 | { "Destination PAN", "wpan.dst_pan", FT_UINT16, BASE_HEX, NULL, 0x0, |
6232 | 16 | NULL, HFILL }}, |
6233 | | |
6234 | 16 | { &hf_ieee802154_dst16, |
6235 | 16 | { "Destination", "wpan.dst16", FT_UINT16, BASE_HEX, NULL, 0x0, |
6236 | 16 | NULL, HFILL }}, |
6237 | | |
6238 | 16 | { &hf_ieee802154_dst64, |
6239 | 16 | { "Destination", "wpan.dst64", FT_EUI64, BASE_NONE, NULL, 0x0, |
6240 | 16 | NULL, HFILL }}, |
6241 | | |
6242 | 16 | { &hf_ieee802154_src_panID, |
6243 | 16 | { "Source PAN", "wpan.src_pan", FT_UINT16, BASE_HEX, NULL, 0x0, |
6244 | 16 | NULL, HFILL }}, |
6245 | | |
6246 | 16 | { &hf_ieee802154_src16, |
6247 | 16 | { "Source", "wpan.src16", FT_UINT16, BASE_HEX, NULL, 0x0, |
6248 | 16 | NULL, HFILL }}, |
6249 | | |
6250 | 16 | { &hf_ieee802154_src64, |
6251 | 16 | { "Extended Source", "wpan.src64", FT_EUI64, BASE_NONE, NULL, 0x0, |
6252 | 16 | NULL, HFILL }}, |
6253 | | |
6254 | 16 | { &hf_ieee802154_addr16, |
6255 | 16 | { "Address", "wpan.addr16", FT_UINT16, BASE_HEX, NULL, 0x0, |
6256 | 16 | NULL, HFILL }}, |
6257 | | |
6258 | 16 | { &hf_ieee802154_addr64, |
6259 | 16 | { "Extended Address", "wpan.addr64", FT_EUI64, BASE_NONE, NULL, 0x0, |
6260 | 16 | NULL, HFILL }}, |
6261 | | |
6262 | 16 | { &hf_ieee802154_src64_origin, |
6263 | 16 | { "Origin", "wpan.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0, |
6264 | 16 | NULL, HFILL }}, |
6265 | | |
6266 | 16 | { &hf_ieee802154_fcs, |
6267 | 16 | { "FCS", "wpan.fcs", FT_UINT16, BASE_HEX, NULL, 0x0, |
6268 | 16 | NULL, HFILL }}, |
6269 | | |
6270 | 16 | { &hf_ieee802154_fcs32, |
6271 | 16 | { "FCS", "wpan.fcs32", FT_UINT32, BASE_HEX, NULL, 0x0, |
6272 | 16 | NULL, HFILL }}, |
6273 | | |
6274 | 16 | { &hf_ieee802154_rssi, |
6275 | 16 | { "RSSI", "wpan.rssi", FT_INT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_decibels), 0x0, |
6276 | 16 | "Received Signal Strength", HFILL }}, |
6277 | | |
6278 | 16 | { &hf_ieee802154_fcs_ok, |
6279 | 16 | { "FCS Valid", "wpan.fcs_ok", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
6280 | 16 | NULL, HFILL }}, |
6281 | | |
6282 | 16 | { &hf_ieee802154_correlation, |
6283 | 16 | { "LQI Correlation Value", "wpan.correlation", FT_UINT8, BASE_DEC, NULL, 0x0, |
6284 | 16 | NULL, HFILL }}, |
6285 | | |
6286 | | /* Information Elements */ |
6287 | | |
6288 | 16 | { &hf_ieee802154_ie_unknown_content, |
6289 | 16 | { "Unknown Content", "wpan.ie.unknown_content", FT_BYTES, SEP_SPACE, NULL, 0x0, |
6290 | 16 | NULL, HFILL }}, |
6291 | | |
6292 | 16 | { &hf_ieee802154_ie_unknown_content_payload, |
6293 | 16 | { "Unknown Content Payload", "wpan.ie.unknown_content_payload", FT_BYTES, SEP_SPACE, NULL, 0x0, |
6294 | 16 | NULL, HFILL }}, |
6295 | | |
6296 | | /* Header IE */ |
6297 | | |
6298 | 16 | { &hf_ieee802154_header_ies, |
6299 | 16 | { "Header IEs", "wpan.header_ie", FT_NONE, BASE_NONE, NULL, |
6300 | 16 | 0x0, NULL, HFILL }}, |
6301 | | |
6302 | 16 | { &hf_ieee802154_header_ie_tlv, |
6303 | 16 | { "IE Header", "wpan.header_ie_tlv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, |
6304 | | |
6305 | 16 | { &hf_ieee802154_header_ie_type, |
6306 | 16 | { "Type", "wpan.header_ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_ie_types), |
6307 | 16 | IEEE802154_HEADER_IE_TYPE_MASK, NULL, HFILL }}, |
6308 | | |
6309 | 16 | { &hf_ieee802154_header_ie_id, |
6310 | 16 | { "Id", "wpan.header_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_header_ie_names), |
6311 | 16 | IEEE802154_HEADER_IE_ID_MASK, NULL, HFILL }}, |
6312 | | |
6313 | 16 | { &hf_ieee802154_header_ie_length, |
6314 | 16 | { "Length", "wpan.header_ie.length", FT_UINT16, BASE_DEC, NULL, |
6315 | 16 | IEEE802154_HEADER_IE_LENGTH_MASK, NULL, HFILL }}, |
6316 | | |
6317 | | |
6318 | | /* Individual Header IEs */ |
6319 | | |
6320 | 16 | { &hf_ieee802154_hie_unsupported, |
6321 | 16 | { "Unsupported Header IE", "wpan.header_ie.unsupported", FT_NONE, BASE_NONE, NULL, 0x0, |
6322 | 16 | NULL, HFILL }}, |
6323 | | |
6324 | 16 | { &hf_ieee802154_hie_ht1, |
6325 | 16 | { "Header Termination 1 IE (Payload IEs follow)", "wpan.header_ie.ht1", FT_NONE, BASE_NONE, NULL, 0x0, |
6326 | 16 | NULL, HFILL }}, |
6327 | | |
6328 | 16 | { &hf_ieee802154_hie_ht2, |
6329 | 16 | { "Header Termination 2 IE (Payload follows)", "wpan.header_ie.ht2", FT_NONE, BASE_NONE, NULL, 0x0, |
6330 | 16 | NULL, HFILL }}, |
6331 | | |
6332 | 16 | { &hf_ieee802154_hie_thread, |
6333 | 16 | { "Thread IE (Payload follows)", "wpan.header_ie.thread", FT_NONE, BASE_NONE, NULL, 0x0, |
6334 | 16 | NULL, HFILL }}, |
6335 | | |
6336 | | |
6337 | | /* Time correction IE */ |
6338 | 16 | { &hf_ieee802154_hie_time_correction, |
6339 | 16 | { "Time Correction IE", "wpan.header_ie.time_correction", FT_NONE, BASE_NONE, NULL, 0x0, |
6340 | 16 | NULL, HFILL }}, |
6341 | | |
6342 | 16 | { &hf_ieee802154_hie_time_correction_time_sync_info, |
6343 | 16 | { "Time Sync Info", "wpan.header_ie.time_correction.time_sync_info", FT_UINT16, BASE_HEX, NULL, 0x0, |
6344 | 16 | NULL, HFILL }}, |
6345 | | |
6346 | 16 | { &hf_ieee802154_nack, |
6347 | 16 | { "Nack", "wpan.nack", FT_BOOLEAN, 16, TFS(&hf_ieee802154_nack_tfs), 0x8000, |
6348 | 16 | NULL, HFILL }}, |
6349 | | |
6350 | 16 | { &hf_ieee802154_hie_time_correction_value, |
6351 | 16 | { "Time Correction", "wpan.header_ie.time_correction.value", FT_INT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0FFF, |
6352 | 16 | "Time correction in microseconds", HFILL }}, |
6353 | | |
6354 | | /* CSL IE */ |
6355 | 16 | { &hf_ieee802154_hie_csl, |
6356 | 16 | { "CSL IE", "wpan.header_ie.csl", FT_NONE, BASE_NONE, NULL, 0x0, |
6357 | 16 | NULL, HFILL }}, |
6358 | | |
6359 | 16 | { &hf_ieee802154_hie_csl_phase, |
6360 | 16 | { "Phase", "wpan.header_ie.csl.phase", FT_INT16, BASE_DEC, NULL, 0x0, |
6361 | 16 | "CSL Phase in units of 10 symbols", HFILL }}, |
6362 | | |
6363 | 16 | { &hf_ieee802154_hie_csl_period, |
6364 | 16 | { "Period", "wpan.header_ie.csl.period", FT_INT16, BASE_DEC, NULL, 0x0, |
6365 | 16 | "CSL Period in units of 10 symbols", HFILL }}, |
6366 | | |
6367 | 16 | { &hf_ieee802154_hie_csl_rendezvous_time, |
6368 | 16 | { "Rendezvous Time", "wpan.header_ie.csl.rendezvous_time", FT_INT16, BASE_DEC, NULL, 0x0, |
6369 | 16 | "CSL Rendezvous Time in units of 10 symbols", HFILL }}, |
6370 | | |
6371 | | /* RendezVous Time IE */ |
6372 | 16 | { &hf_ieee802154_hie_rdv, |
6373 | 16 | { "Rendezvous Time IE", "wpan.header_ie.rdv", FT_NONE, BASE_NONE, NULL, 0x0, |
6374 | 16 | NULL, HFILL }}, |
6375 | | |
6376 | 16 | { &hf_ieee802154_hie_rdv_wakeup_interval, |
6377 | 16 | { "Wake-up Interval", "wpan.header_ie.csl.wakeup_interval", FT_INT16, BASE_DEC, NULL, 0x0, |
6378 | 16 | "Interval between two successive Wake-Up frames, in units of 10 symbols", HFILL }}, |
6379 | | |
6380 | | /* Global Time IE */ |
6381 | 16 | { &hf_ieee802154_hie_global_time, |
6382 | 16 | { "Global Time IE", "wpan.header_ie.global_time", FT_NONE, BASE_NONE, NULL, 0x0, |
6383 | 16 | NULL, HFILL }}, |
6384 | | |
6385 | 16 | { &hf_ieee802154_hie_global_time_value, |
6386 | 16 | { "Global Time", "wpan.header_ie.global_time.value", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, |
6387 | 16 | NULL, HFILL }}, |
6388 | | |
6389 | | /* Vendor Specific IE */ |
6390 | 16 | { &hf_ieee802154_hie_vendor_specific, |
6391 | 16 | { "Vendor Specific IE", "wpan.header_ie.vendor_specific", FT_NONE, BASE_NONE, NULL, 0x0, |
6392 | 16 | NULL, HFILL }}, |
6393 | | |
6394 | 16 | { &hf_ieee802154_hie_vendor_specific_vendor_oui, |
6395 | 16 | { "Vendor OUI", "wpan.header_ie.vendor_specific.vendor_oui", FT_UINT24, BASE_OUI, NULL, 0x0, |
6396 | 16 | NULL, HFILL }}, |
6397 | | |
6398 | 16 | { &hf_ieee802154_hie_vendor_specific_content, |
6399 | 16 | { "Vendor Content", "wpan.header_ie.vendor_specific.content", FT_BYTES, SEP_SPACE, NULL, 0x0, |
6400 | 16 | NULL, HFILL }}, |
6401 | | |
6402 | | /* Payload IEs */ |
6403 | | |
6404 | 16 | { &hf_ieee802154_payload_ies, |
6405 | 16 | { "Payload IEs", "wpan.payload_ie", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
6406 | | |
6407 | 16 | { &hf_ieee802154_payload_ie_tlv, |
6408 | 16 | { "IE Header", "wpan.payload_ie_tlv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
6409 | | |
6410 | 16 | { &hf_ieee802154_payload_ie_type, |
6411 | 16 | { "Type", "wpan.payload_ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_ie_types), |
6412 | 16 | IEEE802154_PAYLOAD_IE_TYPE_MASK, NULL, HFILL }}, |
6413 | | |
6414 | 16 | { &hf_ieee802154_payload_ie_id, |
6415 | 16 | { "Id", "wpan.payload_ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_payload_ie_names), |
6416 | 16 | IEEE802154_PAYLOAD_IE_ID_MASK, NULL, HFILL }}, |
6417 | | |
6418 | 16 | { &hf_ieee802154_payload_ie_length, |
6419 | 16 | { "Length", "wpan.payload_ie.length", FT_UINT16, BASE_DEC, NULL, |
6420 | 16 | IEEE802154_PAYLOAD_IE_LENGTH_MASK, NULL, HFILL }}, |
6421 | | |
6422 | | |
6423 | | /* Individual Payload IEs */ |
6424 | | |
6425 | 16 | { &hf_ieee802154_pie_unsupported, |
6426 | 16 | { "Unknown Payload IE", "wpan.payload_ie.unknown", FT_NONE, BASE_NONE, NULL, 0x0, |
6427 | 16 | NULL, HFILL }}, |
6428 | | |
6429 | 16 | { &hf_ieee802154_pie_termination, |
6430 | 16 | { "Payload Termination IE", "wpan.payload_ie.termination", FT_NONE, BASE_NONE, NULL, 0x0, |
6431 | 16 | NULL, HFILL }}, |
6432 | | |
6433 | 16 | { &hf_ieee802154_pie_vendor, |
6434 | 16 | { "Vendor Specific IE", "wpan.payload_ie.vendor", FT_NONE, BASE_NONE, NULL, 0x0, |
6435 | 16 | NULL, HFILL }}, |
6436 | | |
6437 | 16 | { &hf_ieee802154_pie_vendor_oui, |
6438 | 16 | { "Vendor OUI", "wpan.payload_ie.vendor.oui", FT_UINT24, BASE_OUI, NULL, 0x0, |
6439 | 16 | NULL, HFILL }}, |
6440 | | |
6441 | 16 | { &hf_ieee802154_pie_vendor_variable, |
6442 | 16 | { "Vendor variable", "wpan.payload_ie.vendor.variable", FT_BYTES, BASE_NONE, NULL, 0x0, |
6443 | 16 | NULL, HFILL }}, |
6444 | | |
6445 | 16 | { &hf_ieee802154_mlme, |
6446 | 16 | { "MLME IE", "wpan.mlme", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
6447 | | |
6448 | 16 | { &hf_ieee802154_psie_type, |
6449 | 16 | { "Type", "wpan.mlme.ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_psie_types), |
6450 | 16 | IEEE802154_PSIE_TYPE_MASK, NULL, HFILL }}, |
6451 | | |
6452 | 16 | { &hf_ieee802154_psie, |
6453 | 16 | { "MLME Sub IE", "wpan.mlme.ie", FT_UINT16, BASE_HEX, NULL, |
6454 | 16 | 0x0, NULL, HFILL }}, |
6455 | | |
6456 | 16 | { &hf_ieee802154_psie_id_short, |
6457 | 16 | { "Sub ID", "wpan.mlme.ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_psie_names), |
6458 | 16 | IEEE802154_PSIE_ID_MASK_SHORT, NULL, HFILL }}, |
6459 | | |
6460 | 16 | { &hf_ieee802154_psie_length_short, |
6461 | 16 | { "Length", "wpan.mlme.ie.length", FT_UINT16, BASE_DEC, NULL, |
6462 | 16 | IEEE802154_PSIE_LENGTH_MASK_SHORT, NULL, HFILL }}, |
6463 | | |
6464 | 16 | { &hf_ieee802154_psie_id_long, |
6465 | 16 | { "Sub ID", "wpan.mlme.ie.id", FT_UINT16, BASE_HEX, VALS(ieee802154_psie_names), |
6466 | 16 | IEEE802154_PSIE_ID_MASK_LONG, NULL, HFILL }}, |
6467 | | |
6468 | 16 | { &hf_ieee802154_psie_length_long, |
6469 | 16 | { "Length", "wpan.mlme.ie.length", FT_UINT16, BASE_DEC, NULL, |
6470 | 16 | IEEE802154_PSIE_LENGTH_MASK_LONG, NULL, HFILL }}, |
6471 | | |
6472 | 16 | { &hf_ieee802154_mlme_ie_unsupported, |
6473 | 16 | { "Unsupported Sub IE", "wpan.mlme.unsupported", FT_NONE, BASE_NONE, NULL, |
6474 | 16 | 0, NULL, HFILL }}, |
6475 | | |
6476 | 16 | { &hf_ieee802154_mlme_ie_data, |
6477 | 16 | { "Data", "wpan.mlme.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
6478 | | |
6479 | 16 | { &hf_ieee802154_psie_eb_filter, |
6480 | 16 | { "Enhanced Beacon Filter", "wpan.eb_filter", FT_UINT8, BASE_HEX, NULL, |
6481 | 16 | 0, NULL, HFILL }}, |
6482 | | |
6483 | 16 | { &hf_ieee802154_psie_eb_filter_pjoin, |
6484 | 16 | { "Permit Join Filter", "wpan.eb_filter.pjoin", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), |
6485 | 16 | IEEE802154_MLME_PSIE_EB_FLT_PJOIN, NULL, HFILL }}, |
6486 | | |
6487 | 16 | { &hf_ieee802154_psie_eb_filter_lqi, |
6488 | 16 | { "LQI Filter", "wpan.eb_filter.lqi", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), |
6489 | 16 | IEEE802154_MLME_PSIE_EB_FLT_LQI, NULL, HFILL }}, |
6490 | | |
6491 | 16 | { &hf_ieee802154_psie_eb_filter_lqi_min, |
6492 | 16 | { "Minimum LQI", "wpan.eb_filter.lqi_minimum", FT_UINT8, BASE_DEC, NULL, |
6493 | 16 | 0x0, NULL, HFILL }}, |
6494 | | |
6495 | 16 | { &hf_ieee802154_psie_eb_filter_percent, |
6496 | 16 | { "Probability to Respond", "wpan.eb_filter.contains_prob", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), |
6497 | 16 | IEEE802154_MLME_PSIE_EB_FLT_PERCENT, NULL, HFILL }}, |
6498 | | |
6499 | 16 | { &hf_ieee802154_psie_eb_filter_percent_prob, |
6500 | 16 | { "Response Probability Percentage", "wpan.eb_filter.prob", FT_UINT8, BASE_DEC, NULL, |
6501 | 16 | 0x0, NULL, HFILL }}, |
6502 | | |
6503 | 16 | { &hf_ieee802154_psie_eb_filter_attr_id, |
6504 | 16 | { "Requested Attribute Length", "wpan.eb_filter.attr_id", FT_UINT8, BASE_DEC, NULL, |
6505 | 16 | IEEE802154_MLME_PSIE_EB_FLT_ATTR_LEN, NULL, HFILL }}, |
6506 | | |
6507 | 16 | { &hf_ieee802154_psie_eb_filter_attr_id_bitmap, |
6508 | 16 | { "Attribute ID Bitmap", "wpan.eb_filter.attr_id_bits", FT_UINT24, BASE_HEX, NULL, |
6509 | 16 | 0x0, NULL, HFILL }}, |
6510 | | |
6511 | 16 | { &hf_ieee802154_tsch_sync, |
6512 | 16 | { "TSCH Synchronization IE", "wpan.tsch.time_sync", FT_NONE, BASE_NONE, NULL, 0x0, |
6513 | 16 | NULL, HFILL }}, |
6514 | | |
6515 | 16 | { &hf_ieee802154_tsch_asn, |
6516 | 16 | { "Absolute Slot Number", "wpan.tsch.asn", FT_UINT40, BASE_DEC, NULL, 0x0, |
6517 | 16 | NULL, HFILL }}, |
6518 | | |
6519 | 16 | { &hf_ieee802154_tsch_join_metric, |
6520 | 16 | { "Join Metric", "wpan.tsch.join_metric", FT_UINT8, BASE_DEC, NULL, 0x0, |
6521 | 16 | NULL, HFILL }}, |
6522 | | |
6523 | 16 | { &hf_ieee802154_tsch_timeslot, |
6524 | 16 | { "TSCH Timeslot IE", "wpan.tsch.timeslot", FT_NONE, BASE_NONE, NULL, 0x0, |
6525 | 16 | NULL, HFILL }}, |
6526 | | |
6527 | 16 | { &hf_ieee802154_tsch_timeslot_id, |
6528 | 16 | { "Timeslot ID", "wpan.tsch.timeslot.id", FT_UINT8, BASE_HEX, NULL, 0x0, |
6529 | 16 | "Identifier of the Timeslot Template", HFILL }}, |
6530 | | |
6531 | 16 | { &hf_ieee802154_tsch_timeslot_cca_offset, |
6532 | 16 | { "CCA Offset", "wpan.tsch.timeslot.cca_offset", FT_UINT16, BASE_DEC, NULL, 0x0, |
6533 | 16 | "Time between the beginning of the timeslot and the start of CCA", HFILL }}, |
6534 | | |
6535 | 16 | { &hf_ieee802154_tsch_timeslot_cca, |
6536 | 16 | { "CCA", "wpan.tsch.timeslot.cca", FT_UINT16, BASE_DEC, NULL, 0x0, |
6537 | 16 | "Duration of CCA", HFILL }}, |
6538 | | |
6539 | 16 | { &hf_ieee802154_tsch_timeslot_tx_offset, |
6540 | 16 | { "TX Offset", "wpan.tsch.timeslot.tx_offset", FT_UINT16, BASE_DEC, NULL, 0x0, |
6541 | 16 | "Time between the beginning of the timeslot and the start of frame transmission", HFILL }}, |
6542 | | |
6543 | 16 | { &hf_ieee802154_tsch_timeslot_rx_offset, |
6544 | 16 | { "RX Offset", "wpan.tsch.timeslot.rx_offset", FT_UINT16, BASE_DEC, NULL, 0x0, |
6545 | 16 | "Time between the beginning of the timeslot to when the receiver shall be listening", HFILL }}, |
6546 | | |
6547 | 16 | { &hf_ieee802154_tsch_timeslot_rx_ack_delay, |
6548 | 16 | { "RX Ack Delay", "wpan.tsch.timeslot.rx_ack_delay", FT_UINT16, BASE_DEC, NULL, 0x0, |
6549 | 16 | "Time between the end of frame to when the transmitter shall listen for acknowledgment", HFILL }}, |
6550 | | |
6551 | 16 | { &hf_ieee802154_tsch_timeslot_tx_ack_delay, |
6552 | 16 | { "TX Ack Delay", "wpan.tsch.timeslot.tx_ack_delay", FT_UINT16, BASE_DEC, NULL, 0x0, |
6553 | 16 | "Time between the end of frame to start of acknowledgment", HFILL }}, |
6554 | | |
6555 | 16 | { &hf_ieee802154_tsch_timeslot_rx_wait, |
6556 | 16 | { "RX Wait", "wpan.tsch.timeslot.rx_wait", FT_UINT16, BASE_DEC, NULL, 0x0, |
6557 | 16 | "Time to wait for the start of frame", HFILL }}, |
6558 | | |
6559 | 16 | { &hf_ieee802154_tsch_timeslot_ack_wait, |
6560 | 16 | { "Ack Wait", "wpan.tsch.timeslot.ack_wait", FT_UINT16, BASE_DEC, NULL, 0x0, |
6561 | 16 | "Minimum time to wait for the start of an acknowledgment", HFILL }}, |
6562 | | |
6563 | 16 | { &hf_ieee802154_tsch_timeslot_turnaround, |
6564 | 16 | { "Turn Around", "wpan.tsch.timeslot.turnaround", FT_UINT16, BASE_DEC, NULL, 0x0, |
6565 | 16 | "Transmit to receive turnaround time", HFILL }}, |
6566 | | |
6567 | 16 | { &hf_ieee802154_tsch_timeslot_max_ack, |
6568 | 16 | { "Max Ack", "wpan.tsch.timeslot.max_ack", FT_UINT16, BASE_DEC, NULL, 0x0, |
6569 | 16 | "Transmission time to send an acknowledgment", HFILL }}, |
6570 | | |
6571 | 16 | { &hf_ieee802154_tsch_timeslot_max_tx, |
6572 | 16 | { "Max TX", "wpan.tsch.timeslot.max_tx", FT_UINT24, BASE_DEC, NULL, 0x0, |
6573 | 16 | "Transmission time to send the maximum length frame", HFILL }}, |
6574 | | |
6575 | 16 | { &hf_ieee802154_tsch_timeslot_length, |
6576 | 16 | { "Timeslot Length", "wpan.tsch.timeslot.length", FT_UINT24, BASE_DEC, NULL, 0x0, |
6577 | 16 | "Total length of the timeslot, including any unused time after frame transmission", HFILL }}, |
6578 | | |
6579 | 16 | { &hf_ieee802154_tsch_channel_hopping, |
6580 | 16 | { "Channel Hopping IE", "wpan.channel_hopping", FT_NONE, BASE_NONE, NULL, 0x0, |
6581 | 16 | NULL, HFILL }}, |
6582 | | |
6583 | 16 | { &hf_ieee802154_tsch_slotframe, |
6584 | 16 | { "Slotframe IE", "wpan.tsch.slotframe", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
6585 | | |
6586 | 16 | { &hf_ieee802154_tsch_link_info, |
6587 | 16 | { "Link Information", "wpan.tsch.link_info", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
6588 | | |
6589 | 16 | { &hf_ieee802154_tsch_slotf_link_nb_slotf, |
6590 | 16 | { "Number of Slotframes", "wpan.tsch.slotframe_num", FT_UINT8, BASE_DEC, NULL, 0x0, |
6591 | 16 | NULL, HFILL }}, |
6592 | | |
6593 | 16 | { &hf_ieee802154_tsch_slotf_link_slotf_handle, |
6594 | 16 | { "Slotframe handle", "wpan.tsch.slotframe_handle", FT_UINT8, BASE_DEC, NULL, 0x0, |
6595 | 16 | NULL, HFILL }}, |
6596 | | |
6597 | 16 | { &hf_ieee802154_tsch_slotf_size, |
6598 | 16 | { "Slotframe size", "wpan.tsch.slotframe_size", FT_UINT16, BASE_DEC, NULL, 0x0, |
6599 | 16 | NULL, HFILL }}, |
6600 | | |
6601 | 16 | { &hf_ieee802154_tsch_slotf_link_nb_links, |
6602 | 16 | { "Number of Links", "wpan.tsch.nb_links", FT_UINT8, BASE_DEC, NULL, 0x0, |
6603 | 16 | NULL, HFILL }}, |
6604 | | |
6605 | 16 | { &hf_ieee802154_tsch_slotf_link_timeslot, |
6606 | 16 | { "Timeslot", "wpan.tsch.link_timeslot", FT_UINT16, BASE_DEC, NULL, 0x0, |
6607 | 16 | NULL, HFILL }}, |
6608 | | |
6609 | 16 | { &hf_ieee802154_tsch_slotf_link_channel_offset, |
6610 | 16 | { "Channel Offset", "wpan.tsch.channel_offset", FT_UINT16, BASE_DEC, NULL, 0x0, |
6611 | 16 | NULL, HFILL }}, |
6612 | | |
6613 | 16 | { &hf_ieee802154_tsch_slotf_link_options, |
6614 | 16 | { "Link Options", "wpan.tsch.link_options", FT_UINT8, BASE_HEX, NULL, 0x0, |
6615 | 16 | NULL, HFILL }}, |
6616 | | |
6617 | 16 | { &hf_ieee802154_tsch_slotf_link_options_tx, |
6618 | 16 | { "TX Link", "wpan.tsch.link_options.tx", FT_BOOLEAN, 8, NULL, (1 << 0), |
6619 | 16 | NULL, HFILL }}, |
6620 | | |
6621 | 16 | { &hf_ieee802154_tsch_slotf_link_options_rx, |
6622 | 16 | { "RX Link", "wpan.tsch.link_options.rx", FT_BOOLEAN, 8, NULL, (1 << 1), |
6623 | 16 | NULL, HFILL }}, |
6624 | | |
6625 | 16 | { &hf_ieee802154_tsch_slotf_link_options_shared, |
6626 | 16 | { "Shared Link", "wpan.tsch.link_options.shared", FT_BOOLEAN, 8, NULL, (1 << 2), |
6627 | 16 | NULL, HFILL }}, |
6628 | | |
6629 | 16 | { &hf_ieee802154_tsch_slotf_link_options_timkeeping, |
6630 | 16 | { "Timekeeping", "wpan.tsch.link_options.timekeeping", FT_BOOLEAN, 8, NULL, (1 << 3), |
6631 | 16 | NULL, HFILL }}, |
6632 | | |
6633 | 16 | { &hf_ieee802154_tsch_slotf_link_options_priority, |
6634 | 16 | { "Priority", "wpan.tsch.link_options.priority", FT_BOOLEAN, 8, NULL, (1 << 4), |
6635 | 16 | NULL, HFILL }}, |
6636 | | |
6637 | 16 | { &hf_ieee802154_tsch_hopping_sequence_id, |
6638 | 16 | { "Hopping Sequence ID", "wpan.tsch.hopping_sequence_id", FT_UINT8, BASE_HEX, NULL, 0x0, |
6639 | 16 | NULL, HFILL }}, |
6640 | | |
6641 | | /* IETF IE */ |
6642 | 16 | { &hf_ieee802154_pie_ietf, |
6643 | 16 | { "IETF Payload IE", "wpan.payload_ie.ietf", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
6644 | | |
6645 | 16 | { &hf_ieee802154_p_ie_ietf_sub_id, |
6646 | 16 | { "Sub-ID", "wpan.ietf_ie.sub_id", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, |
6647 | | |
6648 | | /* IETF IE - 6top IE */ |
6649 | 16 | { &hf_ieee802154_6top, |
6650 | 16 | { "6top IE", "wpan.6top", FT_NONE, BASE_NONE, NULL, 0x0, |
6651 | 16 | NULL, HFILL }}, |
6652 | | |
6653 | 16 | { &hf_ieee802154_6top_version, |
6654 | 16 | { "6P Version", "wpan.6top_version", FT_UINT8, BASE_DEC, NULL, IETF_6TOP_VERSION, |
6655 | 16 | NULL, HFILL }}, |
6656 | | |
6657 | 16 | { &hf_ieee802154_6top_type, |
6658 | 16 | { "Type", "wpan.6top_type", FT_UINT8, BASE_HEX, VALS(ietf_6top_types), IETF_6TOP_TYPE, |
6659 | 16 | NULL, HFILL }}, |
6660 | | |
6661 | 16 | { &hf_ieee802154_6top_flags_reserved, |
6662 | 16 | { "Reserved", "wpan.6top_flags_reserved", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_FLAGS_RESERVED, |
6663 | 16 | NULL, HFILL }}, |
6664 | | |
6665 | 16 | { &hf_ieee802154_6top_code, |
6666 | 16 | { "Code", "wpan.6top_code", FT_UINT8, BASE_HEX, NULL, 0x0, |
6667 | 16 | NULL, HFILL }}, |
6668 | | |
6669 | 16 | { &hf_ieee802154_6top_sfid, |
6670 | 16 | { "SFID (6top Scheduling Function ID)", "wpan.6top_sfid", FT_UINT8, BASE_HEX, NULL, 0x0, |
6671 | 16 | NULL, HFILL }}, |
6672 | | |
6673 | 16 | { &hf_ieee802154_6top_seqnum, |
6674 | 16 | { "SeqNum", "wpan.6top_seqnum", FT_UINT8, BASE_DEC, NULL, IETF_6TOP_SEQNUM, |
6675 | 16 | NULL, HFILL }}, |
6676 | | |
6677 | 16 | { &hf_ieee802154_6top_metadata, |
6678 | 16 | { "Metadata", "wpan.6top_metadata", FT_UINT16, BASE_HEX, NULL, 0x0, |
6679 | 16 | NULL, HFILL }}, |
6680 | | |
6681 | 16 | { &hf_ieee802154_6top_cell_options, |
6682 | 16 | { "Cell Options", "wpan.6top_cell_options", FT_UINT8, BASE_HEX, VALS(ietf_6top_cell_options), 0x0, |
6683 | 16 | NULL, HFILL }}, |
6684 | | |
6685 | 16 | { &hf_ieee802154_6top_cell_option_tx, |
6686 | 16 | { "Transmit (TX) Cell", "wpan.6top_cell_option_tx", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_TX, |
6687 | 16 | NULL, HFILL }}, |
6688 | | |
6689 | 16 | { &hf_ieee802154_6top_cell_option_rx, |
6690 | 16 | { "Receive (RX) Cell", "wpan.6top_cell_option_rx", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_RX, |
6691 | 16 | NULL, HFILL }}, |
6692 | | |
6693 | 16 | { &hf_ieee802154_6top_cell_option_shared, |
6694 | 16 | { "SHARED Cell", "wpan.6top_cell_option_shared", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_SHARED, |
6695 | 16 | NULL, HFILL }}, |
6696 | | |
6697 | 16 | { &hf_ieee802154_6top_cell_option_reserved, |
6698 | 16 | { "Reserved", "wpan.6top_cell_option_reserved", FT_UINT8, BASE_HEX, NULL, IETF_6TOP_CELL_OPTION_RESERVED, |
6699 | 16 | NULL, HFILL }}, |
6700 | | |
6701 | 16 | { &hf_ieee802154_6top_num_cells, |
6702 | 16 | { "Number of Cells", "wpan.6top_num_cells", FT_UINT8, BASE_DEC, NULL, 0x0, |
6703 | 16 | NULL, HFILL }}, |
6704 | | |
6705 | 16 | { &hf_ieee802154_6top_cell_list, |
6706 | 16 | { "CellList", "wpan.6top_cell_list", FT_NONE, BASE_NONE, NULL, 0x0, |
6707 | 16 | NULL, HFILL }}, |
6708 | | |
6709 | 16 | { &hf_ieee802154_6top_rel_cell_list, |
6710 | 16 | { "Rel. CellList", "wpan.6top_rel_cell_list", FT_NONE, BASE_NONE, NULL, 0x0, |
6711 | 16 | NULL, HFILL }}, |
6712 | | |
6713 | 16 | { &hf_ieee802154_6top_cand_cell_list, |
6714 | 16 | { "Cand. CellList", "wpan.6top_cand_cell_list", FT_NONE, BASE_NONE, NULL, 0x0, |
6715 | 16 | NULL, HFILL }}, |
6716 | | |
6717 | 16 | { &hf_ieee802154_6top_cell, |
6718 | 16 | { "Cell", "wpan.6top_cell", FT_BYTES, BASE_NONE, NULL, 0x0, |
6719 | 16 | NULL, HFILL }}, |
6720 | | |
6721 | 16 | { &hf_ieee802154_6top_reserved, |
6722 | 16 | { "Reserved", "wpan.6top_reserved", FT_UINT8, BASE_HEX, NULL, 0x0, |
6723 | 16 | NULL, HFILL }}, |
6724 | | |
6725 | 16 | { &hf_ieee802154_6top_offset, |
6726 | 16 | { "Offset", "wpan.6top_offset", FT_UINT16, BASE_DEC, NULL, 0x0, |
6727 | 16 | NULL, HFILL }}, |
6728 | | |
6729 | 16 | { &hf_ieee802154_6top_max_num_cells, |
6730 | 16 | { "Maximum Number of Requested Cells", "wpan.6top_max_num_cells", FT_UINT16, BASE_DEC, NULL, 0x0, |
6731 | 16 | NULL, HFILL }}, |
6732 | | |
6733 | 16 | { &hf_ieee802154_6top_slot_offset, |
6734 | 16 | { "Slot Offset", "wpan.6top_cell_slot_offset", FT_UINT16, BASE_HEX, NULL, 0x0, |
6735 | 16 | NULL, HFILL }}, |
6736 | | |
6737 | 16 | { &hf_ieee802154_6top_channel_offset, |
6738 | 16 | { "Channel Offset", "wpan.6top_channel_offset", FT_UINT16, BASE_HEX, NULL, 0x0, |
6739 | 16 | NULL, HFILL }}, |
6740 | | |
6741 | 16 | { &hf_ieee802154_6top_total_num_cells, |
6742 | 16 | { "Total Number of Cells", "wpan.6top_total_num_cells", FT_UINT16, BASE_DEC, NULL, 0x0, |
6743 | 16 | NULL, HFILL }}, |
6744 | | |
6745 | 16 | { &hf_ieee802154_6top_payload, |
6746 | 16 | { "Payload", "wpan.6top_payload", FT_BYTES, BASE_NONE, NULL, 0x0, |
6747 | 16 | NULL, HFILL }}, |
6748 | | |
6749 | | /* MPX IE (IEEE 802.15.9) */ |
6750 | 16 | { &hf_ieee802159_mpx, |
6751 | 16 | { "MPX IE", "wpan.mpx", FT_NONE, BASE_NONE, NULL, 0x0, |
6752 | 16 | NULL, HFILL } |
6753 | 16 | }, |
6754 | | |
6755 | 16 | { &hf_ieee802159_mpx_transaction_control, |
6756 | 16 | { "Transaction Control", "wpan.mpx.transaction_control", FT_UINT8, BASE_HEX, NULL, 0x0, |
6757 | 16 | NULL, HFILL } |
6758 | 16 | }, |
6759 | | |
6760 | 16 | { &hf_ieee802159_mpx_transfer_type, |
6761 | 16 | { "Transfer Type", "wpan.mpx.transfer_type", FT_UINT8, BASE_HEX, VALS(mpx_transfer_type_vals), IEEE802159_MPX_TRANSFER_TYPE_MASK, |
6762 | 16 | NULL, HFILL } |
6763 | 16 | }, |
6764 | | |
6765 | 16 | { &hf_ieee802159_mpx_transaction_id, |
6766 | 16 | { "Transaction ID", "wpan.mpx.transaction_id", FT_UINT8, BASE_HEX, NULL, IEEE802159_MPX_TRANSACTION_ID_MASK, |
6767 | 16 | NULL, HFILL } |
6768 | 16 | }, |
6769 | | |
6770 | 16 | { &hf_ieee802159_mpx_transaction_id_as_multiplex_id, |
6771 | 16 | { "Multiplex ID", "wpan.mpx.multiplex_id", FT_UINT8, BASE_HEX, VALS(mpx_multiplex_id_vals), IEEE802159_MPX_TRANSACTION_ID_MASK, |
6772 | 16 | "Transaction ID used as Multiplex ID", HFILL } |
6773 | 16 | }, |
6774 | | |
6775 | 16 | { &hf_ieee802159_mpx_fragment_number, |
6776 | 16 | { "Fragment Number", "wpan.mpx.fragment_number", FT_UINT8, BASE_DEC, NULL, 0x0, |
6777 | 16 | NULL, HFILL } |
6778 | 16 | }, |
6779 | | |
6780 | 16 | { &hf_ieee802159_mpx_total_frame_size, |
6781 | 16 | { "Total Frame Size", "wpan.mpx.total_frame_size", FT_UINT16, BASE_DEC, NULL, 0x0, |
6782 | 16 | "Total Upper-Layer Frame Size", HFILL } |
6783 | 16 | }, |
6784 | | |
6785 | 16 | { &hf_ieee802159_mpx_multiplex_id, |
6786 | 16 | { "Multiplex ID", "wpan.mpx.multiplex_id", FT_UINT16, BASE_HEX, NULL, 0x0, |
6787 | 16 | NULL, HFILL } |
6788 | 16 | }, |
6789 | | |
6790 | 16 | { &hf_ieee802159_mpx_kmp_id, |
6791 | 16 | { "KMP ID", "wpan.mpx.kmp.id", FT_UINT8, BASE_DEC, VALS(ieee802154_mpx_kmp_id_vals), 0x0, |
6792 | 16 | NULL, HFILL } |
6793 | 16 | }, |
6794 | | |
6795 | 16 | { &hf_ieee802159_mpx_kmp_vendor_oui, |
6796 | 16 | { "Vendor OUI", "wpan.mpx.kmp.vendor_oui", FT_UINT24, BASE_OUI, NULL, 0x0, |
6797 | 16 | NULL, HFILL } |
6798 | 16 | }, |
6799 | | |
6800 | 16 | { &hf_ieee802159_mpx_fragment, |
6801 | 16 | { "Upper-Layer Frame Fragment", "wpan.mpx.fragment", FT_BYTES, SEP_SPACE, NULL, 0x0, |
6802 | 16 | NULL, HFILL } |
6803 | 16 | }, |
6804 | | |
6805 | 16 | { &hf_ieee802159_mpx_wisun_subid, |
6806 | 16 | { "Wi-SUN Multiplex Sub ID", "wpan.mpx.wisun", FT_UINT8, BASE_HEX, VALS(mpx_wisun_subid_vals), 0x0, |
6807 | 16 | NULL, HFILL } |
6808 | 16 | }, |
6809 | | |
6810 | | /* Command Frame Specific Fields */ |
6811 | | |
6812 | 16 | { &hf_ieee802154_cmd_id, |
6813 | 16 | { "Command Identifier", "wpan.cmd", FT_UINT8, BASE_HEX, VALS(ieee802154_cmd_names), 0x0, |
6814 | 16 | NULL, HFILL }}, |
6815 | | |
6816 | 16 | { &hf_ieee802154_cmd_vendor_oui, |
6817 | 16 | { "Vendor OUI", "wpan.cmd.vendor_oui", FT_UINT24, BASE_OUI, NULL, 0x0, |
6818 | 16 | NULL, HFILL }}, |
6819 | | |
6820 | | /* Capability Information Fields */ |
6821 | | |
6822 | 16 | { &hf_ieee802154_cinfo_alt_coord, |
6823 | 16 | { "Alternate PAN Coordinator", "wpan.cinfo.alt_coord", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALT_PAN_COORD, |
6824 | 16 | "Whether this device can act as a PAN coordinator or not.", HFILL }}, |
6825 | | |
6826 | 16 | { &hf_ieee802154_cinfo_device_type, |
6827 | 16 | { "Device Type", "wpan.cinfo.device_type", FT_BOOLEAN, 8, TFS(&tfs_cinfo_device_type), IEEE802154_CMD_CINFO_DEVICE_TYPE, |
6828 | 16 | "Whether this device is RFD (reduced-function device) or FFD (full-function device).", HFILL }}, |
6829 | | |
6830 | 16 | { &hf_ieee802154_cinfo_power_src, |
6831 | 16 | { "Power Source", "wpan.cinfo.power_src", FT_BOOLEAN, 8, TFS(&tfs_cinfo_power_src), IEEE802154_CMD_CINFO_POWER_SRC, |
6832 | 16 | "Whether this device is operating on AC/mains or battery power.", HFILL }}, |
6833 | | |
6834 | 16 | { &hf_ieee802154_cinfo_idle_rx, |
6835 | 16 | { "Receive On When Idle", "wpan.cinfo.idle_rx", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_IDLE_RX, |
6836 | 16 | "Whether this device can receive packets while idle or not.", HFILL }}, |
6837 | | |
6838 | 16 | { &hf_ieee802154_cinfo_sec_capable, |
6839 | 16 | { "Security Capability", "wpan.cinfo.sec_capable", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_SEC_CAPABLE, |
6840 | 16 | "Whether this device is capable of receiving encrypted packets.", HFILL }}, |
6841 | | |
6842 | 16 | { &hf_ieee802154_cinfo_alloc_addr, |
6843 | 16 | { "Allocate Address", "wpan.cinfo.alloc_addr", FT_BOOLEAN, 8, NULL, IEEE802154_CMD_CINFO_ALLOC_ADDR, |
6844 | 16 | "Whether this device wishes to use a 16-bit short address instead of its IEEE 802.15.4 64-bit long address.", HFILL }}, |
6845 | | |
6846 | | /* Association response fields */ |
6847 | | |
6848 | 16 | { &hf_ieee802154_assoc_addr, |
6849 | 16 | { "Short Address", "wpan.asoc.addr", FT_UINT16, BASE_HEX, NULL, 0x0, |
6850 | 16 | "The short address that the device should assume. An address of 0xfffe indicates that the device should use its IEEE 64-bit long address.", HFILL }}, |
6851 | | |
6852 | 16 | { &hf_ieee802154_assoc_status, |
6853 | 16 | { "Association Status", "wpan.assoc.status", FT_UINT8, BASE_HEX, NULL, 0x0, |
6854 | 16 | NULL, HFILL }}, |
6855 | | |
6856 | 16 | { &hf_ieee802154_disassoc_reason, |
6857 | 16 | { "Disassociation Reason", "wpan.disassoc.reason", FT_UINT8, BASE_HEX, NULL, 0x0, |
6858 | 16 | NULL, HFILL }}, |
6859 | | |
6860 | | /* Coordinator Realignment fields */ |
6861 | | |
6862 | 16 | { &hf_ieee802154_realign_pan, |
6863 | 16 | { "PAN ID", "wpan.realign.pan", FT_UINT16, BASE_HEX, NULL, 0x0, |
6864 | 16 | "The PAN identifier the coordinator wishes to use for future communication.", HFILL }}, |
6865 | | |
6866 | 16 | { &hf_ieee802154_realign_caddr, |
6867 | 16 | { "Coordinator Short Address", "wpan.realign.caddr", FT_UINT16, BASE_HEX, NULL, 0x0, |
6868 | 16 | "The 16-bit address the coordinator wishes to use for future communication.", HFILL }}, |
6869 | | |
6870 | 16 | { &hf_ieee802154_realign_channel, |
6871 | 16 | { "Logical Channel", "wpan.realign.channel", FT_UINT8, BASE_DEC, NULL, 0x0, |
6872 | 16 | "The logical channel the coordinator wishes to use for future communication.", HFILL }}, |
6873 | | |
6874 | 16 | { &hf_ieee802154_realign_addr, |
6875 | 16 | { "Short Address", "wpan.realign.addr", FT_UINT16, BASE_HEX, NULL, 0x0, |
6876 | 16 | "A short-address that the orphaned device shall assume if applicable.", HFILL }}, |
6877 | | |
6878 | 16 | { &hf_ieee802154_realign_channel_page, |
6879 | 16 | { "Channel Page", "wpan.realign.channel_page", FT_UINT8, BASE_DEC, NULL, 0x0, |
6880 | 16 | "The logical channel page the coordinator wishes to use for future communication.", HFILL }}, |
6881 | | |
6882 | 16 | { &hf_ieee802154_gtsreq_len, |
6883 | 16 | { "GTS Length", "wpan.gtsreq.length", FT_UINT8, BASE_DEC, NULL, IEEE802154_CMD_GTS_REQ_LEN, |
6884 | 16 | "Number of superframe slots the device is requesting.", HFILL }}, |
6885 | | |
6886 | 16 | { &hf_ieee802154_gtsreq_dir, |
6887 | 16 | { "GTS Direction", "wpan.gtsreq.direction", FT_BOOLEAN, 8, TFS(&tfs_gtsreq_dir), IEEE802154_CMD_GTS_REQ_DIR, |
6888 | 16 | "The direction of traffic in the guaranteed timeslot.", HFILL }}, |
6889 | | |
6890 | 16 | { &hf_ieee802154_gtsreq_type, |
6891 | 16 | { "Characteristic Type", "wpan.gtsreq.type", FT_BOOLEAN, 8, TFS(&tfs_gtsreq_type), IEEE802154_CMD_GTS_REQ_TYPE, |
6892 | 16 | "Whether this request is to allocate or deallocate a timeslot.", HFILL }}, |
6893 | | |
6894 | | /* Beacon Frame Specific Fields */ |
6895 | | |
6896 | 16 | { &hf_ieee802154_beacon_order, |
6897 | 16 | { "Beacon Interval", "wpan.beacon_order", FT_UINT16, BASE_DEC, NULL, IEEE802154_BEACON_ORDER_MASK, |
6898 | 16 | "Specifies the transmission interval of the beacons.", HFILL }}, |
6899 | | |
6900 | 16 | { &hf_ieee802154_superframe_order, |
6901 | 16 | { "Superframe Interval", "wpan.superframe_order", FT_UINT16, BASE_DEC, NULL, |
6902 | 16 | IEEE802154_SUPERFRAME_ORDER_MASK, |
6903 | 16 | "Specifies the length of time the coordinator will interact with the PAN.", HFILL }}, |
6904 | | |
6905 | 16 | { &hf_ieee802154_cap, |
6906 | 16 | { "Final CAP Slot", "wpan.cap", FT_UINT16, BASE_DEC, NULL, IEEE802154_SUPERFRAME_CAP_MASK, |
6907 | 16 | "Specifies the final superframe slot used by the CAP.", HFILL }}, |
6908 | | |
6909 | 16 | { &hf_ieee802154_superframe_battery_ext, |
6910 | 16 | { "Battery Extension", "wpan.battery_ext", FT_BOOLEAN, 16, NULL, IEEE802154_BATT_EXTENSION_MASK, |
6911 | 16 | "Whether transmissions may not extend past the length of the beacon frame.", HFILL }}, |
6912 | | |
6913 | 16 | { &hf_ieee802154_superframe_coord, |
6914 | 16 | { "PAN Coordinator", "wpan.bcn_coord", FT_BOOLEAN, 16, NULL, IEEE802154_SUPERFRAME_COORD_MASK, |
6915 | 16 | "Whether this beacon frame is being transmitted by the PAN coordinator or not.", HFILL }}, |
6916 | | |
6917 | 16 | { &hf_ieee802154_assoc_permit, |
6918 | 16 | { "Association Permit", "wpan.assoc_permit", FT_BOOLEAN, 16, NULL, IEEE802154_ASSOC_PERMIT_MASK, |
6919 | 16 | "Whether this PAN is accepting association requests or not.", HFILL }}, |
6920 | | |
6921 | 16 | { &hf_ieee802154_gts_count, |
6922 | 16 | { "GTS Descriptor Count", "wpan.gts.count", FT_UINT8, BASE_DEC, NULL, 0x0, |
6923 | 16 | "The number of GTS descriptors present in this beacon frame.", HFILL }}, |
6924 | | |
6925 | 16 | { &hf_ieee802154_gts_permit, |
6926 | 16 | { "GTS Permit", "wpan.gts.permit", FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
6927 | 16 | "Whether the PAN coordinator is accepting GTS requests or not.", HFILL }}, |
6928 | | |
6929 | 16 | { &hf_ieee802154_gts_direction, |
6930 | 16 | { "Direction", "wpan.gts.direction", FT_BOOLEAN, BASE_NONE, TFS(&ieee802154_gts_direction_tfs), 0x0, |
6931 | 16 | "A flag defining the direction of the GTS Slot.", HFILL }}, |
6932 | | |
6933 | 16 | { &hf_ieee802154_gts_address, |
6934 | 16 | { "Address", "wpan.gts.address", FT_UINT16, BASE_HEX, NULL, 0x0, |
6935 | 16 | NULL, HFILL }}, |
6936 | | |
6937 | 16 | { &hf_ieee802154_pending16, |
6938 | 16 | { "Address", "wpan.pending16", FT_UINT16, BASE_HEX, NULL, 0x0, |
6939 | 16 | "Device with pending data to receive.", HFILL }}, |
6940 | | |
6941 | 16 | { &hf_ieee802154_pending64, |
6942 | 16 | { "Address", "wpan.pending64", FT_EUI64, BASE_NONE, NULL, 0x0, |
6943 | 16 | "Device with pending data to receive.", HFILL }}, |
6944 | | |
6945 | | /* Auxiliary Security Header Fields */ |
6946 | 16 | { &hf_ieee802154_aux_security_header, |
6947 | 16 | { "Auxiliary Security Header", "wpan.aux_sec.hdr", FT_NONE, BASE_NONE, NULL, |
6948 | 16 | 0x0, "The Auxiliary Security Header of the frame", HFILL }}, |
6949 | | |
6950 | 16 | { &hf_ieee802154_aux_sec_security_level, |
6951 | 16 | { "Security Level", "wpan.aux_sec.sec_level", FT_UINT8, BASE_HEX, VALS(ieee802154_sec_level_names), |
6952 | 16 | IEEE802154_AUX_SEC_LEVEL_MASK, "The Security Level of the frame", HFILL }}, |
6953 | | |
6954 | 16 | { &hf_ieee802154_aux_sec_security_control, |
6955 | 16 | { "Security Control Field", "wpan.aux_sec.security_control_field", FT_UINT8, BASE_HEX, NULL, |
6956 | 16 | 0x0, NULL, HFILL }}, |
6957 | | |
6958 | 16 | { &hf_ieee802154_aux_sec_key_id_mode, |
6959 | 16 | { "Key Identifier Mode", "wpan.aux_sec.key_id_mode", FT_UINT8, BASE_HEX, VALS(ieee802154_key_id_mode_names), |
6960 | 16 | IEEE802154_AUX_KEY_ID_MODE_MASK, |
6961 | 16 | "The scheme to use by the recipient to lookup the key in its key table", HFILL }}, |
6962 | | |
6963 | 16 | { &hf_ieee802154_aux_sec_frame_counter_suppression, |
6964 | 16 | { "Frame Counter Suppression", "wpan.aux_sec.frame_counter_suppression", FT_BOOLEAN, 8, NULL, |
6965 | 16 | IEEE802154_AUX_FRAME_COUNTER_SUPPRESSION_MASK, |
6966 | 16 | "Whether the frame counter is omitted from the Auxiliary Security Header", HFILL }}, |
6967 | | |
6968 | 16 | { &hf_ieee802154_aux_sec_asn_in_nonce, |
6969 | 16 | { "ASN in Nonce", "wpan.aux_sec.asn_in_nonce", FT_BOOLEAN, 8, NULL, |
6970 | 16 | IEEE802154_AUX_ASN_IN_NONCE_MASK, |
6971 | 16 | "Whether the ASN is used to generate the nonce instead of the frame counter", HFILL }}, |
6972 | | |
6973 | 16 | { &hf_ieee802154_aux_sec_reserved, |
6974 | 16 | { "Reserved", "wpan.aux_sec.reserved", FT_UINT8, BASE_HEX, NULL, IEEE802154_AUX_CTRL_RESERVED_MASK, |
6975 | 16 | NULL, HFILL }}, |
6976 | | |
6977 | 16 | { &hf_ieee802154_aux_sec_frame_counter, |
6978 | 16 | { "Frame Counter", "wpan.aux_sec.frame_counter", FT_UINT32, BASE_DEC, NULL, 0x0, |
6979 | 16 | "Frame counter of the originator of the protected frame", HFILL }}, |
6980 | | |
6981 | 16 | { &hf_ieee802154_aux_sec_key_source, |
6982 | 16 | { "Key Source", "wpan.aux_sec.key_source", FT_UINT64, BASE_HEX, NULL, 0x0, |
6983 | 16 | "Key Source for processing of the protected frame", HFILL }}, |
6984 | | |
6985 | 16 | { &hf_ieee802154_aux_sec_key_source_bytes, |
6986 | 16 | { "Key Source", "wpan.aux_sec.key_source.bytes", FT_BYTES, BASE_NONE, NULL, 0x0, |
6987 | 16 | "Key Source for processing of the protected frame", HFILL }}, |
6988 | | |
6989 | 16 | { &hf_ieee802154_aux_sec_key_index, |
6990 | 16 | { "Key Index", "wpan.aux_sec.key_index", FT_UINT8, BASE_HEX, NULL, 0x0, |
6991 | 16 | "Key Index for processing of the protected frame", HFILL }}, |
6992 | | |
6993 | 16 | { &hf_ieee802154_mic, |
6994 | 16 | { "MIC", "wpan.mic", FT_BYTES, BASE_NONE, NULL, 0x0, |
6995 | 16 | NULL, HFILL }}, |
6996 | | |
6997 | 16 | { &hf_ieee802154_key_number, |
6998 | 16 | { "Key Number", "wpan.key_number", FT_UINT8, BASE_DEC, NULL, 0x0, |
6999 | 16 | "Key number used to decode", HFILL }}, |
7000 | | |
7001 | | /* IEEE 802.15.4-2003 Security Header Fields */ |
7002 | 16 | { &hf_ieee802154_sec_frame_counter, |
7003 | 16 | { "Frame Counter", "wpan.sec_frame_counter", FT_UINT32, BASE_HEX, NULL, 0x0, |
7004 | 16 | "Frame counter of the originator of the protected frame (802.15.4-2003)", HFILL }}, |
7005 | | |
7006 | 16 | { &hf_ieee802154_sec_key_sequence_counter, |
7007 | 16 | { "Key Sequence Counter", "wpan.sec_key_sequence_counter", FT_UINT8, BASE_HEX, NULL, 0x0, |
7008 | 16 | "Key Sequence counter of the originator of the protected frame (802.15.4-2003)", HFILL }}, |
7009 | | |
7010 | 16 | { &hf_ieee802154_no_ack, |
7011 | 16 | { "No ack found", "wpan.no_ack", FT_NONE, BASE_NONE, NULL, 0x0, |
7012 | 16 | "No corresponding ack frame was found", HFILL }}, |
7013 | | |
7014 | 16 | { &hf_ieee802154_no_ack_request, |
7015 | 16 | { "No request found", "wpan.no_ack_request", FT_NONE, BASE_NONE, NULL, 0x0, |
7016 | 16 | "No corresponding request frame was found", HFILL }}, |
7017 | | |
7018 | 16 | { &hf_ieee802154_ack_in, |
7019 | 16 | { "Ack In", "wpan.ack_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0, |
7020 | 16 | "The ack to this request is in this frame", HFILL }}, |
7021 | | |
7022 | 16 | { &hf_ieee802154_ack_to, |
7023 | 16 | { "Ack To", "wpan.ack_to", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_ACK), 0x0, |
7024 | 16 | "This is the ack to the request in this frame", HFILL }}, |
7025 | | |
7026 | 16 | { &hf_ieee802154_ack_time, |
7027 | 16 | { "Ack Time", "wpan.ack_time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, |
7028 | 16 | "The time between the request and the ack", HFILL }}, |
7029 | | |
7030 | | /* ZBOSS dump */ |
7031 | | |
7032 | 16 | { &hf_zboss_page, |
7033 | 16 | { "Page", "wpan-zboss.page", FT_UINT8, BASE_DEC_HEX, VALS(zboss_page_names), 0xFE, |
7034 | 16 | "IEEE802.15.4 page number", HFILL } }, |
7035 | | |
7036 | 16 | { &hf_zboss_channel, |
7037 | 16 | { "Channel", "wpan-zboss.channel", FT_UINT8, BASE_DEC, NULL, 0x0, |
7038 | 16 | "Channel number", HFILL }}, |
7039 | | |
7040 | 16 | { &hf_zboss_direction, |
7041 | 16 | { "ZBOSS Direction", "wpan-zboss.direction", FT_UINT8, BASE_HEX, VALS(zboss_direction_names), 0x01, |
7042 | 16 | "ZBOSS Packet Direction", HFILL }}, |
7043 | | |
7044 | 16 | { &hf_zboss_trace_number, |
7045 | 16 | { "Trace number", "wpan-zboss.trace", FT_UINT32, BASE_DEC, NULL, 0x0, |
7046 | 16 | "Trace item number", HFILL }}, |
7047 | | |
7048 | | /* TAP Packet Fields */ |
7049 | 16 | { &hf_ieee802154_tap_version, |
7050 | 16 | { "Version", "wpan-tap.version", FT_UINT8, BASE_DEC, NULL, 0x0, |
7051 | 16 | "TAP Packet Version", HFILL }}, |
7052 | | |
7053 | 16 | { &hf_ieee802154_tap_reserved, |
7054 | 16 | { "Reserved", "wpan-tap.reserved", FT_UINT8, BASE_DEC, NULL, 0x0, |
7055 | 16 | "TAP Packet Reserved", HFILL }}, |
7056 | | |
7057 | 16 | { &hf_ieee802154_tap_length, |
7058 | 16 | { "Length", "wpan-tap.length", FT_UINT16, BASE_DEC, NULL, 0x0, |
7059 | 16 | "TAP Packet Length", HFILL }}, |
7060 | | |
7061 | 16 | { &hf_ieee802154_tap_data_length, |
7062 | 16 | { "Data Length", "wpan-tap.data_length", FT_UINT16, BASE_DEC, NULL, 0x0, |
7063 | 16 | "IEEE 802.15.4 Data Length", HFILL }}, |
7064 | | |
7065 | 16 | { &hf_ieee802154_tap_tlv_type, |
7066 | 16 | { "TLV Type", "wpan-tap.tlv.type", FT_UINT16, BASE_DEC, VALS(tap_tlv_types), 0x0, |
7067 | 16 | NULL, HFILL }}, |
7068 | | |
7069 | 16 | { &hf_ieee802154_tap_tlv_length, |
7070 | 16 | { "TLV Length", "wpan-tap.tlv.length", FT_UINT16, BASE_DEC, NULL, 0x0, |
7071 | 16 | NULL, HFILL }}, |
7072 | | |
7073 | 16 | { &hf_ieee802154_tap_tlv_unknown, |
7074 | 16 | { "Unknown", "wpan-tap.tlv.unknown", FT_BYTES, BASE_NONE, NULL, 0x0, |
7075 | 16 | NULL, HFILL }}, |
7076 | | |
7077 | 16 | { &hf_ieee802154_tap_tlv_padding, |
7078 | 16 | { "Padding", "wpan-tap.tlv.padding", FT_BYTES, BASE_NONE, NULL, 0x0, |
7079 | 16 | NULL, HFILL }}, |
7080 | | |
7081 | 16 | { &hf_ieee802154_tap_fcs_type, |
7082 | 16 | { "FCS Type", "wpan-tap.fcs_type", FT_UINT8, BASE_DEC, VALS(tap_fcs_type_names), 0x0, |
7083 | 16 | NULL, HFILL }}, |
7084 | | |
7085 | 16 | { &hf_ieee802154_tap_rss, |
7086 | 16 | { "RSS", "wpan-tap.rss", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_dbm), 0x0, |
7087 | 16 | NULL, HFILL }}, |
7088 | | |
7089 | 16 | { &hf_ieee802154_ch_num, |
7090 | 16 | { "Channel", "wpan-tap.ch_num", FT_UINT16, BASE_DEC, NULL, 0x0, |
7091 | 16 | "Channel number", HFILL }}, |
7092 | | |
7093 | 16 | { &hf_ieee802154_ch_page, |
7094 | 16 | { "Page", "wpan-tap.ch_page", FT_UINT8, BASE_DEC, VALS(channel_page_names), 0x0, |
7095 | 16 | "Channel page", HFILL }}, |
7096 | | |
7097 | 16 | { &hf_ieee802154_bit_rate, |
7098 | 16 | { "Bit Rate", "wpan-tap.bit_rate", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_sec), 0x0, |
7099 | 16 | NULL, HFILL }}, |
7100 | | |
7101 | 16 | { &hf_ieee802154_sun_band, |
7102 | 16 | { "Band", "wpan-tap.sun_band", FT_UINT8, BASE_DEC, VALS(sun_bands), 0x0, |
7103 | 16 | NULL, HFILL }}, |
7104 | | |
7105 | 16 | { &hf_ieee802154_sun_type, |
7106 | 16 | { "Type", "wpan-tap.sun_type", FT_UINT8, BASE_DEC, VALS(sun_types), 0x0, |
7107 | 16 | NULL, HFILL }}, |
7108 | | |
7109 | 16 | { &hf_ieee802154_sun_mode, |
7110 | 16 | { "Mode", "wpan-tap.sun_mode", FT_UINT8, BASE_DEC, NULL, 0x0, |
7111 | 16 | NULL, HFILL }}, |
7112 | | |
7113 | 16 | { &hf_ieee802154_mode_fsk_a, |
7114 | 16 | { "FSK-A mode", "wpan-tap.mode.fsk_a", FT_UINT8, BASE_DEC, VALS(fsk_a_modes), 0x0, |
7115 | 16 | NULL, HFILL }}, |
7116 | | |
7117 | 16 | { &hf_ieee802154_mode_fsk_b, |
7118 | 16 | { "FSK-B mode", "wpan-tap.mode.fsk_b", FT_UINT8, BASE_DEC, VALS(fsk_b_modes), 0x0, |
7119 | 16 | NULL, HFILL }}, |
7120 | | |
7121 | 16 | { &hf_ieee802154_mode_oqpsk_a, |
7122 | 16 | { "O-QPSK-A mode", "wpan-tap.mode.oqpsk_a", FT_UINT8, BASE_DEC, VALS(oqpsk_a_modes), 0x0, |
7123 | 16 | NULL, HFILL }}, |
7124 | | |
7125 | 16 | { &hf_ieee802154_mode_oqpsk_b, |
7126 | 16 | { "O-QPSK-B mode", "wpan-tap.mode.oqpsk_b", FT_UINT8, BASE_DEC, VALS(oqpsk_b_modes), 0x0, |
7127 | 16 | NULL, HFILL }}, |
7128 | | |
7129 | 16 | { &hf_ieee802154_mode_oqpsk_c, |
7130 | 16 | { "O-QPSK-C mode", "wpan-tap.mode.oqpsk_c", FT_UINT8, BASE_DEC, VALS(oqpsk_c_modes), 0x0, |
7131 | 16 | NULL, HFILL }}, |
7132 | | |
7133 | 16 | { &hf_ieee802154_mode_ofdm, |
7134 | 16 | { "OFDM mode", "wpan-tap.mode.ofdm", FT_UINT8, BASE_DEC, VALS(ofdm_modes), 0x0, |
7135 | 16 | NULL, HFILL }}, |
7136 | | |
7137 | 16 | { &hf_ieee802154_sof_ts, |
7138 | 16 | { "Start of frame timestamp", "wpan-tap.sof_ts", FT_UINT64, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, |
7139 | 16 | NULL, HFILL }}, |
7140 | | |
7141 | 16 | { &hf_ieee802154_eof_ts, |
7142 | 16 | { "End of frame timestamp", "wpan-tap.eof_ts", FT_UINT64, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, |
7143 | 16 | NULL, HFILL }}, |
7144 | | |
7145 | 16 | { &hf_ieee802154_slot_start_ts, |
7146 | 16 | { "Start of slot timestamp", "wpan-tap.slot_start_ts", FT_UINT64, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, |
7147 | 16 | NULL, HFILL }}, |
7148 | | |
7149 | 16 | { &hf_ieee802154_tap_timeslot_length, |
7150 | 16 | { "Timeslot length", "wpan-tap.timeslot_length", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, |
7151 | 16 | NULL, HFILL }}, |
7152 | | |
7153 | 16 | { &hf_ieee802154_tap_lqi, |
7154 | 16 | { "Link Quality Indicator", "wpan-tap.lqi", FT_UINT8, BASE_DEC, NULL, 0x0, |
7155 | 16 | NULL, HFILL }}, |
7156 | | |
7157 | 16 | { &hf_ieee802154_chplan_start, |
7158 | 16 | { "Channel0 freq", "wpan-tap.chplan.start", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_khz), 0x0, |
7159 | 16 | "Channel 0 center frequency", HFILL }}, |
7160 | | |
7161 | 16 | { &hf_ieee802154_chplan_spacing, |
7162 | 16 | { "Spacing", "wpan-tap.chplan.spacing", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_khz), 0x0, |
7163 | 16 | "Channel spacing", HFILL }}, |
7164 | | |
7165 | 16 | { &hf_ieee802154_chplan_channels, |
7166 | 16 | { "Channels", "wpan-tap.chplan.channels", FT_UINT16, BASE_DEC, NULL, 0x0, |
7167 | 16 | "Number of channels", HFILL }}, |
7168 | | |
7169 | 16 | { &hf_ieee802154_ch_freq, |
7170 | 16 | { "Frequency", "wpan-tap.ch_freq", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_khz), 0x0, |
7171 | 16 | "Channel center frequency", HFILL }}, |
7172 | | |
7173 | 16 | { &hf_ieee802154_frame_start_offset, |
7174 | 16 | { "Frame start offset", "wpan.tsch.frame_start_offset", FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, |
7175 | 16 | "Start of frame timestamp - start of slot timestamp", HFILL }}, |
7176 | | |
7177 | 16 | { &hf_ieee802154_frame_duration, |
7178 | 16 | { "Frame duration", "wpan.tsch.frame_duration", FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, |
7179 | 16 | "End of frame timestamp - start of frame timestamp", HFILL }}, |
7180 | | |
7181 | 16 | { &hf_ieee802154_frame_end_offset, |
7182 | 16 | { "Frame end offset", "wpan.tsch.frame_end_offset", FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, |
7183 | 16 | "End of frame timestamp - (start of slot timestamp + timeslot length)", HFILL }}, |
7184 | | |
7185 | 16 | { &hf_ieee802154_asn, |
7186 | 16 | { "ASN", "wpan-tap.asn", FT_UINT64, BASE_DEC, NULL, 0x0, |
7187 | 16 | "Absolute Slot Number", HFILL }}, |
7188 | | |
7189 | 16 | { &hf_ieee802154_tap_phr_type, |
7190 | 16 | { "PHR Type", "wpan-tap.phr.type", FT_UINT16, BASE_DEC, VALS(ieee802154_phr_type_vals), 0x0, |
7191 | 16 | NULL, HFILL }}, |
7192 | | |
7193 | 16 | { &hf_ieee802154_tap_phr_bits, |
7194 | 16 | { "PHR Bits", "wpan-tap.phr.bits", FT_UINT16, BASE_DEC, NULL, 0x0, |
7195 | 16 | NULL, HFILL }}, |
7196 | | |
7197 | 16 | { &hf_ieee802154_tap_phr_data, |
7198 | 16 | { "PHR Data", "wpan-tap.phr.data", FT_BYTES, BASE_NONE, NULL, 0x0, |
7199 | 16 | NULL, HFILL }}, |
7200 | | |
7201 | 16 | { &hf_ieee802154_tap_phr_fsk, |
7202 | 16 | { "FSK PHR", "wpan-tap.phr.fsk", FT_UINT16, BASE_HEX, NULL, 0x0, |
7203 | 16 | NULL, HFILL }}, |
7204 | | |
7205 | 16 | { &hf_ieee802154_tap_fsk_ms_phr, |
7206 | 16 | { "FSK Mode Switch PHR", "wpan-tap.phr.fsk_ms", FT_UINT16, BASE_HEX, NULL, 0x0, |
7207 | 16 | NULL, HFILL }}, |
7208 | | |
7209 | 16 | { &hf_ieee802154_tap_wisun_ms_phr, |
7210 | 16 | { "Wi-SUN Mode Switch PHR", "wpan-tap.phr.wisun_ms", FT_UINT16, BASE_HEX, NULL, 0x0, |
7211 | 16 | NULL, HFILL }}, |
7212 | | |
7213 | 16 | { &hf_ieee802154_tap_phr_fsk_ms, |
7214 | 16 | { "MS", "wpan-tap.phr.fsk.ms", FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), IEEE802154_TAP_PHR_FSK_MS, |
7215 | 16 | "Mode Switch", HFILL }}, |
7216 | | |
7217 | 16 | { &hf_ieee802154_tap_phr_fsk_fcs, |
7218 | 16 | { "FCS Type", "wpan-tap.phr.fsk.fcs", FT_BOOLEAN, 16, TFS(&tfs_fcs_type), IEEE802154_TAP_PHR_FSK_FCS, |
7219 | 16 | NULL, HFILL }}, |
7220 | | |
7221 | 16 | { &hf_ieee802154_tap_phr_fsk_dw, |
7222 | 16 | { "DW", "wpan-tap.phr.fsk.dw", FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), IEEE802154_TAP_PHR_FSK_DW, |
7223 | 16 | "Data Whitening", HFILL }}, |
7224 | | |
7225 | 16 | { &hf_ieee802154_tap_phr_fsk_length, |
7226 | 16 | { "Frame Length", "wpan-tap.phr.fsk.length", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_LENGTH, |
7227 | 16 | NULL, HFILL }}, |
7228 | | |
7229 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_param, |
7230 | 16 | { "Parameter", "wpan-tap.phr.fsk_ms.length", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_MS_PARAM, |
7231 | 16 | "Mode Switch Parameter", HFILL }}, |
7232 | | |
7233 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_fec, |
7234 | 16 | { "FEC", "wpan-tap.phr.fsk_ms.fec", FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), IEEE802154_TAP_PHR_FSK_MS_FEC, |
7235 | 16 | "New Mode FEC", HFILL }}, |
7236 | | |
7237 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_checksum, |
7238 | 16 | { "Checksum", "wpan-tap.phr.fsk_ms.checksum", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_MS_CHECKSUM, |
7239 | 16 | "BCH(15,11) checksum", HFILL }}, |
7240 | | |
7241 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_parity, |
7242 | 16 | { "Parity", "wpan-tap.phr.fsk_ms.parity", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_FSK_MS_PARITY, |
7243 | 16 | "Parity Check bit", HFILL }}, |
7244 | | |
7245 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_mode_page, |
7246 | 16 | { "Page", "wpan-tap.phr.fsk_ms.page", FT_UINT16, BASE_HEX, VALS(vals_fsk_ms_page), IEEE802154_TAP_PHR_FSK_MS_MODE_PAGE, |
7247 | 16 | "New Mode Page", HFILL }}, |
7248 | | |
7249 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_mode_scheme, |
7250 | 16 | { "Scheme", "wpan-tap.phr.fsk_ms.scheme", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_fsk_ms_scheme), IEEE802154_TAP_PHR_FSK_MS_MODE_SCHEME, |
7251 | 16 | "New Mode Modulation Scheme", HFILL }}, |
7252 | | |
7253 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_mode_mode, |
7254 | 16 | { "Mode", "wpan-tap.phr.fsk_ms.mode", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_fsk_ms_mode), IEEE802154_TAP_PHR_FSK_MS_MODE_MODE, |
7255 | 16 | "New Mode Mode", HFILL }}, |
7256 | | |
7257 | 16 | { &hf_ieee802154_tap_phr_fsk_ms_mode_addl_mode, |
7258 | 16 | { "Additional Mode", "wpan-tap.phr.fsk_ms.mode", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_fsk_ms_additional_modes), IEEE802154_TAP_PHR_FSK_MS_MODE_MODE, |
7259 | 16 | "New Mode Additional Mode", HFILL }}, |
7260 | | |
7261 | 16 | { &hf_ieee802154_tap_phr_wisun_fsk_ms_reserved, |
7262 | 16 | { "Reserved", "wpan-tap.phr.wisun_ms.reserved", FT_UINT16, BASE_HEX, NULL, IEEE802154_TAP_PHR_WISUN_FSK_MS_RESERVED, |
7263 | 16 | NULL, HFILL }}, |
7264 | | |
7265 | 16 | { &hf_ieee802154_tap_phr_wisun_fsk_ms_phymodeid, |
7266 | 16 | { "PhyModeId", "wpan-tap.phr.wisun_ms.phymodeid", FT_UINT16, BASE_HEX, VALS(ieee802154_phr_wisun_phymodeid), IEEE802154_TAP_PHR_WISUN_FSK_MS_PHYMODEID, |
7267 | 16 | "New Wi-SUN PhyModeId", HFILL }}, |
7268 | 16 | }; |
7269 | | |
7270 | | /* Subtrees */ |
7271 | 16 | static int *ett[] = { |
7272 | 16 | &ett_ieee802154_nonask_phy, |
7273 | 16 | &ett_ieee802154_nonask_phy_phr, |
7274 | 16 | &ett_ieee802154_tap, |
7275 | 16 | &ett_ieee802154_tap_header, |
7276 | 16 | &ett_ieee802154_tap_tlv, |
7277 | 16 | &ett_ieee802154, |
7278 | 16 | &ett_ieee802154_fcf, |
7279 | 16 | &ett_ieee802154_auxiliary_security, |
7280 | 16 | &ett_ieee802154_aux_sec_control, |
7281 | 16 | &ett_ieee802154_aux_sec_key_id, |
7282 | 16 | &ett_ieee802154_fcs, |
7283 | 16 | &ett_ieee802154_cmd, |
7284 | 16 | &ett_ieee802154_superframe, |
7285 | 16 | &ett_ieee802154_gts, |
7286 | 16 | &ett_ieee802154_gts_direction, |
7287 | 16 | &ett_ieee802154_gts_descriptors, |
7288 | 16 | &ett_ieee802154_pendaddr, |
7289 | 16 | &ett_ieee802154_header_ies, |
7290 | 16 | &ett_ieee802154_header_ie, |
7291 | 16 | &ett_ieee802154_header_ie_tlv, |
7292 | 16 | &ett_ieee802154_hie_unsupported, |
7293 | 16 | &ett_ieee802154_hie_time_correction, |
7294 | 16 | &ett_ieee802154_hie_ht, |
7295 | 16 | &ett_ieee802154_hie_thread, |
7296 | 16 | &ett_ieee802154_hie_csl, |
7297 | 16 | &ett_ieee802154_hie_rdv, |
7298 | 16 | &ett_ieee802154_hie_global_time, |
7299 | 16 | &ett_ieee802154_hie_vendor_specific, |
7300 | 16 | &ett_ieee802154_payload_ie, |
7301 | 16 | &ett_ieee802154_payload_ie_tlv, |
7302 | 16 | &ett_ieee802154_pie_termination, |
7303 | 16 | &ett_ieee802154_pie_vendor, |
7304 | 16 | &ett_ieee802159_mpx, |
7305 | 16 | &ett_ieee802159_mpx_transaction_control, |
7306 | 16 | &ett_ieee802154_pie_ietf, |
7307 | 16 | &ett_ieee802154_pie_unsupported, |
7308 | 16 | &ett_ieee802154_tsch_slotframe, |
7309 | 16 | &ett_ieee802154_tsch_slotframe_list, |
7310 | 16 | &ett_ieee802154_tsch_slotframe_link, |
7311 | 16 | &ett_ieee802154_tsch_slotframe_link_options, |
7312 | 16 | &ett_ieee802154_tsch_timeslot, |
7313 | 16 | &ett_ieee802154_tsch_synch, |
7314 | 16 | &ett_ieee802154_channel_hopping, |
7315 | 16 | &ett_ieee802154_mlme, |
7316 | 16 | &ett_ieee802154_mlme_payload, |
7317 | 16 | &ett_ieee802154_mlme_payload_data, |
7318 | 16 | &ett_ieee802154_mlme_unsupported, |
7319 | 16 | &ett_ieee802154_psie, |
7320 | 16 | &ett_ieee802154_eb_filter, |
7321 | 16 | &ett_ieee802154_eb_filter_bitmap, |
7322 | 16 | &ett_ieee802154_zigbee, |
7323 | 16 | &ett_ieee802154_zboss, |
7324 | 16 | &ett_ieee802154_p_ie_6top, |
7325 | 16 | &ett_ieee802154_p_ie_6top_cell_options, |
7326 | 16 | &ett_ieee802154_p_ie_6top_cell_list, |
7327 | 16 | &ett_ieee802154_p_ie_6top_rel_cell_list, |
7328 | 16 | &ett_ieee802154_p_ie_6top_cand_cell_list, |
7329 | 16 | &ett_ieee802154_p_ie_6top_cell, |
7330 | 16 | &ett_ieee802154_tap_phr, |
7331 | 16 | }; |
7332 | | |
7333 | 16 | static ei_register_info ei[] = { |
7334 | 16 | { &ei_ieee802154_fcs_bitmask_len, { "wpan.bitmask_len_error", PI_UNDECODED, PI_WARN, |
7335 | 16 | "Only least-significant bytes decoded", EXPFILL }}, |
7336 | 16 | { &ei_ieee802154_invalid_addressing, { "wpan.invalid_addressing", PI_MALFORMED, PI_WARN, |
7337 | 16 | "Invalid Addressing", EXPFILL }}, |
7338 | 16 | { &ei_ieee802154_invalid_panid_compression, { "wpan.invalid_panid_compression", PI_MALFORMED, PI_ERROR, |
7339 | 16 | "Invalid Setting for PAN ID Compression", EXPFILL }}, |
7340 | 16 | { &ei_ieee802154_invalid_panid_compression2, { "wpan.invalid_panid_compression2", PI_MALFORMED, PI_ERROR, |
7341 | 16 | "Invalid Pan ID Compression and addressing combination for Frame Version 2", EXPFILL }}, |
7342 | 16 | { &ei_ieee802154_dst, { "wpan.dst_invalid", PI_MALFORMED, PI_ERROR, |
7343 | 16 | "Invalid Destination Address Mode", EXPFILL }}, |
7344 | 16 | { &ei_ieee802154_src, { "wpan.src_invalid", PI_MALFORMED, PI_ERROR, |
7345 | 16 | "Invalid Source Address Mode", EXPFILL }}, |
7346 | 16 | { &ei_ieee802154_frame_ver, { "wpan.frame_version_unknown", PI_MALFORMED, PI_ERROR, |
7347 | 16 | "Frame Version Unknown Cannot Dissect", EXPFILL }}, |
7348 | | #if 0 |
7349 | | { &ei_ieee802154_frame_type, { "wpan.frame_type_unknown", PI_MALFORMED, PI_ERROR, |
7350 | | "Frame Type Unknown Cannot Dissect", EXPFILL }}, |
7351 | | #endif |
7352 | 16 | { &ei_ieee802154_decrypt_error, { "wpan.decrypt_error", PI_UNDECODED, PI_WARN, |
7353 | 16 | "Decryption error", EXPFILL }}, |
7354 | 16 | { &ei_ieee802154_fcs, { "wpan.fcs.bad", PI_CHECKSUM, PI_WARN, |
7355 | 16 | "Bad FCS", EXPFILL }}, |
7356 | 16 | { &ei_ieee802154_ack_not_found, { "wpan.ack_not_found", PI_SEQUENCE, PI_NOTE, |
7357 | 16 | "Ack not found", EXPFILL }}, |
7358 | 16 | { &ei_ieee802154_ack_request_not_found, { "wpan.ack_request_not_found", PI_SEQUENCE, PI_NOTE, |
7359 | 16 | "Request not found", EXPFILL }}, |
7360 | 16 | { &ei_ieee802154_seqno_suppression, { "wpan.seqno_suppression_invalid", PI_MALFORMED, PI_WARN, |
7361 | 16 | "Sequence Number Suppression invalid for 802.15.4-2003 and 2006", EXPFILL }}, |
7362 | 16 | { &ei_ieee802154_6top_unsupported_type, { "wpan.6top_unsupported_type", PI_PROTOCOL, PI_WARN, |
7363 | 16 | "Unsupported Type of Message", EXPFILL }}, |
7364 | 16 | { &ei_ieee802154_6top_unsupported_command, { "wpan.6top_unsupported_command", PI_PROTOCOL, PI_WARN, |
7365 | 16 | "Unsupported 6top command", EXPFILL }}, |
7366 | 16 | { &ei_ieee802154_time_correction_error, { "wpan.time_correction.error", PI_PROTOCOL, PI_WARN, |
7367 | 16 | "Incorrect value. Reference: IEEE-802.15.4-2015. Table 7-8: Values of the Time Sync Info field for ACK with timing information", EXPFILL}}, |
7368 | 16 | { &ei_ieee802154_6top_unsupported_return_code, { "wpan.6top_unsupported_code", PI_PROTOCOL, PI_WARN, |
7369 | 16 | "Unsupported 6top return code", EXPFILL }}, |
7370 | 16 | { &ei_ieee802154_ie_unsupported_id, { "wpan.ie_unsupported_id", PI_PROTOCOL, PI_WARN, |
7371 | 16 | "Unsupported IE ID", EXPFILL }}, |
7372 | 16 | { &ei_ieee802154_ie_unknown_extra_content, { "wpan.ie_unknown_extra_content", PI_PROTOCOL, PI_WARN, |
7373 | 16 | "Unexpected extra content for IE", EXPFILL }}, |
7374 | 16 | { &ei_ieee802154_ie_unknown_extra_content_payload, { "wpan.ie_unknown_extra_content_payload", PI_PROTOCOL, PI_WARN, |
7375 | 16 | "Unexpected extra content for IE payload", EXPFILL }}, |
7376 | 16 | { &ei_ieee802159_mpx_invalid_transfer_type, { "wpan.payload_ie.mpx.invalid_transfer_type", PI_PROTOCOL, PI_WARN, |
7377 | 16 | "Invalid transfer type (cf. IEEE 802.15.9 Table 19)", EXPFILL }}, |
7378 | 16 | { &ei_ieee802159_mpx_unsupported_kmp, { "wpan.mpx.unsupported_kmp", PI_PROTOCOL, PI_WARN, |
7379 | 16 | "Unsupported KMP ID", EXPFILL }}, |
7380 | 16 | { &ei_ieee802159_mpx_unknown_kmp, { "wpan.mpx.unknown_kmp", PI_PROTOCOL, PI_WARN, |
7381 | 16 | "Unknown KMP ID (cf. IEEE 802.15.9 Table 21)", EXPFILL }}, |
7382 | 16 | { &ei_ieee802154_missing_payload_ie, { "wpan.payload_ie.missing", PI_MALFORMED, PI_WARN, |
7383 | 16 | "Payload IE indicated by Header Termination, but no Payload IE present", EXPFILL }}, |
7384 | 16 | { &ei_ieee802154_payload_ie_in_header, { "wpan.payload_ie.in_header", PI_MALFORMED, PI_WARN, |
7385 | 16 | "Payload IE in header", EXPFILL }}, |
7386 | 16 | { &ei_ieee802154_unsupported_cmd, { "wpan.cmd.unsupported_cmd", PI_PROTOCOL, PI_WARN, |
7387 | 16 | "Unsupported Command ID", EXPFILL }}, |
7388 | 16 | { &ei_ieee802154_unknown_cmd, { "wpan.cmd.unknown_cmd", PI_PROTOCOL, PI_WARN, |
7389 | 16 | "Unknown Command Id (cf. IEEE 802.15.4-2015 Table 7-49)", EXPFILL }}, |
7390 | 16 | { &ei_ieee802154_tap_tlv_invalid_type, { "wpan-tap.tlv.invalid_type", PI_MALFORMED, PI_WARN, |
7391 | 16 | "Invalid TLV type", EXPFILL }}, |
7392 | 16 | { &ei_ieee802154_tap_tlv_invalid_length, { "wpan-tap.tlv.invalid_length", PI_MALFORMED, PI_WARN, |
7393 | 16 | "Invalid TLV length", EXPFILL }}, |
7394 | 16 | { &ei_ieee802154_tap_tlv_padding_not_zeros, { "wpan-tap.tlv.padding_not_zeros", PI_MALFORMED, PI_WARN, |
7395 | 16 | "TLV padding not zero", EXPFILL }}, |
7396 | 16 | { &ei_ieee802154_tap_tlv_invalid_fcs_type, { "wpan-tap.tlv.invalid_fcs_type", PI_MALFORMED, PI_ERROR, |
7397 | 16 | "Invalid FCS type", EXPFILL }}, |
7398 | 16 | { &ei_ieee802154_tap_tlv_reserved_not_zero, { "wpan-tap.tlv.reserved_not_zero", PI_PROTOCOL, PI_WARN, |
7399 | 16 | "Reserved bits not zero", EXPFILL }}, |
7400 | 16 | { &ei_ieee802154_tap_no_payload, { "wpan-tap.tlv.no_payload", PI_COMMENTS_GROUP, PI_COMMENT, |
7401 | 16 | "No payload", EXPFILL }}, |
7402 | 16 | }; |
7403 | | |
7404 | | /* Preferences. */ |
7405 | 16 | module_t *ieee802154_module; |
7406 | 16 | expert_module_t* expert_ieee802154; |
7407 | | |
7408 | 16 | static uat_field_t addr_uat_flds[] = { |
7409 | 16 | UAT_FLD_HEX(addr_uat,addr16,"Short Address", |
7410 | 16 | "16-bit short address in hexadecimal."), |
7411 | 16 | UAT_FLD_HEX(addr_uat,pan,"PAN Identifier", |
7412 | 16 | "16-bit PAN identifier in hexadecimal."), |
7413 | 16 | UAT_FLD_BUFFER(addr_uat,eui64,"EUI-64", |
7414 | 16 | "64-bit extended unique identifier."), |
7415 | 16 | UAT_END_FIELDS |
7416 | 16 | }; |
7417 | | |
7418 | 16 | static uat_field_t key_uat_flds[] = { |
7419 | 16 | UAT_FLD_CSTRING(key_uat,pref_key,"Decryption key", |
7420 | 16 | "128-bit decryption key in hexadecimal format"), |
7421 | 16 | UAT_FLD_DEC(key_uat,key_index,"Decryption key index", |
7422 | 16 | "Key index in decimal format"), |
7423 | 16 | UAT_FLD_VS(key_uat, hash_type, "Key hash", ieee802154_key_hash_vals, "Specifies which hash scheme is used to derived the key"), |
7424 | 16 | UAT_END_FIELDS |
7425 | 16 | }; |
7426 | | |
7427 | 16 | static const enum_val_t fcs_type_vals[] = { |
7428 | 16 | {"cc24xx", "TI CC24xx metadata", IEEE802154_CC24XX_METADATA}, |
7429 | 16 | {"16", "ITU-T CRC-16", IEEE802154_FCS_16_BIT}, |
7430 | 16 | {"32", "ITU-T CRC-32", IEEE802154_FCS_32_BIT}, |
7431 | 16 | {NULL, NULL, -1} |
7432 | 16 | }; |
7433 | | |
7434 | 16 | static build_valid_func ieee802154_da_build_value[1] = {ieee802154_da_value}; |
7435 | 16 | static decode_as_value_t ieee802154_da_values = {ieee802154_da_prompt, 1, ieee802154_da_build_value}; |
7436 | 16 | static decode_as_t ieee802154_da = { |
7437 | 16 | IEEE802154_PROTOABBREV_WPAN, IEEE802154_PROTOABBREV_WPAN_PANID, |
7438 | 16 | 1, 0, &ieee802154_da_values, NULL, NULL, |
7439 | 16 | decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL |
7440 | 16 | }; |
7441 | | |
7442 | | /* Register the init routine. */ |
7443 | 16 | register_init_routine(proto_init_ieee802154); |
7444 | 16 | register_cleanup_routine(proto_cleanup_ieee802154); |
7445 | | |
7446 | | /* Register Protocol name and description. */ |
7447 | 16 | proto_ieee802154 = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN", "IEEE 802.15.4", |
7448 | 16 | IEEE802154_PROTOABBREV_WPAN); |
7449 | 16 | proto_ieee802154_nonask_phy = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN non-ASK PHY", |
7450 | 16 | "IEEE 802.15.4 non-ASK PHY", "wpan-nonask-phy"); |
7451 | 16 | proto_zboss = proto_register_protocol("ZBOSS IEEE 802.15.4 dump", |
7452 | 16 | "ZBOSS dump", "wpan-zboss"); |
7453 | 16 | proto_ieee802154_tap = proto_register_protocol("IEEE 802.15.4 Low-Rate Wireless PAN TAP", |
7454 | 16 | "IEEE 802.15.4 TAP", "wpan-tap"); |
7455 | | |
7456 | | /* Register header fields and subtrees. */ |
7457 | 16 | proto_register_field_array(proto_ieee802154, hf, array_length(hf)); |
7458 | 16 | proto_register_field_array(proto_ieee802154, hf_phy, array_length(hf_phy)); |
7459 | | |
7460 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
7461 | | |
7462 | 16 | expert_ieee802154 = expert_register_protocol(proto_ieee802154); |
7463 | 16 | expert_register_field_array(expert_ieee802154, ei, array_length(ei)); |
7464 | | |
7465 | 16 | ieee802_15_4_short_address_type = address_type_dissector_register("AT_IEEE_802_15_4_SHORT", "IEEE 802.15.4 16-bit short address", |
7466 | 16 | ieee802_15_4_short_address_to_str, ieee802_15_4_short_address_str_len, NULL, NULL, ieee802_15_4_short_address_len, NULL, NULL); |
7467 | | |
7468 | | /* add a user preference to set the 802.15.4 ethertype */ |
7469 | 16 | ieee802154_module = prefs_register_protocol(proto_ieee802154, |
7470 | 16 | proto_reg_handoff_ieee802154); |
7471 | 16 | prefs_register_uint_preference(ieee802154_module, "802154_ethertype", |
7472 | 16 | "802.15.4 Ethertype (in hex)", |
7473 | 16 | "(Hexadecimal) Ethertype used to indicate IEEE 802.15.4 frame.", |
7474 | 16 | 16, &ieee802154_ethertype); |
7475 | 16 | prefs_register_obsolete_preference(ieee802154_module, "802154_cc24xx"); |
7476 | 16 | prefs_register_enum_preference(ieee802154_module, "fcs_format", |
7477 | 16 | "FCS format", |
7478 | 16 | "The FCS format in the captured payload", |
7479 | 16 | &ieee802154_fcs_type, fcs_type_vals, false); |
7480 | 16 | prefs_register_bool_preference(ieee802154_module, "802154_fcs_ok", |
7481 | 16 | "Dissect only good FCS", |
7482 | 16 | "Dissect payload only if FCS is valid.", |
7483 | 16 | &ieee802154_fcs_ok); |
7484 | 16 | prefs_register_bool_preference(ieee802154_module, "802154_ack_tracking", |
7485 | 16 | "Enable ACK tracking", |
7486 | 16 | "Match frames with ACK request to ACK packets", |
7487 | 16 | &ieee802154_ack_tracking); |
7488 | 16 | prefs_register_bool_preference(ieee802154_module, "802154e_compatibility", |
7489 | 16 | "Assume 802.15.4e-2012 for compatibility", |
7490 | 16 | "Parse assuming 802.15.4e quirks for compatibility", |
7491 | 16 | &ieee802154e_compatibility); |
7492 | | |
7493 | | /* Create a UAT for static address mappings. */ |
7494 | 16 | static_addr_uat = uat_new("Static Addresses", |
7495 | 16 | sizeof(static_addr_t), /* record size */ |
7496 | 16 | "802154_addresses", /* filename */ |
7497 | 16 | true, /* from_profile */ |
7498 | 16 | &static_addrs, /* data_ptr */ |
7499 | 16 | &num_static_addrs, /* numitems_ptr */ |
7500 | 16 | UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */ |
7501 | 16 | NULL, /* help */ |
7502 | 16 | addr_uat_copy_cb, /* copy callback */ |
7503 | 16 | addr_uat_update_cb, /* update callback */ |
7504 | 16 | addr_uat_free_cb, /* free callback */ |
7505 | 16 | NULL, /* post update callback */ |
7506 | 16 | NULL, /* reset callback */ |
7507 | 16 | addr_uat_flds); /* UAT field definitions */ |
7508 | 16 | prefs_register_uat_preference(ieee802154_module, "static_addr", |
7509 | 16 | "Static Addresses", |
7510 | 16 | "A table of static address mappings between 16-bit short addressing and EUI-64 addresses", |
7511 | 16 | static_addr_uat); |
7512 | | |
7513 | | /* Create a UAT for key management. */ |
7514 | 16 | ieee802154_key_uat = uat_new("Keys", |
7515 | 16 | sizeof(ieee802154_key_t), /* record size */ |
7516 | 16 | "ieee802154_keys", /* filename */ |
7517 | 16 | true, /* from_profile */ |
7518 | 16 | &ieee802154_keys, /* data_ptr */ |
7519 | 16 | &num_ieee802154_keys, /* numitems_ptr */ |
7520 | 16 | UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */ |
7521 | 16 | NULL, /* help */ |
7522 | 16 | ieee802154_key_copy_cb, /* copy callback */ |
7523 | 16 | ieee802154_key_update_cb, /* update callback */ |
7524 | 16 | ieee802154_key_free_cb, /* free callback */ |
7525 | 16 | ieee802154_key_post_update_cb, /* post update callback */ |
7526 | 16 | NULL, /* reset callback */ |
7527 | 16 | key_uat_flds); /* UAT field definitions */ |
7528 | 16 | prefs_register_uat_preference(ieee802154_module, "ieee802154_keys", |
7529 | 16 | "Decryption Keys", |
7530 | 16 | "Decryption key configuration data", |
7531 | 16 | ieee802154_key_uat); |
7532 | | |
7533 | | /* Register preferences for a decryption key */ |
7534 | 16 | prefs_register_obsolete_preference(ieee802154_module, "802154_key"); |
7535 | | |
7536 | 16 | prefs_register_enum_preference(ieee802154_module, "802154_sec_suite", |
7537 | 16 | "Security Suite (802.15.4-2003)", |
7538 | 16 | "Specifies the security suite to use for 802.15.4-2003 secured frames" |
7539 | 16 | " (only supported suites are listed). Option ignored for 802.15.4-2006" |
7540 | 16 | " and unsecured frames.", |
7541 | 16 | &ieee802154_sec_suite, ieee802154_2003_sec_suite_enums, false); |
7542 | | |
7543 | 16 | prefs_register_bool_preference(ieee802154_module, "802154_extend_auth", |
7544 | 16 | "Extend authentication data (802.15.4-2003)", |
7545 | 16 | "Set if the manufacturer extends the authentication data with the" |
7546 | 16 | " security header. Option ignored for 802.15.4-2006 and unsecured frames.", |
7547 | 16 | &ieee802154_extend_auth); |
7548 | | |
7549 | | /* Register the subdissector list */ |
7550 | 16 | panid_dissector_table = register_dissector_table(IEEE802154_PROTOABBREV_WPAN_PANID, "IEEE 802.15.4 PANID", proto_ieee802154, FT_UINT16, BASE_HEX); |
7551 | 16 | ieee802154_heur_subdissector_list = register_heur_dissector_list_with_description(IEEE802154_PROTOABBREV_WPAN, "IEEE 802.15.4 PANID", proto_ieee802154); |
7552 | 16 | ieee802154_beacon_subdissector_list = register_heur_dissector_list_with_description(IEEE802154_PROTOABBREV_WPAN_BEACON, "IEEE 802.15.4 FCF beacon", proto_ieee802154); |
7553 | | |
7554 | | /* Register dissector tables */ |
7555 | 16 | header_ie_dissector_table = register_dissector_table(IEEE802154_HEADER_IE_DTABLE, "IEEE 802.15.4 Header IEs", proto_ieee802154, FT_UINT8, BASE_HEX); |
7556 | 16 | payload_ie_dissector_table = register_dissector_table(IEEE802154_PAYLOAD_IE_DTABLE, "IEEE 802.15.4 Payload IEs", proto_ieee802154, FT_UINT8, BASE_HEX); |
7557 | 16 | mlme_ie_dissector_table = register_dissector_table(IEEE802154_MLME_IE_DTABLE, "IEEE 802.15.4 Nested IEs", proto_ieee802154, FT_UINT8, BASE_HEX); |
7558 | 16 | cmd_vendor_dissector_table = register_dissector_table(IEEE802154_CMD_VENDOR_DTABLE, "IEEE 802.15.4 Vendor Specific Commands", proto_ieee802154, FT_UINT24, BASE_HEX ); |
7559 | | |
7560 | | /* Register dissectors with Wireshark */ |
7561 | 16 | ieee802154_handle = register_dissector("wpan", dissect_ieee802154, proto_ieee802154); |
7562 | 16 | ieee802154_fcs_handle = register_dissector("wpan_fcs", dissect_ieee802154_fcs, proto_ieee802154); |
7563 | 16 | ieee802154_nofcs_handle = register_dissector("wpan_nofcs", dissect_ieee802154_nofcs, proto_ieee802154); |
7564 | 16 | register_dissector("wpan_cc24xx", dissect_ieee802154_cc24xx, proto_ieee802154); |
7565 | 16 | ieee802154_nonask_phy_handle = register_dissector("wpan-nonask-phy", dissect_ieee802154_nonask_phy, proto_ieee802154_nonask_phy); |
7566 | 16 | ieee802154_tap_handle = register_dissector("wpan-tap", dissect_ieee802154_tap, proto_ieee802154_tap); |
7567 | | |
7568 | | /* Setup registration for other dissectors to provide mac key hash algorithms */ |
7569 | 16 | mac_key_hash_handlers = wmem_tree_new(wmem_epan_scope()); |
7570 | | |
7571 | | /* Register a Decode-As handler */ |
7572 | 16 | register_decode_as(&ieee802154_da); |
7573 | | |
7574 | | /* Create trees for transactions */ |
7575 | 16 | transaction_unmatched_pdus = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
7576 | 16 | transaction_matched_pdus = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
7577 | | |
7578 | 16 | ieee802154_tap = register_tap(IEEE802154_PROTOABBREV_WPAN); |
7579 | | |
7580 | 16 | register_conversation_table(proto_ieee802154, true, ieee802154_conversation_packet, ieee802154_endpoint_packet); |
7581 | 16 | register_conversation_filter(IEEE802154_PROTOABBREV_WPAN, "IEEE 802.15.4", ieee802154_filter_valid, ieee802154_build_filter, NULL); |
7582 | 16 | } /* proto_register_ieee802154 */ |
7583 | | |
7584 | | |
7585 | | /** |
7586 | | * Registers the IEEE 802.15.4 dissector with Wireshark. |
7587 | | * Will be called every time 'apply' is pressed in the preferences menu. |
7588 | | * as well as during Wireshark initialization |
7589 | | */ |
7590 | | void proto_reg_handoff_ieee802154(void) |
7591 | 16 | { |
7592 | 16 | static bool prefs_initialized = false; |
7593 | 16 | static unsigned int old_ieee802154_ethertype; |
7594 | | |
7595 | 16 | if (!prefs_initialized) { |
7596 | | /* Get the dissector handles. */ |
7597 | 16 | zigbee_ie_handle = find_dissector_add_dependency("zbee_ie", proto_ieee802154); |
7598 | 16 | zigbee_nwk_handle = find_dissector("zbee_nwk"); |
7599 | | |
7600 | 16 | thread_ie_handle = find_dissector_add_dependency("thread_ie",proto_ieee802154); |
7601 | 16 | dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4, ieee802154_handle); |
7602 | 16 | dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_NONASK_PHY, ieee802154_nonask_phy_handle); |
7603 | 16 | dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_NOFCS, ieee802154_nofcs_handle); |
7604 | 16 | dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE802_15_4_TAP, ieee802154_tap_handle); |
7605 | 16 | dissector_add_uint("sll.ltype", LINUX_SLL_P_IEEE802154, ieee802154_handle); |
7606 | | |
7607 | | /* Register internal IE handlers */ |
7608 | 16 | dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_TIME_CORR, create_dissector_handle(dissect_hie_time_correction, -1)); |
7609 | 16 | dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_CSL, create_dissector_handle(dissect_hie_csl, -1)); |
7610 | 16 | dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_RENDEZVOUS, create_dissector_handle(dissect_hie_rendezvous_time, -1)); |
7611 | 16 | dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_GLOBAL_TIME, create_dissector_handle(dissect_hie_global_time, -1)); |
7612 | 16 | dissector_add_uint(IEEE802154_HEADER_IE_DTABLE, IEEE802154_HEADER_IE_VENDOR_SPECIFIC, create_dissector_handle(dissect_hie_vendor_specific, -1)); |
7613 | | |
7614 | 16 | dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_MLME, create_dissector_handle(dissect_pie_mlme, -1)); |
7615 | 16 | dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_VENDOR, create_dissector_handle(dissect_pie_vendor, -1)); |
7616 | 16 | dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_MPX, create_dissector_handle(dissect_mpx_ie, -1)); |
7617 | 16 | dissector_add_uint(IEEE802154_PAYLOAD_IE_DTABLE, IEEE802154_PAYLOAD_IE_IETF, create_dissector_handle(dissect_ietf_ie, -1)); |
7618 | | |
7619 | 16 | dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_CHANNEL_HOPPING, create_dissector_handle(dissect_802154_channel_hopping, -1)); |
7620 | 16 | dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_TSCH_SYNCH, create_dissector_handle(dissect_802154_tsch_time_sync, -1)); |
7621 | 16 | dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_TSCH_SLOTFR_LINK, create_dissector_handle(dissect_802154_tsch_slotframe_link, -1)); |
7622 | 16 | dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_TSCH_TIMESLOT, create_dissector_handle(dissect_802154_tsch_timeslot, -1)); |
7623 | 16 | dissector_add_uint(IEEE802154_MLME_IE_DTABLE, IEEE802154_MLME_SUBIE_ENHANCED_BEACON_FILTER, create_dissector_handle(dissect_802154_eb_filter, -1)); |
7624 | | |
7625 | | /* For the MPX-IE */ |
7626 | 16 | ethertype_table = find_dissector_table("ethertype"); |
7627 | 16 | eapol_handle = find_dissector("eapol"); |
7628 | 16 | lowpan_handle = find_dissector("6lowpan"); |
7629 | 16 | wisun_sec_handle = find_dissector("wisun.sec"); |
7630 | 16 | prefs_initialized = true; |
7631 | 16 | } else { |
7632 | 0 | dissector_delete_uint("ethertype", old_ieee802154_ethertype, ieee802154_handle); |
7633 | 0 | } |
7634 | | |
7635 | 16 | old_ieee802154_ethertype = ieee802154_ethertype; |
7636 | | |
7637 | | /* Register dissector handles. */ |
7638 | 16 | dissector_add_uint("ethertype", ieee802154_ethertype, ieee802154_handle); |
7639 | | |
7640 | 16 | } /* proto_reg_handoff_ieee802154 */ |
7641 | | |
7642 | | /* |
7643 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
7644 | | * |
7645 | | * Local variables: |
7646 | | * c-basic-offset: 4 |
7647 | | * tab-width: 8 |
7648 | | * indent-tabs-mode: nil |
7649 | | * End: |
7650 | | * |
7651 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
7652 | | * :indentSize=4:tabSize=8:noTabs=true: |
7653 | | */ |