3 * Siemens AG, All rights reserved.
4 * Dmitry Eremin-Solenikov (dbaryshkov@gmail.com)
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
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.
23 /* \summary: IEEE 802.15.4 printer */
29 #include <netdissect-stdinc.h>
31 #include "netdissect.h"
32 #include "addrtoname.h"
36 #define CHECK_BIT(num,bit) (((num) >> (bit)) & 0x1)
38 #define BROKEN_6TISCH_PAN_ID_COMPRESSION 0
40 /* Frame types from Table 7-1 of 802.15.4-2015 */
41 static const char *ftypes
[] = {
47 "Multipurpose", /* 5 */
52 /* Element IDs for Header IEs from Table 7-7 of 802.15.4-2015 */
53 static const char *h_ie_names
[] = {
54 "Vendor Specific Header IE", /* 0x00 */
55 "Reserved 0x01", /* 0x01 */
56 "Reserved 0x02", /* 0x02 */
57 "Reserved 0x03", /* 0x03 */
58 "Reserved 0x04", /* 0x04 */
59 "Reserved 0x05", /* 0x05 */
60 "Reserved 0x06", /* 0x06 */
61 "Reserved 0x07", /* 0x07 */
62 "Reserved 0x08", /* 0x08 */
63 "Reserved 0x09", /* 0x09 */
64 "Reserved 0x0a", /* 0x0a */
65 "Reserved 0x0b", /* 0x0b */
66 "Reserved 0x0c", /* 0x0c */
67 "Reserved 0x0d", /* 0x0d */
68 "Reserved 0x0e", /* 0x0e */
69 "Reserved 0x0f", /* 0x0f */
70 "Reserved 0x10", /* 0x10 */
71 "Reserved 0x11", /* 0x11 */
72 "Reserved 0x12", /* 0x12 */
73 "Reserved 0x13", /* 0x13 */
74 "Reserved 0x14", /* 0x14 */
75 "Reserved 0x15", /* 0x15 */
76 "Reserved 0x16", /* 0x16 */
77 "Reserved 0x17", /* 0x17 */
78 "Reserved 0x18", /* 0x18 */
79 "Reserved 0x19", /* 0x19 */
80 "LE CSL IE", /* 0x1a */
81 "LE RIT IE", /* 0x1b */
82 "DSME PAN descriptor IE", /* 0x1c */
83 "Rendezvous Time IE", /* 0x1d */
84 "Time Correction IE", /* 0x1e */
85 "Reserved 0x1f", /* 0x1f */
86 "Reserved 0x20", /* 0x20 */
87 "Extended DSME PAN descriptor IE", /* 0x21 */
88 "Fragment Sequence Context Description IE", /* 0x22 */
89 "Simplified Superframe Specification IE", /* 0x23 */
90 "Simplified GTS Specification IE", /* 0x24 */
91 "LECIM Capabilities IE", /* 0x25 */
92 "TRLE Descriptor IE", /* 0x26 */
93 "RCC Capabilities IE", /* 0x27 */
94 "RCCN Descriptor IE", /* 0x28 */
95 "Global Time IE", /* 0x29 */
96 "Omnibus Header IE", /* 0x2a */
98 "Reserved 0x2c", /* 0x2c */
99 "Reserved 0x2d", /* 0x2d */
100 "Reserved 0x2e", /* 0x2e */
101 "Reserved 0x2f", /* 0x2f */
102 "Reserved 0x30", /* 0x30 */
103 "Reserved 0x31", /* 0x31 */
104 "Reserved 0x32", /* 0x32 */
105 "Reserved 0x33", /* 0x33 */
106 "Reserved 0x34", /* 0x34 */
107 "Reserved 0x35", /* 0x35 */
108 "Reserved 0x36", /* 0x36 */
109 "Reserved 0x37", /* 0x37 */
110 "Reserved 0x38", /* 0x38 */
111 "Reserved 0x39", /* 0x39 */
112 "Reserved 0x3a", /* 0x3a */
113 "Reserved 0x3b", /* 0x3b */
114 "Reserved 0x3c", /* 0x3c */
115 "Reserved 0x3d", /* 0x3d */
116 "Reserved 0x3e", /* 0x3e */
117 "Reserved 0x3f", /* 0x3f */
118 "Reserved 0x40", /* 0x40 */
119 "Reserved 0x41", /* 0x41 */
120 "Reserved 0x42", /* 0x42 */
121 "Reserved 0x43", /* 0x43 */
122 "Reserved 0x44", /* 0x44 */
123 "Reserved 0x45", /* 0x45 */
124 "Reserved 0x46", /* 0x46 */
125 "Reserved 0x47", /* 0x47 */
126 "Reserved 0x48", /* 0x48 */
127 "Reserved 0x49", /* 0x49 */
128 "Reserved 0x4a", /* 0x4a */
129 "Reserved 0x4b", /* 0x4b */
130 "Reserved 0x4c", /* 0x4c */
131 "Reserved 0x4d", /* 0x4d */
132 "Reserved 0x4e", /* 0x4e */
133 "Reserved 0x4f", /* 0x4f */
134 "Reserved 0x50", /* 0x50 */
135 "Reserved 0x51", /* 0x51 */
136 "Reserved 0x52", /* 0x52 */
137 "Reserved 0x53", /* 0x53 */
138 "Reserved 0x54", /* 0x54 */
139 "Reserved 0x55", /* 0x55 */
140 "Reserved 0x56", /* 0x56 */
141 "Reserved 0x57", /* 0x57 */
142 "Reserved 0x58", /* 0x58 */
143 "Reserved 0x59", /* 0x59 */
144 "Reserved 0x5a", /* 0x5a */
145 "Reserved 0x5b", /* 0x5b */
146 "Reserved 0x5c", /* 0x5c */
147 "Reserved 0x5d", /* 0x5d */
148 "Reserved 0x5e", /* 0x5e */
149 "Reserved 0x5f", /* 0x5f */
150 "Reserved 0x60", /* 0x60 */
151 "Reserved 0x61", /* 0x61 */
152 "Reserved 0x62", /* 0x62 */
153 "Reserved 0x63", /* 0x63 */
154 "Reserved 0x64", /* 0x64 */
155 "Reserved 0x65", /* 0x65 */
156 "Reserved 0x66", /* 0x66 */
157 "Reserved 0x67", /* 0x67 */
158 "Reserved 0x68", /* 0x68 */
159 "Reserved 0x69", /* 0x69 */
160 "Reserved 0x6a", /* 0x6a */
161 "Reserved 0x6b", /* 0x6b */
162 "Reserved 0x6c", /* 0x6c */
163 "Reserved 0x6d", /* 0x6d */
164 "Reserved 0x6e", /* 0x6e */
165 "Reserved 0x6f", /* 0x6f */
166 "Reserved 0x70", /* 0x70 */
167 "Reserved 0x71", /* 0x71 */
168 "Reserved 0x72", /* 0x72 */
169 "Reserved 0x73", /* 0x73 */
170 "Reserved 0x74", /* 0x74 */
171 "Reserved 0x75", /* 0x75 */
172 "Reserved 0x76", /* 0x76 */
173 "Reserved 0x77", /* 0x77 */
174 "Reserved 0x78", /* 0x78 */
175 "Reserved 0x79", /* 0x79 */
176 "Reserved 0x7a", /* 0x7a */
177 "Reserved 0x7b", /* 0x7b */
178 "Reserved 0x7c", /* 0x7c */
179 "Reserved 0x7d", /* 0x7d */
180 "Header Termination 1 IE", /* 0x7e */
181 "Header Termination 2 IE" /* 0x7f */
184 /* Payload IE Group IDs from Table 7-15 of 802.15.4-2015 */
185 static const char *p_ie_names
[] = {
186 "ESDU IE", /* 0x00 */
187 "MLME IE", /* 0x01 */
188 "Vendor Specific Nested IE", /* 0x02 */
189 "Multiplexed IE (802.15.9)", /* 0x03 */
190 "Omnibus Payload Group IE", /* 0x04 */
191 "IETF IE", /* 0x05 */
192 "Reserved 0x06", /* 0x06 */
193 "Reserved 0x07", /* 0x07 */
194 "Reserved 0x08", /* 0x08 */
195 "Reserved 0x09", /* 0x09 */
196 "Reserved 0x0a", /* 0x0a */
197 "Reserved 0x0b", /* 0x0b */
198 "Reserved 0x0c", /* 0x0c */
199 "Reserved 0x0d", /* 0x0d */
200 "Reserved 0x0e", /* 0x0e */
201 "List termination" /* 0x0f */
204 /* Sub-ID for short format from Table 7-16 of 802.15.4-2015 */
205 static const char *p_mlme_short_names
[] = {
206 "Reserved for long format 0x0", /* 0x00 */
207 "Reserved for long format 0x1", /* 0x01 */
208 "Reserved for long format 0x2", /* 0x02 */
209 "Reserved for long format 0x3", /* 0x03 */
210 "Reserved for long format 0x4", /* 0x04 */
211 "Reserved for long format 0x5", /* 0x05 */
212 "Reserved for long format 0x6", /* 0x06 */
213 "Reserved for long format 0x7", /* 0x07 */
214 "Reserved for long format 0x8", /* 0x08 */
215 "Reserved for long format 0x9", /* 0x09 */
216 "Reserved for long format 0xa", /* 0x0a */
217 "Reserved for long format 0xb", /* 0x0b */
218 "Reserved for long format 0xc", /* 0x0c */
219 "Reserved for long format 0xd", /* 0x0d */
220 "Reserved for long format 0xe", /* 0x0e */
221 "Reserved for long format 0xf", /* 0x0f */
222 "Reserved 0x10", /* 0x10 */
223 "Reserved 0x11", /* 0x11 */
224 "Reserved 0x12", /* 0x12 */
225 "Reserved 0x13", /* 0x13 */
226 "Reserved 0x14", /* 0x14 */
227 "Reserved 0x15", /* 0x15 */
228 "Reserved 0x16", /* 0x16 */
229 "Reserved 0x17", /* 0x17 */
230 "Reserved 0x18", /* 0x18 */
231 "Reserved 0x19", /* 0x19 */
232 "TSCH Synchronization IE", /* 0x1a */
233 "TSCH Slotframe and Link IE", /* 0x1b */
234 "TSCH Timeslot IE", /* 0x1c */
235 "Hopping timing IE", /* 0x1d */
236 "Enhanced Beacon Filter IE", /* 0x1e */
237 "MAC Metrics IE", /* 0x1f */
238 "All MAC Metrics IE", /* 0x20 */
239 "Coexistence Specification IE", /* 0x21 */
240 "SUN Device Capabilities IE", /* 0x22 */
241 "SUN FSK Generic PHY IE", /* 0x23 */
242 "Mode Switch Parameter IE", /* 0x24 */
243 "PHY Parameter Change IE", /* 0x25 */
244 "O-QPSK PHY Mode IE", /* 0x26 */
245 "PCA Allocation IE", /* 0x27 */
246 "LECIM DSSS Operating Mode IE", /* 0x28 */
247 "LECIM FSK Operating Mode IE", /* 0x29 */
248 "Reserved 0x2a", /* 0x2a */
249 "TVWS PHY Operating Mode Description IE", /* 0x2b */
250 "TVWS Device Capabilities IE", /* 0x2c */
251 "TVWS Device Category IE", /* 0x2d */
252 "TVWS Device Identiication IE", /* 0x2e */
253 "TVWS Device Location IE", /* 0x2f */
254 "TVWS Channel Information Query IE", /* 0x30 */
255 "TVWS Channel Information Source IE", /* 0x31 */
257 "Timestamp IE", /* 0x33 */
258 "Timestamp Difference IE", /* 0x34 */
259 "TMCTP Sepcification IE", /* 0x35 */
260 "RCC PHY Operating Mode IE", /* 0x36 */
261 "Reserved 0x37", /* 0x37 */
262 "Reserved 0x38", /* 0x38 */
263 "Reserved 0x39", /* 0x39 */
264 "Reserved 0x3a", /* 0x3a */
265 "Reserved 0x3b", /* 0x3b */
266 "Reserved 0x3c", /* 0x3c */
267 "Reserved 0x3d", /* 0x3d */
268 "Reserved 0x3e", /* 0x3e */
269 "Reserved 0x3f", /* 0x3f */
270 "Reserved 0x40", /* 0x40 */
271 "Reserved 0x41", /* 0x41 */
272 "Reserved 0x42", /* 0x42 */
273 "Reserved 0x43", /* 0x43 */
274 "Reserved 0x44", /* 0x44 */
275 "Reserved 0x45", /* 0x45 */
276 "Reserved 0x46", /* 0x46 */
277 "Reserved 0x47", /* 0x47 */
278 "Reserved 0x48", /* 0x48 */
279 "Reserved 0x49", /* 0x49 */
280 "Reserved 0x4a", /* 0x4a */
281 "Reserved 0x4b", /* 0x4b */
282 "Reserved 0x4c", /* 0x4c */
283 "Reserved 0x4d", /* 0x4d */
284 "Reserved 0x4e", /* 0x4e */
285 "Reserved 0x4f", /* 0x4f */
286 "Reserved 0x50", /* 0x50 */
287 "Reserved 0x51", /* 0x51 */
288 "Reserved 0x52", /* 0x52 */
289 "Reserved 0x53", /* 0x53 */
290 "Reserved 0x54", /* 0x54 */
291 "Reserved 0x55", /* 0x55 */
292 "Reserved 0x56", /* 0x56 */
293 "Reserved 0x57", /* 0x57 */
294 "Reserved 0x58", /* 0x58 */
295 "Reserved 0x59", /* 0x59 */
296 "Reserved 0x5a", /* 0x5a */
297 "Reserved 0x5b", /* 0x5b */
298 "Reserved 0x5c", /* 0x5c */
299 "Reserved 0x5d", /* 0x5d */
300 "Reserved 0x5e", /* 0x5e */
301 "Reserved 0x5f", /* 0x5f */
302 "Reserved 0x60", /* 0x60 */
303 "Reserved 0x61", /* 0x61 */
304 "Reserved 0x62", /* 0x62 */
305 "Reserved 0x63", /* 0x63 */
306 "Reserved 0x64", /* 0x64 */
307 "Reserved 0x65", /* 0x65 */
308 "Reserved 0x66", /* 0x66 */
309 "Reserved 0x67", /* 0x67 */
310 "Reserved 0x68", /* 0x68 */
311 "Reserved 0x69", /* 0x69 */
312 "Reserved 0x6a", /* 0x6a */
313 "Reserved 0x6b", /* 0x6b */
314 "Reserved 0x6c", /* 0x6c */
315 "Reserved 0x6d", /* 0x6d */
316 "Reserved 0x6e", /* 0x6e */
317 "Reserved 0x6f", /* 0x6f */
318 "Reserved 0x70", /* 0x70 */
319 "Reserved 0x71", /* 0x71 */
320 "Reserved 0x72", /* 0x72 */
321 "Reserved 0x73", /* 0x73 */
322 "Reserved 0x74", /* 0x74 */
323 "Reserved 0x75", /* 0x75 */
324 "Reserved 0x76", /* 0x76 */
325 "Reserved 0x77", /* 0x77 */
326 "Reserved 0x78", /* 0x78 */
327 "Reserved 0x79", /* 0x79 */
328 "Reserved 0x7a", /* 0x7a */
329 "Reserved 0x7b", /* 0x7b */
330 "Reserved 0x7c", /* 0x7c */
331 "Reserved 0x7d", /* 0x7d */
332 "Reserved 0x7e", /* 0x7e */
333 "Reserved 0x7f" /* 0x7f */
336 /* Sub-ID for long format from Table 7-17 of 802.15.4-2015 */
337 static const char *p_mlme_long_names
[] = {
338 "Reserved 0x00", /* 0x00 */
339 "Reserved 0x01", /* 0x01 */
340 "Reserved 0x02", /* 0x02 */
341 "Reserved 0x03", /* 0x03 */
342 "Reserved 0x04", /* 0x04 */
343 "Reserved 0x05", /* 0x05 */
344 "Reserved 0x06", /* 0x06 */
345 "Reserved 0x07", /* 0x07 */
346 "Vendor Specific MLME Nested IE", /* 0x08 */
347 "Channel Hopping IE", /* 0x09 */
348 "Reserved 0x0a", /* 0x0a */
349 "Reserved 0x0b", /* 0x0b */
350 "Reserved 0x0c", /* 0x0c */
351 "Reserved 0x0d", /* 0x0d */
352 "Reserved 0x0e", /* 0x0e */
353 "Reserved 0x0f" /* 0x0f */
356 /* MAC commands from Table 7-49 of 802.15.4-2015 */
357 static const char *mac_c_names
[] = {
358 "Reserved 0x00", /* 0x00 */
359 "Association Request command", /* 0x01 */
360 "Association Response command", /* 0x02 */
361 "Disassociation Notification command", /* 0x03 */
362 "Data Request command", /* 0x04 */
363 "PAN ID Conflict Notification command", /* 0x05 */
364 "Orphan Notification command", /* 0x06 */
365 "Beacon Request command", /* 0x07 */
366 "Coordinator realignment command", /* 0x08 */
367 "GTS request command", /* 0x09 */
368 "TRLE Management Request command", /* 0x0a */
369 "TRLE Management Response command", /* 0x0b */
370 "Reserved 0x0c", /* 0x0c */
371 "Reserved 0x0d", /* 0x0d */
372 "Reserved 0x0e", /* 0x0e */
373 "Reserved 0x0f", /* 0x0f */
374 "Reserved 0x10", /* 0x10 */
375 "Reserved 0x11", /* 0x11 */
376 "Reserved 0x12", /* 0x12 */
377 "DSME Association Request command", /* 0x13 */
378 "DSME Association Response command", /* 0x14 */
379 "DSME GTS Request command", /* 0x15 */
380 "DSME GTS Response command", /* 0x16 */
381 "DSME GTS Notify command", /* 0x17 */
382 "DSME Information Request command", /* 0x18 */
383 "DSME Information Response command", /* 0x19 */
384 "DSME Beacon Allocation Notification command",/* 0x1a */
385 "DSME Beacon Collision Notification command", /* 0x1b */
386 "DSME Link Report command", /* 0x1c */
387 "Reserved 0x1d", /* 0x1d */
388 "Reserved 0x1e", /* 0x1e */
389 "Reserved 0x1f", /* 0x1f */
390 "RIT Data Request command", /* 0x20 */
391 "DBS Request command", /* 0x21 */
392 "DBS Response command", /* 0x22 */
393 "RIT Data Response command", /* 0x23 */
394 "Vendor Specific command", /* 0x24 */
395 "Reserved 0x25", /* 0x25 */
396 "Reserved 0x26", /* 0x26 */
397 "Reserved 0x27", /* 0x27 */
398 "Reserved 0x28", /* 0x28 */
399 "Reserved 0x29", /* 0x29 */
400 "Reserved 0x2a", /* 0x2a */
401 "Reserved 0x2b", /* 0x2b */
402 "Reserved 0x2c", /* 0x2c */
403 "Reserved 0x2d", /* 0x2d */
404 "Reserved 0x2e", /* 0x2e */
405 "Reserved 0x2f" /* 0x2f */
410 * IEEE 802.15.4 CRC 16 function. This is using CCITT polynomical of 0x1021,
411 * but the initial value is 0, and the bits are reversed for both in and out.
412 * See secton 7.2.10 of 802.15.4-2015 for more information.
415 ieee802_15_4_crc16(const u_char
*p
,
421 crc
= 0x0000; /* Note, initial value is 0x0000 not 0xffff. */
425 /* Reverse bits on input */
426 y
= (((y
& 0xaa) >> 1) | ((y
& 0x55) << 1));
427 y
= (((y
& 0xcc) >> 2) | ((y
& 0x33) << 2));
428 y
= (((y
& 0xf0) >> 4) | ((y
& 0x0f) << 4));
433 ((unsigned short)(x
<< 12)) ^
434 ((unsigned short)(x
<<5)) ^
437 /* Reverse bits on output */
438 crc
= (((crc
& 0xaaaa) >> 1) | ((crc
& 0x5555) << 1));
439 crc
= (((crc
& 0xcccc) >> 2) | ((crc
& 0x3333) << 2));
440 crc
= (((crc
& 0xf0f0) >> 4) | ((crc
& 0x0f0f) << 4));
441 crc
= (((crc
& 0xff00) >> 8) | ((crc
& 0x00ff) << 8));
446 * Find out the address length based on the address type. See table 7-3 of
447 * 802.15.4-2015. Returns the address length.
450 ieee802_15_4_addr_len(uint16_t addr_type
)
453 case 0x00: /* None. */
456 case 0x01: /* Reserved, there used to be 8-bit address type in one
457 * amendment, but that and the feature using it was removed
458 * during 802.15.4-2015 maintenance process. */
461 case 0x02: /* Short. */
464 case 0x03: /* Extended. */
472 * Print out the ieee 802.15.4 address.
475 ieee802_15_4_print_addr(netdissect_options
*ndo
, const u_char
*p
,
478 switch (dst_addr_len
) {
480 ND_PRINT((ndo
, "none"));
483 ND_PRINT((ndo
, "%04x", EXTRACT_LE_16BITS(p
)));
486 ND_PRINT((ndo
, "%s", le64addr_string(ndo
, p
)));
493 * Beacon frame superframe specification structure. Used in the old Beacon
494 * frames, and in the DSME PAN Descriptor IE. See section 7.3.1.3 of the
498 ieee802_15_4_print_superframe_specification(netdissect_options
*ndo
,
501 if (ndo
->ndo_vflag
< 1) {
504 ND_PRINT((ndo
, "\n\tBeacon order = %d, Superframe order = %d, ",
505 (ss
& 0xf), ((ss
>> 4) & 0xf)));
506 ND_PRINT((ndo
, "Final CAP Slot = %d",
508 if (CHECK_BIT(ss
, 12)) { ND_PRINT((ndo
, ", BLE enabled")); }
509 if (CHECK_BIT(ss
, 14)) { ND_PRINT((ndo
, ", PAN Coordinator")); }
510 if (CHECK_BIT(ss
, 15)) { ND_PRINT((ndo
, ", Assocation Permit")); }
514 * Beacon frame gts info structure. Used in the old Beacon frames, and
515 * in the DSME PAN Descriptor IE. See section 7.3.1.4 of 802.15.4-2015.
517 * Returns number of byts consumed from the packet or -1 in case of error.
520 ieee802_15_4_print_gts_info(netdissect_options
*ndo
,
524 uint8_t gts_spec
, gts_cnt
;
527 gts_spec
= EXTRACT_LE_8BITS(p
);
528 gts_cnt
= gts_spec
& 0x7;
531 if (ndo
->ndo_vflag
> 0) {
532 ND_PRINT((ndo
, "\n\tGTS Descriptor Count = %d, ", gts_cnt
));
536 len
= 1 + 1 + gts_cnt
* 3;
538 if (data_len
< len
) {
539 ND_PRINT((ndo
, " [ERROR: Truncated GTS Info List]"));
542 if (ndo
->ndo_vflag
< 2) {
545 ND_PRINT((ndo
, "GTS Descriptor Count = %d, ", gts_cnt
));
546 ND_PRINT((ndo
, "GTS Directions Mask = %02x, [ ",
547 EXTRACT_LE_8BITS(p
+ 1) & 0x7f));
549 for(i
= 0; i
< gts_cnt
; i
++) {
550 ND_PRINT((ndo
, "[ "));
551 ieee802_15_4_print_addr(ndo
, p
+ 2 + i
* 3, 2);
552 ND_PRINT((ndo
, ", Start slot = %d, Length = %d ] ",
553 EXTRACT_LE_8BITS(p
+ 2 + i
* 3 + 1) & 0x0f,
554 (EXTRACT_LE_8BITS(p
+ 2 + i
* 3 + 1) >> 4) & 0x0f));
556 ND_PRINT((ndo
, "]"));
561 * Beacon frame pending address structure. Used in the old Beacon frames, and
562 * in the DSME PAN Descriptor IE. See section 7.3.1.5 of 802.15.4-2015.
564 * Returns number of byts consumed from the packet or -1 in case of error.
567 ieee802_15_4_print_pending_addresses(netdissect_options
*ndo
,
571 uint8_t pas
, s_cnt
, e_cnt
, len
, i
;
573 pas
= EXTRACT_LE_8BITS(p
);
575 e_cnt
= (pas
>> 4) & 0x7;
576 len
= 1 + s_cnt
* 2 + e_cnt
* 8;
577 if (ndo
->ndo_vflag
> 0) {
578 ND_PRINT((ndo
, "\n\tPending address list, "
579 "# short addresses = %d, # extended addresses = %d",
582 if (data_len
< len
) {
583 ND_PRINT((ndo
, " [ERROR: Pending address list truncated]"));
586 if (ndo
->ndo_vflag
< 2) {
590 ND_PRINT((ndo
, ", Short address list = [ "));
591 for(i
= 0; i
< s_cnt
; i
++) {
592 ieee802_15_4_print_addr(ndo
, p
+ 1 + i
* 2, 2);
593 ND_PRINT((ndo
, " "));
595 ND_PRINT((ndo
, "]"));
598 ND_PRINT((ndo
, ", Extended address list = [ "));
599 for(i
= 0; i
< e_cnt
; i
++) {
600 ieee802_15_4_print_addr(ndo
, p
+ 1 + s_cnt
* 2 +
602 ND_PRINT((ndo
, " "));
604 ND_PRINT((ndo
, "]"));
610 * Print header ie content.
613 ieee802_15_4_print_header_ie(netdissect_options
*ndo
,
620 switch (element_id
) {
621 case 0x00: /* Vendor Specific Header IE */
623 ND_PRINT((ndo
, "[ERROR: Vendor OUI missing]"));
625 ND_PRINT((ndo
, "OUI = 0x%02x%02x%02x, ", EXTRACT_LE_8BITS(p
),
626 EXTRACT_LE_8BITS(p
+ 1), EXTRACT_LE_8BITS(p
+ 2)));
627 ND_PRINT((ndo
, "Data = "));
628 for(i
= 3; i
< ie_len
; i
++) {
629 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
633 case 0x1a: /* LE CSL IE */
635 ND_PRINT((ndo
, "[ERROR: Truncated CSL IE]"));
637 ND_PRINT((ndo
, "CSL Phase = %d, CSL Period = %d",
638 EXTRACT_LE_16BITS(p
), EXTRACT_LE_16BITS(p
+ 2)));
640 ND_PRINT((ndo
, ", Rendezvous time = %d", EXTRACT_LE_16BITS(p
+ 4)));
642 if (ie_len
!= 4 && ie_len
!= 6) {
643 ND_PRINT((ndo
, " [ERROR: CSL IE length wrong]"));
647 case 0x1b: /* LE RIT IE */
649 ND_PRINT((ndo
, "[ERROR: Truncated RIT IE]"));
651 ND_PRINT((ndo
, "Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d",
653 EXTRACT_LE_8BITS(p
+ 1),
654 EXTRACT_LE_16BITS(p
+ 2)));
657 case 0x1c: /* DSME PAN Descriptor IE */
659 case 0x21: /* Extended DSME PAN descriptior IE */
661 ND_PRINT((ndo
, "[ERROR: Truncated DSME PAN IE]"));
664 int len
, hopping_present
;
668 ss
= EXTRACT_LE_16BITS(p
);
669 ieee802_15_4_print_superframe_specification(ndo
, ss
);
671 ND_PRINT((ndo
, "[ERROR: Truncated before pending addresses field]"));
675 len
= ieee802_15_4_print_pending_addresses(ndo
, p
+ ptr
, ie_len
- ptr
);
681 if (element_id
== 0x21) {
682 /* Extended version. */
683 if (ie_len
< ptr
+ 2) {
684 ND_PRINT((ndo
, "[ERROR: Truncated before DSME Superframe Specification]"));
687 ss
= EXTRACT_LE_16BITS(p
+ ptr
);
689 ND_PRINT((ndo
, "Multi-superframe Order = %d", ss
& 0xff));
690 ND_PRINT((ndo
, ", %s", ((ss
& 0x100) ? "Channel hopping mode" :
691 "Channel adaptation mode")));
692 if (ss
& 0x400) { ND_PRINT((ndo
, ", CAP reduction enabled")); }
693 if (ss
& 0x800) { ND_PRINT((ndo
, ", Deferred beacon enabled")); }
695 ND_PRINT((ndo
, ", Hopping Sequence Present"));
699 if (ie_len
< ptr
+ 1) {
700 ND_PRINT((ndo
, "[ERROR: Truncated before DSME Superframe Specification]"));
703 ss
= EXTRACT_LE_8BITS(p
+ ptr
);
705 ND_PRINT((ndo
, "Multi-superframe Order = %d", ss
& 0x0f));
706 ND_PRINT((ndo
, ", %s", ((ss
& 0x10) ? "Channel hopping mode" :
707 "Channel adaptation mode")));
708 if (ss
& 0x40) { ND_PRINT((ndo
, ", CAP reduction enabled")); }
709 if (ss
& 0x80) { ND_PRINT((ndo
, ", Deferred beacon enabled")); }
711 if (ie_len
< ptr
+ 8) {
712 ND_PRINT((ndo
, " [ERROR: Truncated before Time syncronization specification]"));
715 ND_PRINT((ndo
, "Beacon timestamp = %" PRIu64
", offset = %d",
716 EXTRACT_LE_48BITS(p
+ ptr
),
717 EXTRACT_LE_16BITS(p
+ ptr
+ 6)));
719 if (ie_len
< ptr
+ 4) {
720 ND_PRINT((ndo
, " [ERROR: Truncated before Beacon Bitmap]"));
724 len
= EXTRACT_LE_16BITS(p
+ ptr
+ 2);
725 ND_PRINT((ndo
, "SD Index = %d, Bitmap len = %d, ",
726 EXTRACT_LE_16BITS(p
+ ptr
), len
));
728 if (ie_len
< ptr
+ len
) {
729 ND_PRINT((ndo
, " [ERROR: Truncated in SD bitmap]"));
732 ND_PRINT((ndo
, " SD Bitmap = "));
733 for(i
= 0; i
< len
; i
++) {
734 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ ptr
+ i
)));
738 if (ie_len
< ptr
+ 5) {
739 ND_PRINT((ndo
, " [ERROR: Truncated before Channel hopping specification]"));
743 len
= EXTRACT_LE_16BITS(p
+ ptr
+ 4);
744 ND_PRINT((ndo
, "Hopping Seq ID = %d, PAN Coordinator BSN = %d, "
745 "Channel offset = %d, Bitmap length = %d, ",
746 EXTRACT_LE_8BITS(p
+ ptr
),
747 EXTRACT_LE_8BITS(p
+ ptr
+ 1),
748 EXTRACT_LE_16BITS(p
+ ptr
+ 2),
751 if (ie_len
< ptr
+ len
) {
752 ND_PRINT((ndo
, " [ERROR: Truncated in Channel offset bitmap]"));
755 ND_PRINT((ndo
, " Channel offset bitmap = "));
756 for(i
= 0; i
< len
; i
++) {
757 ND_PRINT((ndo
, "%02x ",
758 EXTRACT_LE_8BITS(p
+ ptr
+ i
)));
761 if (hopping_present
) {
762 if (ie_len
< ptr
+ 1) {
763 ND_PRINT((ndo
, " [ERROR: Truncated in Hopping Sequence length]"));
766 len
= EXTRACT_LE_8BITS(p
+ ptr
);
768 ND_PRINT((ndo
, "Hopping Seq length = %d [ ", len
));
770 /* The specification is not clear how the
771 hopping sequence is encoded, I assume two octet
772 unsigned integers for each channel. */
774 if (ie_len
< ptr
+ len
* 2) {
775 ND_PRINT((ndo
, " [ERROR: Truncated in Channel offset bitmap]"));
778 for(i
= 0; i
< len
; i
++) {
779 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_16BITS(p
+ ptr
+ i
* 2)));
781 ND_PRINT((ndo
, "]"));
786 case 0x1d: /* Rendezvous Tome IE */
788 ND_PRINT((ndo
, "[ERROR: Length != 2]"));
790 uint16_t r_time
, w_u_interval
;
791 r_time
= EXTRACT_LE_16BITS(p
);
792 w_u_interval
= EXTRACT_LE_16BITS(p
+ 2);
794 ND_PRINT((ndo
, "Rendezvous time = %d, Wake-up Interval = %d",
795 r_time
, w_u_interval
));
798 case 0x1e: /* Time correction IE */
800 ND_PRINT((ndo
, "[ERROR: Length != 2]"));
805 val
= EXTRACT_LE_16BITS(p
);
806 if (val
& 0x8000) { ND_PRINT((ndo
, "Negative ")); }
812 ND_PRINT((ndo
, "Ack time correction = %d, ", timecorr
));
815 case 0x22: /* Frament Sequence Content Description IE */
816 /* XXX Not implemented */
817 case 0x23: /* Simplified Superframe Specification IE */
818 /* XXX Not implemented */
819 case 0x24: /* Simplified GTS Specification IE */
820 /* XXX Not implemented */
821 case 0x25: /* LECIM Capabilities IE */
822 /* XXX Not implemented */
823 case 0x26: /* TRLE Descriptor IE */
824 /* XXX Not implemented */
825 case 0x27: /* RCC Capabilities IE */
826 /* XXX Not implemented */
827 case 0x28: /* RCCN Descriptor IE */
828 /* XXX Not implemented */
829 case 0x29: /* Global Time IE */
830 /* XXX Not implemented */
831 case 0x2b: /* DA IE */
832 /* XXX Not implemented */
834 ND_PRINT((ndo
, "IE Data = "));
835 for(i
= 0; i
< ie_len
; i
++) {
836 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
843 * Parse and print Header IE list. See 7.4.2 of 802.15.4-2015 for
846 * Returns number of byts consumed from the packet or -1 in case of error.
849 ieee802_15_4_print_header_ie_list(netdissect_options
*ndo
,
852 int *payload_ie_present
)
854 int len
, ie
, ie_len
, element_id
, i
;
856 *payload_ie_present
= 0;
860 ND_PRINT((ndo
, "[ERROR: Truncated header IE]"));
863 /* Extract IE Header */
864 ie
= EXTRACT_LE_16BITS(p
);
865 if (CHECK_BIT(ie
, 15)) {
866 ND_PRINT((ndo
, "[ERROR: Header IE with type 1] "));
868 /* Get length and Element ID */
870 element_id
= (ie
>> 7) & 0xff;
871 if (element_id
> 127) {
872 ND_PRINT((ndo
, "Reserved Element ID %02x, length = %d ",
873 element_id
, ie_len
));
876 ND_PRINT((ndo
, "\n\t%s [",
877 h_ie_names
[element_id
]));
879 ND_PRINT((ndo
, "\n\t%s [ length = %d, ",
880 h_ie_names
[element_id
], ie_len
));
883 if (caplen
< ie_len
) {
884 ND_PRINT((ndo
, "[ERROR: Truncated IE data]"));
890 /* Parse and print content. */
891 if (ndo
->ndo_vflag
> 3 && ie_len
!= 0) {
892 ieee802_15_4_print_header_ie(ndo
, p
, ie_len
, element_id
);
895 ND_PRINT((ndo
, "IE Data = "));
896 for(i
= 0; i
< ie_len
; i
++) {
897 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
901 ND_PRINT((ndo
, "] "));
904 caplen
-= 2 + ie_len
;
905 if (element_id
== 0x7e) {
906 *payload_ie_present
= 1;
909 if (element_id
== 0x7f) {
912 } while (caplen
> 0);
917 * Print MLME ie content.
920 ieee802_15_4_print_mlme_ie(netdissect_options
*ndo
,
927 /* Note, as there is no overlap with the long and short
928 MLME sub IDs, we can just use one switch here. */
930 case 0x08: /* Vendor Specific Nested IE */
931 if (sub_ie_len
< 3) {
932 ND_PRINT((ndo
, "[ERROR: Vendor OUI missing]"));
934 ND_PRINT((ndo
, "OUI = 0x%02x%02x%02x, ",
936 EXTRACT_LE_8BITS(p
+ 1),
937 EXTRACT_LE_8BITS(p
+ 2)));
938 ND_PRINT((ndo
, "Data = "));
939 for(i
= 3; i
< sub_ie_len
; i
++) {
940 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
944 case 0x09: /* Channel Hopping IE */
945 if (sub_ie_len
< 1) {
946 ND_PRINT((ndo
, "[ERROR: Hopping sequence ID missing]"));
947 } else if (sub_ie_len
== 1) {
948 ND_PRINT((ndo
, "Hopping Sequence ID = %d", EXTRACT_LE_8BITS(p
)));
952 int channel_page
, number_of_channels
;
954 ND_PRINT((ndo
, "Hopping Sequence ID = %d", EXTRACT_LE_8BITS(p
)));
957 if (sub_ie_len
< 7) {
958 ND_PRINT((ndo
, "[ERROR: IE truncated]"));
961 channel_page
= EXTRACT_LE_8BITS(p
);
962 number_of_channels
= EXTRACT_LE_16BITS(p
+ 1);
963 ND_PRINT((ndo
, "Channel Page = %d, Number of Channels = %d, ",
964 channel_page
, number_of_channels
));
965 ND_PRINT((ndo
, "Phy Configuration = 0x%08x, ",
966 EXTRACT_LE_32BITS(p
+ 3)));
969 if (channel_page
== 9 || channel_page
== 10) {
970 len
= (number_of_channels
+ 7) / 8;
971 if (sub_ie_len
< len
) {
972 ND_PRINT((ndo
, "[ERROR: IE truncated]"));
975 ND_PRINT((ndo
, "Extended bitmap = 0x"));
976 for(i
= 0; i
< len
; i
++) {
977 ND_PRINT((ndo
, "%02x", EXTRACT_LE_8BITS(p
+ i
)));
979 ND_PRINT((ndo
, ", "));
983 if (sub_ie_len
< 2) {
984 ND_PRINT((ndo
, "[ERROR: IE truncated]"));
987 len
= EXTRACT_LE_16BITS(p
);
990 ND_PRINT((ndo
, "Hopping Seq length = %d [ ", len
));
992 if (sub_ie_len
< len
* 2) {
993 ND_PRINT((ndo
, " [ERROR: IE truncated]"));
996 for(i
= 0; i
< len
; i
++) {
997 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_16BITS(p
+ i
* 2)));
999 ND_PRINT((ndo
, "]"));
1001 sub_ie_len
-= len
* 2;
1002 if (sub_ie_len
< 2) {
1003 ND_PRINT((ndo
, "[ERROR: IE truncated]"));
1006 ND_PRINT((ndo
, "Current hop = %d", EXTRACT_LE_16BITS(p
)));
1010 case 0x1a: /* TSCH Syncronization IE. */
1011 if (sub_ie_len
< 6) {
1012 ND_PRINT((ndo
, "[ERROR: Length != 6]"));
1014 ND_PRINT((ndo
, "ASN = %02x%02x%02x%02x%02x, Join Metric = %d ",
1015 EXTRACT_LE_8BITS(p
+ 4), EXTRACT_LE_8BITS(p
+ 3),
1016 EXTRACT_LE_8BITS(p
+ 2), EXTRACT_LE_8BITS(p
+ 1),
1017 EXTRACT_LE_8BITS(p
+ 0), EXTRACT_LE_8BITS(p
+ 5)));
1019 case 0x1b: /* TSCH Slotframe and Link IE. */
1021 int sf_num
, off
, links
, opts
;
1023 if (sub_ie_len
< 1) {
1024 ND_PRINT((ndo
, "[ERROR: Truncated IE]"));
1027 sf_num
= EXTRACT_LE_8BITS(p
);
1028 ND_PRINT((ndo
, "Slotframes = %d ", sf_num
));
1030 for(i
= 0; i
< sf_num
; i
++) {
1031 if (sub_ie_len
< off
+ 4) {
1032 ND_PRINT((ndo
, "[ERROR: Truncated IE before slotframes]"));
1035 links
= EXTRACT_LE_8BITS(p
+ off
+ 3);
1036 ND_PRINT((ndo
, "\n\t\t\t[ Handle %d, size = %d, links = %d ",
1037 EXTRACT_LE_8BITS(p
+ off
),
1038 EXTRACT_LE_16BITS(p
+ off
+ 1),
1041 for(j
= 0; j
< links
; j
++) {
1042 if (sub_ie_len
< off
+ 5) {
1043 ND_PRINT((ndo
, "[ERROR: Truncated IE links]"));
1046 opts
= EXTRACT_LE_8BITS(p
+ off
+ 4);
1047 ND_PRINT((ndo
, "\n\t\t\t\t[ Timeslot = %d, Offset = %d, Options = ",
1048 EXTRACT_LE_16BITS(p
+ off
),
1049 EXTRACT_LE_16BITS(p
+ off
+ 2)));
1050 if (opts
& 0x1) { ND_PRINT((ndo
, "TX ")); }
1051 if (opts
& 0x2) { ND_PRINT((ndo
, "RX ")); }
1052 if (opts
& 0x4) { ND_PRINT((ndo
, "Shared ")); }
1053 if (opts
& 0x8) { ND_PRINT((ndo
, "Timekeeping ")); }
1054 if (opts
& 0x10) { ND_PRINT((ndo
, "Priority ")); }
1056 ND_PRINT((ndo
, "] "));
1058 ND_PRINT((ndo
, "] "));
1062 case 0x1c: /* TSCH Timeslot IE. */
1063 if (sub_ie_len
== 1) {
1064 ND_PRINT((ndo
, "Time slot ID = %d ", EXTRACT_LE_8BITS(p
)));
1065 } else if (sub_ie_len
== 25) {
1066 ND_PRINT((ndo
, "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 ",
1067 EXTRACT_LE_8BITS(p
),
1068 EXTRACT_LE_16BITS(p
+ 1),
1069 EXTRACT_LE_16BITS(p
+ 3),
1070 EXTRACT_LE_16BITS(p
+ 5),
1071 EXTRACT_LE_16BITS(p
+ 7),
1072 EXTRACT_LE_16BITS(p
+ 9),
1073 EXTRACT_LE_16BITS(p
+ 11),
1074 EXTRACT_LE_16BITS(p
+ 13),
1075 EXTRACT_LE_16BITS(p
+ 15),
1076 EXTRACT_LE_16BITS(p
+ 17),
1077 EXTRACT_LE_16BITS(p
+ 19),
1078 EXTRACT_LE_16BITS(p
+ 21),
1079 EXTRACT_LE_16BITS(p
+ 23)));
1080 } else if (sub_ie_len
== 27) {
1081 ND_PRINT((ndo
, "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 ",
1082 EXTRACT_LE_8BITS(p
),
1083 EXTRACT_LE_16BITS(p
+ 1),
1084 EXTRACT_LE_16BITS(p
+ 3),
1085 EXTRACT_LE_16BITS(p
+ 5),
1086 EXTRACT_LE_16BITS(p
+ 7),
1087 EXTRACT_LE_16BITS(p
+ 9),
1088 EXTRACT_LE_16BITS(p
+ 11),
1089 EXTRACT_LE_16BITS(p
+ 13),
1090 EXTRACT_LE_16BITS(p
+ 15),
1091 EXTRACT_LE_16BITS(p
+ 17),
1092 EXTRACT_LE_16BITS(p
+ 19),
1093 EXTRACT_LE_24BITS(p
+ 21),
1094 EXTRACT_LE_24BITS(p
+ 24)));
1096 ND_PRINT((ndo
, "[ERROR: Length not 1, 25, or 27]"));
1097 ND_PRINT((ndo
, "\n\t\t\tIE Data = "));
1098 for(i
= 0; i
< sub_ie_len
; i
++) {
1099 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1103 case 0x1d: /* Hopping timing IE */
1104 /* XXX Not implemented */
1105 case 0x1e: /* Enhanced Beacon Filter IE */
1106 /* XXX Not implemented */
1107 case 0x1f: /* MAC Metrics IE */
1108 /* XXX Not implemented */
1109 case 0x20: /* All MAC Metrics IE */
1110 /* XXX Not implemented */
1111 case 0x21: /* Coexistence Specification IE */
1112 /* XXX Not implemented */
1113 case 0x22: /* SUN Device Capabilities IE */
1114 /* XXX Not implemented */
1115 case 0x23: /* SUN FSK Generic PHY IE */
1116 /* XXX Not implemented */
1117 case 0x24: /* Mode Switch Parameter IE */
1118 /* XXX Not implemented */
1119 case 0x25: /* PHY Parameter Change IE */
1120 /* XXX Not implemented */
1121 case 0x26: /* O-QPSK PHY Mode IE */
1122 /* XXX Not implemented */
1123 case 0x27: /* PCA Allocation IE */
1124 /* XXX Not implemented */
1125 case 0x28: /* LECIM DSSS Operating Mode IE */
1126 /* XXX Not implemented */
1127 case 0x29: /* LECIM FSK Operating Mode IE */
1128 /* XXX Not implemented */
1129 case 0x2b: /* TVWS PHY Operating Mode Description IE */
1130 /* XXX Not implemented */
1131 case 0x2c: /* TVWS Device Capabilities IE */
1132 /* XXX Not implemented */
1133 case 0x2d: /* TVWS Device Catagory IE */
1134 /* XXX Not implemented */
1135 case 0x2e: /* TVWS Device Identification IE */
1136 /* XXX Not implemented */
1137 case 0x2f: /* TVWS Device Location IE */
1138 /* XXX Not implemented */
1139 case 0x30: /* TVWS Channel Information Query IE */
1140 /* XXX Not implemented */
1141 case 0x31: /* TVWS Channel Information Source IE */
1142 /* XXX Not implemented */
1143 case 0x32: /* CTM IE */
1144 /* XXX Not implemented */
1145 case 0x33: /* Timestamp IE */
1146 /* XXX Not implemented */
1147 case 0x34: /* Timestamp Difference IE */
1148 /* XXX Not implemented */
1149 case 0x35: /* TMCTP Specification IE */
1150 /* XXX Not implemented */
1151 case 0x36: /* TCC PHY Operating Mode IE */
1152 /* XXX Not implemented */
1154 ND_PRINT((ndo
, "IE Data = "));
1155 for(i
= 0; i
< sub_ie_len
; i
++) {
1156 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1163 * MLME IE list parsing and printing. See 7.4.3.2 of 802.15.4-2015
1164 * for more information.
1167 ieee802_15_4_print_mlme_ie_list(netdissect_options
*ndo
,
1171 int ie
, sub_ie_len
, sub_id
, i
, type
;
1175 ND_PRINT((ndo
, "[ERROR: Truncated MLME IE]"));
1178 /* Extract IE header */
1179 ie
= EXTRACT_LE_16BITS(p
);
1180 type
= CHECK_BIT(ie
, 15);
1183 sub_ie_len
= ie
& 0x3ff;
1184 sub_id
= (ie
>> 11) & 0x0f;
1186 sub_ie_len
= ie
& 0xff;
1187 sub_id
= (ie
>> 8) & 0x7f;
1190 /* Skip the IE header */
1194 ND_PRINT((ndo
, "\n\t\t%s [ length = %d, ",
1195 p_mlme_short_names
[sub_id
], sub_ie_len
));
1197 ND_PRINT((ndo
, "\n\t\t%s [ length = %d, ",
1198 p_mlme_long_names
[sub_id
], sub_ie_len
));
1201 if (ie_len
< sub_ie_len
) {
1202 ND_PRINT((ndo
, "[ERROR: Truncated IE data]"));
1205 if (sub_ie_len
!= 0) {
1206 if (ndo
->ndo_vflag
> 3) {
1207 ieee802_15_4_print_mlme_ie(ndo
, p
, sub_ie_len
, sub_id
);
1208 } else if (ndo
->ndo_vflag
> 2) {
1209 ND_PRINT((ndo
, "IE Data = "));
1210 for(i
= 0; i
< sub_ie_len
; i
++) {
1211 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1215 ND_PRINT((ndo
, "] "));
1217 ie_len
-= 2 + sub_ie_len
;
1218 } while (ie_len
> 0);
1223 * Payload IE list parsing and printing. See 7.4.3 of 802.15.4-2015
1224 * for more information.
1226 * Returns number of byts consumed from the packet or -1 in case of error.
1229 ieee802_15_4_print_payload_ie_list(netdissect_options
*ndo
,
1233 int len
, ie
, ie_len
, group_id
, i
;
1238 ND_PRINT((ndo
, "[ERROR: Truncated header IE]"));
1241 /* Extract IE header */
1242 ie
= EXTRACT_LE_16BITS(p
);
1243 if ((CHECK_BIT(ie
, 15)) == 0) {
1244 ND_PRINT((ndo
, "[ERROR: Payload IE with type 0] "));
1246 ie_len
= ie
& 0x3ff;
1247 group_id
= (ie
>> 11) & 0x0f;
1249 /* Skip the IE header */
1252 ND_PRINT((ndo
, "\n\t%s [", p_ie_names
[group_id
]));
1254 ND_PRINT((ndo
, "\n\t%s [ length = %d, ",
1255 p_ie_names
[group_id
], ie_len
));
1257 if (caplen
< ie_len
) {
1258 ND_PRINT((ndo
, "[ERROR: Truncated IE data]"));
1261 if (ndo
->ndo_vflag
> 3 && ie_len
!= 0) {
1263 case 0x1: /* MLME IE */
1264 ieee802_15_4_print_mlme_ie_list(ndo
, p
, ie_len
);
1266 case 0x2: /* Vendor Specific Nested IE */
1268 ND_PRINT((ndo
, "[ERROR: Vendor OUI missing]"));
1270 ND_PRINT((ndo
, "OUI = 0x%02x%02x%02x, ",
1271 EXTRACT_LE_8BITS(p
),
1272 EXTRACT_LE_8BITS(p
+ 1),
1273 EXTRACT_LE_8BITS(p
+ 2)));
1274 ND_PRINT((ndo
, "Data = "));
1275 for(i
= 3; i
< ie_len
; i
++) {
1276 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1280 case 0x3: /* Multiplexed IE (802.15.9) */
1282 ND_PRINT((ndo
, "[ERROR: Transaction control byte missing]"));
1284 int transfer_type
, tid
, fragment_number
, data_start
;
1285 transfer_type
= EXTRACT_LE_8BITS(p
) & 0x7;
1286 tid
= EXTRACT_LE_8BITS(p
) >> 3;
1287 switch (transfer_type
) {
1288 case 0x00: /* Full upper layer frame. */
1289 case 0x01: /* Full upper layer frame with small Multiplex ID. */
1291 ND_PRINT((ndo
, "Type = Full upper layer fragment%s, ",
1292 (transfer_type
== 0x01 ?
1293 " with small Multiplex ID" : "")));
1294 if (transfer_type
== 0x00) {
1296 ND_PRINT((ndo
, "[ERROR: Multiplex ID missing]"));
1299 ND_PRINT((ndo
, "tid = 0x%02x, Multiplex ID = 0x%04x, ",
1300 tid
, EXTRACT_LE_16BITS(p
+ 1)));
1303 ND_PRINT((ndo
, "Multiplex ID = 0x%04x, ", tid
));
1305 ND_PRINT((ndo
, "Upper layer data = "));
1306 for(i
= data_start
; i
< ie_len
; i
++) {
1307 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1310 case 0x02: /* First, or middle, Fragments */
1311 case 0x04: /* Last fragment */
1313 ND_PRINT((ndo
, "[ERROR: fragment number missing]"));
1315 fragment_number
= EXTRACT_LE_8BITS(p
+ 1);
1316 ND_PRINT((ndo
, "Type = %s, tid = 0x%02x, fragment = 0x%02x, ",
1317 (transfer_type
== 0x02 ?
1318 (fragment_number
== 0 ?
1319 "First fragment" : "Middle fragment") :
1320 "Last fragment"), tid
,
1323 if (fragment_number
== 0) {
1325 ND_PRINT((ndo
, "[ERROR: Total upper layer size or multiplex ID missing]"));
1327 int total_size
, multiplex_id
;
1328 total_size
= EXTRACT_LE_16BITS(p
+ 2);
1329 multiplex_id
= EXTRACT_LE_16BITS(p
+ 4);
1330 ND_PRINT((ndo
, "Total upper layer size = 0x%04x, Multiplex ID = 0x%04x, ",
1331 total_size
, multiplex_id
));
1335 ND_PRINT((ndo
, "Upper layer data = "));
1336 for(i
= data_start
; i
< ie_len
; i
++) {
1337 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1341 case 0x06: /* Abort code */
1343 ND_PRINT((ndo
, "Type = Abort, tid = 0x%02x, no max size given",
1345 } else if (ie_len
== 3) {
1346 ND_PRINT((ndo
, "Type = Abort, tid = 0x%02x, max size = 0x%04x",
1347 tid
, EXTRACT_LE_16BITS(p
+ 1)));
1349 ND_PRINT((ndo
, "Type = Abort, tid = 0x%02x, invalid length = %d (not 1 or 3)",
1351 ND_PRINT((ndo
, "Abort data = "));
1352 for(i
= 1; i
< ie_len
; i
++) {
1353 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1357 case 0x03: /* Reserved */
1358 case 0x05: /* Reserved */
1359 case 0x07: /* Reserved */
1360 ND_PRINT((ndo
, "Type = %d (Reserved), tid = 0x%02x, ",
1361 transfer_type
, tid
));
1362 ND_PRINT((ndo
, "Upper layer data = "));
1363 for(i
= 1; i
< ie_len
; i
++) {
1364 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1370 case 0x5: /* IETF IE */
1372 ND_PRINT((ndo
, "[ERROR: Subtype ID missing]"));
1374 ND_PRINT((ndo
, "Subtype ID = 0x%02x, Subtype content = ",
1375 EXTRACT_LE_8BITS(p
)));
1376 for(i
= 1; i
< ie_len
; i
++) {
1377 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1382 ND_PRINT((ndo
, "IE Data = "));
1383 for(i
= 0; i
< ie_len
; i
++) {
1384 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1390 ND_PRINT((ndo
, "IE Data = "));
1391 for(i
= 0; i
< ie_len
; i
++) {
1392 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1396 ND_PRINT((ndo
, "]\n\t"));
1399 caplen
-= 2 + ie_len
;
1400 if (group_id
== 0xf) {
1403 } while (caplen
> 0);
1408 * Parse and print auxiliary security header.
1410 * Returns number of byts consumed from the packet or -1 in case of error.
1413 ieee802_15_4_print_aux_sec_header(netdissect_options
*ndo
,
1416 int *security_level
)
1418 int sc
, key_id_mode
, len
;
1421 ND_PRINT((ndo
, "[ERROR: Truncated before Aux Security Header]"));
1424 sc
= EXTRACT_LE_8BITS(p
);
1426 *security_level
= sc
& 0x7;
1427 key_id_mode
= (sc
>> 3) & 0x3;
1432 if (ndo
->ndo_vflag
> 0) {
1433 ND_PRINT((ndo
, "\n\tSecurity Level %d, Key Id Mode %d, ",
1434 *security_level
, key_id_mode
));
1436 if ((CHECK_BIT(sc
, 5)) == 0) {
1438 ND_PRINT((ndo
, "[ERROR: Truncated before Frame Counter]"));
1444 if (ndo
->ndo_vflag
> 1) {
1445 ND_PRINT((ndo
, "Frame Counter 0x%08x ",
1446 EXTRACT_LE_32BITS(p
+ 1)));
1449 switch (key_id_mode
) {
1450 case 0x00: /* Implicit. */
1451 if (ndo
->ndo_vflag
> 1) {
1452 ND_PRINT((ndo
, "Implicit"));
1456 case 0x01: /* Key Index, nothing to print here. */
1458 case 0x02: /* PAN and Short address Key Source, and Key Index. */
1460 ND_PRINT((ndo
, "[ERROR: Truncated before Key Source]"));
1463 if (ndo
->ndo_vflag
> 1) {
1464 ND_PRINT((ndo
, "KeySource 0x%04x:%0x4x, ",
1465 EXTRACT_LE_16BITS(p
), EXTRACT_LE_16BITS(p
+ 2)));
1471 case 0x03: /* Extended address and Key Index. */
1473 ND_PRINT((ndo
, "[ERROR: Truncated before Key Source]"));
1476 if (ndo
->ndo_vflag
> 1) {
1477 ND_PRINT((ndo
, "KeySource %s, ", le64addr_string(ndo
, p
)));
1485 ND_PRINT((ndo
, "[ERROR: Truncated before Key Index]"));
1488 if (ndo
->ndo_vflag
> 1) {
1489 ND_PRINT((ndo
, "KeyIndex 0x%02x, ", EXTRACT_LE_8BITS(p
)));
1498 * Print command data.
1500 * Returns number of byts consumed from the packet or -1 in case of error.
1503 ieee802_15_4_print_command_data(netdissect_options
*ndo
,
1510 switch (command_id
) {
1511 case 0x01: /* Assocation Request */
1513 ND_PRINT((ndo
, "Invalid Assocation request command length"));
1517 cap_info
= EXTRACT_LE_8BITS(p
);
1518 ND_PRINT((ndo
, "%s%s%s%s%s%s",
1519 ((cap_info
& 0x02) ? "FFD, " : "RFD, "),
1520 ((cap_info
& 0x04) ? "AC powered, " : ""),
1521 ((cap_info
& 0x08) ? "Receiver on when idle, " : ""),
1522 ((cap_info
& 0x10) ? "Fast association, " : ""),
1523 ((cap_info
& 0x40) ? "Security supported, " : ""),
1524 ((cap_info
& 0x80) ? "Allocate address, " : "")));
1528 case 0x02: /* Assocation Response */
1530 ND_PRINT((ndo
, "Invalid Assocation response command length"));
1533 ND_PRINT((ndo
, "Short address = "));
1534 ieee802_15_4_print_addr(ndo
, p
, 2);
1535 switch (EXTRACT_LE_8BITS(p
+ 2)) {
1537 ND_PRINT((ndo
, ", Association successful"));
1540 ND_PRINT((ndo
, ", PAN at capacity"));
1543 ND_PRINT((ndo
, ", PAN access denied"));
1546 ND_PRINT((ndo
, ", Hooping sequence offset duplication"));
1549 ND_PRINT((ndo
, ", Fast association successful"));
1552 ND_PRINT((ndo
, ", Status = 0x%02x", EXTRACT_LE_8BITS(p
+ 2)));
1558 case 0x03: /* Diassociation Notification command */
1560 ND_PRINT((ndo
, "Invalid Disassociation Notification command length"));
1563 switch (EXTRACT_LE_8BITS(p
)) {
1565 ND_PRINT((ndo
, "Reserved"));
1568 ND_PRINT((ndo
, "Reason = The coordinator wishes the device to leave PAN"));
1571 ND_PRINT((ndo
, "Reason = The device wishes to leave the PAN"));
1574 ND_PRINT((ndo
, "Reason = 0x%02x", EXTRACT_LE_8BITS(p
+ 2)));
1580 /* Following ones do not have any data. */
1581 case 0x04: /* Data Request command */
1582 case 0x05: /* PAN ID Conflict Notification command */
1583 case 0x06: /* Orphan Notification command */
1584 case 0x07: /* Beacon Request command */
1585 /* Should not have any data. */
1587 case 0x08: /* Coordinator Realignment command */
1588 if (caplen
< 7 || caplen
> 8) {
1589 ND_PRINT((ndo
, "Invalid Coordinator Realignment command length"));
1592 uint16_t channel
, page
;
1594 ND_PRINT((ndo
, "Pan ID = 0x%04x, Coordinator short address = ",
1595 EXTRACT_LE_16BITS(p
)));
1596 ieee802_15_4_print_addr(ndo
, p
+ 2, 2);
1597 channel
= EXTRACT_LE_8BITS(p
+ 4);
1600 page
= EXTRACT_LE_8BITS(p
+ 7);
1604 if (CHECK_BIT(page
, 7)) {
1605 /* No page present, instead we have msb of
1606 channel in the page. */
1607 channel
|= (page
& 0x7f) << 8;
1608 ND_PRINT((ndo
, ", Channel Number = %d", channel
));
1610 ND_PRINT((ndo
, ", Channel Number = %d, page = %d",
1613 ND_PRINT((ndo
, ", Short address = "));
1614 ieee802_15_4_print_addr(ndo
, p
+ 5, 2);
1618 case 0x09: /* GTS Request command */
1620 ND_PRINT((ndo
, "Invalid GTS Request command length"));
1625 gts
= EXTRACT_LE_8BITS(p
);
1626 ND_PRINT((ndo
, "GTS Length = %d, %s, %s",
1628 (CHECK_BIT(gts
, 4) ? "Receive-only GTS" : "Transmit-only GTS"),
1629 (CHECK_BIT(gts
, 5) ? "GTS allocation" : "GTS deallocations")));
1633 case 0x13: /* DSME Association Request command */
1634 /* XXX Not implemented */
1635 case 0x14: /* DSME Association Response command */
1636 /* XXX Not implemented */
1637 case 0x15: /* DSME GTS Request command */
1638 /* XXX Not implemented */
1639 case 0x16: /* DSME GTS Response command */
1640 /* XXX Not implemented */
1641 case 0x17: /* DSME GTS GTS Notify command */
1642 /* XXX Not implemented */
1643 case 0x18: /* DSME Information Request command */
1644 /* XXX Not implemented */
1645 case 0x19: /* DSME Information Response command */
1646 /* XXX Not implemented */
1647 case 0x1a: /* DSME Beacon Allocation Notification command */
1648 /* XXX Not implemented */
1649 case 0x1b: /* DSME Beacon Collision Notification command */
1650 /* XXX Not implemented */
1651 case 0x1c: /* DSME Link Report command */
1652 /* XXX Not implemented */
1653 case 0x20: /* RIT Data Request command */
1654 /* XXX Not implemented */
1655 case 0x21: /* DBS Request command */
1656 /* XXX Not implemented */
1657 case 0x22: /* DBS Response command */
1658 /* XXX Not implemented */
1659 case 0x23: /* RIT Data Response command */
1660 /* XXX Not implemented */
1661 case 0x24: /* Vendor Specific command */
1662 /* XXX Not implemented */
1663 case 0x0a: /* TRLE Management Request command */
1664 /* XXX Not implemented */
1665 case 0x0b: /* TRLE Management Response command */
1666 /* XXX Not implemented */
1668 ND_PRINT((ndo
, "Command Data = "));
1669 for(i
= 0; i
< caplen
; i
++) {
1670 ND_PRINT((ndo
, "%02x ", EXTRACT_LE_8BITS(p
+ i
)));
1678 * Parse and print frames folloing standard format.
1680 * Returns FALSE in case of error.
1683 ieee802_15_4_std_frames(netdissect_options
*ndo
,
1684 const u_char
*p
, u_int caplen
,
1687 int len
, frame_version
, pan_id_comp
;
1689 int src_pan
, dst_pan
, src_addr_len
, dst_addr_len
;
1690 int security_level
, miclen
= 0;
1691 int payload_ie_present
;
1692 uint8_t seq
, fcs_len
;
1693 uint32_t fcs
, crc_check
;
1694 const u_char
*mic_start
= NULL
;
1696 payload_ie_present
= 0;
1698 /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
1701 /* Cannot have FCS, assume fcs_len of 0. */
1707 fcs
= EXTRACT_LE_16BITS(p
+ caplen
- 2);
1708 crc_check
= ieee802_15_4_crc16(p
, caplen
- 2);
1709 if (crc_check
!= fcs
) {
1710 /* Wrong fcs, might not contain fcs, do not remove it. */
1717 /* Frame version. */
1718 frame_version
= (fc
>> 12) & 0x03;
1719 frame_type
= fc
& 0x7;
1720 ND_PRINT((ndo
, "v%d ", frame_version
));
1722 if (ndo
->ndo_vflag
> 2) {
1723 if (CHECK_BIT(fc
, 3)) { ND_PRINT((ndo
, "Security Enabled, ")); }
1724 if (CHECK_BIT(fc
, 4)) { ND_PRINT((ndo
, "Frame Pending, ")); }
1725 if (CHECK_BIT(fc
, 5)) { ND_PRINT((ndo
, "AR, ")); }
1726 if (CHECK_BIT(fc
, 6)) { ND_PRINT((ndo
, "PAN ID Compression, ")); }
1727 if (CHECK_BIT(fc
, 8)) { ND_PRINT((ndo
, "Sequence Number Suppression, ")); }
1728 if (CHECK_BIT(fc
, 9)) { ND_PRINT((ndo
, "IE present, ")); }
1731 /* Check for the sequence number supression. */
1732 if (CHECK_BIT(fc
, 8)) {
1733 /* Sequence number is suppressed. */
1734 if (frame_version
< 2) {
1735 /* Sequence number can only be supressed for frame
1736 version 2 or higher, this is invalid frame. */
1737 ND_PRINT((ndo
, "[ERROR: Sequence number suppressed on frames where version < 2]"));
1740 ND_PRINT((ndo
,"seq suppressed "));
1744 seq
= EXTRACT_LE_8BITS(p
+ 2);
1748 ND_PRINT((ndo
,"seq %02x ", seq
));
1751 /* See which parts of addresses we have. */
1752 dst_addr_len
= ieee802_15_4_addr_len((fc
>> 10) & 0x3);
1753 src_addr_len
= ieee802_15_4_addr_len((fc
>> 14) & 0x3);
1754 if (src_addr_len
< 0) {
1755 ND_PRINT((ndo
,"[ERROR: Invalid src address mode]"));
1758 if (dst_addr_len
< 0) {
1759 ND_PRINT((ndo
,"[ERROR: Invalid dst address mode]"));
1764 pan_id_comp
= CHECK_BIT(fc
, 6);
1766 /* The PAN ID Compression rules are complicated. */
1768 /* First check old versions, where the rules are simple. */
1769 if (frame_version
< 2) {
1773 if (dst_addr_len
<= 0 || src_addr_len
<= 0) {
1774 /* Invalid frame, PAN ID Compression must be 0
1775 if only one address in the frame. */
1776 ND_PRINT((ndo
,"[ERROR: PAN ID Compression != 0, and only one address with frame version < 2]"));
1782 if (dst_addr_len
<= 0) {
1785 if (src_addr_len
<= 0) {
1789 /* Frame version 2 rules are more complicated, and they depend
1790 on the address modes of the frame, generic rules are same,
1791 but then there are some special cases. */
1799 if (dst_addr_len
<= 0) {
1802 if (src_addr_len
<= 0) {
1806 if (src_addr_len
== 0 &&
1807 dst_addr_len
== 0) {
1808 /* Both addresses are missing, but PAN ID
1809 compression set, special case we have
1810 destination PAN but no addresses. */
1812 } else if ((src_addr_len
== 0 &&
1813 dst_addr_len
> 0) ||
1814 (src_addr_len
> 0 &&
1815 dst_addr_len
== 0)) {
1816 /* Only one address present, and PAN ID
1817 compression is set, we do not have PAN id at
1821 } else if (src_addr_len
== 8 &&
1822 dst_addr_len
== 8) {
1823 /* Both addresses are Extended, and PAN ID
1824 compression set, we do not have PAN ID at
1830 /* Special cases where PAN ID Compression is not set. */
1831 if (src_addr_len
== 8 &&
1832 dst_addr_len
== 8) {
1833 /* Both addresses are Extended, and PAN ID
1834 compression not set, we do have only one PAN
1835 ID (destination). */
1839 #ifdef BROKEN_6TISCH_PAN_ID_COMPRESSION
1840 if (src_addr_len
== 8 &&
1841 dst_addr_len
== 2) {
1842 /* Special case for the broken 6tisch
1846 #endif /* BROKEN_6TISCH_PAN_ID_COMPRESSION */
1850 /* Print dst PAN and address. */
1853 ND_PRINT((ndo
, "[ERROR: Truncated before dst_pan]"));
1856 ND_PRINT((ndo
, "%04x:", EXTRACT_LE_16BITS(p
)));
1860 ND_PRINT((ndo
, "-:"));
1862 if (caplen
< (u_int
) dst_addr_len
) {
1863 ND_PRINT((ndo
, "[ERROR: Truncated before dst_addr]"));
1866 ieee802_15_4_print_addr(ndo
, p
, dst_addr_len
);
1868 caplen
-= dst_addr_len
;
1870 ND_PRINT((ndo
," < "));
1872 /* Print src PAN and address. */
1875 ND_PRINT((ndo
, "[ERROR: Truncated before dst_pan]"));
1878 ND_PRINT((ndo
, "%04x:", EXTRACT_LE_16BITS(p
)));
1882 ND_PRINT((ndo
, "-:"));
1884 if (caplen
< (u_int
) src_addr_len
) {
1885 ND_PRINT((ndo
, "[ERROR: Truncated before dst_addr]"));
1888 ieee802_15_4_print_addr(ndo
, p
, src_addr_len
);
1889 ND_PRINT((ndo
, " "));
1891 caplen
-= src_addr_len
;
1892 if (CHECK_BIT(fc
, 3)) {
1893 len
= ieee802_15_4_print_aux_sec_header(ndo
, p
, caplen
, &security_level
);
1903 switch (security_level
) {
1904 case 0: /*FALLTHOUGH */
1908 case 1: /*FALLTHOUGH */
1912 case 2: /*FALLTHOUGH */
1916 case 3: /*FALLTHOUGH */
1924 if (caplen
< (u_int
) miclen
) {
1925 ND_PRINT((ndo
, "[ERROR: Truncated before MIC]"));
1929 mic_start
= p
+ caplen
;
1932 /* Parse Information elements if present */
1933 if (CHECK_BIT(fc
, 9)) {
1934 /* Yes we have those. */
1935 len
= ieee802_15_4_print_header_ie_list(ndo
, p
, caplen
,
1936 &payload_ie_present
);
1944 if (payload_ie_present
) {
1945 if (security_level
>= 4) {
1946 ND_PRINT((ndo
, "Payload IEs present, but encrypted, cannot print "));
1948 len
= ieee802_15_4_print_payload_ie_list(ndo
, p
, caplen
);
1958 if (ndo
->ndo_vflag
> 2 && miclen
!= 0) {
1959 ND_PRINT((ndo
, "\n\tMIC "));
1961 for(len
= 0; len
< miclen
; len
+= 4) {
1962 ND_PRINT((ndo
, "%08x", EXTRACT_32BITS(mic_start
+ len
)));
1964 ND_PRINT((ndo
, " "));
1968 if (ndo
->ndo_vflag
> 2) {
1969 if (crc_check
== fcs
) {
1970 ND_PRINT((ndo
, "FCS %04x ", fcs
));
1972 ND_PRINT((ndo
, "wrong FCS %04x vs %04x (assume no FCS stored) ",
1978 switch (frame_type
) {
1979 case 0x00: /* Beacon */
1980 if (frame_version
< 2) {
1982 ND_PRINT((ndo
, "[ERROR: Truncated before beacon information]"));
1987 ss
= EXTRACT_LE_16BITS(p
);
1988 ieee802_15_4_print_superframe_specification(ndo
, ss
);
1994 ND_PRINT((ndo
, "[ERROR: Truncated before GTS info]"));
1998 len
= ieee802_15_4_print_gts_info(ndo
, p
, caplen
);
2006 /* Pending Addresses */
2008 ND_PRINT((ndo
, "[ERROR: Truncated before pending addresses]"));
2011 len
= ieee802_15_4_print_pending_addresses(ndo
, p
, caplen
);
2019 if (!ndo
->ndo_suppress_default_print
)
2020 ND_DEFAULTPRINT(p
, caplen
);
2023 case 0x01: /* Data */
2024 case 0x02: /* Acknowledgement */
2025 if (!ndo
->ndo_suppress_default_print
)
2026 ND_DEFAULTPRINT(p
, caplen
);
2028 case 0x03: /* MAC Command */
2030 ND_PRINT((ndo
, "[ERROR: Truncated before Command ID]"));
2034 command_id
= EXTRACT_LE_8BITS(p
);
2035 if (command_id
>= 0x30) {
2036 ND_PRINT((ndo
, "Command ID = Reserved 0x%02x ", command_id
));
2038 ND_PRINT((ndo
, "Command ID = %s ", mac_c_names
[command_id
]));
2043 len
= ieee802_15_4_print_command_data(ndo
, command_id
, p
, caplen
);
2050 if (!ndo
->ndo_suppress_default_print
)
2051 ND_DEFAULTPRINT(p
, caplen
);
2058 * Print and parse Multipurpose frames.
2060 * Returns FALSE in case of error.
2063 ieee802_15_4_mp_frame(netdissect_options
*ndo
,
2064 const u_char
*p
, u_int caplen
,
2067 int len
, frame_version
, pan_id_present
;
2068 int src_addr_len
, dst_addr_len
;
2069 int security_level
, miclen
= 0;
2070 int ie_present
, payload_ie_present
, security_enabled
;
2071 uint8_t seq
, fcs_len
;
2072 uint32_t fcs
, crc_check
;
2073 const u_char
*mic_start
= NULL
;
2077 payload_ie_present
= 0;
2078 security_enabled
= 0;
2080 /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
2083 /* Cannot have FCS, assume fcs_len of 0. */
2089 fcs
= EXTRACT_LE_16BITS(p
+ caplen
- 2);
2090 crc_check
= ieee802_15_4_crc16(p
, caplen
- 2);
2091 if (crc_check
!= fcs
) {
2092 /* Wrong fcs, might not contain fcs, do not remove it. */
2099 if (CHECK_BIT(fc
, 3)) {
2100 /* Long Frame Control */
2102 /* Frame version. */
2103 frame_version
= (fc
>> 12) & 0x03;
2104 ND_PRINT((ndo
, "v%d ", frame_version
));
2106 pan_id_present
= CHECK_BIT(fc
, 8);
2107 ie_present
= CHECK_BIT(fc
, 15);
2108 security_enabled
= CHECK_BIT(fc
, 9);
2110 if (ndo
->ndo_vflag
> 2) {
2111 if (security_enabled
) { ND_PRINT((ndo
, "Security Enabled, ")); }
2112 if (CHECK_BIT(fc
, 11)) { ND_PRINT((ndo
, "Frame Pending, ")); }
2113 if (CHECK_BIT(fc
, 14)) { ND_PRINT((ndo
, "AR, ")); }
2114 if (pan_id_present
) { ND_PRINT((ndo
, "PAN ID Present, ")); }
2115 if (CHECK_BIT(fc
, 10)) {
2116 ND_PRINT((ndo
, "Sequence Number Suppression, "));
2118 if (ie_present
) { ND_PRINT((ndo
, "IE present, ")); }
2121 /* Check for the sequence number supression. */
2122 if (CHECK_BIT(fc
, 10)) {
2123 /* Sequence number is suppressed, but long version. */
2127 seq
= EXTRACT_LE_8BITS(p
+ 2);
2131 ND_PRINT((ndo
,"seq %02x ", seq
));
2134 /* Short format of header, but with seq no */
2135 seq
= EXTRACT_LE_8BITS(p
+ 1);
2139 ND_PRINT((ndo
,"seq %02x ", seq
));
2142 /* See which parts of addresses we have. */
2143 dst_addr_len
= ieee802_15_4_addr_len((fc
>> 4) & 0x3);
2144 src_addr_len
= ieee802_15_4_addr_len((fc
>> 6) & 0x3);
2145 if (src_addr_len
< 0) {
2146 ND_PRINT((ndo
,"[ERROR: Invalid src address mode]"));
2149 if (dst_addr_len
< 0) {
2150 ND_PRINT((ndo
,"[ERROR: Invalid dst address mode]"));
2154 /* Print dst PAN and address. */
2155 if (pan_id_present
) {
2157 ND_PRINT((ndo
, "[ERROR: Truncated before dst_pan]"));
2160 ND_PRINT((ndo
, "%04x:", EXTRACT_LE_16BITS(p
)));
2164 ND_PRINT((ndo
, "-:"));
2166 if (caplen
< (u_int
) dst_addr_len
) {
2167 ND_PRINT((ndo
, "[ERROR: Truncated before dst_addr]"));
2170 ieee802_15_4_print_addr(ndo
, p
, dst_addr_len
);
2172 caplen
-= dst_addr_len
;
2174 ND_PRINT((ndo
," < "));
2176 /* Print src PAN and address. */
2177 ND_PRINT((ndo
, " -:"));
2178 if (caplen
< (u_int
) src_addr_len
) {
2179 ND_PRINT((ndo
, "[ERROR: Truncated before dst_addr]"));
2182 ieee802_15_4_print_addr(ndo
, p
, src_addr_len
);
2183 ND_PRINT((ndo
, " "));
2185 caplen
-= src_addr_len
;
2187 if (security_enabled
) {
2188 len
= ieee802_15_4_print_aux_sec_header(ndo
, p
, caplen
, &security_level
);
2198 switch (security_level
) {
2199 case 0: /*FALLTHOUGH */
2203 case 1: /*FALLTHOUGH */
2207 case 2: /*FALLTHOUGH */
2211 case 3: /*FALLTHOUGH */
2219 if (caplen
< (u_int
) miclen
) {
2220 ND_PRINT((ndo
, "[ERROR: Truncated before MIC]"));
2224 mic_start
= p
+ caplen
;
2227 /* Parse Information elements if present */
2229 /* Yes we have those. */
2230 len
= ieee802_15_4_print_header_ie_list(ndo
, p
, caplen
,
2231 &payload_ie_present
);
2239 if (payload_ie_present
) {
2240 if (security_level
>= 4) {
2241 ND_PRINT((ndo
, "Payload IEs present, but encrypted, cannot print "));
2243 len
= ieee802_15_4_print_payload_ie_list(ndo
, p
, caplen
);
2253 if (ndo
->ndo_vflag
> 2 && miclen
!= 0) {
2254 ND_PRINT((ndo
, "\n\tMIC "));
2256 for(len
= 0; len
< miclen
; len
+= 4) {
2257 ND_PRINT((ndo
, "%08x", EXTRACT_32BITS(mic_start
+ len
)));
2259 ND_PRINT((ndo
, " "));
2264 if (ndo
->ndo_vflag
> 2) {
2265 if (crc_check
== fcs
) {
2266 ND_PRINT((ndo
, "FCS %04x ", fcs
));
2268 ND_PRINT((ndo
, "wrong FCS %04x vs %04x (assume no FCS stored) ",
2273 if (!ndo
->ndo_suppress_default_print
)
2274 ND_DEFAULTPRINT(p
, caplen
);
2282 * Returns FALSE in case of error.
2285 ieee802_15_4_frag_frame(netdissect_options
*ndo
__attribute__ ((unused
)),
2286 const u_char
*p
__attribute__ ((unused
)),
2287 u_int caplen
__attribute__ ((unused
)),
2288 uint16_t fc
__attribute__ ((unused
)))
2290 /* Not implement yet, might be bit hard to implement, as the
2291 * information to set up the fragment is coming in the previous frame
2292 * in the Fragment Sequence Context Description IE, thus we need to
2293 * store information from there, so we can use it here. */
2298 * Interal call to dissector taking packet + len instead of pcap_pkthdr.
2300 * Returns FALSE in case of error.
2303 ieee802_15_4_print(netdissect_options
*ndo
,
2304 const u_char
*p
, u_int caplen
)
2310 ND_PRINT((ndo
, "[|802.15.4] %x", caplen
));
2314 fc
= EXTRACT_LE_16BITS(p
);
2316 /* First we need to check the frame type to know how to parse the rest
2317 of the FC. Frame type is the first 3 bit of the frame control field.
2320 frame_type
= fc
& 0x7;
2321 ND_PRINT((ndo
,"IEEE 802.15.4 %s packet ", ftypes
[frame_type
]));
2323 switch (frame_type
) {
2324 case 0x00: /* Beacon */
2325 case 0x01: /* Data */
2326 case 0x02: /* Acknowledgement */
2327 case 0x03: /* MAC Command */
2328 return ieee802_15_4_std_frames(ndo
, p
, caplen
, fc
);
2330 case 0x04: /* Reserved */
2333 case 0x05: /* Multipurpose */
2334 return ieee802_15_4_mp_frame(ndo
, p
, caplen
, fc
);
2336 case 0x06: /* Fragment or Frak */
2337 return ieee802_15_4_frag_frame(ndo
, p
, caplen
, fc
);
2339 case 0x07: /* Extended */
2347 * Main function to print packets.
2351 ieee802_15_4_if_print(netdissect_options
*ndo
,
2352 const struct pcap_pkthdr
*h
, const u_char
*p
)
2354 u_int caplen
= h
->caplen
;
2355 return ieee802_15_4_print(ndo
, p
, caplen
);