### 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

Show analyzer invocation
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-28-100304-3595-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-ieee802154.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

1 | /* packet-ieee802154.c
2 | *
3 | * Multipurpose frame support
4 | * By Devan Lai <devanl@davisinstruments.com>
5 | * Copyright 2019 Davis Instruments
6 | *
7 | * IEEE 802.15.4-2015 CCM* nonce for TSCH mode
8 | * By Maxime Brunelle <Maxime.Brunelle@trilliant.com>
9 | * Copyright 2019 Trilliant Inc.
10 | *
11 | * IEEE802154 TAP link type
12 | * By James Ko <jck@exegin.com>
13 | * Copyright 2019 Exegin Technologies Limited
14 | *
15 | * 4-byte FCS support and ACK tracking
16 | * By Carl Levesque Imbeault <carl.levesque@trilliant.com>
17 | * Copyright 2018 Trilliant Inc.
18 | * Integrated and added FCS type enum
19 | * by James Ko <jck@exegin.com>
20 | * Copyright 2019 Exegin Technologies Limited
21 | *
22 | * Auxiliary Security Header support and
23 | * option to force TI CC24xx FCS format
24 | * By Jean-Francois Wauthy <jfw@info.fundp.ac.be>
25 | * Copyright 2009 The University of Namur, Belgium
26 | *
27 | * IEEE 802.15.4 Dissectors for Wireshark
28 | * By Owen Kirby <osk@exegin.com>
29 | * Copyright 2007 Exegin Technologies Limited
30 | *
31 | * Wireshark - Network traffic analyzer
32 | * By Gerald Combs <gerald@wireshark.org>
33 | * Copyright 1998 Gerald Combs
34 | *
35 | * SPDX-License-Identifier: GPL-2.0-or-later
36 | *------------------------------------------------------------
37 | *
38 | * In IEEE 802.15.4 packets, all fields are little endian. And
39 | * Each byte is transmitted least significant bit first (reflected
40 | * bit ordering).
41 | *------------------------------------------------------------
42 | *
43 | * Most IEEE 802.15.4 Packets have the following format:
44 | * | FCF |Seq No| Addressing | Data | FCS |
45 | * |2 bytes|1 byte|0 to 20 bytes|Length-(Overhead) bytes|2/4 Bytes|
46 | *------------------------------------------------------------
47 | *
48 | * Multipurpose frame packets have the following format:
49 | * | FCF | Seq No | Addressing | Data | FCS |
50 | * |1/2 bytes|0/1 bytes|0 to 20 bytes|Length-(Overhead) bytes|2 bytes|
51 | *------------------------------------------------------------
52 | *
53 | * CRC16 is calculated using the x^16 + x^12 + x^5 + 1 polynomial
54 | * as specified by ITU-T, and is calculated over the IEEE 802.15.4
55 | * packet (excluding the FCS) as transmitted over the air. Note,
56 | * that because the least significant bits are transmitted first, this
57 | * will require reversing the bit-order in each byte. Also, unlike
58 | * most CRC algorithms, IEEE 802.15.4 uses an initial and final value
59 | * of 0x0000, instead of 0xffff (which is used by the ITU-T).
60 | *
61 | * For a 4-byte FCS, CRC32 is calculated using the ITU-T CRC32.
62 | *
63 | * (Fun fact: the reference to "a 32-bit CRC equivalent to ANSI X3.66-1979"
64 | * in IEEE Std 802.15.4-2015 nonwithstanding, ANSI X3.66-1979 does not
65 | * describe any 32-bit CRC, only a 16-bit CRC from ITU-T V.41. ITU-T
66 | * V.42 describes both a 16-bit and 32-bit CRC; all the 16-bit CRCs
67 | * floating around seem to use the same generator polynomial,
68 | * x^16 + x^12 + x^5 + 1, but have different initial conditions and
69 | * no-error final remainder; the 32-bit CRC from V.42 and the one
70 | * described in IEEE Std 802.15.4-2015 also use the same generator
71 | * polynomial.)
72 | *------------------------------------------------------------
73 | *
74 | * This dissector supports both link-layer IEEE 802.15.4 captures
75 | * and IEEE 802.15.4 packets encapsulated within other layers.
76 | * Additionally, support has been provided for 16-bit and 32-bit
77 | * FCS, as well as for frames with no FCS but with a 16-bit
78 | * ChipCon/Texas Instruments CC24xx-style metadata field.
79 | *------------------------------------------------------------
80 | */
81 |
82 | /* Include files */
83 | #include "config.h"
84 | #include <epan/packet.h>
85 | #include <epan/decode_as.h>
86 | #include <epan/exceptions.h>
87 | #include <epan/crc16-tvb.h>
88 | #include <epan/crc32-tvb.h>
89 | #include <epan/expert.h>
90 | #include <epan/addr_resolv.h>
91 | #include <epan/address_types.h>
92 | #include <epan/conversation.h>
93 | #include <epan/conversation_table.h>
94 | #include <epan/conversation_filter.h>
95 | #include <epan/prefs.h>
96 | #include <epan/uat.h>
97 | #include <epan/strutil.h>
98 | #include <epan/to_str.h>
99 | #include <epan/show_exception.h>
100 | #include <epan/proto_data.h>
101 | #include <epan/etypes.h>
102 | #include <epan/oui.h>
103 | #include <epan/tap.h>
104 | #include <epan/tfs.h>
105 | #include <epan/unit_strings.h>
106 | #include <wsutil/pint.h>
107 |
108 | /* Use libgcrypt for cipher libraries. */
109 | #include <wsutil/wsgcrypt.h>
110 |
111 | #include <wsutil/ws_padding_to.h>
112 |
113 | #include "packet-ieee802154.h"
114 | #include "packet-sll.h"
115 | #include "packet-zbee-tlv.h"
116 |
117 | void proto_register_ieee802154(void);
118 | void proto_reg_handoff_ieee802154(void);
119 |
120 | /* Dissection Options for dissect_ieee802154_common */
121 | #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 */
125 | static unsigned int ieee802154_ethertype = 0x809A;
126 |
127 | static int ieee802154_fcs_type = IEEE802154_FCS_16_BIT1;
128 |
129 | /* 802.15.4 TAP Fields */
130 | typedef enum {
131 | IEEE802154_TAP_FCS_TYPE = 0x0000,
132 | IEEE802154_TAP_RSS = 0x0001,
133 | IEEE802154_TAP_BIT_RATE = 0x0002,
134 | IEEE802154_TAP_CHANNEL_ASSIGNMENT = 0x0003,
135 | IEEE802154_TAP_SUN_PHY_INFO = 0x0004,
136 | IEEE802154_TAP_START_OF_FRAME_TS = 0x0005,
137 | IEEE802154_TAP_END_OF_FRAME_TS = 0x0006,
138 | IEEE802154_TAP_ASN = 0x0007,
139 | IEEE802154_TAP_SLOT_START_TS = 0x0008,
140 | IEEE802154_TAP_TIMESLOT_LENGTH = 0x0009,
141 | IEEE802154_TAP_LQI = 0x000A,
142 | IEEE802154_TAP_CHANNEL_FREQUENCY = 0x000B,
143 | IEEE802154_TAP_CHANNEL_PLAN = 0x000C,
144 | IEEE802154_TAP_PHY_HEADER = 0x000D,
145 | } ieee802154_info_type_t;
146 |
147 | typedef enum {
148 | PHR_RAW = 0,
149 | PHR_O_QPSK = 1,
150 | PHR_CSS = 2,
151 | PHR_HRP_UWB = 3,
152 | PHR_MSK = 4,
153 | PHR_LRP_UWB = 5,
154 | PHR_SUN_FSK = 6,
155 | PHR_SUN_OFDM = 7,
156 | PHR_SUN_O_QPSK = 8,
157 | PHR_LECIM_FSK = 9,
158 | PHR_TVWS_FSK = 10,
159 | PHR_TVWS_OFDM = 11,
160 | PHR_TVWS_NB_OFDM = 12,
161 | PHR_RCC_LMR = 13,
162 | PHR_CMB_O_QPSK = 14,
163 | PHR_CMB_GFSK = 15,
164 | PHR_TASK = 16,
165 | PHR_RS_GFSK = 17,
166 | PHR_WISUN_FSK_MS = 18,
167 | } ieee802154_tap_phr_type_t;
168 |
169 | typedef enum {
170 | IEEE802154_FCS_TYPE_NONE = 0,
171 | IEEE802154_FCS_TYPE_16_BIT = 1, /* ITU-T CRC16 */
172 | IEEE802154_FCS_TYPE_32_BIT = 2, /* ITU-T CRC32 */
173 | } ieee802154_fcs_type_t;
174 |
175 | typedef enum {
176 | IEEE802154_SUN_TYPE_FSK_A = 0x00,
177 | IEEE802154_SUN_TYPE_FSK_B = 0x01,
178 | IEEE802154_SUN_TYPE_OQPSK_A = 0x02,
179 | IEEE802154_SUN_TYPE_OQPSK_B = 0x03,
180 | IEEE802154_SUN_TYPE_OQPSK_C = 0x04,
181 | IEEE802154_SUN_TYPE_OFDM_OPT1 = 0x05,
182 | IEEE802154_SUN_TYPE_OFDM_OPT2 = 0x06,
183 | IEEE802154_SUN_TYPE_OFDM_OPT3 = 0x07,
184 | IEEE802154_SUN_TYPE_OFDM_OPT4 = 0x08,
185 | } ieee802154_sun_type_t;
186 |
187 | /* boolean value set if the FCS must be ok before payload is dissected */
188 | static bool_Bool ieee802154_fcs_ok = true1;
189 |
190 | /* boolean value set to enable ack tracking */
191 | static bool_Bool ieee802154_ack_tracking;
192 |
193 | /* boolean value set to enable 802.15.4e dissection compatibility */
194 | static bool_Bool ieee802154e_compatibility;
195 |
196 | /* TSCH ASN for nonce in decryption */
197 | static uint64_t ieee802154_tsch_asn;
198 |
199 | static const char *ieee802154_user = "User";
200 |
201 | static wmem_tree_t* mac_key_hash_handlers;
202 |
203 | /*
204 | * Address Hash Tables
205 | *
206 | */
207 | ieee802154_map_tab_t ieee802154_map = { NULL((void*)0), NULL((void*)0) };
208 |
209 | /*
210 | * Static Address Mapping UAT
211 | *
212 | */
213 | /* UAT entry structure. */
214 | typedef struct {
215 | unsigned char *eui64;
216 | unsigned eui64_len;
217 | unsigned addr16;
218 | unsigned pan;
219 | } static_addr_t;
220 |
221 | /* UAT variables */
222 | static uat_t *static_addr_uat;
223 | static static_addr_t *static_addrs;
224 | static unsigned num_static_addrs;
225 |
226 | static void*
227 | addr_uat_copy_cb(void *dest, const void *source, size_t len _U___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. */
241 | static bool_Bool
242 | addr_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 |
263 | static void
264 | addr_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. */
271 | UAT_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); }
272 | UAT_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); }
273 | UAT_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 */
280 | static uat_t *ieee802154_key_uat;
281 | static ieee802154_key_t *ieee802154_keys;
282 | static unsigned num_ieee802154_keys;
283 |
284 | static void ieee802154_key_post_update_cb(void)
285 | {
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 |
326 | static 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 |
358 | static 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 |
369 | static 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. */
376 | UAT_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; } }
377 | UAT_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); }
378 | UAT_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. */
387 | static int dissect_ieee802154_nonask_phy (tvbuff_t *, packet_info *, proto_tree *, void *);
388 | static int dissect_ieee802154 (tvbuff_t *, packet_info *, proto_tree *, void *);
389 | static int dissect_ieee802154_nofcs (tvbuff_t *, packet_info *, proto_tree *, void *);
390 | static int dissect_ieee802154_cc24xx (tvbuff_t *, packet_info *, proto_tree *, void *);
391 | static int dissect_ieee802154_tap (tvbuff_t *, packet_info *, proto_tree *, void *);
392 | static tvbuff_t *dissect_zboss_specific (tvbuff_t *, packet_info *, proto_tree *);
393 | static void dissect_ieee802154_common (tvbuff_t *, packet_info *, proto_tree *, unsigned, unsigned);
394 | static void ieee802154_dissect_fcs(tvbuff_t *tvb, proto_tree *ieee802154_tree, unsigned fcs_len, bool_Bool fcs_ok);
395 | static void ieee802154_dissect_cc24xx_metadata(tvbuff_t *tvb, proto_tree *ieee802154_tree, bool_Bool fcs_ok);
396 | static ieee802154_fcs_type_t dissect_ieee802154_tap_tlvs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
397 |
398 | /* Information Elements */
399 | static int dissect_ieee802154_header_ie (tvbuff_t *, packet_info *, proto_tree *, unsigned, ieee802154_packet *);
400 | static int dissect_ieee802154_payload_ie (tvbuff_t *, packet_info *, proto_tree *, unsigned, ieee802154_packet *);
401 | static int dissect_802154_eb_filter (tvbuff_t *, packet_info *, proto_tree *, void *);
402 | static int dissect_802154_tsch_time_sync (tvbuff_t *, packet_info *, proto_tree *, void *);
403 | static int dissect_802154_tsch_timeslot (tvbuff_t *, packet_info *, proto_tree *, void *);
404 | static int dissect_802154_tsch_slotframe_link (tvbuff_t *, packet_info *, proto_tree *, void *);
405 | static int dissect_802154_channel_hopping (tvbuff_t *, packet_info *, proto_tree *, void *);
406 | /* Sub-dissector helpers. */
407 | static void dissect_ieee802154_fcf (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *, unsigned *);
408 | static void dissect_ieee802154_command (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
409 | static void dissect_ieee802154_assoc_req (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
410 | static void dissect_ieee802154_assoc_rsp (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
411 | static void dissect_ieee802154_disassoc (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
412 | static void dissect_ieee802154_realign (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
413 | static void dissect_ieee802154_gtsreq (tvbuff_t *, packet_info *, proto_tree *, ieee802154_packet *);
414 |
415 | /* Decryption helpers. */
416 | static tvbuff_t *dissect_ieee802154_decrypt(tvbuff_t *, unsigned, packet_info *, ieee802154_packet *, ieee802154_decrypt_info_t*);
417 |
418 | static unsigned ieee802154_set_mac_key(ieee802154_packet *packet, unsigned char *key, unsigned char *alt_key, ieee802154_key_t *uat_key);
419 | static unsigned ieee802154_set_trel_key(ieee802154_packet* packet, unsigned char* key, unsigned char* alt_key, ieee802154_key_t* uat_key);
420 | static void tsch_ccm_init_nonce(uint64_t addr, uint64_t asn, uint8_t* generic_nonce);
421 |
422 | /* Initialize Protocol and Registered fields */
423 | static int proto_ieee802154_nonask_phy;
424 | static int hf_ieee802154_nonask_phy_preamble;
425 | static int hf_ieee802154_nonask_phy_sfd;
426 | static int hf_ieee802154_nonask_phy_length;
427 | static int hf_ieee802154_nonask_phr;
428 |
429 | static int proto_ieee802154;
430 | static int proto_ieee802154_tap;
431 | static int hf_ieee802154_frame_length;
432 | static int hf_ieee802154_fcf;
433 | static int hf_ieee802154_frame_type;
434 | static int hf_ieee802154_security;
435 | static int hf_ieee802154_pending;
436 | static int hf_ieee802154_ack_request;
437 | static int hf_ieee802154_pan_id_compression;
438 | static int hf_ieee802154_fcf_reserved;
439 | static int hf_ieee802154_seqno_suppression;
440 | static int hf_ieee802154_ie_present;
441 | static int hf_ieee802154_src_addr_mode;
442 | static int hf_ieee802154_version;
443 | static int hf_ieee802154_dst_addr_mode;
444 |
445 | static int hf_ieee802154_mpf_long_frame_control;
446 | static int hf_ieee802154_mpf_dst_addr_mode;
447 | static int hf_ieee802154_mpf_src_addr_mode;
448 | static int hf_ieee802154_mpf_pan_id_present;
449 | static int hf_ieee802154_mpf_security;
450 | static int hf_ieee802154_mpf_seqno_suppression;
451 | static int hf_ieee802154_mpf_pending;
452 | static int hf_ieee802154_mpf_version;
453 | static int hf_ieee802154_mpf_ack_request;
454 | static int hf_ieee802154_mpf_ie_present;
455 |
456 | static int hf_ieee802154_header_ies;
457 | static int hf_ieee802154_header_ie_tlv;
458 | static int hf_ieee802154_header_ie_type;
459 | static int hf_ieee802154_header_ie_id;
460 | static int hf_ieee802154_header_ie_length;
461 | static int hf_ieee802154_ie_unknown_content;
462 | static int hf_ieee802154_ie_unknown_content_payload;
463 | static int hf_ieee802154_hie_unsupported;
464 | static int hf_ieee802154_hie_time_correction;
465 | static int hf_ieee802154_hie_ht1;
466 | static int hf_ieee802154_hie_ht2;
467 | static int hf_ieee802154_hie_thread;
468 | static int hf_ieee802154_nack;
469 | static int hf_ieee802154_hie_time_correction_time_sync_info;
470 | static int hf_ieee802154_hie_time_correction_value;
471 | static int hf_ieee802154_hie_csl;
472 | static int hf_ieee802154_hie_csl_phase;
473 | static int hf_ieee802154_hie_csl_period;
474 | static int hf_ieee802154_hie_csl_rendezvous_time;
475 | static int hf_ieee802154_hie_rdv;
476 | static int hf_ieee802154_hie_rdv_wakeup_interval;
477 | static int hf_ieee802154_hie_global_time;
478 | static int hf_ieee802154_hie_global_time_value;
479 | static int hf_ieee802154_hie_vendor_specific;
480 | static int hf_ieee802154_hie_vendor_specific_vendor_oui;
481 | static int hf_ieee802154_hie_vendor_specific_content;
482 | static int hf_ieee802154_payload_ies;
483 | static int hf_ieee802154_payload_ie_tlv;
484 | static int hf_ieee802154_payload_ie_type;
485 | static int hf_ieee802154_payload_ie_id;
486 | static int hf_ieee802154_payload_ie_length;
487 | static int hf_ieee802154_pie_unsupported;
488 | static int hf_ieee802154_pie_termination;
489 | static int hf_ieee802154_pie_vendor;
490 | static int hf_ieee802154_pie_vendor_oui;
491 | static int hf_ieee802154_pie_vendor_variable;
492 | static int hf_ieee802154_pie_ietf;
493 | static int hf_ieee802154_mlme;
494 | static int hf_ieee802154_mlme_ie_data;
495 | static int hf_ieee802154_mlme_ie_unsupported;
496 | static int hf_ieee802154_psie;
497 | static int hf_ieee802154_psie_type;
498 | static int hf_ieee802154_psie_id_short;
499 | static int hf_ieee802154_psie_length_short;
500 | static int hf_ieee802154_psie_id_long;
501 | static int hf_ieee802154_psie_length_long;
502 |
503 | static int hf_ieee802154_tsch_sync;
504 | static int hf_ieee802154_tsch_asn;
505 | static int hf_ieee802154_tsch_join_metric;
506 | static int hf_ieee802154_tsch_slotframe;
507 | static int hf_ieee802154_tsch_link_info;
508 | static int hf_ieee802154_tsch_slotf_link_nb_slotf;
509 | static int hf_ieee802154_tsch_slotf_link_slotf_handle;
510 | static int hf_ieee802154_tsch_slotf_size;
511 | static int hf_ieee802154_tsch_slotf_link_nb_links;
512 | static int hf_ieee802154_tsch_slotf_link_timeslot;
513 | static int hf_ieee802154_tsch_slotf_link_channel_offset;
514 | static int hf_ieee802154_tsch_slotf_link_options;
515 | static int hf_ieee802154_tsch_slotf_link_options_tx;
516 | static int hf_ieee802154_tsch_slotf_link_options_rx;
517 | static int hf_ieee802154_tsch_slotf_link_options_shared;
518 | static int hf_ieee802154_tsch_slotf_link_options_timkeeping;
519 | static int hf_ieee802154_tsch_slotf_link_options_priority;
520 | static int hf_ieee802154_tsch_channel_hopping;
521 | static int hf_ieee802154_tsch_hopping_sequence_id;
522 | static int hf_ieee802154_tsch_timeslot;
523 | static int hf_ieee802154_tsch_timeslot_id;
524 | static int hf_ieee802154_tsch_timeslot_cca_offset;
525 | static int hf_ieee802154_tsch_timeslot_cca;
526 | static int hf_ieee802154_tsch_timeslot_tx_offset;
527 | static int hf_ieee802154_tsch_timeslot_rx_offset;
528 | static int hf_ieee802154_tsch_timeslot_rx_ack_delay;
529 | static int hf_ieee802154_tsch_timeslot_tx_ack_delay;
530 | static int hf_ieee802154_tsch_timeslot_rx_wait;
531 | static int hf_ieee802154_tsch_timeslot_ack_wait;
532 | static int hf_ieee802154_tsch_timeslot_turnaround;
533 | static int hf_ieee802154_tsch_timeslot_max_ack;
534 | static int hf_ieee802154_tsch_timeslot_max_tx;
535 | static int hf_ieee802154_tsch_timeslot_length;
536 |
537 | static int hf_ieee802154_psie_eb_filter;
538 | static int hf_ieee802154_psie_eb_filter_pjoin;
539 | static int hf_ieee802154_psie_eb_filter_lqi;
540 | static int hf_ieee802154_psie_eb_filter_lqi_min;
541 | static int hf_ieee802154_psie_eb_filter_percent;
542 | static int hf_ieee802154_psie_eb_filter_percent_prob;
543 | static int hf_ieee802154_psie_eb_filter_attr_id;
544 | static int hf_ieee802154_psie_eb_filter_attr_id_bitmap;
545 | static int hf_ieee802154_p_ie_ietf_sub_id;
546 |
547 | static int hf_ieee802154_6top;
548 | static int hf_ieee802154_6top_version;
549 | static int hf_ieee802154_6top_type;
550 | static int hf_ieee802154_6top_flags_reserved;
551 | static int hf_ieee802154_6top_code;
552 | static int hf_ieee802154_6top_sfid;
553 | static int hf_ieee802154_6top_seqnum;
554 | static int hf_ieee802154_6top_metadata;
555 | static int hf_ieee802154_6top_cell_options;
556 | static int hf_ieee802154_6top_cell_option_tx;
557 | static int hf_ieee802154_6top_cell_option_rx;
558 | static int hf_ieee802154_6top_cell_option_shared;
559 | static int hf_ieee802154_6top_cell_option_reserved;
560 | static int hf_ieee802154_6top_num_cells;
561 | static int hf_ieee802154_6top_cell_list;
562 | static int hf_ieee802154_6top_rel_cell_list;
563 | static int hf_ieee802154_6top_cand_cell_list;
564 | static int hf_ieee802154_6top_cell;
565 | static int hf_ieee802154_6top_reserved;
566 | static int hf_ieee802154_6top_offset;
567 | static int hf_ieee802154_6top_max_num_cells;
568 | static int hf_ieee802154_6top_slot_offset;
569 | static int hf_ieee802154_6top_channel_offset;
570 | static int hf_ieee802154_6top_total_num_cells;
571 | static int hf_ieee802154_6top_payload;
572 |
573 | static int hf_ieee802159_mpx;
574 | static int hf_ieee802159_mpx_transaction_control;
575 | static int hf_ieee802159_mpx_transfer_type;
576 | static int hf_ieee802159_mpx_transaction_id;
577 | static int hf_ieee802159_mpx_transaction_id_as_multiplex_id;
578 | static int hf_ieee802159_mpx_fragment_number;
579 | static int hf_ieee802159_mpx_total_frame_size;
580 | static int hf_ieee802159_mpx_multiplex_id;
581 | static int hf_ieee802159_mpx_kmp_id;
582 | static int hf_ieee802159_mpx_kmp_vendor_oui;
583 | static int hf_ieee802159_mpx_fragment;
584 | static int hf_ieee802159_mpx_wisun_subid;
585 |
586 | static int proto_zboss;
587 | static int hf_zboss_direction;
588 | static int hf_zboss_page;
589 | static int hf_zboss_channel;
590 | static int hf_zboss_trace_number;
591 |
592 | static int hf_ieee802154_seqno;
593 | static int hf_ieee802154_dst_panID;
594 | static int hf_ieee802154_dst16;
595 | static int hf_ieee802154_dst64;
596 | static int hf_ieee802154_src_panID;
597 | static int hf_ieee802154_src16;
598 | static int hf_ieee802154_src64;
599 | static int hf_ieee802154_src64_origin;
600 | static int hf_ieee802154_addr16;
601 | static int hf_ieee802154_addr64;
602 | static int hf_ieee802154_fcs;
603 | static int hf_ieee802154_fcs32;
604 | static int hf_ieee802154_rssi;
605 | static int hf_ieee802154_fcs_ok;
606 | static int hf_ieee802154_correlation;
607 |
608 | /* Registered fields for Command Packets */
609 | static int hf_ieee802154_cmd_id;
610 | static int hf_ieee802154_cinfo_alt_coord;
611 | static int hf_ieee802154_cinfo_device_type;
612 | static int hf_ieee802154_cinfo_power_src;
613 | static int hf_ieee802154_cinfo_idle_rx;
614 | static int hf_ieee802154_cinfo_sec_capable;
615 | static int hf_ieee802154_cinfo_alloc_addr;
616 | static int hf_ieee802154_assoc_addr;
617 | static int hf_ieee802154_assoc_status;
618 | static int hf_ieee802154_disassoc_reason;
619 | static int hf_ieee802154_realign_pan;
620 | static int hf_ieee802154_realign_caddr;
621 | static int hf_ieee802154_realign_channel;
622 | static int hf_ieee802154_realign_addr;
623 | static int hf_ieee802154_realign_channel_page;
624 | static int hf_ieee802154_gtsreq_len;
625 | static int hf_ieee802154_gtsreq_dir;
626 | static int hf_ieee802154_gtsreq_type;
627 | static int hf_ieee802154_cmd_vendor_oui;
628 |
629 | /* Registered fields for Beacon Packets */
630 | static int hf_ieee802154_beacon_order;
631 | static int hf_ieee802154_superframe_order;
632 | static int hf_ieee802154_cap;
633 | static int hf_ieee802154_superframe_battery_ext;
634 | static int hf_ieee802154_superframe_coord;
635 | static int hf_ieee802154_assoc_permit;
636 | static int hf_ieee802154_gts_count;
637 | static int hf_ieee802154_gts_permit;
638 | static int hf_ieee802154_gts_direction;
639 | static int hf_ieee802154_gts_address;
640 | static int hf_ieee802154_pending16;
641 | static int hf_ieee802154_pending64;
642 |
643 | /* Registered fields for Auxiliary Security Header */
644 | static int hf_ieee802154_aux_security_header;
645 | static int hf_ieee802154_aux_sec_security_control;
646 | static int hf_ieee802154_aux_sec_security_level;
647 | static int hf_ieee802154_aux_sec_key_id_mode;
648 | static int hf_ieee802154_aux_sec_frame_counter_suppression;
649 | static int hf_ieee802154_aux_sec_asn_in_nonce;
650 | static int hf_ieee802154_aux_sec_reserved;
651 | static int hf_ieee802154_aux_sec_frame_counter;
652 | static int hf_ieee802154_aux_sec_key_source;
653 | static int hf_ieee802154_aux_sec_key_source_bytes;
654 | static int hf_ieee802154_aux_sec_key_index;
655 | static int hf_ieee802154_mic;
656 | static int hf_ieee802154_key_number;
657 |
658 | /* 802.15.4-2003 security */
659 | static int hf_ieee802154_sec_frame_counter;
660 | static int hf_ieee802154_sec_key_sequence_counter;
661 |
662 | /* 802.15.4 ack */
663 | static int hf_ieee802154_no_ack;
664 | static int hf_ieee802154_no_ack_request;
665 | static int hf_ieee802154_ack_in;
666 | static int hf_ieee802154_ack_to;
667 | static int hf_ieee802154_ack_time;
668 |
669 | /* 802.15.4 TAP */
670 | static int hf_ieee802154_tap_version;
671 | static int hf_ieee802154_tap_reserved;
672 | static int hf_ieee802154_tap_length;
673 | static int hf_ieee802154_tap_data_length;
674 | static int hf_ieee802154_tap_tlv_type;
675 | static int hf_ieee802154_tap_tlv_length;
676 | static int hf_ieee802154_tap_tlv_unknown;
677 | static int hf_ieee802154_tap_tlv_padding;
678 | static int hf_ieee802154_tap_fcs_type;
679 | static int hf_ieee802154_tap_rss;
680 | static int hf_ieee802154_ch_page;
681 | static int hf_ieee802154_ch_num;
682 | static int hf_ieee802154_bit_rate;
683 | static int hf_ieee802154_sun_band;
684 | static int hf_ieee802154_sun_type;
685 | static int hf_ieee802154_sun_mode;
686 | static int hf_ieee802154_mode_fsk_a;
687 | static int hf_ieee802154_mode_fsk_b;
688 | static int hf_ieee802154_mode_oqpsk_a;
689 | static int hf_ieee802154_mode_oqpsk_b;
690 | static int hf_ieee802154_mode_oqpsk_c;
691 | static int hf_ieee802154_mode_ofdm;
692 | static int hf_ieee802154_sof_ts;
693 | static int hf_ieee802154_eof_ts;
694 | static int hf_ieee802154_slot_start_ts;
695 | static int hf_ieee802154_tap_timeslot_length;
696 | static int hf_ieee802154_tap_lqi;
697 | static int hf_ieee802154_chplan_start;
698 | static int hf_ieee802154_chplan_spacing;
699 | static int hf_ieee802154_chplan_channels;
700 | static int hf_ieee802154_ch_freq;
701 | static int hf_ieee802154_frame_start_offset;
702 | static int hf_ieee802154_frame_duration;
703 | static int hf_ieee802154_frame_end_offset;
704 | static int hf_ieee802154_asn;
705 |
706 | static int hf_ieee802154_tap_phr_type;
707 | static int hf_ieee802154_tap_phr_bits;
708 | static int hf_ieee802154_tap_phr_data;
709 |
710 | static int hf_ieee802154_tap_phr_fsk;
711 | static int hf_ieee802154_tap_fsk_ms_phr;
712 | static int hf_ieee802154_tap_wisun_ms_phr;
713 |
714 | static int hf_ieee802154_tap_phr_fsk_ms;
715 | static int hf_ieee802154_tap_phr_fsk_fcs;
716 | static int hf_ieee802154_tap_phr_fsk_dw;
717 | static int hf_ieee802154_tap_phr_fsk_length;
718 |
719 | static int hf_ieee802154_tap_phr_fsk_ms_param;
720 | static int hf_ieee802154_tap_phr_fsk_ms_fec;
721 | static int hf_ieee802154_tap_phr_fsk_ms_checksum;
722 | static int hf_ieee802154_tap_phr_fsk_ms_parity;
723 |
724 | static int hf_ieee802154_tap_phr_fsk_ms_mode_page;
725 | static int hf_ieee802154_tap_phr_fsk_ms_mode_scheme;
726 | static int hf_ieee802154_tap_phr_fsk_ms_mode_mode;
727 | static int hf_ieee802154_tap_phr_fsk_ms_mode_addl_mode;
728 | static int hf_ieee802154_tap_phr_wisun_fsk_ms_reserved;
729 | static int hf_ieee802154_tap_phr_wisun_fsk_ms_phymodeid;
730 |
731 | /* Bit-masks for SUN FSK PHR per IEEE 802.15.4-2020 19.2.4 */
732 | #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 |
756 | typedef struct _ieee802154_transaction_t {
757 | uint64_t dst64;
758 | uint64_t src64;
759 | int32_t dst_addr_mode;
760 | int32_t src_addr_mode;
761 | uint16_t dst16;
762 | uint16_t src16;
763 | uint32_t rqst_frame;
764 | uint32_t ack_frame;
765 | nstime_t rqst_time;
766 | nstime_t ack_time;
767 | bool_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 |
773 | static 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 |
775 | static wmem_tree_t *transaction_unmatched_pdus;
776 | static wmem_tree_t *transaction_matched_pdus;
777 |
778 | static ieee802154_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key);
779 | static ieee802154_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, const ieee802154_packet *packet, uint32_t *key);
780 |
781 | /* Initialize Subtree Pointers */
782 | static int ett_ieee802154_nonask_phy;
783 | static int ett_ieee802154_nonask_phy_phr;
784 | static int ett_ieee802154_tap;
785 | static int ett_ieee802154_tap_header;
786 | static int ett_ieee802154_tap_tlv;
787 | static int ett_ieee802154;
788 | static int ett_ieee802154_fcf;
789 | static int ett_ieee802154_auxiliary_security;
790 | static int ett_ieee802154_aux_sec_control;
791 | static int ett_ieee802154_aux_sec_key_id;
792 | static int ett_ieee802154_fcs;
793 | static int ett_ieee802154_cmd;
794 | static int ett_ieee802154_superframe;
795 | static int ett_ieee802154_gts;
796 | static int ett_ieee802154_gts_direction;
797 | static int ett_ieee802154_gts_descriptors;
798 | static int ett_ieee802154_pendaddr;
799 | static int ett_ieee802154_header_ies;
800 | static int ett_ieee802154_header_ie;
801 | static int ett_ieee802154_header_ie_tlv;
802 | static int ett_ieee802154_hie_unsupported;
803 | static int ett_ieee802154_hie_time_correction;
804 | static int ett_ieee802154_hie_ht;
805 | static int ett_ieee802154_hie_thread;
806 | static int ett_ieee802154_hie_csl;
807 | static int ett_ieee802154_hie_rdv;
808 | static int ett_ieee802154_hie_global_time;
809 | static int ett_ieee802154_hie_vendor_specific;
810 | static int ett_ieee802154_payload_ie;
811 | static int ett_ieee802154_payload_ie_tlv;
812 | static int ett_ieee802154_pie_termination;
813 | static int ett_ieee802154_pie_vendor;
814 | static int ett_ieee802154_pie_ietf;
815 | static int ett_ieee802154_pie_unsupported;
816 | static int ett_ieee802154_mlme;
817 | static int ett_ieee802154_mlme_payload;
818 | static int ett_ieee802154_mlme_payload_data;
819 | static int ett_ieee802154_mlme_unsupported;
820 | static int ett_ieee802154_tsch_slotframe;
821 | static int ett_ieee802154_tsch_slotframe_list;
822 | static int ett_ieee802154_tsch_slotframe_link;
823 | static int ett_ieee802154_tsch_slotframe_link_options;
824 | static int ett_ieee802154_tsch_timeslot;
825 | static int ett_ieee802154_tsch_synch;
826 | static int ett_ieee802154_channel_hopping;
827 | static int ett_ieee802154_psie;
828 | static int ett_ieee802154_eb_filter;
829 | static int ett_ieee802154_eb_filter_bitmap;
830 | static int ett_ieee802154_zigbee;
831 | static int ett_ieee802154_zboss;
832 | static int ett_ieee802154_p_ie_6top;
833 | static int ett_ieee802154_p_ie_6top_cell_options;
834 | static int ett_ieee802154_p_ie_6top_cell_list;
835 | static int ett_ieee802154_p_ie_6top_cand_cell_list;
836 | static int ett_ieee802154_p_ie_6top_rel_cell_list;
837 | static int ett_ieee802154_p_ie_6top_cell;
838 | static int ett_ieee802159_mpx;
839 | static int ett_ieee802159_mpx_transaction_control;
840 | static int ett_ieee802154_tap_phr;
841 |
842 | static expert_field ei_ieee802154_fcs_bitmask_len;
843 | static expert_field ei_ieee802154_invalid_addressing;
844 | static expert_field ei_ieee802154_invalid_panid_compression;
845 | static expert_field ei_ieee802154_invalid_panid_compression2;
846 | static expert_field ei_ieee802154_fcs;
847 | static expert_field ei_ieee802154_decrypt_error;
848 | static expert_field ei_ieee802154_dst;
849 | static expert_field ei_ieee802154_src;
850 | static expert_field ei_ieee802154_frame_ver;
851 | /* static expert_field ei_ieee802154_frame_type; */
852 | static expert_field ei_ieee802154_seqno_suppression;
853 | static expert_field ei_ieee802154_ack_not_found;
854 | static expert_field ei_ieee802154_ack_request_not_found;
855 | static expert_field ei_ieee802154_time_correction_error;
856 | static expert_field ei_ieee802154_6top_unsupported_type;
857 | static expert_field ei_ieee802154_6top_unsupported_return_code;
858 | static expert_field ei_ieee802154_6top_unsupported_command;
859 | static expert_field ei_ieee802154_ie_unsupported_id;
860 | static expert_field ei_ieee802154_ie_unknown_extra_content;
861 | static expert_field ei_ieee802154_ie_unknown_extra_content_payload;
862 | static expert_field ei_ieee802159_mpx_invalid_transfer_type;
863 | static expert_field ei_ieee802159_mpx_unsupported_kmp;
864 | static expert_field ei_ieee802159_mpx_unknown_kmp;
865 | static expert_field ei_ieee802154_missing_payload_ie;
866 | static expert_field ei_ieee802154_payload_ie_in_header;
867 | static expert_field ei_ieee802154_unsupported_cmd;
868 | static expert_field ei_ieee802154_unknown_cmd;
869 | static expert_field ei_ieee802154_tap_tlv_invalid_type;
870 | static expert_field ei_ieee802154_tap_tlv_invalid_length;
871 | static expert_field ei_ieee802154_tap_tlv_padding_not_zeros;
872 | static expert_field ei_ieee802154_tap_tlv_invalid_fcs_type;
873 | static expert_field ei_ieee802154_tap_tlv_reserved_not_zero;
874 | static expert_field ei_ieee802154_tap_no_payload;
875 |
876 | static int ieee802_15_4_short_address_type = -1;
877 | /*
878 | * Dissector handles
879 | * - beacon dissection is always heuristic.
880 | * - the PANID table is for stateful dissectors only (ie: Decode-As)
881 | * - otherwise, data dissectors fall back to the heuristic dissectors.
882 | */
883 | static dissector_table_t panid_dissector_table;
884 | static heur_dissector_list_t ieee802154_beacon_subdissector_list;
885 | static heur_dissector_list_t ieee802154_heur_subdissector_list;
886 |
887 | /* For the IEs and the vendor specific command */
888 | static dissector_table_t header_ie_dissector_table;
889 | static dissector_table_t payload_ie_dissector_table;
890 | static dissector_table_t mlme_ie_dissector_table;
891 | static dissector_table_t cmd_vendor_dissector_table;
892 |
893 | static dissector_handle_t zigbee_ie_handle;
894 | static dissector_handle_t zigbee_nwk_handle;
895 | static dissector_handle_t ieee802154_handle;
896 | static dissector_handle_t ieee802154_nonask_phy_handle;
897 | static dissector_handle_t ieee802154_nofcs_handle;
898 | static dissector_handle_t ieee802154_tap_handle;
899 |
900 | /* Thread 802.15.4 - 2015 */
901 | static dissector_handle_t thread_ie_handle;
902 |
903 | static int ieee802154_tap;
904 |
905 | /* Handles for MPX-IE the Multiplex ID */
906 | static dissector_table_t ethertype_table;
907 | static dissector_handle_t eapol_handle;
908 | static dissector_handle_t lowpan_handle;
909 | static dissector_handle_t wisun_sec_handle;
910 |
911 | /* Versions */
912 | static 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 */
921 | static 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 |
933 | static 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 |
941 | static 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 |
971 | static 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 |
983 | static 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 |
991 | static 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! */
998 | static 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 */
1006 | static 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 |
1013 | static const value_string ieee802154_ie_types[] = {
1014 | { 0, "Header" },
1015 | { 1, "Payload" },
1016 | { 0, NULL((void*)0) }
1017 | };
1018 |
1019 | static const value_string ieee802154_psie_types[] = {
1020 | { 0, "Short" },
1021 | { 1, "Long" },
1022 | { 0, NULL((void*)0) }
1023 | };
1024 |
1025 | static 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 |
1048 | static const true_false_string hf_ieee802154_nack_tfs = {
1049 | "Negative Acknowledgement",
1050 | "Acknowledgement"
1051 | };
1052 |
1053 | static 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 |
1064 | static 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 |
1099 | const 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 |
1108 | static const value_string zboss_direction_names[] = {
1109 | { 0, "IN" },
1110 | { 1, "OUT" },
1111 | { 0, NULL((void*)0) }
1112 | };
1113 |
1114 | static 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 |
1132 | static 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 */
1140 | static 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 */
1174 | static 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 |
1187 | static 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 |
1199 | static 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 |
1214 | static 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 |
1222 | static 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 |
1234 | static 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 |
1246 | static 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 |
1257 | static 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 |
1275 | static 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 |
1282 | static 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 |
1293 | static 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 |
1307 | static 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 |
1319 | static 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 |
1328 | static 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
1335 | const 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 |
1348 | static 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 |
1355 | static 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 */
1379 | static const true_false_string tfs_fcs_type = { "2-octet FCS", "4-octet FCS" };
1380 | static const value_string vals_fsk_ms_page[] = {
1381 | {0, "9"},
1382 | {1, "10"},
1383 | {0, NULL((void*)0)}
1384 | };
1385 |
1386 | static 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 |
1394 | static 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 |
1402 | static 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 */
1410 | static 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 */
1446 | static int ieee802154_sec_suite = SECURITY_LEVEL_ENC_MIC_64;
1447 | static 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 |
1467 | static 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 |
1485 | static int ieee802_15_4_short_address_str_len(const address* addr _U___attribute__((unused)))
1486 | {
1487 | return 11;
1488 | }
1489 |
1490 | static int ieee802_15_4_short_address_len(void)
1491 | {
1492 | return 2;
1493 | }
1494 |
1495 | /* ======================================================================= */
1496 | static 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 | /* ======================================================================= */
1510 | static 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 |
1586 | static 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 | */
1747 | static void
1748 | dissect_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 |
1880 | void 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 |
1888 | void 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 |
1962 | tvbuff_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 | */
2009 | static bool_Bool
2010 | is_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 | */
2020 | static bool_Bool
2021 | is_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 | */
2055 | static int
2056 | dissect_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 */
2106 | static unsigned
2107 | ieee802154_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 | */
2125 | static int
2126 | dissect_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 | */
2161 | static int
2162 | dissect_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 | */
2179 | static tvbuff_t *
2180 | dissect_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 | */
2228 | static int
2229 | dissect_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 | */
2248 | static int
2249 | dissect_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 | */
2351 | static void
2352 | dissect_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 |
2507 | unsigned
2508 | ieee802154_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 | */
3019 | tvbuff_t*
3020 | ieee802154_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 |
3123 | unsigned 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 |
3137 | unsigned 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 | */
3223 | static void
3224 | ieee802154_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 | */
3274 | static void
3275 | ieee802154_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 |
3298 | static void
3299 | dissect_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 |
3348 | static void
3349 | dissect_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 | */
3483 | static proto_tree*
3484 | ieee802154_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 |
3513 | static ieee802154_fcs_type_t
3514 | dissect_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 | */
3691 | proto_tree*
3692 | ieee802154_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 | */
3725 | static proto_tree*
3726 | ieee802154_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 | */
3763 | static int
3764 | dissect_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 | */
3780 | static int
3781 | dissect_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 | */
3793 | static int
3794 | dissect_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 | */
3847 | static int
3848 | dissect_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 | */
3895 | static int
3896 | dissect_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 | */
4113 | void
4114 | dissect_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 | */
4138 | void
4139 | dissect_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 | */
4217 | void
4218 | dissect_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 | */
4260 | proto_tree*
4261 | ieee802154_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 | */
4293 | static int
4294 | dissect_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 | */
4312 | static int
4313 | dissect_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 | */
4341 | static int
4342 | dissect_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 |
4363 | static int
4364 | dissect_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 | */
4374 | static int
4375 | dissect_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 | */
4396 | static int
4397 | dissect_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 | */
4440 | static int
4441 | dissect_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 |
4522 | static int
4523 | dissect_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 | */
4570 | static int
4571 | dissect_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 | */
4615 | static int
4616 | dissect_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 | */
4760 | static int
4761 | dissect_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 | */
4798 | static int
4799 | dissect_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 |
4849 | static const true_false_string tfs_cinfo_device_type = { "FFD", "RFD" };
4850 | static 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 |
4861 | static void
4862 | dissect_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 | */
4900 | static void
4901 | dissect_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 | */
4964 | static void
4965 | dissect_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 | */
5017 | static void
5018 | dissect_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 |
5082 | static const true_false_string tfs_gtsreq_dir = { "Receive", "Transmit" };
5083 | static 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 |
5099 | static void
5100 | dissect_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 | */
5130 | static void
5131 | dissect_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 | */
5273 | static tvbuff_t *
5274 | dissect_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 | */
5474 | void
5475 | ccm_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 | */
5516 | static void
5517 | tsch_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 | */
5547 | bool_Bool
5548 | ccm_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 | */
5594 | bool_Bool
5595 | ccm_cbc_mac(const uint8_t *key, const uint8_t *iv, const uint8_t *a, int a_len, const uint8_t *m, int m_len, uint8_t *mic)
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], 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[m_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. */
5708 | unsigned 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. */
5714 | gboolean 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. */
5721 | unsigned ieee802154_long_addr_hash(const void *key)
5722 | {
5723 | return (unsigned)(((const ieee802154_long_addr *)key)->addr) & 0xFFFFFFFF;
5724 | }
5725 |
5726 | /* Key equal function. */
5727 | gboolean 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. */
5733 | static 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 |
5751 | static 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 | }
5785 | static 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 | */
5807 | ieee802154_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 | */
5869 | bool_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 | */
5896 | bool_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 | */
5916 | static void
5917 | proto_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 | */
5933 | static void
5934 | proto_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. */
5941 | static 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)*/
5952 | static 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 |
5962 | static 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 |
5988 | static ct_dissector_info_t ieee802154_ct_dissector_info = {&ieee802154_conv_get_filter_type };
5989 |
5990 | static 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 |
6002 | static 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 |
6014 | static et_dissector_info_t ieee802154_endpoint_dissector_info = {&ieee802154_endpoint_get_filter_type };
6015 |
6016 | static 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 |
6032 | static 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 |
6039 | static 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 | */
6051 | void 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 | */
7532 | void 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 | */