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