Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-ieee802154.c
Warning:line 1976, column 13
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

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