xref: /netbsd-src/external/bsd/tcpdump/dist/print-802_15_4.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
1 /*
2  * Copyright (c) 2009
3  *	Siemens AG, All rights reserved.
4  *	Dmitry Eremin-Solenikov (dbaryshkov@gmail.com)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that: (1) source code distributions
8  * retain the above copyright notice and this paragraph in its entirety, (2)
9  * distributions including binary code include the above copyright notice and
10  * this paragraph in its entirety in the documentation or other materials
11  * provided with the distribution, and (3) all advertising materials mentioning
12  * features or use of this software display the following acknowledgement:
13  * ``This product includes software developed by the University of California,
14  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15  * the University nor the names of its contributors may be used to endorse
16  * or promote products derived from this software without specific prior
17  * written permission.
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21  */
22 
23 #include <sys/cdefs.h>
24 #ifndef lint
25 __RCSID("$NetBSD: print-802_15_4.c,v 1.6 2024/09/02 16:15:30 christos Exp $");
26 #endif
27 
28 /* \summary: IEEE 802.15.4 printer */
29 
30 #include <config.h>
31 
32 #include "netdissect-stdinc.h"
33 
34 #define ND_LONGJMP_FROM_TCHECK
35 #include "netdissect.h"
36 #include "addrtoname.h"
37 
38 #include "extract.h"
39 
40 #define CHECK_BIT(num,bit) (((num) >> (bit)) & 0x1)
41 
42 #define BROKEN_6TISCH_PAN_ID_COMPRESSION 0
43 
44 /* Frame types from Table 7-1 of 802.15.4-2015 */
45 static const char *ftypes[] = {
46 	"Beacon",			/* 0 */
47 	"Data",				/* 1 */
48 	"ACK",				/* 2 */
49 	"Command",			/* 3 */
50 	"Reserved",			/* 4 */
51 	"Multipurpose",			/* 5 */
52 	"Fragment",			/* 6 */
53 	"Extended"			/* 7 */
54 };
55 
56 /* Element IDs for Header IEs from Table 7-7 of 802.15.4-2015 */
57 static const char *h_ie_names[] = {
58 	"Vendor Specific Header IE",			/* 0x00 */
59 	"Reserved 0x01",				/* 0x01 */
60 	"Reserved 0x02",				/* 0x02 */
61 	"Reserved 0x03",				/* 0x03 */
62 	"Reserved 0x04",				/* 0x04 */
63 	"Reserved 0x05",				/* 0x05 */
64 	"Reserved 0x06",				/* 0x06 */
65 	"Reserved 0x07",				/* 0x07 */
66 	"Reserved 0x08",				/* 0x08 */
67 	"Reserved 0x09",				/* 0x09 */
68 	"Reserved 0x0a",				/* 0x0a */
69 	"Reserved 0x0b",				/* 0x0b */
70 	"Reserved 0x0c",				/* 0x0c */
71 	"Reserved 0x0d",				/* 0x0d */
72 	"Reserved 0x0e",				/* 0x0e */
73 	"Reserved 0x0f",				/* 0x0f */
74 	"Reserved 0x10",				/* 0x10 */
75 	"Reserved 0x11",				/* 0x11 */
76 	"Reserved 0x12",				/* 0x12 */
77 	"Reserved 0x13",				/* 0x13 */
78 	"Reserved 0x14",				/* 0x14 */
79 	"Reserved 0x15",				/* 0x15 */
80 	"Reserved 0x16",				/* 0x16 */
81 	"Reserved 0x17",				/* 0x17 */
82 	"Reserved 0x18",				/* 0x18 */
83 	"Reserved 0x19",				/* 0x19 */
84 	"LE CSL IE",					/* 0x1a */
85 	"LE RIT IE",					/* 0x1b */
86 	"DSME PAN descriptor IE",			/* 0x1c */
87 	"Rendezvous Time IE",				/* 0x1d */
88 	"Time Correction IE",				/* 0x1e */
89 	"Reserved 0x1f",				/* 0x1f */
90 	"Reserved 0x20",				/* 0x20 */
91 	"Extended DSME PAN descriptor IE",		/* 0x21 */
92 	"Fragment Sequence Context Description IE",	/* 0x22 */
93 	"Simplified Superframe Specification IE",	/* 0x23 */
94 	"Simplified GTS Specification IE",		/* 0x24 */
95 	"LECIM Capabilities IE",			/* 0x25 */
96 	"TRLE Descriptor IE",				/* 0x26 */
97 	"RCC Capabilities IE",				/* 0x27 */
98 	"RCCN Descriptor IE",				/* 0x28 */
99 	"Global Time IE",				/* 0x29 */
100 	"Omnibus Header IE",				/* 0x2a */
101 	"DA IE",					/* 0x2b */
102 	"Reserved 0x2c",				/* 0x2c */
103 	"Reserved 0x2d",				/* 0x2d */
104 	"Reserved 0x2e",				/* 0x2e */
105 	"Reserved 0x2f",				/* 0x2f */
106 	"Reserved 0x30",				/* 0x30 */
107 	"Reserved 0x31",				/* 0x31 */
108 	"Reserved 0x32",				/* 0x32 */
109 	"Reserved 0x33",				/* 0x33 */
110 	"Reserved 0x34",				/* 0x34 */
111 	"Reserved 0x35",				/* 0x35 */
112 	"Reserved 0x36",				/* 0x36 */
113 	"Reserved 0x37",				/* 0x37 */
114 	"Reserved 0x38",				/* 0x38 */
115 	"Reserved 0x39",				/* 0x39 */
116 	"Reserved 0x3a",				/* 0x3a */
117 	"Reserved 0x3b",				/* 0x3b */
118 	"Reserved 0x3c",				/* 0x3c */
119 	"Reserved 0x3d",				/* 0x3d */
120 	"Reserved 0x3e",				/* 0x3e */
121 	"Reserved 0x3f",				/* 0x3f */
122 	"Reserved 0x40",				/* 0x40 */
123 	"Reserved 0x41",				/* 0x41 */
124 	"Reserved 0x42",				/* 0x42 */
125 	"Reserved 0x43",				/* 0x43 */
126 	"Reserved 0x44",				/* 0x44 */
127 	"Reserved 0x45",				/* 0x45 */
128 	"Reserved 0x46",				/* 0x46 */
129 	"Reserved 0x47",				/* 0x47 */
130 	"Reserved 0x48",				/* 0x48 */
131 	"Reserved 0x49",				/* 0x49 */
132 	"Reserved 0x4a",				/* 0x4a */
133 	"Reserved 0x4b",				/* 0x4b */
134 	"Reserved 0x4c",				/* 0x4c */
135 	"Reserved 0x4d",				/* 0x4d */
136 	"Reserved 0x4e",				/* 0x4e */
137 	"Reserved 0x4f",				/* 0x4f */
138 	"Reserved 0x50",				/* 0x50 */
139 	"Reserved 0x51",				/* 0x51 */
140 	"Reserved 0x52",				/* 0x52 */
141 	"Reserved 0x53",				/* 0x53 */
142 	"Reserved 0x54",				/* 0x54 */
143 	"Reserved 0x55",				/* 0x55 */
144 	"Reserved 0x56",				/* 0x56 */
145 	"Reserved 0x57",				/* 0x57 */
146 	"Reserved 0x58",				/* 0x58 */
147 	"Reserved 0x59",				/* 0x59 */
148 	"Reserved 0x5a",				/* 0x5a */
149 	"Reserved 0x5b",				/* 0x5b */
150 	"Reserved 0x5c",				/* 0x5c */
151 	"Reserved 0x5d",				/* 0x5d */
152 	"Reserved 0x5e",				/* 0x5e */
153 	"Reserved 0x5f",				/* 0x5f */
154 	"Reserved 0x60",				/* 0x60 */
155 	"Reserved 0x61",				/* 0x61 */
156 	"Reserved 0x62",				/* 0x62 */
157 	"Reserved 0x63",				/* 0x63 */
158 	"Reserved 0x64",				/* 0x64 */
159 	"Reserved 0x65",				/* 0x65 */
160 	"Reserved 0x66",				/* 0x66 */
161 	"Reserved 0x67",				/* 0x67 */
162 	"Reserved 0x68",				/* 0x68 */
163 	"Reserved 0x69",				/* 0x69 */
164 	"Reserved 0x6a",				/* 0x6a */
165 	"Reserved 0x6b",				/* 0x6b */
166 	"Reserved 0x6c",				/* 0x6c */
167 	"Reserved 0x6d",				/* 0x6d */
168 	"Reserved 0x6e",				/* 0x6e */
169 	"Reserved 0x6f",				/* 0x6f */
170 	"Reserved 0x70",				/* 0x70 */
171 	"Reserved 0x71",				/* 0x71 */
172 	"Reserved 0x72",				/* 0x72 */
173 	"Reserved 0x73",				/* 0x73 */
174 	"Reserved 0x74",				/* 0x74 */
175 	"Reserved 0x75",				/* 0x75 */
176 	"Reserved 0x76",				/* 0x76 */
177 	"Reserved 0x77",				/* 0x77 */
178 	"Reserved 0x78",				/* 0x78 */
179 	"Reserved 0x79",				/* 0x79 */
180 	"Reserved 0x7a",				/* 0x7a */
181 	"Reserved 0x7b",				/* 0x7b */
182 	"Reserved 0x7c",				/* 0x7c */
183 	"Reserved 0x7d",				/* 0x7d */
184 	"Header Termination 1 IE",			/* 0x7e */
185 	"Header Termination 2 IE"			/* 0x7f */
186 };
187 
188 /* Payload IE Group IDs from Table 7-15 of 802.15.4-2015 */
189 static const char *p_ie_names[] = {
190 	"ESDU IE",			/* 0x00 */
191 	"MLME IE",			/* 0x01 */
192 	"Vendor Specific Nested IE",	/* 0x02 */
193 	"Multiplexed IE (802.15.9)",	/* 0x03 */
194 	"Omnibus Payload Group IE",	/* 0x04 */
195 	"IETF IE",			/* 0x05 */
196 	"Reserved 0x06",		/* 0x06 */
197 	"Reserved 0x07",		/* 0x07 */
198 	"Reserved 0x08",		/* 0x08 */
199 	"Reserved 0x09",		/* 0x09 */
200 	"Reserved 0x0a",		/* 0x0a */
201 	"Reserved 0x0b",		/* 0x0b */
202 	"Reserved 0x0c",		/* 0x0c */
203 	"Reserved 0x0d",		/* 0x0d */
204 	"Reserved 0x0e",		/* 0x0e */
205 	"List termination"		/* 0x0f */
206 };
207 
208 /* Sub-ID for short format from Table 7-16 of 802.15.4-2015 */
209 static const char *p_mlme_short_names[] = {
210 	"Reserved for long format 0x0",			/* 0x00 */
211 	"Reserved for long format 0x1",			/* 0x01 */
212 	"Reserved for long format 0x2",			/* 0x02 */
213 	"Reserved for long format 0x3",			/* 0x03 */
214 	"Reserved for long format 0x4",			/* 0x04 */
215 	"Reserved for long format 0x5",			/* 0x05 */
216 	"Reserved for long format 0x6",			/* 0x06 */
217 	"Reserved for long format 0x7",			/* 0x07 */
218 	"Reserved for long format 0x8",			/* 0x08 */
219 	"Reserved for long format 0x9",			/* 0x09 */
220 	"Reserved for long format 0xa",			/* 0x0a */
221 	"Reserved for long format 0xb",			/* 0x0b */
222 	"Reserved for long format 0xc",			/* 0x0c */
223 	"Reserved for long format 0xd",			/* 0x0d */
224 	"Reserved for long format 0xe",			/* 0x0e */
225 	"Reserved for long format 0xf",			/* 0x0f */
226 	"Reserved 0x10",				/* 0x10 */
227 	"Reserved 0x11",				/* 0x11 */
228 	"Reserved 0x12",				/* 0x12 */
229 	"Reserved 0x13",				/* 0x13 */
230 	"Reserved 0x14",				/* 0x14 */
231 	"Reserved 0x15",				/* 0x15 */
232 	"Reserved 0x16",				/* 0x16 */
233 	"Reserved 0x17",				/* 0x17 */
234 	"Reserved 0x18",				/* 0x18 */
235 	"Reserved 0x19",				/* 0x19 */
236 	"TSCH Synchronization IE",			/* 0x1a */
237 	"TSCH Slotframe and Link IE",			/* 0x1b */
238 	"TSCH Timeslot IE",				/* 0x1c */
239 	"Hopping timing IE",				/* 0x1d */
240 	"Enhanced Beacon Filter IE",			/* 0x1e */
241 	"MAC Metrics IE",				/* 0x1f */
242 	"All MAC Metrics IE",				/* 0x20 */
243 	"Coexistence Specification IE",			/* 0x21 */
244 	"SUN Device Capabilities IE",			/* 0x22 */
245 	"SUN FSK Generic PHY IE",			/* 0x23 */
246 	"Mode Switch Parameter IE",			/* 0x24 */
247 	"PHY Parameter Change IE",			/* 0x25 */
248 	"O-QPSK PHY Mode IE",				/* 0x26 */
249 	"PCA Allocation IE",				/* 0x27 */
250 	"LECIM DSSS Operating Mode IE",			/* 0x28 */
251 	"LECIM FSK Operating Mode IE",			/* 0x29 */
252 	"Reserved 0x2a",				/* 0x2a */
253 	"TVWS PHY Operating Mode Description IE",	/* 0x2b */
254 	"TVWS Device Capabilities IE",			/* 0x2c */
255 	"TVWS Device Category IE",			/* 0x2d */
256 	"TVWS Device Identification IE",		/* 0x2e */
257 	"TVWS Device Location IE",			/* 0x2f */
258 	"TVWS Channel Information Query IE",		/* 0x30 */
259 	"TVWS Channel Information Source IE",		/* 0x31 */
260 	"CTM IE",					/* 0x32 */
261 	"Timestamp IE",					/* 0x33 */
262 	"Timestamp Difference IE",			/* 0x34 */
263 	"TMCTP Specification IE",			/* 0x35 */
264 	"RCC PHY Operating Mode IE",			/* 0x36 */
265 	"Reserved 0x37",				/* 0x37 */
266 	"Reserved 0x38",				/* 0x38 */
267 	"Reserved 0x39",				/* 0x39 */
268 	"Reserved 0x3a",				/* 0x3a */
269 	"Reserved 0x3b",				/* 0x3b */
270 	"Reserved 0x3c",				/* 0x3c */
271 	"Reserved 0x3d",				/* 0x3d */
272 	"Reserved 0x3e",				/* 0x3e */
273 	"Reserved 0x3f",				/* 0x3f */
274 	"Reserved 0x40",				/* 0x40 */
275 	"Reserved 0x41",				/* 0x41 */
276 	"Reserved 0x42",				/* 0x42 */
277 	"Reserved 0x43",				/* 0x43 */
278 	"Reserved 0x44",				/* 0x44 */
279 	"Reserved 0x45",				/* 0x45 */
280 	"Reserved 0x46",				/* 0x46 */
281 	"Reserved 0x47",				/* 0x47 */
282 	"Reserved 0x48",				/* 0x48 */
283 	"Reserved 0x49",				/* 0x49 */
284 	"Reserved 0x4a",				/* 0x4a */
285 	"Reserved 0x4b",				/* 0x4b */
286 	"Reserved 0x4c",				/* 0x4c */
287 	"Reserved 0x4d",				/* 0x4d */
288 	"Reserved 0x4e",				/* 0x4e */
289 	"Reserved 0x4f",				/* 0x4f */
290 	"Reserved 0x50",				/* 0x50 */
291 	"Reserved 0x51",				/* 0x51 */
292 	"Reserved 0x52",				/* 0x52 */
293 	"Reserved 0x53",				/* 0x53 */
294 	"Reserved 0x54",				/* 0x54 */
295 	"Reserved 0x55",				/* 0x55 */
296 	"Reserved 0x56",				/* 0x56 */
297 	"Reserved 0x57",				/* 0x57 */
298 	"Reserved 0x58",				/* 0x58 */
299 	"Reserved 0x59",				/* 0x59 */
300 	"Reserved 0x5a",				/* 0x5a */
301 	"Reserved 0x5b",				/* 0x5b */
302 	"Reserved 0x5c",				/* 0x5c */
303 	"Reserved 0x5d",				/* 0x5d */
304 	"Reserved 0x5e",				/* 0x5e */
305 	"Reserved 0x5f",				/* 0x5f */
306 	"Reserved 0x60",				/* 0x60 */
307 	"Reserved 0x61",				/* 0x61 */
308 	"Reserved 0x62",				/* 0x62 */
309 	"Reserved 0x63",				/* 0x63 */
310 	"Reserved 0x64",				/* 0x64 */
311 	"Reserved 0x65",				/* 0x65 */
312 	"Reserved 0x66",				/* 0x66 */
313 	"Reserved 0x67",				/* 0x67 */
314 	"Reserved 0x68",				/* 0x68 */
315 	"Reserved 0x69",				/* 0x69 */
316 	"Reserved 0x6a",				/* 0x6a */
317 	"Reserved 0x6b",				/* 0x6b */
318 	"Reserved 0x6c",				/* 0x6c */
319 	"Reserved 0x6d",				/* 0x6d */
320 	"Reserved 0x6e",				/* 0x6e */
321 	"Reserved 0x6f",				/* 0x6f */
322 	"Reserved 0x70",				/* 0x70 */
323 	"Reserved 0x71",				/* 0x71 */
324 	"Reserved 0x72",				/* 0x72 */
325 	"Reserved 0x73",				/* 0x73 */
326 	"Reserved 0x74",				/* 0x74 */
327 	"Reserved 0x75",				/* 0x75 */
328 	"Reserved 0x76",				/* 0x76 */
329 	"Reserved 0x77",				/* 0x77 */
330 	"Reserved 0x78",				/* 0x78 */
331 	"Reserved 0x79",				/* 0x79 */
332 	"Reserved 0x7a",				/* 0x7a */
333 	"Reserved 0x7b",				/* 0x7b */
334 	"Reserved 0x7c",				/* 0x7c */
335 	"Reserved 0x7d",				/* 0x7d */
336 	"Reserved 0x7e",				/* 0x7e */
337 	"Reserved 0x7f"					/* 0x7f */
338 };
339 
340 /* Sub-ID for long format from Table 7-17 of 802.15.4-2015 */
341 static const char *p_mlme_long_names[] = {
342 	"Reserved 0x00",			/* 0x00 */
343 	"Reserved 0x01",			/* 0x01 */
344 	"Reserved 0x02",			/* 0x02 */
345 	"Reserved 0x03",			/* 0x03 */
346 	"Reserved 0x04",			/* 0x04 */
347 	"Reserved 0x05",			/* 0x05 */
348 	"Reserved 0x06",			/* 0x06 */
349 	"Reserved 0x07",			/* 0x07 */
350 	"Vendor Specific MLME Nested IE",	/* 0x08 */
351 	"Channel Hopping IE",			/* 0x09 */
352 	"Reserved 0x0a",			/* 0x0a */
353 	"Reserved 0x0b",			/* 0x0b */
354 	"Reserved 0x0c",			/* 0x0c */
355 	"Reserved 0x0d",			/* 0x0d */
356 	"Reserved 0x0e",			/* 0x0e */
357 	"Reserved 0x0f"				/* 0x0f */
358 };
359 
360 /* MAC commands from Table 7-49 of 802.15.4-2015 */
361 static const char *mac_c_names[] = {
362 	"Reserved 0x00",				/* 0x00 */
363 	"Association Request command",			/* 0x01 */
364 	"Association Response command",			/* 0x02 */
365 	"Disassociation Notification command",		/* 0x03 */
366 	"Data Request command",				/* 0x04 */
367 	"PAN ID Conflict Notification command",		/* 0x05 */
368 	"Orphan Notification command",			/* 0x06 */
369 	"Beacon Request command",			/* 0x07 */
370 	"Coordinator realignment command",		/* 0x08 */
371 	"GTS request command",				/* 0x09 */
372 	"TRLE Management Request command",		/* 0x0a */
373 	"TRLE Management Response command",		/* 0x0b */
374 	"Reserved 0x0c",				/* 0x0c */
375 	"Reserved 0x0d",				/* 0x0d */
376 	"Reserved 0x0e",				/* 0x0e */
377 	"Reserved 0x0f",				/* 0x0f */
378 	"Reserved 0x10",				/* 0x10 */
379 	"Reserved 0x11",				/* 0x11 */
380 	"Reserved 0x12",				/* 0x12 */
381 	"DSME Association Request command",		/* 0x13 */
382 	"DSME Association Response command",		/* 0x14 */
383 	"DSME GTS Request command",			/* 0x15 */
384 	"DSME GTS Response command",			/* 0x16 */
385 	"DSME GTS Notify command",			/* 0x17 */
386 	"DSME Information Request command",		/* 0x18 */
387 	"DSME Information Response command",		/* 0x19 */
388 	"DSME Beacon Allocation Notification command",	/* 0x1a */
389 	"DSME Beacon Collision Notification command",	/* 0x1b */
390 	"DSME Link Report command",			/* 0x1c */
391 	"Reserved 0x1d",				/* 0x1d */
392 	"Reserved 0x1e",				/* 0x1e */
393 	"Reserved 0x1f",				/* 0x1f */
394 	"RIT Data Request command",			/* 0x20 */
395 	"DBS Request command",				/* 0x21 */
396 	"DBS Response command",				/* 0x22 */
397 	"RIT Data Response command",			/* 0x23 */
398 	"Vendor Specific command",			/* 0x24 */
399 	"Reserved 0x25",				/* 0x25 */
400 	"Reserved 0x26",				/* 0x26 */
401 	"Reserved 0x27",				/* 0x27 */
402 	"Reserved 0x28",				/* 0x28 */
403 	"Reserved 0x29",				/* 0x29 */
404 	"Reserved 0x2a",				/* 0x2a */
405 	"Reserved 0x2b",				/* 0x2b */
406 	"Reserved 0x2c",				/* 0x2c */
407 	"Reserved 0x2d",				/* 0x2d */
408 	"Reserved 0x2e",				/* 0x2e */
409 	"Reserved 0x2f"					/* 0x2f */
410 };
411 
412 /*
413  * Frame Control subfields.
414  */
415 #define FC_FRAME_TYPE(fc)              ((fc) & 0x7)
416 #define FC_FRAME_VERSION(fc)           (((fc) >> 12) & 0x3)
417 
418 #define FC_ADDRESSING_MODE_NONE         0x00
419 #define FC_ADDRESSING_MODE_RESERVED     0x01
420 #define FC_ADDRESSING_MODE_SHORT        0x02
421 #define FC_ADDRESSING_MODE_LONG         0x03
422 
423 /*
424  * IEEE 802.15.4 CRC 16 function. This is using the CCITT polynomial of 0x1021,
425  * but the initial value is 0, and the bits are reversed for both in and out.
426  * See section 7.2.10 of 802.15.4-2015 for more information.
427  */
428 static uint16_t
429 ieee802_15_4_crc16(netdissect_options *ndo, const u_char *p,
430 		   u_int data_len)
431 {
432 	uint16_t crc;
433 	u_char x, y;
434 
435 	crc = 0x0000; /* Note, initial value is 0x0000 not 0xffff. */
436 
437 	while (data_len != 0){
438 		y = GET_U_1(p);
439 		p++;
440 		/* Reverse bits on input */
441 		y = (((y & 0xaa) >> 1) | ((y & 0x55) << 1));
442 		y = (((y & 0xcc) >> 2) | ((y & 0x33) << 2));
443 		y = (((y & 0xf0) >> 4) | ((y & 0x0f) << 4));
444 		/* Update CRC */
445 		x = crc >> 8 ^ y;
446 		x ^= x >> 4;
447 		crc = ((uint16_t)(crc << 8)) ^
448 			((uint16_t)(x << 12)) ^
449 			((uint16_t)(x << 5)) ^
450 			((uint16_t)x);
451 		data_len--;
452 	}
453 	/* Reverse bits on output */
454 	crc = (((crc & 0xaaaa) >> 1) | ((crc & 0x5555) << 1));
455 	crc = (((crc & 0xcccc) >> 2) | ((crc & 0x3333) << 2));
456 	crc = (((crc & 0xf0f0) >> 4) | ((crc & 0x0f0f) << 4));
457 	crc = (((crc & 0xff00) >> 8) | ((crc & 0x00ff) << 8));
458 	return crc;
459 }
460 
461 /*
462  * Reverses the bits of the 32-bit word.
463  */
464 static uint32_t
465 ieee802_15_4_reverse32(uint32_t x)
466 {
467 	x = ((x & 0x55555555) <<  1) | ((x >>  1) & 0x55555555);
468 	x = ((x & 0x33333333) <<  2) | ((x >>  2) & 0x33333333);
469 	x = ((x & 0x0F0F0F0F) <<  4) | ((x >>  4) & 0x0F0F0F0F);
470 	x = (x << 24) | ((x & 0xFF00) << 8) |
471 		((x >> 8) & 0xFF00) | (x >> 24);
472 	return x;
473 }
474 
475 /*
476  * IEEE 802.15.4 CRC 32 function. This is using the ANSI X3.66-1979 polynomial of
477  * 0x04C11DB7, but the initial value is 0, and the bits are reversed for both
478  * in and out. See section 7.2.10 of 802.15.4-2015 for more information.
479  */
480 static uint32_t
481 ieee802_15_4_crc32(netdissect_options *ndo, const u_char *p,
482 		   u_int data_len)
483 {
484 	uint32_t crc, byte;
485 	int b;
486 
487 	crc = 0x00000000; /* Note, initial value is 0x00000000 not 0xffffffff */
488 
489 	while (data_len != 0){
490 		byte = GET_U_1(p);
491 		p++;
492 		/* Reverse bits on input */
493 		byte = ieee802_15_4_reverse32(byte);
494 		/* Update CRC */
495 		for(b = 0; b <= 7; b++) {
496 		  if ((int) (crc ^ byte) < 0)
497 		    crc = (crc << 1) ^ 0x04C11DB7;
498 		  else
499 		    crc = crc << 1;
500 		  byte = byte << 1;
501 		}
502 		data_len--;
503 	}
504 	/* Reverse bits on output */
505 	crc = ieee802_15_4_reverse32(crc);
506 	return crc;
507 }
508 
509 /*
510  * Find out the address length based on the address type. See table 7-3 of
511  * 802.15.4-2015. Returns the address length.
512  */
513 static int
514 ieee802_15_4_addr_len(uint16_t addr_type)
515 {
516 	switch (addr_type) {
517 	case FC_ADDRESSING_MODE_NONE: /* None. */
518 		return 0;
519 		break;
520 	case FC_ADDRESSING_MODE_RESERVED: /* Reserved, there used to be 8-bit
521 					   * address type in one amendment, but
522 					   * that and the feature using it was
523 					   * removed during 802.15.4-2015
524 					   * maintenance process. */
525 		return -1;
526 		break;
527 	case FC_ADDRESSING_MODE_SHORT: /* Short. */
528 		return 2;
529 		break;
530 	case FC_ADDRESSING_MODE_LONG: /* Extended. */
531 		return 8;
532 		break;
533 	}
534 	return 0;
535 }
536 
537 /*
538  * Print out the ieee 802.15.4 address.
539  */
540 static void
541 ieee802_15_4_print_addr(netdissect_options *ndo, const u_char *p,
542 			int dst_addr_len)
543 {
544 	switch (dst_addr_len) {
545 	case 0:
546 		ND_PRINT("none");
547 		break;
548 	case 2:
549 		ND_PRINT("%04x", GET_LE_U_2(p));
550 		break;
551 	case 8:
552 		ND_PRINT("%s", GET_LE64ADDR_STRING(p));
553 		break;
554 	}
555 }
556 
557 /*
558  * Beacon frame superframe specification structure. Used in the old Beacon
559  * frames, and in the DSME PAN Descriptor IE. See section 7.3.1.3 of the
560  * 802.15.4-2015.
561  */
562 static void
563 ieee802_15_4_print_superframe_specification(netdissect_options *ndo,
564 					    uint16_t ss)
565 {
566 	if (ndo->ndo_vflag < 1) {
567 		return;
568 	}
569 	ND_PRINT("\n\tBeacon order = %d, Superframe order = %d, ",
570 		 (ss & 0xf), ((ss >> 4) & 0xf));
571 	ND_PRINT("Final CAP Slot = %d",
572 		 ((ss >> 8) & 0xf));
573 	if (CHECK_BIT(ss, 12)) { ND_PRINT(", BLE enabled"); }
574 	if (CHECK_BIT(ss, 14)) { ND_PRINT(", PAN Coordinator"); }
575 	if (CHECK_BIT(ss, 15)) { ND_PRINT(", Association Permit"); }
576 }
577 
578 /*
579  * Beacon frame gts info structure. Used in the old Beacon frames, and
580  * in the DSME PAN Descriptor IE. See section 7.3.1.4 of 802.15.4-2015.
581  *
582  * Returns number of byts consumed from the packet or -1 in case of error.
583  */
584 static int
585 ieee802_15_4_print_gts_info(netdissect_options *ndo,
586 			    const u_char *p,
587 			    u_int data_len)
588 {
589 	uint8_t gts_spec, gts_cnt;
590 	u_int len;
591 	int i;
592 
593 	gts_spec = GET_U_1(p);
594 	gts_cnt = gts_spec & 0x7;
595 
596 	if (gts_cnt == 0) {
597 		if (ndo->ndo_vflag > 0) {
598 			ND_PRINT("\n\tGTS Descriptor Count = %d, ", gts_cnt);
599 		}
600 		return 1;
601 	}
602 	len = 1 + 1 + gts_cnt * 3;
603 
604 	if (data_len < len) {
605 		ND_PRINT(" [ERROR: Truncated GTS Info List]");
606 		return -1;
607 	}
608 	if (ndo->ndo_vflag < 2) {
609 		return len;
610 	}
611 	ND_PRINT("GTS Descriptor Count = %d, ", gts_cnt);
612 	ND_PRINT("GTS Directions Mask = %02x, [ ",
613 		 GET_U_1(p + 1) & 0x7f);
614 
615 	for(i = 0; i < gts_cnt; i++) {
616 		ND_PRINT("[ ");
617 		ieee802_15_4_print_addr(ndo, p + 2 + i * 3, 2);
618 		ND_PRINT(", Start slot = %d, Length = %d ] ",
619 			 GET_U_1(p + 2 + i * 3 + 1) & 0x0f,
620 			 (GET_U_1(p + 2 + i * 3 + 1) >> 4) & 0x0f);
621 	}
622 	ND_PRINT("]");
623 	return len;
624 }
625 
626 /*
627  * Beacon frame pending address structure. Used in the old Beacon frames, and
628  * in the DSME PAN Descriptor IE. See section 7.3.1.5 of 802.15.4-2015.
629  *
630  * Returns number of byts consumed from the packet or -1 in case of error.
631  */
632 static int16_t
633 ieee802_15_4_print_pending_addresses(netdissect_options *ndo,
634 				     const u_char *p,
635 				     u_int data_len)
636 {
637 	uint8_t pas, s_cnt, e_cnt, len, i;
638 
639 	pas = GET_U_1(p);
640 	s_cnt = pas & 0x7;
641 	e_cnt = (pas >> 4) & 0x7;
642 	len = 1 + s_cnt * 2 + e_cnt * 8;
643 	if (ndo->ndo_vflag > 0) {
644 		ND_PRINT("\n\tPending address list, "
645 			 "# short addresses = %d, # extended addresses = %d",
646 			 s_cnt, e_cnt);
647 	}
648 	if (data_len < len) {
649 		ND_PRINT(" [ERROR: Pending address list truncated]");
650 		return -1;
651 	}
652 	if (ndo->ndo_vflag < 2) {
653 		return len;
654 	}
655 	if (s_cnt != 0) {
656 		ND_PRINT(", Short address list = [ ");
657 		for(i = 0; i < s_cnt; i++) {
658 			ieee802_15_4_print_addr(ndo, p + 1 + i * 2, 2);
659 			ND_PRINT(" ");
660 		}
661 		ND_PRINT("]");
662 	}
663 	if (e_cnt != 0) {
664 		ND_PRINT(", Extended address list = [ ");
665 		for(i = 0; i < e_cnt; i++) {
666 			ieee802_15_4_print_addr(ndo, p + 1 + s_cnt * 2 +
667 						i * 8, 8);
668 			ND_PRINT(" ");
669 		}
670 		ND_PRINT("]");
671 	}
672 	return len;
673 }
674 
675 /*
676  * Print header ie content.
677  */
678 static void
679 ieee802_15_4_print_header_ie(netdissect_options *ndo,
680 			     const u_char *p,
681 			     uint16_t ie_len,
682 			     int element_id)
683 {
684 	int i;
685 
686 	switch (element_id) {
687 	case 0x00: /* Vendor Specific Header IE */
688 		if (ie_len < 3) {
689 			ND_PRINT("[ERROR: Vendor OUI missing]");
690 		} else {
691 			ND_PRINT("OUI = 0x%02x%02x%02x, ", GET_U_1(p),
692 				 GET_U_1(p + 1), GET_U_1(p + 2));
693 			ND_PRINT("Data = ");
694 			for(i = 3; i < ie_len; i++) {
695 				ND_PRINT("%02x ", GET_U_1(p + i));
696 			}
697 		}
698 		break;
699 	case 0x1a: /* LE CSL IE */
700 		if (ie_len < 4) {
701 			ND_PRINT("[ERROR: Truncated CSL IE]");
702 		} else {
703 			ND_PRINT("CSL Phase = %d, CSL Period = %d",
704 				 GET_LE_U_2(p), GET_LE_U_2(p + 2));
705 			if (ie_len >= 6) {
706 				ND_PRINT(", Rendezvous time = %d",
707 					 GET_LE_U_2(p + 4));
708 			}
709 			if (ie_len != 4 && ie_len != 6) {
710 				ND_PRINT(" [ERROR: CSL IE length wrong]");
711 			}
712 		}
713 		break;
714 	case 0x1b: /* LE RIT IE */
715 		if (ie_len < 4) {
716 			ND_PRINT("[ERROR: Truncated RIT IE]");
717 		} else {
718 			ND_PRINT("Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d",
719 				 GET_U_1(p),
720 				 GET_U_1(p + 1),
721 				 GET_LE_U_2(p + 2));
722 		}
723 		break;
724 	case 0x1c: /* DSME PAN Descriptor IE */
725 		/*FALLTHROUGH*/
726 	case 0x21: /* Extended DSME PAN descriptor IE */
727 		if (ie_len < 2) {
728 			ND_PRINT("[ERROR: Truncated DSME PAN IE]");
729 		} else {
730 			uint16_t ss, ptr, ulen;
731 			int16_t len;
732 			int hopping_present;
733 
734 			hopping_present = 0;
735 
736 			ss = GET_LE_U_2(p);
737 			ieee802_15_4_print_superframe_specification(ndo, ss);
738 			if (ie_len < 3) {
739 				ND_PRINT("[ERROR: Truncated before pending addresses field]");
740 				break;
741 			}
742 			ptr = 2;
743 			len = ieee802_15_4_print_pending_addresses(ndo,
744 								   p + ptr,
745 								   ie_len -
746 								   ptr);
747 			if (len < 0) {
748 				break;
749 			}
750 			ptr += len;
751 
752 			if (element_id == 0x21) {
753 				/* Extended version. */
754 				if (ie_len < ptr + 2) {
755 					ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
756 					break;
757 				}
758 				ss = GET_LE_U_2(p + ptr);
759 				ptr += 2;
760 				ND_PRINT("Multi-superframe Order = %d", ss & 0xff);
761 				ND_PRINT(", %s", ((ss & 0x100) ?
762 						  "Channel hopping mode" :
763 						  "Channel adaptation mode"));
764 				if (ss & 0x400) {
765 					ND_PRINT(", CAP reduction enabled");
766 				}
767 				if (ss & 0x800) {
768 					ND_PRINT(", Deferred beacon enabled");
769 				}
770 				if (ss & 0x1000) {
771 					ND_PRINT(", Hopping Sequence Present");
772 					hopping_present = 1;
773 				}
774 			} else {
775 				if (ie_len < ptr + 1) {
776 					ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
777 					break;
778 				}
779 				ss = GET_U_1(p + ptr);
780 				ptr++;
781 				ND_PRINT("Multi-superframe Order = %d",
782 					 ss & 0x0f);
783 				ND_PRINT(", %s", ((ss & 0x10) ?
784 						  "Channel hopping mode" :
785 						  "Channel adaptation mode"));
786 				if (ss & 0x40) {
787 					ND_PRINT(", CAP reduction enabled");
788 				}
789 				if (ss & 0x80) {
790 					ND_PRINT(", Deferred beacon enabled");
791 				}
792 			}
793 			if (ie_len < ptr + 8) {
794 				ND_PRINT(" [ERROR: Truncated before Time synchronization specification]");
795 				break;
796 			}
797 			ND_PRINT("Beacon timestamp = %" PRIu64 ", offset = %d",
798 				 GET_LE_U_6(p + ptr),
799 				 GET_LE_U_2(p + ptr + 6));
800 			ptr += 8;
801 			if (ie_len < ptr + 4) {
802 				ND_PRINT(" [ERROR: Truncated before Beacon Bitmap]");
803 				break;
804 			}
805 
806 			ulen = GET_LE_U_2(p + ptr + 2);
807 			ND_PRINT("SD Index = %d, Bitmap len = %d, ",
808 				 GET_LE_U_2(p + ptr), ulen);
809 			ptr += 4;
810 			if (ie_len < ptr + ulen) {
811 				ND_PRINT(" [ERROR: Truncated in SD bitmap]");
812 				break;
813 			}
814 			ND_PRINT(" SD Bitmap = ");
815 			for(i = 0; i < ulen; i++) {
816 				ND_PRINT("%02x ", GET_U_1(p + ptr + i));
817 			}
818 			ptr += ulen;
819 
820 			if (ie_len < ptr + 5) {
821 				ND_PRINT(" [ERROR: Truncated before Channel hopping specification]");
822 				break;
823 			}
824 
825 			ulen = GET_LE_U_2(p + ptr + 4);
826 			ND_PRINT("Hopping Seq ID = %d, PAN Coordinator BSN = %d, "
827 				 "Channel offset = %d, Bitmap length = %d, ",
828 				 GET_U_1(p + ptr),
829 				 GET_U_1(p + ptr + 1),
830 				 GET_LE_U_2(p + ptr + 2),
831 				 ulen);
832 			ptr += 5;
833 			if (ie_len < ptr + ulen) {
834 				ND_PRINT(" [ERROR: Truncated in Channel offset bitmap]");
835 				break;
836 			}
837 			ND_PRINT(" Channel offset bitmap = ");
838 			for(i = 0; i < ulen; i++) {
839 				ND_PRINT("%02x ", GET_U_1(p + ptr + i));
840 			}
841 			ptr += ulen;
842 			if (hopping_present) {
843 				if (ie_len < ptr + 1) {
844 					ND_PRINT(" [ERROR: Truncated in Hopping Sequence length]");
845 					break;
846 				}
847 				ulen = GET_U_1(p + ptr);
848 				ptr++;
849 				ND_PRINT("Hopping Seq length = %d [ ", ulen);
850 
851 				/* The specification is not clear how the
852 				   hopping sequence is encoded, I assume two
853 				   octet unsigned integers for each channel. */
854 
855 				if (ie_len < ptr + ulen * 2) {
856 					ND_PRINT(" [ERROR: Truncated in Channel offset bitmap]");
857 					break;
858 				}
859 				for(i = 0; i < ulen; i++) {
860 					ND_PRINT("%02x ",
861 						 GET_LE_U_2(p + ptr + i * 2));
862 				}
863 				ND_PRINT("]");
864 				ptr += ulen * 2;
865 			}
866 		}
867 		break;
868 	case 0x1d: /* Rendezvous Tome IE */
869 		if (ie_len != 4) {
870 			ND_PRINT("[ERROR: Length != 2]");
871 		} else {
872 			uint16_t r_time, w_u_interval;
873 			r_time = GET_LE_U_2(p);
874 			w_u_interval = GET_LE_U_2(p + 2);
875 
876 			ND_PRINT("Rendezvous time = %d, Wake-up Interval = %d",
877 				 r_time, w_u_interval);
878 		}
879 		break;
880 	case 0x1e: /* Time correction IE */
881 		if (ie_len != 2) {
882 			ND_PRINT("[ERROR: Length != 2]");
883 		} else {
884 			uint16_t val;
885 			int16_t timecorr;
886 
887 			val = GET_LE_U_2(p);
888 			if (val & 0x8000) { ND_PRINT("Negative "); }
889 			val &= 0xfff;
890 			val <<= 4;
891 			timecorr = val;
892 			timecorr >>= 4;
893 
894 			ND_PRINT("Ack time correction = %d, ", timecorr);
895 		}
896 		break;
897 	case 0x22: /* Fragment Sequence Content Description IE */
898 		/* XXX Not implemented */
899 	case 0x23: /* Simplified Superframe Specification IE */
900 		/* XXX Not implemented */
901 	case 0x24: /* Simplified GTS Specification IE */
902 		/* XXX Not implemented */
903 	case 0x25: /* LECIM Capabilities IE */
904 		/* XXX Not implemented */
905 	case 0x26: /* TRLE Descriptor IE */
906 		/* XXX Not implemented */
907 	case 0x27: /* RCC Capabilities IE */
908 		/* XXX Not implemented */
909 	case 0x28: /* RCCN Descriptor IE */
910 		/* XXX Not implemented */
911 	case 0x29: /* Global Time IE */
912 		/* XXX Not implemented */
913 	case 0x2b: /* DA IE */
914 		/* XXX Not implemented */
915 	default:
916 		ND_PRINT("IE Data = ");
917 		for(i = 0; i < ie_len; i++) {
918 			ND_PRINT("%02x ", GET_U_1(p + i));
919 		}
920 		break;
921 	}
922 }
923 
924 /*
925  * Parse and print Header IE list. See 7.4.2 of 802.15.4-2015 for
926  * more information.
927  *
928  * Returns number of byts consumed from the packet or -1 in case of error.
929  */
930 static int
931 ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
932 				  const u_char *p,
933 				  u_int caplen,
934 				  int *payload_ie_present)
935 {
936 	int len, ie, element_id, i;
937 	uint16_t ie_len;
938 
939 	*payload_ie_present = 0;
940 	len = 0;
941 	do {
942 		if (caplen < 2) {
943 			ND_PRINT("[ERROR: Truncated header IE]");
944 			return -1;
945 		}
946 		/* Extract IE Header */
947 		ie = GET_LE_U_2(p);
948 		if (CHECK_BIT(ie, 15)) {
949 			ND_PRINT("[ERROR: Header IE with type 1] ");
950 		}
951 		/* Get length and Element ID */
952 		ie_len = ie & 0x7f;
953 		element_id = (ie >> 7) & 0xff;
954 		if (element_id > 127) {
955 			ND_PRINT("Reserved Element ID %02x, length = %d ",
956 				 element_id, ie_len);
957 		} else {
958 			if (ie_len == 0) {
959 				ND_PRINT("\n\t%s [", h_ie_names[element_id]);
960 			} else {
961 				ND_PRINT("\n\t%s [ length = %d, ",
962 					 h_ie_names[element_id], ie_len);
963 			}
964 		}
965 		if (caplen < 2U + ie_len) {
966 			ND_PRINT("[ERROR: Truncated IE data]");
967 			return -1;
968 		}
969 		/* Skip header */
970 		p += 2;
971 
972 		/* Parse and print content. */
973 		if (ndo->ndo_vflag > 3 && ie_len != 0) {
974 			ieee802_15_4_print_header_ie(ndo, p,
975 						     ie_len, element_id);
976 		} else {
977 			if (ie_len != 0) {
978 				ND_PRINT("IE Data = ");
979 				for(i = 0; i < ie_len; i++) {
980 					ND_PRINT("%02x ", GET_U_1(p + i));
981 				}
982 			}
983 		}
984 		ND_PRINT("] ");
985 		len += 2 + ie_len;
986 		p += ie_len;
987 		caplen -= 2 + ie_len;
988 		if (element_id == 0x7e) {
989 			*payload_ie_present = 1;
990 			break;
991 		}
992 		if (element_id == 0x7f) {
993 			break;
994 		}
995 	} while (caplen != 0);
996 	return len;
997 }
998 
999 /*
1000  * Print MLME ie content.
1001  */
1002 static void
1003 ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
1004 			   const u_char *p,
1005 			   uint16_t sub_ie_len,
1006 			   int sub_id)
1007 {
1008 	int i, j;
1009 	uint16_t len;
1010 
1011 	/* Note, as there is no overlap with the long and short
1012 	   MLME sub IDs, we can just use one switch here. */
1013 	switch (sub_id) {
1014 	case 0x08: /* Vendor Specific Nested IE */
1015 		if (sub_ie_len < 3) {
1016 			ND_PRINT("[ERROR: Vendor OUI missing]");
1017 		} else {
1018 			ND_PRINT("OUI = 0x%02x%02x%02x, ",
1019 				 GET_U_1(p),
1020 				 GET_U_1(p + 1),
1021 				 GET_U_1(p + 2));
1022 			ND_PRINT("Data = ");
1023 			for(i = 3; i < sub_ie_len; i++) {
1024 				ND_PRINT("%02x ", GET_U_1(p + i));
1025 			}
1026 		}
1027 		break;
1028 	case 0x09: /* Channel Hopping IE */
1029 		if (sub_ie_len < 1) {
1030 			ND_PRINT("[ERROR: Hopping sequence ID missing]");
1031 		} else if (sub_ie_len == 1) {
1032 			ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p));
1033 			p++;
1034 			sub_ie_len--;
1035 		} else {
1036 			uint16_t channel_page, number_of_channels;
1037 
1038 			ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p));
1039 			p++;
1040 			sub_ie_len--;
1041 			if (sub_ie_len < 7) {
1042 				ND_PRINT("[ERROR: IE truncated]");
1043 				break;
1044 			}
1045 			channel_page = GET_U_1(p);
1046 			number_of_channels = GET_LE_U_2(p + 1);
1047 			ND_PRINT("Channel Page = %d, Number of Channels = %d, ",
1048 				 channel_page, number_of_channels);
1049 			ND_PRINT("Phy Configuration = 0x%08x, ",
1050 				 GET_LE_U_4(p + 3));
1051 			p += 7;
1052 			sub_ie_len -= 7;
1053 			if (channel_page == 9 || channel_page == 10) {
1054 				len = (number_of_channels + 7) / 8;
1055 				if (sub_ie_len < len) {
1056 					ND_PRINT("[ERROR: IE truncated]");
1057 					break;
1058 				}
1059 				ND_PRINT("Extended bitmap = 0x");
1060 				for(i = 0; i < len; i++) {
1061 					ND_PRINT("%02x", GET_U_1(p + i));
1062 				}
1063 				ND_PRINT(", ");
1064 				p += len;
1065 				sub_ie_len -= len;
1066 			}
1067 			if (sub_ie_len < 2) {
1068 				ND_PRINT("[ERROR: IE truncated]");
1069 				break;
1070 			}
1071 			len = GET_LE_U_2(p);
1072 			p += 2;
1073 			sub_ie_len -= 2;
1074 			ND_PRINT("Hopping Seq length = %d [ ", len);
1075 
1076 			if (sub_ie_len < len * 2) {
1077 				ND_PRINT(" [ERROR: IE truncated]");
1078 				break;
1079 			}
1080 			for(i = 0; i < len; i++) {
1081 				ND_PRINT("%02x ", GET_LE_U_2(p + i * 2));
1082 			}
1083 			ND_PRINT("]");
1084 			p += len * 2;
1085 			sub_ie_len -= len * 2;
1086 			if (sub_ie_len < 2) {
1087 				ND_PRINT("[ERROR: IE truncated]");
1088 				break;
1089 			}
1090 			ND_PRINT("Current hop = %d", GET_LE_U_2(p));
1091 		}
1092 
1093 		break;
1094 	case 0x1a: /* TSCH Synchronization IE. */
1095 		if (sub_ie_len < 6) {
1096 			ND_PRINT("[ERROR: Length != 6]");
1097 		}
1098 		ND_PRINT("ASN = %010" PRIx64 ", Join Metric = %d ",
1099 			 GET_LE_U_5(p), GET_U_1(p + 5));
1100 		break;
1101 	case 0x1b: /* TSCH Slotframe and Link IE. */
1102 		{
1103 			int sf_num, off, links, opts;
1104 
1105 			if (sub_ie_len < 1) {
1106 				ND_PRINT("[ERROR: Truncated IE]");
1107 				break;
1108 			}
1109 			sf_num = GET_U_1(p);
1110 			ND_PRINT("Slotframes = %d ", sf_num);
1111 			off = 1;
1112 			for(i = 0; i < sf_num; i++) {
1113 				if (sub_ie_len < off + 4) {
1114 					ND_PRINT("[ERROR: Truncated IE before slotframes]");
1115 					break;
1116 				}
1117 				links = GET_U_1(p + off + 3);
1118 				ND_PRINT("\n\t\t\t[ Handle %d, size = %d, links = %d ",
1119 					 GET_U_1(p + off),
1120 					 GET_LE_U_2(p + off + 1),
1121 					 links);
1122 				off += 4;
1123 				for(j = 0; j < links; j++) {
1124 					if (sub_ie_len < off + 5) {
1125 						ND_PRINT("[ERROR: Truncated IE links]");
1126 						break;
1127 					}
1128 					opts = GET_U_1(p + off + 4);
1129 					ND_PRINT("\n\t\t\t\t[ Timeslot =  %d, Offset = %d, Options = ",
1130 						 GET_LE_U_2(p + off),
1131 						 GET_LE_U_2(p + off + 2));
1132 					if (opts & 0x1) { ND_PRINT("TX "); }
1133 					if (opts & 0x2) { ND_PRINT("RX "); }
1134 					if (opts & 0x4) { ND_PRINT("Shared "); }
1135 					if (opts & 0x8) {
1136 						ND_PRINT("Timekeeping ");
1137 					}
1138 					if (opts & 0x10) {
1139 						ND_PRINT("Priority ");
1140 					}
1141 					off += 5;
1142 					ND_PRINT("] ");
1143 				}
1144 				ND_PRINT("] ");
1145 			}
1146 		}
1147 		break;
1148 	case 0x1c: /* TSCH Timeslot IE. */
1149 		if (sub_ie_len == 1) {
1150 			ND_PRINT("Time slot ID = %d ", GET_U_1(p));
1151 		} else if (sub_ie_len == 25) {
1152 			ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ",
1153 				 GET_U_1(p),
1154 				 GET_LE_U_2(p + 1),
1155 				 GET_LE_U_2(p + 3),
1156 				 GET_LE_U_2(p + 5),
1157 				 GET_LE_U_2(p + 7),
1158 				 GET_LE_U_2(p + 9),
1159 				 GET_LE_U_2(p + 11),
1160 				 GET_LE_U_2(p + 13),
1161 				 GET_LE_U_2(p + 15),
1162 				 GET_LE_U_2(p + 17),
1163 				 GET_LE_U_2(p + 19),
1164 				 GET_LE_U_2(p + 21),
1165 				 GET_LE_U_2(p + 23));
1166 		} else if (sub_ie_len == 27) {
1167 			ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ",
1168 				 GET_U_1(p),
1169 				 GET_LE_U_2(p + 1),
1170 				 GET_LE_U_2(p + 3),
1171 				 GET_LE_U_2(p + 5),
1172 				 GET_LE_U_2(p + 7),
1173 				 GET_LE_U_2(p + 9),
1174 				 GET_LE_U_2(p + 11),
1175 				 GET_LE_U_2(p + 13),
1176 				 GET_LE_U_2(p + 15),
1177 				 GET_LE_U_2(p + 17),
1178 				 GET_LE_U_2(p + 19),
1179 				 GET_LE_U_3(p + 21),
1180 				 GET_LE_U_3(p + 24));
1181 		} else {
1182 			ND_PRINT("[ERROR: Length not 1, 25, or 27]");
1183 			ND_PRINT("\n\t\t\tIE Data = ");
1184 			for(i = 0; i < sub_ie_len; i++) {
1185 				ND_PRINT("%02x ", GET_U_1(p + i));
1186 			}
1187 		}
1188 		break;
1189 	case 0x1d: /* Hopping timing IE */
1190 		/* XXX Not implemented */
1191 	case 0x1e: /* Enhanced Beacon Filter IE */
1192 		/* XXX Not implemented */
1193 	case 0x1f: /* MAC Metrics IE */
1194 		/* XXX Not implemented */
1195 	case 0x20: /* All MAC Metrics IE */
1196 		/* XXX Not implemented */
1197 	case 0x21: /* Coexistence Specification IE */
1198 		/* XXX Not implemented */
1199 	case 0x22: /* SUN Device Capabilities IE */
1200 		/* XXX Not implemented */
1201 	case 0x23: /* SUN FSK Generic PHY IE */
1202 		/* XXX Not implemented */
1203 	case 0x24: /* Mode Switch Parameter IE */
1204 		/* XXX Not implemented */
1205 	case 0x25: /* PHY Parameter Change IE */
1206 		/* XXX Not implemented */
1207 	case 0x26: /* O-QPSK PHY Mode IE */
1208 		/* XXX Not implemented */
1209 	case 0x27: /* PCA Allocation IE */
1210 		/* XXX Not implemented */
1211 	case 0x28: /* LECIM DSSS Operating Mode IE */
1212 		/* XXX Not implemented */
1213 	case 0x29: /* LECIM FSK Operating Mode IE */
1214 		/* XXX Not implemented */
1215 	case 0x2b: /* TVWS PHY Operating Mode Description IE */
1216 		/* XXX Not implemented */
1217 	case 0x2c: /* TVWS Device Capabilities IE */
1218 		/* XXX Not implemented */
1219 	case 0x2d: /* TVWS Device Category IE */
1220 		/* XXX Not implemented */
1221 	case 0x2e: /* TVWS Device Identification IE */
1222 		/* XXX Not implemented */
1223 	case 0x2f: /* TVWS Device Location IE */
1224 		/* XXX Not implemented */
1225 	case 0x30: /* TVWS Channel Information Query IE */
1226 		/* XXX Not implemented */
1227 	case 0x31: /* TVWS Channel Information Source IE */
1228 		/* XXX Not implemented */
1229 	case 0x32: /* CTM IE */
1230 		/* XXX Not implemented */
1231 	case 0x33: /* Timestamp IE */
1232 		/* XXX Not implemented */
1233 	case 0x34: /* Timestamp Difference IE */
1234 		/* XXX Not implemented */
1235 	case 0x35: /* TMCTP Specification IE */
1236 		/* XXX Not implemented */
1237 	case 0x36: /* TCC PHY Operating Mode IE */
1238 		/* XXX Not implemented */
1239 	default:
1240 		ND_PRINT("IE Data = ");
1241 		for(i = 0; i < sub_ie_len; i++) {
1242 			ND_PRINT("%02x ", GET_U_1(p + i));
1243 		}
1244 		break;
1245 	}
1246 }
1247 
1248 /*
1249  * MLME IE list parsing and printing. See 7.4.3.2 of 802.15.4-2015
1250  * for more information.
1251  */
1252 static void
1253 ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
1254 				const u_char *p,
1255 				uint16_t ie_len)
1256 {
1257 	int ie, sub_id, i, type;
1258 	uint16_t sub_ie_len;
1259 
1260 	do {
1261 		if (ie_len < 2) {
1262 			ND_PRINT("[ERROR: Truncated MLME IE]");
1263 			return;
1264 		}
1265 		/* Extract IE header */
1266 		ie = GET_LE_U_2(p);
1267 		type = CHECK_BIT(ie, 15);
1268 		if (type) {
1269 			/* Long type */
1270 			sub_ie_len = ie & 0x3ff;
1271 			sub_id = (ie >> 11) & 0x0f;
1272 		} else {
1273 			sub_ie_len = ie & 0xff;
1274 			sub_id = (ie >> 8) & 0x7f;
1275 		}
1276 
1277 		/* Skip the IE header */
1278 		p += 2;
1279 
1280 		if (type == 0) {
1281 			ND_PRINT("\n\t\t%s [ length = %d, ",
1282 				 p_mlme_short_names[sub_id], sub_ie_len);
1283 		} else {
1284 			ND_PRINT("\n\t\t%s [ length = %d, ",
1285 				 p_mlme_long_names[sub_id], sub_ie_len);
1286 		}
1287 
1288 		if (ie_len < 2 + sub_ie_len) {
1289 			ND_PRINT("[ERROR: Truncated IE data]");
1290 			return;
1291 		}
1292 		if (sub_ie_len != 0) {
1293 			if (ndo->ndo_vflag > 3) {
1294 				ieee802_15_4_print_mlme_ie(ndo, p, sub_ie_len, sub_id);
1295 			} else if (ndo->ndo_vflag > 2) {
1296 				ND_PRINT("IE Data = ");
1297 				for(i = 0; i < sub_ie_len; i++) {
1298 					ND_PRINT("%02x ", GET_U_1(p + i));
1299 				}
1300 			}
1301 		}
1302 		ND_PRINT("] ");
1303 		p += sub_ie_len;
1304 		ie_len -= 2 + sub_ie_len;
1305 	} while (ie_len != 0);
1306 }
1307 
1308 /*
1309  * Multiplexed IE (802.15.9) parsing and printing.
1310  *
1311  * Returns number of bytes consumed from packet or -1 in case of error.
1312  */
1313 static void
1314 ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
1315 			  const u_char *p,
1316 			  uint16_t ie_len)
1317 {
1318 	int transfer_type, tid;
1319 	int fragment_number, data_start;
1320 	int i;
1321 
1322 	data_start = 0;
1323 	if (ie_len < 1) {
1324 		ND_PRINT("[ERROR: Transaction control byte missing]");
1325 		return;
1326 	}
1327 
1328 	transfer_type = GET_U_1(p) & 0x7;
1329 	tid = GET_U_1(p) >> 3;
1330 	switch (transfer_type) {
1331 	case 0x00: /* Full upper layer frame. */
1332 	case 0x01: /* Full upper layer frame with small Multiplex ID. */
1333 		ND_PRINT("Type = Full upper layer fragment%s, ",
1334 			 (transfer_type == 0x01 ?
1335 			  " with small Multiplex ID" : ""));
1336 		if (transfer_type == 0x00) {
1337 			if (ie_len < 3) {
1338 				ND_PRINT("[ERROR: Multiplex ID missing]");
1339 				return;
1340 			}
1341 			data_start = 3;
1342 			ND_PRINT("tid = 0x%02x, Multiplex ID = 0x%04x, ",
1343 				 tid, GET_LE_U_2(p + 1));
1344 		} else {
1345 			data_start = 1;
1346 			ND_PRINT("Multiplex ID = 0x%04x, ", tid);
1347 		}
1348 		break;
1349 	case 0x02: /* First, or middle, Fragments */
1350 	case 0x04: /* Last fragment */
1351 		if (ie_len < 2) {
1352 			ND_PRINT("[ERROR: fragment number missing]");
1353 			return;
1354 		}
1355 
1356 		fragment_number = GET_U_1(p + 1);
1357 		ND_PRINT("Type = %s, tid = 0x%02x, fragment = 0x%02x, ",
1358 			 (transfer_type == 0x02 ?
1359 			  (fragment_number == 0 ?
1360 			   "First fragment" : "Middle fragment") :
1361 			  "Last fragment"), tid,
1362 			 fragment_number);
1363 		data_start = 2;
1364 		if (fragment_number == 0) {
1365 			int total_size, multiplex_id;
1366 
1367 			if (ie_len < 6) {
1368 				ND_PRINT("[ERROR: Total upper layer size or multiplex ID missing]");
1369 				return;
1370 			}
1371 			total_size = GET_LE_U_2(p + 2);
1372 			multiplex_id = GET_LE_U_2(p + 4);
1373 			ND_PRINT("Total upper layer size = 0x%04x, Multiplex ID = 0x%04x, ",
1374 				 total_size, multiplex_id);
1375 			data_start = 6;
1376 		}
1377 		break;
1378 	case 0x06: /* Abort code */
1379 		if (ie_len == 1) {
1380 			ND_PRINT("Type = Abort, tid = 0x%02x, no max size given",
1381 				 tid);
1382 		} else if (ie_len == 3) {
1383 			ND_PRINT("Type = Abort, tid = 0x%02x, max size = 0x%04x",
1384 				 tid, GET_LE_U_2(p + 1));
1385 		} else {
1386 			ND_PRINT("Type = Abort, tid = 0x%02x, invalid length = %d (not 1 or 3)",
1387 				 tid, ie_len);
1388 			ND_PRINT("Abort data = ");
1389 			for(i = 1; i < ie_len; i++) {
1390 				ND_PRINT("%02x ", GET_U_1(p + i));
1391 			}
1392 		}
1393 		return;
1394 		/* NOTREACHED */
1395 		break;
1396 	case 0x03: /* Reserved */
1397 	case 0x05: /* Reserved */
1398 	case 0x07: /* Reserved */
1399 		ND_PRINT("Type = %d (Reserved), tid = 0x%02x, ",
1400 			 transfer_type, tid);
1401 		data_start = 1;
1402 		break;
1403 	}
1404 
1405 	ND_PRINT("Upper layer data = ");
1406 	for(i = data_start; i < ie_len; i++) {
1407 		ND_PRINT("%02x ", GET_U_1(p + i));
1408 	}
1409 }
1410 
1411 /*
1412  * Payload IE list parsing and printing. See 7.4.3 of 802.15.4-2015
1413  * for more information.
1414  *
1415  * Returns number of byts consumed from the packet or -1 in case of error.
1416  */
1417 static int
1418 ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
1419 				   const u_char *p,
1420 				   u_int caplen)
1421 {
1422 	int len, ie, group_id, i;
1423 	uint16_t ie_len;
1424 
1425 	len = 0;
1426 	do {
1427 		if (caplen < 2) {
1428 			ND_PRINT("[ERROR: Truncated header IE]");
1429 			return -1;
1430 		}
1431 		/* Extract IE header */
1432 		ie = GET_LE_U_2(p);
1433 		if ((CHECK_BIT(ie, 15)) == 0) {
1434 			ND_PRINT("[ERROR: Payload IE with type 0] ");
1435 		}
1436 		ie_len = ie & 0x3ff;
1437 		group_id = (ie >> 11) & 0x0f;
1438 
1439 		/* Skip the IE header */
1440 		p += 2;
1441 		if (ie_len == 0) {
1442 			ND_PRINT("\n\t%s [", p_ie_names[group_id]);
1443 		} else {
1444 			ND_PRINT("\n\t%s [ length = %d, ",
1445 				 p_ie_names[group_id], ie_len);
1446 		}
1447 		if (caplen < 2U + ie_len) {
1448 			ND_PRINT("[ERROR: Truncated IE data]");
1449 			return -1;
1450 		}
1451 		if (ndo->ndo_vflag > 3 && ie_len != 0) {
1452 			switch (group_id) {
1453 			case 0x1: /* MLME IE */
1454 				ieee802_15_4_print_mlme_ie_list(ndo, p, ie_len);
1455 				break;
1456 			case 0x2: /* Vendor Specific Nested IE */
1457 				if (ie_len < 3) {
1458 					ND_PRINT("[ERROR: Vendor OUI missing]");
1459 				} else {
1460 					ND_PRINT("OUI = 0x%02x%02x%02x, ",
1461 						 GET_U_1(p),
1462 						 GET_U_1(p + 1),
1463 						 GET_U_1(p + 2));
1464 					ND_PRINT("Data = ");
1465 					for(i = 3; i < ie_len; i++) {
1466 						ND_PRINT("%02x ",
1467 							 GET_U_1(p + i));
1468 					}
1469 				}
1470 				break;
1471 			case 0x3: /* Multiplexed IE (802.15.9) */
1472 				ieee802_15_4_print_mpx_ie(ndo, p, ie_len);
1473 				break;
1474 			case 0x5: /* IETF IE */
1475 				if (ie_len < 1) {
1476 					ND_PRINT("[ERROR: Subtype ID missing]");
1477 				} else {
1478 					ND_PRINT("Subtype ID = 0x%02x, Subtype content = ",
1479 						 GET_U_1(p));
1480 					for(i = 1; i < ie_len; i++) {
1481 						ND_PRINT("%02x ",
1482 							 GET_U_1(p + i));
1483 					}
1484 				}
1485 				break;
1486 			default:
1487 				ND_PRINT("IE Data = ");
1488 				for(i = 0; i < ie_len; i++) {
1489 					ND_PRINT("%02x ", GET_U_1(p + i));
1490 				}
1491 				break;
1492 			}
1493 		} else {
1494 			if (ie_len != 0) {
1495 				ND_PRINT("IE Data = ");
1496 				for(i = 0; i < ie_len; i++) {
1497 					ND_PRINT("%02x ", GET_U_1(p + i));
1498 				}
1499 			}
1500 		}
1501 		ND_PRINT("]\n\t");
1502 		len += 2 + ie_len;
1503 		p += ie_len;
1504 		caplen -= 2 + ie_len;
1505 		if (group_id == 0xf) {
1506 			break;
1507 		}
1508 	} while (caplen != 0);
1509 	return len;
1510 }
1511 
1512 /*
1513  * Parse and print auxiliary security header.
1514  *
1515  * Returns number of byts consumed from the packet or -1 in case of error.
1516  */
1517 static int
1518 ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
1519 				  const u_char *p,
1520 				  u_int caplen,
1521 				  int *security_level)
1522 {
1523 	int sc, key_id_mode, len;
1524 
1525 	if (caplen < 1) {
1526 		ND_PRINT("[ERROR: Truncated before Aux Security Header]");
1527 		return -1;
1528 	}
1529 	sc = GET_U_1(p);
1530 	len = 1;
1531 	*security_level = sc & 0x7;
1532 	key_id_mode = (sc >> 3) & 0x3;
1533 
1534 	caplen -= 1;
1535 	p += 1;
1536 
1537 	if (ndo->ndo_vflag > 0) {
1538 		ND_PRINT("\n\tSecurity Level %d, Key Id Mode %d, ",
1539 			 *security_level, key_id_mode);
1540 	}
1541 	if ((CHECK_BIT(sc, 5)) == 0) {
1542 		if (caplen < 4) {
1543 			ND_PRINT("[ERROR: Truncated before Frame Counter]");
1544 			return -1;
1545 		}
1546 		if (ndo->ndo_vflag > 1) {
1547 			ND_PRINT("Frame Counter 0x%08x ",
1548 				 GET_LE_U_4(p));
1549 		}
1550 		p += 4;
1551 		caplen -= 4;
1552 		len += 4;
1553 	}
1554 	switch (key_id_mode) {
1555 	case 0x00: /* Implicit. */
1556 		if (ndo->ndo_vflag > 1) {
1557 			ND_PRINT("Implicit");
1558 		}
1559 		return len;
1560 		break;
1561 	case 0x01: /* Key Index, nothing to print here. */
1562 		break;
1563 	case 0x02: /* PAN and Short address Key Source, and Key Index. */
1564 		if (caplen < 4) {
1565 			ND_PRINT("[ERROR: Truncated before Key Source]");
1566 			return -1;
1567 		}
1568 		if (ndo->ndo_vflag > 1) {
1569 			ND_PRINT("KeySource 0x%04x:%0x4x, ",
1570 				 GET_LE_U_2(p), GET_LE_U_2(p + 2));
1571 		}
1572 		p += 4;
1573 		caplen -= 4;
1574 		len += 4;
1575 		break;
1576 	case 0x03: /* Extended address and Key Index. */
1577 		if (caplen < 8) {
1578 			ND_PRINT("[ERROR: Truncated before Key Source]");
1579 			return -1;
1580 		}
1581 		if (ndo->ndo_vflag > 1) {
1582 			ND_PRINT("KeySource %s, ", GET_LE64ADDR_STRING(p));
1583 		}
1584 		p += 4;
1585 		caplen -= 4;
1586 		len += 4;
1587 		break;
1588 	}
1589 	if (caplen < 1) {
1590 		ND_PRINT("[ERROR: Truncated before Key Index]");
1591 		return -1;
1592 	}
1593 	if (ndo->ndo_vflag > 1) {
1594 		ND_PRINT("KeyIndex 0x%02x, ", GET_U_1(p));
1595 	}
1596 	caplen -= 1;
1597 	p += 1;
1598 	len += 1;
1599 	return len;
1600 }
1601 
1602 /*
1603  * Print command data.
1604  *
1605  * Returns number of byts consumed from the packet or -1 in case of error.
1606  */
1607 static int
1608 ieee802_15_4_print_command_data(netdissect_options *ndo,
1609 				uint8_t command_id,
1610 				const u_char *p,
1611 				u_int caplen)
1612 {
1613 	u_int i;
1614 
1615 	switch (command_id) {
1616 	case 0x01: /* Association Request */
1617 		if (caplen != 1) {
1618 			ND_PRINT("Invalid Association request command length");
1619 			return -1;
1620 		} else {
1621 			uint8_t cap_info;
1622 			cap_info = GET_U_1(p);
1623 			ND_PRINT("%s%s%s%s%s%s",
1624 				 ((cap_info & 0x02) ?
1625 				  "FFD, " : "RFD, "),
1626 				 ((cap_info & 0x04) ?
1627 				  "AC powered, " : ""),
1628 				 ((cap_info & 0x08) ?
1629 				  "Receiver on when idle, " : ""),
1630 				 ((cap_info & 0x10) ?
1631 				  "Fast association, " : ""),
1632 				 ((cap_info & 0x40) ?
1633 				  "Security supported, " : ""),
1634 				 ((cap_info & 0x80) ?
1635 				  "Allocate address, " : ""));
1636 			return caplen;
1637 		}
1638 		break;
1639 	case 0x02: /* Association Response */
1640 		if (caplen != 3) {
1641 			ND_PRINT("Invalid Association response command length");
1642 			return -1;
1643 		} else {
1644 			ND_PRINT("Short address = ");
1645 			ieee802_15_4_print_addr(ndo, p, 2);
1646 			switch (GET_U_1(p + 2)) {
1647 			case 0x00:
1648 				ND_PRINT(", Association successful");
1649 				break;
1650 			case 0x01:
1651 				ND_PRINT(", PAN at capacity");
1652 				break;
1653 			case 0x02:
1654 				ND_PRINT(", PAN access denied");
1655 				break;
1656 			case 0x03:
1657 				ND_PRINT(", Hooping sequence offset duplication");
1658 				break;
1659 			case 0x80:
1660 				ND_PRINT(", Fast association successful");
1661 				break;
1662 			default:
1663 				ND_PRINT(", Status = 0x%02x",
1664 					 GET_U_1(p + 2));
1665 				break;
1666 			}
1667 			return caplen;
1668 		}
1669 		break;
1670 	case 0x03: /* Disassociation Notification command */
1671 		if (caplen != 1) {
1672 			ND_PRINT("Invalid Disassociation Notification command length");
1673 			return -1;
1674 		} else {
1675 			switch (GET_U_1(p)) {
1676 			case 0x00:
1677 				ND_PRINT("Reserved");
1678 				break;
1679 			case 0x01:
1680 				ND_PRINT("Reason = The coordinator wishes the device to leave PAN");
1681 				break;
1682 			case 0x02:
1683 				ND_PRINT("Reason = The device wishes to leave the PAN");
1684 				break;
1685 			default:
1686 				ND_PRINT("Reason = 0x%02x", GET_U_1(p + 2));
1687 				break;
1688 			}
1689 			return caplen;
1690 		}
1691 
1692 		/* Following ones do not have any data. */
1693 	case 0x04: /* Data Request command */
1694 	case 0x05: /* PAN ID Conflict Notification command */
1695 	case 0x06: /* Orphan Notification command */
1696 	case 0x07: /* Beacon Request command */
1697 		/* Should not have any data. */
1698 		return 0;
1699 	case 0x08: /* Coordinator Realignment command */
1700 		if (caplen < 7 || caplen > 8) {
1701 			ND_PRINT("Invalid Coordinator Realignment command length");
1702 			return -1;
1703 		} else {
1704 			uint16_t channel, page;
1705 
1706 			ND_PRINT("Pan ID = 0x%04x, Coordinator short address = ",
1707 				 GET_LE_U_2(p));
1708 			ieee802_15_4_print_addr(ndo, p + 2, 2);
1709 			channel = GET_U_1(p + 4);
1710 
1711 			if (caplen == 8) {
1712 				page = GET_U_1(p + 7);
1713 			} else {
1714 				page = 0x80;
1715 			}
1716 			if (CHECK_BIT(page, 7)) {
1717 				/* No page present, instead we have msb of
1718 				   channel in the page. */
1719 				channel |= (page & 0x7f) << 8;
1720 				ND_PRINT(", Channel Number = %d", channel);
1721 			} else {
1722 				ND_PRINT(", Channel Number = %d, page = %d",
1723 					 channel, page);
1724 			}
1725 			ND_PRINT(", Short address = ");
1726 			ieee802_15_4_print_addr(ndo, p + 5, 2);
1727 			return caplen;
1728 		}
1729 		break;
1730 	case 0x09: /* GTS Request command */
1731 		if (caplen != 1) {
1732 			ND_PRINT("Invalid GTS Request command length");
1733 			return -1;
1734 		} else {
1735 			uint8_t gts;
1736 
1737 			gts = GET_U_1(p);
1738 			ND_PRINT("GTS Length = %d, %s, %s",
1739 				 gts & 0xf,
1740 				 (CHECK_BIT(gts, 4) ?
1741 				  "Receive-only GTS" : "Transmit-only GTS"),
1742 				 (CHECK_BIT(gts, 5) ?
1743 				  "GTS allocation" : "GTS deallocations"));
1744 			return caplen;
1745 		}
1746 		break;
1747 	case 0x13: /* DSME Association Request command */
1748 		/* XXX Not implemented */
1749 	case 0x14: /* DSME Association Response command */
1750 		/* XXX Not implemented */
1751 	case 0x15: /* DSME GTS Request command */
1752 		/* XXX Not implemented */
1753 	case 0x16: /* DSME GTS Response command */
1754 		/* XXX Not implemented */
1755 	case 0x17: /* DSME GTS Notify command */
1756 		/* XXX Not implemented */
1757 	case 0x18: /* DSME Information Request command */
1758 		/* XXX Not implemented */
1759 	case 0x19: /* DSME Information Response command */
1760 		/* XXX Not implemented */
1761 	case 0x1a: /* DSME Beacon Allocation Notification command */
1762 		/* XXX Not implemented */
1763 	case 0x1b: /* DSME Beacon Collision Notification command */
1764 		/* XXX Not implemented */
1765 	case 0x1c: /* DSME Link Report command */
1766 		/* XXX Not implemented */
1767 	case 0x20: /* RIT Data Request command */
1768 		/* XXX Not implemented */
1769 	case 0x21: /* DBS Request command */
1770 		/* XXX Not implemented */
1771 	case 0x22: /* DBS Response command */
1772 		/* XXX Not implemented */
1773 	case 0x23: /* RIT Data Response command */
1774 		/* XXX Not implemented */
1775 	case 0x24: /* Vendor Specific command */
1776 		/* XXX Not implemented */
1777 	case 0x0a: /* TRLE Management Request command */
1778 		/* XXX Not implemented */
1779 	case 0x0b: /* TRLE Management Response command */
1780 		/* XXX Not implemented */
1781 	default:
1782 		ND_PRINT("Command Data = ");
1783 		for(i = 0; i < caplen; i++) {
1784 			ND_PRINT("%02x ", GET_U_1(p + i));
1785 		}
1786 		break;
1787 	}
1788 	return 0;
1789 }
1790 
1791 /*
1792  * Parse and print frames following standard format.
1793  *
1794  * Returns FALSE in case of error.
1795  */
1796 static u_int
1797 ieee802_15_4_std_frames(netdissect_options *ndo,
1798 			const u_char *p, u_int caplen,
1799 			uint16_t fc)
1800 {
1801 	int len, frame_version, pan_id_comp;
1802 	int frame_type;
1803 	int src_pan, dst_pan, src_addr_len, dst_addr_len;
1804 	int security_level;
1805 	u_int miclen = 0;
1806 	int payload_ie_present;
1807 	uint8_t seq;
1808 	uint32_t fcs, crc_check;
1809 	const u_char *mic_start = NULL;
1810 
1811 	payload_ie_present = 0;
1812 
1813 	crc_check = 0;
1814 	/* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
1815 	   know about that. */
1816 	if (caplen < 4) {
1817 		/* Cannot have FCS, assume no FCS. */
1818 		fcs = 0;
1819 	} else {
1820 		/* Test for 4 octet FCS. */
1821 		fcs = GET_LE_U_4(p + caplen - 4);
1822 		crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4);
1823 		if (crc_check == fcs) {
1824 			/* Remove FCS */
1825 			caplen -= 4;
1826 		} else {
1827 			/* Test for 2 octet FCS. */
1828 			fcs = GET_LE_U_2(p + caplen - 2);
1829 			crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
1830 			if (crc_check == fcs) {
1831 				/* Remove FCS */
1832 				caplen -= 2;
1833 			} else {
1834 				/* Wrong FCS, FCS might not be included in the
1835 				   captured frame, do not remove it. */
1836 			}
1837 		}
1838 	}
1839 
1840 	/* Frame version. */
1841 	frame_version = FC_FRAME_VERSION(fc);
1842 	frame_type = FC_FRAME_TYPE(fc);
1843 	ND_PRINT("v%d ", frame_version);
1844 
1845 	if (ndo->ndo_vflag > 2) {
1846 		if (CHECK_BIT(fc, 3)) { ND_PRINT("Security Enabled, "); }
1847 		if (CHECK_BIT(fc, 4)) { ND_PRINT("Frame Pending, "); }
1848 		if (CHECK_BIT(fc, 5)) { ND_PRINT("AR, "); }
1849 		if (CHECK_BIT(fc, 6)) { ND_PRINT("PAN ID Compression, "); }
1850 		if (CHECK_BIT(fc, 8)) { ND_PRINT("Sequence Number Suppression, "); }
1851 		if (CHECK_BIT(fc, 9)) { ND_PRINT("IE present, "); }
1852 	}
1853 
1854 	/* Check for the sequence number suppression. */
1855 	if (CHECK_BIT(fc, 8)) {
1856 		/* Sequence number is suppressed. */
1857 		if (frame_version < 2) {
1858 			/* Sequence number can only be suppressed for frame
1859 			   version 2 or higher, this is invalid frame. */
1860 			ND_PRINT("[ERROR: Sequence number suppressed on frames where version < 2]");
1861 		}
1862 		if (ndo->ndo_vflag)
1863 			ND_PRINT("seq suppressed ");
1864 		if (caplen < 2) {
1865 			nd_print_trunc(ndo);
1866 			return 0;
1867 		}
1868 		p += 2;
1869 		caplen -= 2;
1870 	} else {
1871 		seq = GET_U_1(p + 2);
1872 		if (ndo->ndo_vflag)
1873 			ND_PRINT("seq %02x ", seq);
1874 		if (caplen < 3) {
1875 			nd_print_trunc(ndo);
1876 			return 0;
1877 		}
1878 		p += 3;
1879 		caplen -= 3;
1880 	}
1881 
1882 	/* See which parts of addresses we have. */
1883 	dst_addr_len = ieee802_15_4_addr_len((fc >> 10) & 0x3);
1884 	src_addr_len = ieee802_15_4_addr_len((fc >> 14) & 0x3);
1885 	if (src_addr_len < 0) {
1886 		ND_PRINT("[ERROR: Invalid src address mode]");
1887 		return 0;
1888 	}
1889 	if (dst_addr_len < 0) {
1890 		ND_PRINT("[ERROR: Invalid dst address mode]");
1891 		return 0;
1892 	}
1893 	src_pan = 0;
1894 	dst_pan = 0;
1895 	pan_id_comp = CHECK_BIT(fc, 6);
1896 
1897 	/* The PAN ID Compression rules are complicated. */
1898 
1899 	/* First check old versions, where the rules are simple. */
1900 	if (frame_version < 2) {
1901 		if (pan_id_comp) {
1902 			src_pan = 0;
1903 			dst_pan = 1;
1904 			if (dst_addr_len <= 0 || src_addr_len <= 0) {
1905 				/* Invalid frame, PAN ID Compression must be 0
1906 				   if only one address in the frame. */
1907 				ND_PRINT("[ERROR: PAN ID Compression != 0, and only one address with frame version < 2]");
1908 			}
1909 		} else {
1910 			src_pan = 1;
1911 			dst_pan = 1;
1912 		}
1913 		if (dst_addr_len <= 0) {
1914 			dst_pan = 0;
1915 		}
1916 		if (src_addr_len <= 0) {
1917 			src_pan = 0;
1918 		}
1919 	} else {
1920 		/* Frame version 2 rules are more complicated, and they depend
1921 		   on the address modes of the frame, generic rules are same,
1922 		   but then there are some special cases. */
1923 		if (pan_id_comp) {
1924 			src_pan = 0;
1925 			dst_pan = 1;
1926 		} else {
1927 			src_pan = 1;
1928 			dst_pan = 1;
1929 		}
1930 		if (dst_addr_len <= 0) {
1931 			dst_pan = 0;
1932 		}
1933 		if (src_addr_len <= 0) {
1934 			src_pan = 0;
1935 		}
1936 		if (pan_id_comp) {
1937 			if (src_addr_len == 0 &&
1938 			    dst_addr_len == 0) {
1939 				/* Both addresses are missing, but PAN ID
1940 				   compression set, special case we have
1941 				   destination PAN but no addresses. */
1942 				dst_pan = 1;
1943 			} else if ((src_addr_len == 0 &&
1944 				    dst_addr_len > 0) ||
1945 				   (src_addr_len > 0 &&
1946 				    dst_addr_len == 0)) {
1947 				/* Only one address present, and PAN ID
1948 				   compression is set, we do not have PAN id at
1949 				   all. */
1950 				dst_pan = 0;
1951 				src_pan = 0;
1952 			} else if (src_addr_len == 8 &&
1953 				   dst_addr_len == 8) {
1954 				/* Both addresses are Extended, and PAN ID
1955 				   compression set, we do not have PAN ID at
1956 				   all. */
1957 				dst_pan = 0;
1958 				src_pan = 0;
1959 			}
1960 		} else {
1961 			/* Special cases where PAN ID Compression is not set. */
1962 			if (src_addr_len == 8 &&
1963 			    dst_addr_len == 8) {
1964 				/* Both addresses are Extended, and PAN ID
1965 				   compression not set, we do have only one PAN
1966 				   ID (destination). */
1967 				dst_pan = 1;
1968 				src_pan = 0;
1969 			}
1970 #ifdef BROKEN_6TISCH_PAN_ID_COMPRESSION
1971 			if (src_addr_len == 8 &&
1972 			    dst_addr_len == 2) {
1973 				/* Special case for the broken 6tisch
1974 				   implementations. */
1975 				src_pan = 0;
1976 			}
1977 #endif /* BROKEN_6TISCH_PAN_ID_COMPRESSION */
1978 		}
1979 	}
1980 
1981 	/* Print dst PAN and address. */
1982 	if (dst_pan) {
1983 		if (caplen < 2) {
1984 			ND_PRINT("[ERROR: Truncated before dst_pan]");
1985 			return 0;
1986 		}
1987 		ND_PRINT("%04x:", GET_LE_U_2(p));
1988 		p += 2;
1989 		caplen -= 2;
1990 	} else {
1991 		ND_PRINT("-:");
1992 	}
1993 	if (caplen < (u_int) dst_addr_len) {
1994 		ND_PRINT("[ERROR: Truncated before dst_addr]");
1995 		return 0;
1996 	}
1997 	ieee802_15_4_print_addr(ndo, p, dst_addr_len);
1998 	p += dst_addr_len;
1999 	caplen -= dst_addr_len;
2000 
2001 	ND_PRINT(" < ");
2002 
2003 	/* Print src PAN and address. */
2004 	if (src_pan) {
2005 		if (caplen < 2) {
2006 			ND_PRINT("[ERROR: Truncated before dst_pan]");
2007 			return 0;
2008 		}
2009 		ND_PRINT("%04x:", GET_LE_U_2(p));
2010 		p += 2;
2011 		caplen -= 2;
2012 	} else {
2013 		ND_PRINT("-:");
2014 	}
2015 	if (caplen < (u_int) src_addr_len) {
2016 		ND_PRINT("[ERROR: Truncated before dst_addr]");
2017 		return 0;
2018 	}
2019 	ieee802_15_4_print_addr(ndo, p, src_addr_len);
2020 	ND_PRINT(" ");
2021 	p += src_addr_len;
2022 	caplen -= src_addr_len;
2023 	if (CHECK_BIT(fc, 3)) {
2024 		/*
2025 		 * XXX - if frame_version is 0, this is the 2003
2026 		 * spec, and you don't have the auxiliary security
2027 		 * header, you have a frame counter and key index
2028 		 * for the AES-CTR and AES-CCM security suites but
2029 		 * not for the AES-CBC-MAC security suite.
2030 		 */
2031 		len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen,
2032 							&security_level);
2033 		if (len < 0) {
2034 			return 0;
2035 		}
2036 		ND_TCHECK_LEN(p, len);
2037 		p += len;
2038 		caplen -= len;
2039 	} else {
2040 		security_level = 0;
2041 	}
2042 
2043 	switch (security_level) {
2044 	case 0: /*FALLTHROUGH */
2045 	case 4:
2046 		miclen = 0;
2047 		break;
2048 	case 1: /*FALLTHROUGH */
2049 	case 5:
2050 		miclen = 4;
2051 		break;
2052 	case 2: /*FALLTHROUGH */
2053 	case 6:
2054 		miclen = 8;
2055 		break;
2056 	case 3: /*FALLTHROUGH */
2057 	case 7:
2058 		miclen = 16;
2059 		break;
2060 	}
2061 
2062 	/* Remove MIC */
2063 	if (miclen != 0) {
2064 		if (caplen < miclen) {
2065 			ND_PRINT("[ERROR: Truncated before MIC]");
2066 			return 0;
2067 		}
2068 		caplen -= miclen;
2069 		mic_start = p + caplen;
2070 	}
2071 
2072 	/* Parse Information elements if present */
2073 	if (CHECK_BIT(fc, 9)) {
2074 		/* Yes we have those. */
2075 		len = ieee802_15_4_print_header_ie_list(ndo, p, caplen,
2076 							&payload_ie_present);
2077 		if (len < 0) {
2078 			return 0;
2079 		}
2080 		p += len;
2081 		caplen -= len;
2082 	}
2083 
2084 	if (payload_ie_present) {
2085 		if (security_level >= 4) {
2086 			ND_PRINT("Payload IEs present, but encrypted, cannot print ");
2087 		} else {
2088 			len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen);
2089 			if (len < 0) {
2090 				return 0;
2091 			}
2092 			p += len;
2093 			caplen -= len;
2094 		}
2095 	}
2096 
2097 	/* Print MIC */
2098 	if (ndo->ndo_vflag > 2 && miclen != 0) {
2099 		ND_PRINT("\n\tMIC ");
2100 
2101 		for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
2102 			ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
2103 		}
2104 		ND_PRINT(" ");
2105 	}
2106 
2107 	/* Print FCS */
2108 	if (ndo->ndo_vflag > 2) {
2109 		if (crc_check == fcs) {
2110 			ND_PRINT("FCS %x ", fcs);
2111 		} else {
2112 			ND_PRINT("wrong FCS %x vs %x (assume no FCS stored) ",
2113 				 fcs, crc_check);
2114 		}
2115 	}
2116 
2117 	/* Payload print */
2118 	switch (frame_type) {
2119 	case 0x00: /* Beacon */
2120 		if (frame_version < 2) {
2121 			if (caplen < 2) {
2122 				ND_PRINT("[ERROR: Truncated before beacon information]");
2123 				break;
2124 			} else {
2125 				uint16_t ss;
2126 
2127 				ss = GET_LE_U_2(p);
2128 				ieee802_15_4_print_superframe_specification(ndo, ss);
2129 				p += 2;
2130 				caplen -= 2;
2131 
2132 				/* GTS */
2133 				if (caplen < 1) {
2134 					ND_PRINT("[ERROR: Truncated before GTS info]");
2135 					break;
2136 				}
2137 
2138 				len = ieee802_15_4_print_gts_info(ndo, p, caplen);
2139 				if (len < 0) {
2140 					break;
2141 				}
2142 
2143 				p += len;
2144 				caplen -= len;
2145 
2146 				/* Pending Addresses */
2147 				if (caplen < 1) {
2148 					ND_PRINT("[ERROR: Truncated before pending addresses]");
2149 					break;
2150 				}
2151 				len = ieee802_15_4_print_pending_addresses(ndo, p, caplen);
2152 				if (len < 0) {
2153 					break;
2154 				}
2155 				ND_TCHECK_LEN(p, len);
2156 				p += len;
2157 				caplen -= len;
2158 			}
2159 		}
2160 		if (!ndo->ndo_suppress_default_print)
2161 			ND_DEFAULTPRINT(p, caplen);
2162 
2163 		break;
2164 	case 0x01: /* Data */
2165 	case 0x02: /* Acknowledgement */
2166 		if (!ndo->ndo_suppress_default_print)
2167 			ND_DEFAULTPRINT(p, caplen);
2168 		break;
2169 	case 0x03: /* MAC Command */
2170 		if (caplen < 1) {
2171 			ND_PRINT("[ERROR: Truncated before Command ID]");
2172 		} else {
2173 			uint8_t command_id;
2174 
2175 			command_id = GET_U_1(p);
2176 			if (command_id >= 0x30) {
2177 				ND_PRINT("Command ID = Reserved 0x%02x ",
2178 					 command_id);
2179 			} else {
2180 				ND_PRINT("Command ID = %s ",
2181 					 mac_c_names[command_id]);
2182 			}
2183 			p++;
2184 			caplen--;
2185 			if (caplen != 0) {
2186 				len = ieee802_15_4_print_command_data(ndo, command_id, p, caplen);
2187 				if (len >= 0) {
2188 					p += len;
2189 					caplen -= len;
2190 				}
2191 			}
2192 		}
2193 		if (!ndo->ndo_suppress_default_print)
2194 			ND_DEFAULTPRINT(p, caplen);
2195 		break;
2196 	}
2197 	return 1;
2198 }
2199 
2200 /*
2201  * Print and parse Multipurpose frames.
2202  *
2203  * Returns FALSE in case of error.
2204  */
2205 static u_int
2206 ieee802_15_4_mp_frame(netdissect_options *ndo,
2207 		      const u_char *p, u_int caplen,
2208 		      uint16_t fc)
2209 {
2210 	int len, frame_version, pan_id_present;
2211 	int src_addr_len, dst_addr_len;
2212 	int security_level;
2213 	u_int miclen = 0;
2214 	int ie_present, payload_ie_present, security_enabled;
2215 	uint8_t seq;
2216 	uint32_t fcs, crc_check;
2217 	const u_char *mic_start = NULL;
2218 
2219 	pan_id_present = 0;
2220 	ie_present = 0;
2221 	payload_ie_present = 0;
2222 	security_enabled = 0;
2223 	crc_check = 0;
2224 
2225 	/* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
2226 	   know about that. */
2227 	if (caplen < 3) {
2228 		/* Cannot have FCS, assume no FCS. */
2229 		fcs = 0;
2230 	} else {
2231 		if (caplen > 4) {
2232 			/* Test for 4 octet FCS. */
2233 			fcs = GET_LE_U_4(p + caplen - 4);
2234 			crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4);
2235 			if (crc_check == fcs) {
2236 				/* Remove FCS */
2237 				caplen -= 4;
2238 			} else {
2239 				fcs = GET_LE_U_2(p + caplen - 2);
2240 				crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
2241 				if (crc_check == fcs) {
2242 					/* Remove FCS */
2243 					caplen -= 2;
2244 				}
2245 			}
2246 		} else {
2247 			fcs = GET_LE_U_2(p + caplen - 2);
2248 			crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
2249 			if (crc_check == fcs) {
2250 				/* Remove FCS */
2251 				caplen -= 2;
2252 			}
2253 		}
2254 	}
2255 
2256 	if (CHECK_BIT(fc, 3)) {
2257 		/* Long Frame Control */
2258 
2259 		/* Frame version. */
2260 		frame_version = FC_FRAME_VERSION(fc);
2261 		ND_PRINT("v%d ", frame_version);
2262 
2263 		pan_id_present = CHECK_BIT(fc, 8);
2264 		ie_present = CHECK_BIT(fc, 15);
2265 		security_enabled = CHECK_BIT(fc, 9);
2266 
2267 		if (ndo->ndo_vflag > 2) {
2268 			if (security_enabled) { ND_PRINT("Security Enabled, "); }
2269 			if (CHECK_BIT(fc, 11)) { ND_PRINT("Frame Pending, "); }
2270 			if (CHECK_BIT(fc, 14)) { ND_PRINT("AR, "); }
2271 			if (pan_id_present) { ND_PRINT("PAN ID Present, "); }
2272 			if (CHECK_BIT(fc, 10)) {
2273 				ND_PRINT("Sequence Number Suppression, ");
2274 			}
2275 			if (ie_present) { ND_PRINT("IE present, "); }
2276 		}
2277 
2278 		/* Check for the sequence number suppression. */
2279 		if (CHECK_BIT(fc, 10)) {
2280 			/* Sequence number is suppressed, but long version. */
2281 			if (caplen < 2) {
2282 				nd_print_trunc(ndo);
2283 				return 0;
2284 			}
2285 			p += 2;
2286 			caplen -= 2;
2287 		} else {
2288 			seq = GET_U_1(p + 2);
2289 			if (ndo->ndo_vflag)
2290 				ND_PRINT("seq %02x ", seq);
2291 			if (caplen < 3) {
2292 				nd_print_trunc(ndo);
2293 				return 0;
2294 			}
2295 			p += 3;
2296 			caplen -= 3;
2297 		}
2298 	} else {
2299 		/* Short format of header, but with seq no */
2300 		seq = GET_U_1(p + 1);
2301 		p += 2;
2302 		caplen -= 2;
2303 		if (ndo->ndo_vflag)
2304 			ND_PRINT("seq %02x ", seq);
2305 	}
2306 
2307 	/* See which parts of addresses we have. */
2308 	dst_addr_len = ieee802_15_4_addr_len((fc >> 4) & 0x3);
2309 	src_addr_len = ieee802_15_4_addr_len((fc >> 6) & 0x3);
2310 	if (src_addr_len < 0) {
2311 		ND_PRINT("[ERROR: Invalid src address mode]");
2312 		return 0;
2313 	}
2314 	if (dst_addr_len < 0) {
2315 		ND_PRINT("[ERROR: Invalid dst address mode]");
2316 		return 0;
2317 	}
2318 
2319 	/* Print dst PAN and address. */
2320 	if (pan_id_present) {
2321 		if (caplen < 2) {
2322 			ND_PRINT("[ERROR: Truncated before dst_pan]");
2323 			return 0;
2324 		}
2325 		ND_PRINT("%04x:", GET_LE_U_2(p));
2326 		p += 2;
2327 		caplen -= 2;
2328 	} else {
2329 		ND_PRINT("-:");
2330 	}
2331 	if (caplen < (u_int) dst_addr_len) {
2332 		ND_PRINT("[ERROR: Truncated before dst_addr]");
2333 		return 0;
2334 	}
2335 	ieee802_15_4_print_addr(ndo, p, dst_addr_len);
2336 	p += dst_addr_len;
2337 	caplen -= dst_addr_len;
2338 
2339 	ND_PRINT(" < ");
2340 
2341 	/* Print src PAN and address. */
2342 	ND_PRINT(" -:");
2343 	if (caplen < (u_int) src_addr_len) {
2344 		ND_PRINT("[ERROR: Truncated before dst_addr]");
2345 		return 0;
2346 	}
2347 	ieee802_15_4_print_addr(ndo, p, src_addr_len);
2348 	ND_PRINT(" ");
2349 	p += src_addr_len;
2350 	caplen -= src_addr_len;
2351 
2352 	if (security_enabled) {
2353 		len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen,
2354 							&security_level);
2355 		if (len < 0) {
2356 			return 0;
2357 		}
2358 		ND_TCHECK_LEN(p, len);
2359 		p += len;
2360 		caplen -= len;
2361 	} else {
2362 		security_level = 0;
2363 	}
2364 
2365 	switch (security_level) {
2366 	case 0: /*FALLTHROUGH */
2367 	case 4:
2368 		miclen = 0;
2369 		break;
2370 	case 1: /*FALLTHROUGH */
2371 	case 5:
2372 		miclen = 4;
2373 		break;
2374 	case 2: /*FALLTHROUGH */
2375 	case 6:
2376 		miclen = 8;
2377 		break;
2378 	case 3: /*FALLTHROUGH */
2379 	case 7:
2380 		miclen = 16;
2381 		break;
2382 	}
2383 
2384 	/* Remove MIC */
2385 	if (miclen != 0) {
2386 		if (caplen < miclen) {
2387 			ND_PRINT("[ERROR: Truncated before MIC]");
2388 			return 0;
2389 		}
2390 		caplen -= miclen;
2391 		mic_start = p + caplen;
2392 	}
2393 
2394 	/* Parse Information elements if present */
2395 	if (ie_present) {
2396 		/* Yes we have those. */
2397 		len = ieee802_15_4_print_header_ie_list(ndo, p, caplen,
2398 							&payload_ie_present);
2399 		if (len < 0) {
2400 			return 0;
2401 		}
2402 		p += len;
2403 		caplen -= len;
2404 	}
2405 
2406 	if (payload_ie_present) {
2407 		if (security_level >= 4) {
2408 			ND_PRINT("Payload IEs present, but encrypted, cannot print ");
2409 		} else {
2410 			len = ieee802_15_4_print_payload_ie_list(ndo, p,
2411 								 caplen);
2412 			if (len < 0) {
2413 				return 0;
2414 			}
2415 			p += len;
2416 			caplen -= len;
2417 		}
2418 	}
2419 
2420 	/* Print MIC */
2421 	if (ndo->ndo_vflag > 2 && miclen != 0) {
2422 		ND_PRINT("\n\tMIC ");
2423 
2424 		for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
2425 			ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
2426 		}
2427 		ND_PRINT(" ");
2428 	}
2429 
2430 
2431 	/* Print FCS */
2432 	if (ndo->ndo_vflag > 2) {
2433 		if (crc_check == fcs) {
2434 			ND_PRINT("FCS %x ", fcs);
2435 		} else {
2436 			ND_PRINT("wrong FCS %x vs %x (assume no FCS stored) ",
2437 				 fcs, crc_check);
2438 		}
2439 	}
2440 
2441 	if (!ndo->ndo_suppress_default_print)
2442 		ND_DEFAULTPRINT(p, caplen);
2443 
2444 	return 1;
2445 }
2446 
2447 /*
2448  * Print frag frame.
2449  *
2450  * Returns FALSE in case of error.
2451  */
2452 static u_int
2453 ieee802_15_4_frag_frame(netdissect_options *ndo _U_,
2454 			const u_char *p _U_,
2455 			u_int caplen _U_,
2456 			uint16_t fc _U_)
2457 {
2458 	/* Not implement yet, might be bit hard to implement, as the
2459 	 * information to set up the fragment is coming in the previous frame
2460 	 * in the Fragment Sequence Context Description IE, thus we need to
2461 	 * store information from there, so we can use it here. */
2462 	return 0;
2463 }
2464 
2465 /*
2466  * Internal call to dissector taking packet + len instead of pcap_pkthdr.
2467  *
2468  * Returns FALSE in case of error.
2469  */
2470 u_int
2471 ieee802_15_4_print(netdissect_options *ndo,
2472 		   const u_char *p, u_int caplen)
2473 {
2474 	int frame_type;
2475 	uint16_t fc;
2476 
2477 	ndo->ndo_protocol = "802.15.4";
2478 
2479 	if (caplen < 2) {
2480 		nd_print_trunc(ndo);
2481 		return caplen;
2482 	}
2483 
2484 	fc = GET_LE_U_2(p);
2485 
2486 	/* First we need to check the frame type to know how to parse the rest
2487 	   of the FC. Frame type is the first 3 bit of the frame control field.
2488 	*/
2489 
2490 	frame_type = FC_FRAME_TYPE(fc);
2491 	ND_PRINT("IEEE 802.15.4 %s packet ", ftypes[frame_type]);
2492 
2493 	switch (frame_type) {
2494 	case 0x00: /* Beacon */
2495 	case 0x01: /* Data */
2496 	case 0x02: /* Acknowledgement */
2497 	case 0x03: /* MAC Command */
2498 		return ieee802_15_4_std_frames(ndo, p, caplen, fc);
2499 		break;
2500 	case 0x04: /* Reserved */
2501 		return 0;
2502 		break;
2503 	case 0x05: /* Multipurpose */
2504 		return ieee802_15_4_mp_frame(ndo, p, caplen, fc);
2505 		break;
2506 	case 0x06: /* Fragment or Frak */
2507 		return ieee802_15_4_frag_frame(ndo, p, caplen, fc);
2508 		break;
2509 	case 0x07: /* Extended */
2510 		return 0;
2511 		break;
2512 	}
2513 	return 0;
2514 }
2515 
2516 /*
2517  * Main function to print packets.
2518  */
2519 
2520 void
2521 ieee802_15_4_if_print(netdissect_options *ndo,
2522                       const struct pcap_pkthdr *h, const u_char *p)
2523 {
2524 	u_int caplen = h->caplen;
2525 	ndo->ndo_protocol = "802.15.4";
2526 	ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p, caplen);
2527 }
2528 
2529 /* For DLT_IEEE802_15_4_TAP */
2530 /* https://github.com/jkcko/ieee802.15.4-tap */
2531 void
2532 ieee802_15_4_tap_if_print(netdissect_options *ndo,
2533                           const struct pcap_pkthdr *h, const u_char *p)
2534 {
2535 	uint8_t version;
2536 	uint16_t length;
2537 
2538 	ndo->ndo_protocol = "802.15.4_tap";
2539 	if (h->caplen < 4) {
2540 		nd_print_trunc(ndo);
2541 		ndo->ndo_ll_hdr_len += h->caplen;
2542 		return;
2543 	}
2544 
2545 	version = GET_U_1(p);
2546 	length = GET_LE_U_2(p + 2);
2547 	if (version != 0 || length < 4) {
2548 		nd_print_invalid(ndo);
2549 		return;
2550 	}
2551 
2552 	if (h->caplen < length) {
2553 		nd_print_trunc(ndo);
2554 		ndo->ndo_ll_hdr_len += h->caplen;
2555 		return;
2556 	}
2557 
2558 	ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p+length, h->caplen-length) + length;
2559 }
2560