]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_15_4.c
Added 802.15.9 and IETF IE parser.
[tcpdump] / print-802_15_4.c
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 /* \summary: IEEE 802.15.4 printer */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <netdissect-stdinc.h>
30
31 #include "netdissect.h"
32 #include "addrtoname.h"
33
34 #include "extract.h"
35
36 #define CHECK_BIT(num,bit) (((num) >> (bit)) & 0x1)
37
38 #define BROKEN_6TISCH_PAN_ID_COMPRESSION 0
39
40 /* Frame types from Table 7-1 of 802.15.4-2015 */
41 static const char *ftypes[] = {
42 "Beacon", /* 0 */
43 "Data", /* 1 */
44 "ACK", /* 2 */
45 "Command", /* 3 */
46 "Reserved", /* 4 */
47 "Multipurpose", /* 5 */
48 "Fragment", /* 6 */
49 "Extended" /* 7 */
50 };
51
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 */
97 "DA IE", /* 0x2b */
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 */
182 };
183
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 */
202 };
203
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 */
256 "CTM IE", /* 0x32 */
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 */
334 };
335
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 */
354 };
355
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 */
406 };
407
408
409 /*
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.
413 */
414 static uint16_t
415 ieee802_15_4_crc16(const u_char *p,
416 uint16_t data_len)
417 {
418 uint16_t crc;
419 u_char x, y;
420
421 crc = 0x0000; /* Note, initial value is 0x0000 not 0xffff. */
422
423 while (data_len--){
424 y = *p++;
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));
429 /* Update CRC */
430 x = crc >> 8 ^ y;
431 x ^= x >> 4;
432 crc = (crc << 8) ^
433 ((unsigned short)(x << 12)) ^
434 ((unsigned short)(x <<5)) ^
435 ((unsigned short)x);
436 }
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));
442 return crc;
443 }
444
445 /*
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.
448 */
449 static int
450 ieee802_15_4_addr_len(uint16_t addr_type)
451 {
452 switch (addr_type) {
453 case 0x00: /* None. */
454 return 0;
455 break;
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. */
459 return -1;
460 break;
461 case 0x02: /* Short. */
462 return 2;
463 break;
464 case 0x03: /* Extended. */
465 return 8;
466 break;
467 }
468 return 0;
469 }
470
471 /*
472 * Print out the ieee 802.15.4 address.
473 */
474 static void
475 ieee802_15_4_print_addr(netdissect_options *ndo, const u_char *p,
476 int dst_addr_len)
477 {
478 switch (dst_addr_len) {
479 case 0:
480 ND_PRINT((ndo, "none"));
481 break;
482 case 2:
483 ND_PRINT((ndo, "%04x", EXTRACT_LE_16BITS(p)));
484 break;
485 case 8:
486 ND_PRINT((ndo, "%s", le64addr_string(ndo, p)));
487 break;
488 }
489 return;
490 }
491
492 /*
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
495 * 802.15.4-2015.
496 */
497 static void
498 ieee802_15_4_print_superframe_specification(netdissect_options *ndo,
499 uint16_t ss)
500 {
501 if (ndo->ndo_vflag < 1) {
502 return;
503 }
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",
507 ((ss >> 8) & 0xf)));
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")); }
511 }
512
513 /*
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.
516 *
517 * Returns number of byts consumed from the packet or -1 in case of error.
518 */
519 static int
520 ieee802_15_4_print_gts_info(netdissect_options *ndo,
521 const u_char *p,
522 uint16_t data_len)
523 {
524 uint8_t gts_spec, gts_cnt;
525 int len, i;
526
527 gts_spec = EXTRACT_LE_8BITS(p);
528 gts_cnt = gts_spec & 0x7;
529
530 if (gts_cnt == 0) {
531 if (ndo->ndo_vflag > 0) {
532 ND_PRINT((ndo, "\n\tGTS Descriptor Count = %d, ", gts_cnt));
533 }
534 return 1;
535 }
536 len = 1 + 1 + gts_cnt * 3;
537
538 if (data_len < len) {
539 ND_PRINT((ndo, " [ERROR: Truncated GTS Info List]"));
540 return -1;
541 }
542 if (ndo->ndo_vflag < 2) {
543 return len;
544 }
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));
548
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));
555 }
556 ND_PRINT((ndo, "]"));
557 return len;
558 }
559
560 /*
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.
563 *
564 * Returns number of byts consumed from the packet or -1 in case of error.
565 */
566 static int
567 ieee802_15_4_print_pending_addresses(netdissect_options *ndo,
568 const u_char *p,
569 uint16_t data_len)
570 {
571 uint8_t pas, s_cnt, e_cnt, len, i;
572
573 pas = EXTRACT_LE_8BITS(p);
574 s_cnt = pas & 0x7;
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",
580 s_cnt, e_cnt));
581 }
582 if (data_len < len) {
583 ND_PRINT((ndo, " [ERROR: Pending address list truncated]"));
584 return -1;
585 }
586 if (ndo->ndo_vflag < 2) {
587 return len;
588 }
589 if (s_cnt != 0) {
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, " "));
594 }
595 ND_PRINT((ndo, "]"));
596 }
597 if (s_cnt != 0) {
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 +
601 e_cnt * 8, 8);
602 ND_PRINT((ndo, " "));
603 }
604 ND_PRINT((ndo, "]"));
605 }
606 return len;
607 }
608
609 /*
610 * Print header ie content.
611 */
612 static void
613 ieee802_15_4_print_header_ie(netdissect_options *ndo,
614 const u_char *p,
615 uint16_t ie_len,
616 int element_id)
617 {
618 int i;
619
620 switch (element_id) {
621 case 0x00: /* Vendor Specific Header IE */
622 if (ie_len < 3) {
623 ND_PRINT((ndo, "[ERROR: Vendor OUI missing]"));
624 } else {
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)));
630 }
631 }
632 break;
633 case 0x1a: /* LE CSL IE */
634 if (ie_len < 4) {
635 ND_PRINT((ndo, "[ERROR: Truncated CSL IE]"));
636 } else {
637 ND_PRINT((ndo, "CSL Phase = %d, CSL Period = %d",
638 EXTRACT_LE_16BITS(p), EXTRACT_LE_16BITS(p + 2)));
639 if (ie_len >= 6) {
640 ND_PRINT((ndo, ", Rendezvous time = %d", EXTRACT_LE_16BITS(p + 4)));
641 }
642 if (ie_len != 4 && ie_len != 6) {
643 ND_PRINT((ndo, " [ERROR: CSL IE length wrong]"));
644 }
645 }
646 break;
647 case 0x1b: /* LE RIT IE */
648 if (ie_len < 4) {
649 ND_PRINT((ndo, "[ERROR: Truncated RIT IE]"));
650 } else {
651 ND_PRINT((ndo, "Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d",
652 EXTRACT_LE_8BITS(p),
653 EXTRACT_LE_8BITS(p + 1),
654 EXTRACT_LE_16BITS(p + 2)));
655 }
656 break;
657 case 0x1c: /* DSME PAN Descriptor IE */
658 /*FALLTHROUGH*/
659 case 0x21: /* Extended DSME PAN descriptior IE */
660 if (ie_len < 2) {
661 ND_PRINT((ndo, "[ERROR: Truncated DSME PAN IE]"));
662 } else {
663 uint16_t ss, ptr;
664 int len, hopping_present;
665
666 hopping_present = 0;
667
668 ss = EXTRACT_LE_16BITS(p);
669 ieee802_15_4_print_superframe_specification(ndo, ss);
670 if (ie_len < 3) {
671 ND_PRINT((ndo, "[ERROR: Truncated before pending addresses field]"));
672 break;
673 }
674 ptr = 2;
675 len = ieee802_15_4_print_pending_addresses(ndo, p + ptr, ie_len - ptr);
676 if (len < 0) {
677 break;
678 }
679 ptr += len;
680
681 if (element_id == 0x21) {
682 /* Extended version. */
683 if (ie_len < ptr + 2) {
684 ND_PRINT((ndo, "[ERROR: Truncated before DSME Superframe Specification]"));
685 break;
686 }
687 ss = EXTRACT_LE_16BITS(p + ptr);
688 ptr += 2;
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")); }
694 if (ss & 0x1000) {
695 ND_PRINT((ndo, ", Hopping Sequence Present"));
696 hopping_present = 1;
697 }
698 } else {
699 if (ie_len < ptr + 1) {
700 ND_PRINT((ndo, "[ERROR: Truncated before DSME Superframe Specification]"));
701 break;
702 }
703 ss = EXTRACT_LE_8BITS(p + ptr);
704 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")); }
710 }
711 if (ie_len < ptr + 8) {
712 ND_PRINT((ndo, " [ERROR: Truncated before Time syncronization specification]"));
713 break;
714 }
715 ND_PRINT((ndo, "Beacon timestamp = %" PRIu64 ", offset = %d",
716 EXTRACT_LE_48BITS(p + ptr),
717 EXTRACT_LE_16BITS(p + ptr + 6)));
718 ptr += 8;
719 if (ie_len < ptr + 4) {
720 ND_PRINT((ndo, " [ERROR: Truncated before Beacon Bitmap]"));
721 break;
722 }
723
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));
727 ptr += 4;
728 if (ie_len < ptr + len) {
729 ND_PRINT((ndo, " [ERROR: Truncated in SD bitmap]"));
730 break;
731 }
732 ND_PRINT((ndo, " SD Bitmap = "));
733 for(i = 0; i < len; i++) {
734 ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + ptr + i)));
735 }
736 ptr += len;
737
738 if (ie_len < ptr + 5) {
739 ND_PRINT((ndo, " [ERROR: Truncated before Channel hopping specification]"));
740 break;
741 }
742
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),
749 len));
750 ptr += 5;
751 if (ie_len < ptr + len) {
752 ND_PRINT((ndo, " [ERROR: Truncated in Channel offset bitmap]"));
753 break;
754 }
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)));
759 }
760 ptr += len;
761 if (hopping_present) {
762 if (ie_len < ptr + 1) {
763 ND_PRINT((ndo, " [ERROR: Truncated in Hopping Sequence length]"));
764 break;
765 }
766 len = EXTRACT_LE_8BITS(p + ptr);
767 ptr++;
768 ND_PRINT((ndo, "Hopping Seq length = %d [ ", len));
769
770 /* The specification is not clear how the
771 hopping sequence is encoded, I assume two octet
772 unsigned integers for each channel. */
773
774 if (ie_len < ptr + len * 2) {
775 ND_PRINT((ndo, " [ERROR: Truncated in Channel offset bitmap]"));
776 break;
777 }
778 for(i = 0; i < len; i++) {
779 ND_PRINT((ndo, "%02x ", EXTRACT_LE_16BITS(p + ptr + i * 2)));
780 }
781 ND_PRINT((ndo, "]"));
782 ptr += len * 2;
783 }
784 }
785 break;
786 case 0x1d: /* Rendezvous Tome IE */
787 if (ie_len != 4) {
788 ND_PRINT((ndo, "[ERROR: Length != 2]"));
789 } else {
790 uint16_t r_time, w_u_interval;
791 r_time = EXTRACT_LE_16BITS(p);
792 w_u_interval = EXTRACT_LE_16BITS(p + 2);
793
794 ND_PRINT((ndo, "Rendezvous time = %d, Wake-up Interval = %d",
795 r_time, w_u_interval));
796 }
797 break;
798 case 0x1e: /* Time correction IE */
799 if (ie_len != 2) {
800 ND_PRINT((ndo, "[ERROR: Length != 2]"));
801 } else {
802 uint16_t val;
803 int16_t timecorr;
804
805 val = EXTRACT_LE_16BITS(p);
806 if (val & 0x8000) { ND_PRINT((ndo, "Negative ")); }
807 val &= 0xfff;
808 val <<= 4;
809 timecorr = val;
810 timecorr >>= 4;
811
812 ND_PRINT((ndo, "Ack time correction = %d, ", timecorr));
813 }
814 break;
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 */
833 default:
834 ND_PRINT((ndo, "IE Data = "));
835 for(i = 0; i < ie_len; i++) {
836 ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
837 }
838 break;
839 }
840 }
841
842 /*
843 * Parse and print Header IE list. See 7.4.2 of 802.15.4-2015 for
844 * more information.
845 *
846 * Returns number of byts consumed from the packet or -1 in case of error.
847 */
848 static int
849 ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
850 const u_char *p,
851 uint16_t caplen,
852 int *payload_ie_present)
853 {
854 int len, ie, ie_len, element_id, i;
855
856 *payload_ie_present = 0;
857 len = 0;
858 do {
859 if (caplen < 2) {
860 ND_PRINT((ndo, "[ERROR: Truncated header IE]"));
861 return -1;
862 }
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] "));
867 }
868 /* Get length and Element ID */
869 ie_len = ie & 0x7f;
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));
874 } else {
875 if (ie_len == 0) {
876 ND_PRINT((ndo, "\n\t%s [",
877 h_ie_names[element_id]));
878 } else {
879 ND_PRINT((ndo, "\n\t%s [ length = %d, ",
880 h_ie_names[element_id], ie_len));
881 }
882 }
883 if (caplen < ie_len) {
884 ND_PRINT((ndo, "[ERROR: Truncated IE data]"));
885 return -1;
886 }
887 /* Skip header */
888 p += 2;
889
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);
893 } else {
894 if (ie_len != 0) {
895 ND_PRINT((ndo, "IE Data = "));
896 for(i = 0; i < ie_len; i++) {
897 ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
898 }
899 }
900 }
901 ND_PRINT((ndo, "] "));
902 len += 2 + ie_len;
903 p += ie_len;
904 caplen -= 2 + ie_len;
905 if (element_id == 0x7e) {
906 *payload_ie_present = 1;
907 break;
908 }
909 if (element_id == 0x7f) {
910 break;
911 }
912 } while (caplen > 0);
913 return len;
914 }
915
916 /*
917 * Print MLME ie content.
918 */
919 static void
920 ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
921 const u_char *p,
922 uint16_t sub_ie_len,
923 int sub_id)
924 {
925 int i, j, len;
926
927 /* Note, as there is no overlap with the long and short
928 MLME sub IDs, we can just use one switch here. */
929 switch (sub_id) {
930 case 0x08: /* Vendor Specific Nested IE */
931 if (sub_ie_len < 3) {
932 ND_PRINT((ndo, "[ERROR: Vendor OUI missing]"));
933 } else {
934 ND_PRINT((ndo, "OUI = 0x%02x%02x%02x, ",
935 EXTRACT_LE_8BITS(p),
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)));
941 }
942 }
943 break;
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)));
949 p++;
950 sub_ie_len--;
951 } else {
952 int channel_page, number_of_channels;
953
954 ND_PRINT((ndo, "Hopping Sequence ID = %d", EXTRACT_LE_8BITS(p)));
955 p++;
956 sub_ie_len--;
957 if (sub_ie_len < 7) {
958 ND_PRINT((ndo, "[ERROR: IE truncated]"));
959 break;
960 }
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)));
967 p += 7;
968 sub_ie_len -= 7;
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]"));
973 break;
974 }
975 ND_PRINT((ndo, "Extended bitmap = 0x"));
976 for(i = 0; i < len; i++) {
977 ND_PRINT((ndo, "%02x", EXTRACT_LE_8BITS(p + i)));
978 }
979 ND_PRINT((ndo, ", "));
980 p += len;
981 sub_ie_len -= len;
982 }
983 if (sub_ie_len < 2) {
984 ND_PRINT((ndo, "[ERROR: IE truncated]"));
985 break;
986 }
987 len = EXTRACT_LE_16BITS(p);
988 p += 2;
989 sub_ie_len -= 2;
990 ND_PRINT((ndo, "Hopping Seq length = %d [ ", len));
991
992 if (sub_ie_len < len * 2) {
993 ND_PRINT((ndo, " [ERROR: IE truncated]"));
994 break;
995 }
996 for(i = 0; i < len; i++) {
997 ND_PRINT((ndo, "%02x ", EXTRACT_LE_16BITS(p + i * 2)));
998 }
999 ND_PRINT((ndo, "]"));
1000 p += len * 2;
1001 sub_ie_len -= len * 2;
1002 if (sub_ie_len < 2) {
1003 ND_PRINT((ndo, "[ERROR: IE truncated]"));
1004 break;
1005 }
1006 ND_PRINT((ndo, "Current hop = %d", EXTRACT_LE_16BITS(p)));
1007 }
1008
1009 break;
1010 case 0x1a: /* TSCH Syncronization IE. */
1011 if (sub_ie_len < 6) {
1012 ND_PRINT((ndo, "[ERROR: Length != 6]"));
1013 }
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)));
1018 break;
1019 case 0x1b: /* TSCH Slotframe and Link IE. */
1020 {
1021 int sf_num, off, links, opts;
1022
1023 if (sub_ie_len < 1) {
1024 ND_PRINT((ndo, "[ERROR: Truncated IE]"));
1025 break;
1026 }
1027 sf_num = EXTRACT_LE_8BITS(p);
1028 ND_PRINT((ndo, "Slotframes = %d ", sf_num));
1029 off = 1;
1030 for(i = 0; i < sf_num; i++) {
1031 if (sub_ie_len < off + 4) {
1032 ND_PRINT((ndo, "[ERROR: Truncated IE before slotframes]"));
1033 break;
1034 }
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),
1039 links));
1040 off += 4;
1041 for(j = 0; j < links; j++) {
1042 if (sub_ie_len < off + 5) {
1043 ND_PRINT((ndo, "[ERROR: Truncated IE links]"));
1044 break;
1045 }
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 ")); }
1055 off += 5;
1056 ND_PRINT((ndo, "] "));
1057 }
1058 ND_PRINT((ndo, "] "));
1059 }
1060 }
1061 break;
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)));
1095 } else {
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)));
1100 }
1101 }
1102 break;
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 */
1153 default:
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)));
1157 }
1158 break;
1159 }
1160 }
1161
1162 /*
1163 * MLME IE list parsing and printing. See 7.4.3.2 of 802.15.4-2015
1164 * for more information.
1165 */
1166 static void
1167 ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
1168 const u_char *p,
1169 uint16_t ie_len)
1170 {
1171 int ie, sub_ie_len, sub_id, i, type;
1172
1173 do {
1174 if (ie_len < 2) {
1175 ND_PRINT((ndo, "[ERROR: Truncated MLME IE]"));
1176 return;
1177 }
1178 /* Extract IE header */
1179 ie = EXTRACT_LE_16BITS(p);
1180 type = CHECK_BIT(ie, 15);
1181 if (type) {
1182 /* Long type */
1183 sub_ie_len = ie & 0x3ff;
1184 sub_id = (ie >> 11) & 0x0f;
1185 } else {
1186 sub_ie_len = ie & 0xff;
1187 sub_id = (ie >> 8) & 0x7f;
1188 }
1189
1190 /* Skip the IE header */
1191 p += 2;
1192
1193 if (type == 0) {
1194 ND_PRINT((ndo, "\n\t\t%s [ length = %d, ",
1195 p_mlme_short_names[sub_id], sub_ie_len));
1196 } else {
1197 ND_PRINT((ndo, "\n\t\t%s [ length = %d, ",
1198 p_mlme_long_names[sub_id], sub_ie_len));
1199 }
1200
1201 if (ie_len < sub_ie_len) {
1202 ND_PRINT((ndo, "[ERROR: Truncated IE data]"));
1203 return;
1204 }
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)));
1212 }
1213 }
1214 }
1215 ND_PRINT((ndo, "] "));
1216 p += sub_ie_len;
1217 ie_len -= 2 + sub_ie_len;
1218 } while (ie_len > 0);
1219 return;
1220 }
1221
1222 /*
1223 * Payload IE list parsing and printing. See 7.4.3 of 802.15.4-2015
1224 * for more information.
1225 *
1226 * Returns number of byts consumed from the packet or -1 in case of error.
1227 */
1228 static int
1229 ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
1230 const u_char *p,
1231 uint16_t caplen)
1232 {
1233 int len, ie, ie_len, group_id, i;
1234
1235 len = 0;
1236 do {
1237 if (caplen < 2) {
1238 ND_PRINT((ndo, "[ERROR: Truncated header IE]"));
1239 return -1;
1240 }
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] "));
1245 }
1246 ie_len = ie & 0x3ff;
1247 group_id = (ie >> 11) & 0x0f;
1248
1249 /* Skip the IE header */
1250 p += 2;
1251 if (ie_len == 0) {
1252 ND_PRINT((ndo, "\n\t%s [", p_ie_names[group_id]));
1253 } else {
1254 ND_PRINT((ndo, "\n\t%s [ length = %d, ",
1255 p_ie_names[group_id], ie_len));
1256 }
1257 if (caplen < ie_len) {
1258 ND_PRINT((ndo, "[ERROR: Truncated IE data]"));
1259 return -1;
1260 }
1261 if (ndo->ndo_vflag > 3 && ie_len != 0) {
1262 switch (group_id) {
1263 case 0x1: /* MLME IE */
1264 ieee802_15_4_print_mlme_ie_list(ndo, p, ie_len);
1265 break;
1266 case 0x2: /* Vendor Specific Nested IE */
1267 if (ie_len < 3) {
1268 ND_PRINT((ndo, "[ERROR: Vendor OUI missing]"));
1269 } else {
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)));
1277 }
1278 }
1279 break;
1280 case 0x3: /* Multiplexed IE (802.15.9) */
1281 if (ie_len < 1) {
1282 ND_PRINT((ndo, "[ERROR: Transaction control byte missing]"));
1283 } else {
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. */
1290 data_start = 1;
1291 ND_PRINT((ndo, "Type = Full upper layer fragment%s, ",
1292 (transfer_type == 0x01 ?
1293 " with small Multiplex ID" : "")));
1294 if (transfer_type == 0x00) {
1295 if (ie_len < 3) {
1296 ND_PRINT((ndo, "[ERROR: Multiplex ID missing]"));
1297 } else {
1298 data_start = 3;
1299 ND_PRINT((ndo, "tid = 0x%02x, Multiplex ID = 0x%04x, ",
1300 tid, EXTRACT_LE_16BITS(p + 1)));
1301 }
1302 } else {
1303 ND_PRINT((ndo, "Multiplex ID = 0x%04x, ", tid));
1304 }
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)));
1308 }
1309 break;
1310 case 0x02: /* First, or middle, Fragments */
1311 case 0x04: /* Last fragment */
1312 if (ie_len < 2) {
1313 ND_PRINT((ndo, "[ERROR: fragment number missing]"));
1314 } else {
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,
1321 fragment_number));
1322 data_start = 2;
1323 if (fragment_number == 0) {
1324 if (ie_len < 6) {
1325 ND_PRINT((ndo, "[ERROR: Total upper layer size or multiplex ID missing]"));
1326 } else {
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));
1332 }
1333 data_start = 6;
1334 }
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)));
1338 }
1339 }
1340 break;
1341 case 0x06: /* Abort code */
1342 if (ie_len == 1) {
1343 ND_PRINT((ndo, "Type = Abort, tid = 0x%02x, no max size given",
1344 tid));
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)));
1348 } else {
1349 ND_PRINT((ndo, "Type = Abort, tid = 0x%02x, invalid length = %d (not 1 or 3)",
1350 tid, ie_len));
1351 ND_PRINT((ndo, "Abort data = "));
1352 for(i = 1; i < ie_len; i++) {
1353 ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
1354 }
1355 }
1356 break;
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)));
1365 }
1366 break;
1367 }
1368 }
1369 break;
1370 case 0x5: /* IETF IE */
1371 if (ie_len < 1) {
1372 ND_PRINT((ndo, "[ERROR: Subtype ID missing]"));
1373 } else {
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)));
1378 }
1379 }
1380 break;
1381 default:
1382 ND_PRINT((ndo, "IE Data = "));
1383 for(i = 0; i < ie_len; i++) {
1384 ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
1385 }
1386 break;
1387 }
1388 } else {
1389 if (ie_len != 0) {
1390 ND_PRINT((ndo, "IE Data = "));
1391 for(i = 0; i < ie_len; i++) {
1392 ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
1393 }
1394 }
1395 }
1396 ND_PRINT((ndo, "]\n\t"));
1397 len += 2 + ie_len;
1398 p += ie_len;
1399 caplen -= 2 + ie_len;
1400 if (group_id == 0xf) {
1401 break;
1402 }
1403 } while (caplen > 0);
1404 return len;
1405 }
1406
1407 /*
1408 * Parse and print auxiliary security header.
1409 *
1410 * Returns number of byts consumed from the packet or -1 in case of error.
1411 */
1412 static int
1413 ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
1414 const u_char *p,
1415 uint16_t caplen,
1416 int *security_level)
1417 {
1418 int sc, key_id_mode, len;
1419
1420 if (caplen < 1) {
1421 ND_PRINT((ndo, "[ERROR: Truncated before Aux Security Header]"));
1422 return -1;
1423 }
1424 sc = EXTRACT_LE_8BITS(p);
1425 len = 1;
1426 *security_level = sc & 0x7;
1427 key_id_mode = (sc >> 3) & 0x3;
1428
1429 caplen -= 1;
1430 p += 1;
1431
1432 if (ndo->ndo_vflag > 0) {
1433 ND_PRINT((ndo, "\n\tSecurity Level %d, Key Id Mode %d, ",
1434 *security_level, key_id_mode));
1435 }
1436 if ((CHECK_BIT(sc, 5)) == 0) {
1437 if (caplen < 4) {
1438 ND_PRINT((ndo, "[ERROR: Truncated before Frame Counter]"));
1439 return -1;
1440 }
1441 len += 4;
1442 caplen -= 4;
1443 p += 4;
1444 if (ndo->ndo_vflag > 1) {
1445 ND_PRINT((ndo, "Frame Counter 0x%08x ",
1446 EXTRACT_LE_32BITS(p + 1)));
1447 }
1448 }
1449 switch (key_id_mode) {
1450 case 0x00: /* Implicit. */
1451 if (ndo->ndo_vflag > 1) {
1452 ND_PRINT((ndo, "Implicit"));
1453 }
1454 return len;
1455 break;
1456 case 0x01: /* Key Index, nothing to print here. */
1457 break;
1458 case 0x02: /* PAN and Short address Key Source, and Key Index. */
1459 if (caplen < 4) {
1460 ND_PRINT((ndo, "[ERROR: Truncated before Key Source]"));
1461 return -1;
1462 }
1463 if (ndo->ndo_vflag > 1) {
1464 ND_PRINT((ndo, "KeySource 0x%04x:%0x4x, ",
1465 EXTRACT_LE_16BITS(p), EXTRACT_LE_16BITS(p + 2)));
1466 }
1467 p += 4;
1468 caplen -= 4;
1469 len += 4;
1470 break;
1471 case 0x03: /* Extended address and Key Index. */
1472 if (caplen < 8) {
1473 ND_PRINT((ndo, "[ERROR: Truncated before Key Source]"));
1474 return -1;
1475 }
1476 if (ndo->ndo_vflag > 1) {
1477 ND_PRINT((ndo, "KeySource %s, ", le64addr_string(ndo, p)));
1478 }
1479 p += 4;
1480 caplen -= 4;
1481 len += 4;
1482 break;
1483 }
1484 if (caplen < 1) {
1485 ND_PRINT((ndo, "[ERROR: Truncated before Key Index]"));
1486 return -1;
1487 }
1488 if (ndo->ndo_vflag > 1) {
1489 ND_PRINT((ndo, "KeyIndex 0x%02x, ", EXTRACT_LE_8BITS(p)));
1490 }
1491 caplen -= 1;
1492 p += 1;
1493 len += 1;
1494 return len;
1495 }
1496
1497 /*
1498 * Print command data.
1499 *
1500 * Returns number of byts consumed from the packet or -1 in case of error.
1501 */
1502 static int
1503 ieee802_15_4_print_command_data(netdissect_options *ndo,
1504 uint8_t command_id,
1505 const u_char *p,
1506 u_int caplen)
1507 {
1508 u_int i;
1509
1510 switch (command_id) {
1511 case 0x01: /* Assocation Request */
1512 if (caplen != 1) {
1513 ND_PRINT((ndo, "Invalid Assocation request command length"));
1514 return -1;
1515 } else {
1516 uint8_t cap_info;
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, " : "")));
1525 return caplen;
1526 }
1527 break;
1528 case 0x02: /* Assocation Response */
1529 if (caplen != 3) {
1530 ND_PRINT((ndo, "Invalid Assocation response command length"));
1531 return -1;
1532 } else {
1533 ND_PRINT((ndo, "Short address = "));
1534 ieee802_15_4_print_addr(ndo, p, 2);
1535 switch (EXTRACT_LE_8BITS(p + 2)) {
1536 case 0x00:
1537 ND_PRINT((ndo, ", Association successful"));
1538 break;
1539 case 0x01:
1540 ND_PRINT((ndo, ", PAN at capacity"));
1541 break;
1542 case 0x02:
1543 ND_PRINT((ndo, ", PAN access denied"));
1544 break;
1545 case 0x03:
1546 ND_PRINT((ndo, ", Hooping sequence offset duplication"));
1547 break;
1548 case 0x80:
1549 ND_PRINT((ndo, ", Fast association successful"));
1550 break;
1551 default:
1552 ND_PRINT((ndo, ", Status = 0x%02x", EXTRACT_LE_8BITS(p + 2)));
1553 break;
1554 }
1555 return caplen;
1556 }
1557 break;
1558 case 0x03: /* Diassociation Notification command */
1559 if (caplen != 1) {
1560 ND_PRINT((ndo, "Invalid Disassociation Notification command length"));
1561 return -1;
1562 } else {
1563 switch (EXTRACT_LE_8BITS(p)) {
1564 case 0x00:
1565 ND_PRINT((ndo, "Reserved"));
1566 break;
1567 case 0x01:
1568 ND_PRINT((ndo, "Reason = The coordinator wishes the device to leave PAN"));
1569 break;
1570 case 0x02:
1571 ND_PRINT((ndo, "Reason = The device wishes to leave the PAN"));
1572 break;
1573 default:
1574 ND_PRINT((ndo, "Reason = 0x%02x", EXTRACT_LE_8BITS(p + 2)));
1575 break;
1576 }
1577 return caplen;
1578 }
1579
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. */
1586 return 0;
1587 case 0x08: /* Coordinator Realignment command */
1588 if (caplen < 7 || caplen > 8) {
1589 ND_PRINT((ndo, "Invalid Coordinator Realignment command length"));
1590 return -1;
1591 } else {
1592 uint16_t channel, page;
1593
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);
1598
1599 if (caplen == 8) {
1600 page = EXTRACT_LE_8BITS(p + 7);
1601 } else {
1602 page = 0x80;
1603 }
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));
1609 } else {
1610 ND_PRINT((ndo, ", Channel Number = %d, page = %d",
1611 channel, page));
1612 }
1613 ND_PRINT((ndo, ", Short address = "));
1614 ieee802_15_4_print_addr(ndo, p + 5, 2);
1615 return caplen;
1616 }
1617 break;
1618 case 0x09: /* GTS Request command */
1619 if (caplen != 1) {
1620 ND_PRINT((ndo, "Invalid GTS Request command length"));
1621 return -1;
1622 } else {
1623 uint8_t gts;
1624
1625 gts = EXTRACT_LE_8BITS(p);
1626 ND_PRINT((ndo, "GTS Length = %d, %s, %s",
1627 gts & 0xf,
1628 (CHECK_BIT(gts, 4) ? "Receive-only GTS" : "Transmit-only GTS"),
1629 (CHECK_BIT(gts, 5) ? "GTS allocation" : "GTS deallocations")));
1630 return caplen;
1631 }
1632 break;
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 */
1667 default:
1668 ND_PRINT((ndo, "Command Data = "));
1669 for(i = 0; i < caplen; i++) {
1670 ND_PRINT((ndo, "%02x ", EXTRACT_LE_8BITS(p + i)));
1671 }
1672 break;
1673 }
1674 return 0;
1675 }
1676
1677 /*
1678 * Parse and print frames folloing standard format.
1679 *
1680 * Returns FALSE in case of error.
1681 */
1682 static u_int
1683 ieee802_15_4_std_frames(netdissect_options *ndo,
1684 const u_char *p, u_int caplen,
1685 uint16_t fc)
1686 {
1687 int len, frame_version, pan_id_comp;
1688 int frame_type;
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;
1695
1696 payload_ie_present = 0;
1697
1698 /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
1699 know about that. */
1700 if (caplen < 2) {
1701 /* Cannot have FCS, assume fcs_len of 0. */
1702 fcs_len = 0;
1703 fcs = 0;
1704 } else {
1705 fcs_len = 2;
1706
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. */
1711 } else {
1712 /* Remove FCS */
1713 caplen -= fcs_len;
1714 }
1715 }
1716
1717 /* Frame version. */
1718 frame_version = (fc >> 12) & 0x03;
1719 frame_type = fc & 0x7;
1720 ND_PRINT((ndo, "v%d ", frame_version));
1721
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, ")); }
1729 }
1730
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]"));
1738 }
1739 if (ndo->ndo_vflag)
1740 ND_PRINT((ndo,"seq suppressed "));
1741 p += 2;
1742 caplen -= 2;
1743 } else {
1744 seq = EXTRACT_LE_8BITS(p + 2);
1745 p += 3;
1746 caplen -= 3;
1747 if (ndo->ndo_vflag)
1748 ND_PRINT((ndo,"seq %02x ", seq));
1749 }
1750
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]"));
1756 return 0;
1757 }
1758 if (dst_addr_len < 0) {
1759 ND_PRINT((ndo,"[ERROR: Invalid dst address mode]"));
1760 return 0;
1761 }
1762 src_pan = 0;
1763 dst_pan = 0;
1764 pan_id_comp = CHECK_BIT(fc, 6);
1765
1766 /* The PAN ID Compression rules are complicated. */
1767
1768 /* First check old versions, where the rules are simple. */
1769 if (frame_version < 2) {
1770 if (pan_id_comp) {
1771 src_pan = 0;
1772 dst_pan = 1;
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]"));
1777 }
1778 } else {
1779 src_pan = 1;
1780 dst_pan = 1;
1781 }
1782 if (dst_addr_len <= 0) {
1783 dst_pan = 0;
1784 }
1785 if (src_addr_len <= 0) {
1786 src_pan = 0;
1787 }
1788 } else {
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. */
1792 if (pan_id_comp) {
1793 src_pan = 0;
1794 dst_pan = 1;
1795 } else {
1796 src_pan = 1;
1797 dst_pan = 1;
1798 }
1799 if (dst_addr_len <= 0) {
1800 dst_pan = 0;
1801 }
1802 if (src_addr_len <= 0) {
1803 src_pan = 0;
1804 }
1805 if (pan_id_comp) {
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. */
1811 dst_pan = 1;
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
1818 all. */
1819 dst_pan = 0;
1820 src_pan = 0;
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
1825 all. */
1826 dst_pan = 0;
1827 src_pan = 0;
1828 }
1829 } else {
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). */
1836 dst_pan = 1;
1837 src_pan = 0;
1838 }
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
1843 implementations. */
1844 src_pan = 0;
1845 }
1846 #endif /* BROKEN_6TISCH_PAN_ID_COMPRESSION */
1847 }
1848 }
1849
1850 /* Print dst PAN and address. */
1851 if (dst_pan) {
1852 if (caplen < 2) {
1853 ND_PRINT((ndo, "[ERROR: Truncated before dst_pan]"));
1854 return 0;
1855 }
1856 ND_PRINT((ndo, "%04x:", EXTRACT_LE_16BITS(p)));
1857 p += 2;
1858 caplen -= 2;
1859 } else {
1860 ND_PRINT((ndo, "-:"));
1861 }
1862 if (caplen < (u_int) dst_addr_len) {
1863 ND_PRINT((ndo, "[ERROR: Truncated before dst_addr]"));
1864 return 0;
1865 }
1866 ieee802_15_4_print_addr(ndo, p, dst_addr_len);
1867 p += dst_addr_len;
1868 caplen -= dst_addr_len;
1869
1870 ND_PRINT((ndo," < "));
1871
1872 /* Print src PAN and address. */
1873 if (src_pan) {
1874 if (caplen < 2) {
1875 ND_PRINT((ndo, "[ERROR: Truncated before dst_pan]"));
1876 return 0;
1877 }
1878 ND_PRINT((ndo, "%04x:", EXTRACT_LE_16BITS(p)));
1879 p += 2;
1880 caplen -= 2;
1881 } else {
1882 ND_PRINT((ndo, "-:"));
1883 }
1884 if (caplen < (u_int) src_addr_len) {
1885 ND_PRINT((ndo, "[ERROR: Truncated before dst_addr]"));
1886 return 0;
1887 }
1888 ieee802_15_4_print_addr(ndo, p, src_addr_len);
1889 ND_PRINT((ndo, " "));
1890 p += src_addr_len;
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);
1894 if (len < 0) {
1895 return 0;
1896 }
1897 p += len;
1898 caplen -= len;
1899 } else {
1900 security_level = 0;
1901 }
1902
1903 switch (security_level) {
1904 case 0: /*FALLTHOUGH */
1905 case 4:
1906 miclen = 0;
1907 break;
1908 case 1: /*FALLTHOUGH */
1909 case 5:
1910 miclen = 4;
1911 break;
1912 case 2: /*FALLTHOUGH */
1913 case 6:
1914 miclen = 8;
1915 break;
1916 case 3: /*FALLTHOUGH */
1917 case 7:
1918 miclen = 16;
1919 break;
1920 }
1921
1922 /* Remove MIC */
1923 if (miclen > 0) {
1924 if (caplen < (u_int) miclen) {
1925 ND_PRINT((ndo, "[ERROR: Truncated before MIC]"));
1926 return 0;
1927 }
1928 caplen -= miclen;
1929 mic_start = p + caplen;
1930 }
1931
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);
1937 if (len < 0) {
1938 return 0;
1939 }
1940 p += len;
1941 caplen -= len;
1942 }
1943
1944 if (payload_ie_present) {
1945 if (security_level >= 4) {
1946 ND_PRINT((ndo, "Payload IEs present, but encrypted, cannot print "));
1947 } else {
1948 len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen);
1949 if (len < 0) {
1950 return 0;
1951 }
1952 p += len;
1953 caplen -= len;
1954 }
1955 }
1956
1957 /* Print MIC */
1958 if (ndo->ndo_vflag > 2 && miclen != 0) {
1959 ND_PRINT((ndo, "\n\tMIC "));
1960
1961 for(len = 0; len < miclen; len += 4) {
1962 ND_PRINT((ndo, "%08x", EXTRACT_32BITS(mic_start + len)));
1963 }
1964 ND_PRINT((ndo, " "));
1965 }
1966
1967 /* Print FCS */
1968 if (ndo->ndo_vflag > 2) {
1969 if (crc_check == fcs) {
1970 ND_PRINT((ndo, "FCS %04x ", fcs));
1971 } else {
1972 ND_PRINT((ndo, "wrong FCS %04x vs %04x (assume no FCS stored) ",
1973 fcs, crc_check));
1974 }
1975 }
1976
1977 /* Payload print */
1978 switch (frame_type) {
1979 case 0x00: /* Beacon */
1980 if (frame_version < 2) {
1981 if (caplen < 2) {
1982 ND_PRINT((ndo, "[ERROR: Truncated before beacon information]"));
1983 break;
1984 } else {
1985 uint16_t ss;
1986
1987 ss = EXTRACT_LE_16BITS(p);
1988 ieee802_15_4_print_superframe_specification(ndo, ss);
1989 p += 2;
1990 caplen -= 2;
1991
1992 /* GTS */
1993 if (caplen < 1) {
1994 ND_PRINT((ndo, "[ERROR: Truncated before GTS info]"));
1995 break;
1996 }
1997
1998 len = ieee802_15_4_print_gts_info(ndo, p, caplen);
1999 if (len < 0) {
2000 break;
2001 }
2002
2003 p += len;
2004 caplen -= len;
2005
2006 /* Pending Addresses */
2007 if (caplen < 1) {
2008 ND_PRINT((ndo, "[ERROR: Truncated before pending addresses]"));
2009 break;
2010 }
2011 len = ieee802_15_4_print_pending_addresses(ndo, p, caplen);
2012 if (len < 0) {
2013 break;
2014 }
2015 p += len;
2016 caplen -= len;
2017 }
2018 }
2019 if (!ndo->ndo_suppress_default_print)
2020 ND_DEFAULTPRINT(p, caplen);
2021
2022 break;
2023 case 0x01: /* Data */
2024 case 0x02: /* Acknowledgement */
2025 if (!ndo->ndo_suppress_default_print)
2026 ND_DEFAULTPRINT(p, caplen);
2027 break;
2028 case 0x03: /* MAC Command */
2029 if (caplen < 1) {
2030 ND_PRINT((ndo, "[ERROR: Truncated before Command ID]"));
2031 } else {
2032 uint8_t command_id;
2033
2034 command_id = EXTRACT_LE_8BITS(p);
2035 if (command_id >= 0x30) {
2036 ND_PRINT((ndo, "Command ID = Reserved 0x%02x ", command_id));
2037 } else {
2038 ND_PRINT((ndo, "Command ID = %s ", mac_c_names[command_id]));
2039 }
2040 p++;
2041 caplen--;
2042 if (caplen != 0) {
2043 len = ieee802_15_4_print_command_data(ndo, command_id, p, caplen);
2044 if (len >= 0) {
2045 p += len;
2046 caplen -= len;
2047 }
2048 }
2049 }
2050 if (!ndo->ndo_suppress_default_print)
2051 ND_DEFAULTPRINT(p, caplen);
2052 break;
2053 }
2054 return 1;
2055 }
2056
2057 /*
2058 * Print and parse Multipurpose frames.
2059 *
2060 * Returns FALSE in case of error.
2061 */
2062 static u_int
2063 ieee802_15_4_mp_frame(netdissect_options *ndo,
2064 const u_char *p, u_int caplen,
2065 uint16_t fc)
2066 {
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;
2074
2075 pan_id_present = 0;
2076 ie_present = 0;
2077 payload_ie_present = 0;
2078 security_enabled = 0;
2079
2080 /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
2081 know about that. */
2082 if (caplen < 2) {
2083 /* Cannot have FCS, assume fcs_len of 0. */
2084 fcs_len = 0;
2085 fcs = 0;
2086 } else {
2087 fcs_len = 2;
2088
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. */
2093 } else {
2094 /* Remove FCS */
2095 caplen -= fcs_len;
2096 }
2097 }
2098
2099 if (CHECK_BIT(fc, 3)) {
2100 /* Long Frame Control */
2101
2102 /* Frame version. */
2103 frame_version = (fc >> 12) & 0x03;
2104 ND_PRINT((ndo, "v%d ", frame_version));
2105
2106 pan_id_present = CHECK_BIT(fc, 8);
2107 ie_present = CHECK_BIT(fc, 15);
2108 security_enabled = CHECK_BIT(fc, 9);
2109
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, "));
2117 }
2118 if (ie_present) { ND_PRINT((ndo, "IE present, ")); }
2119 }
2120
2121 /* Check for the sequence number supression. */
2122 if (CHECK_BIT(fc, 10)) {
2123 /* Sequence number is suppressed, but long version. */
2124 p += 2;
2125 caplen -= 2;
2126 } else {
2127 seq = EXTRACT_LE_8BITS(p + 2);
2128 p += 3;
2129 caplen -= 3;
2130 if (ndo->ndo_vflag)
2131 ND_PRINT((ndo,"seq %02x ", seq));
2132 }
2133 } else {
2134 /* Short format of header, but with seq no */
2135 seq = EXTRACT_LE_8BITS(p + 1);
2136 p += 2;
2137 caplen -= 2;
2138 if (ndo->ndo_vflag)
2139 ND_PRINT((ndo,"seq %02x ", seq));
2140 }
2141
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]"));
2147 return 0;
2148 }
2149 if (dst_addr_len < 0) {
2150 ND_PRINT((ndo,"[ERROR: Invalid dst address mode]"));
2151 return 0;
2152 }
2153
2154 /* Print dst PAN and address. */
2155 if (pan_id_present) {
2156 if (caplen < 2) {
2157 ND_PRINT((ndo, "[ERROR: Truncated before dst_pan]"));
2158 return 0;
2159 }
2160 ND_PRINT((ndo, "%04x:", EXTRACT_LE_16BITS(p)));
2161 p += 2;
2162 caplen -= 2;
2163 } else {
2164 ND_PRINT((ndo, "-:"));
2165 }
2166 if (caplen < (u_int) dst_addr_len) {
2167 ND_PRINT((ndo, "[ERROR: Truncated before dst_addr]"));
2168 return 0;
2169 }
2170 ieee802_15_4_print_addr(ndo, p, dst_addr_len);
2171 p += dst_addr_len;
2172 caplen -= dst_addr_len;
2173
2174 ND_PRINT((ndo," < "));
2175
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]"));
2180 return 0;
2181 }
2182 ieee802_15_4_print_addr(ndo, p, src_addr_len);
2183 ND_PRINT((ndo, " "));
2184 p += src_addr_len;
2185 caplen -= src_addr_len;
2186
2187 if (security_enabled) {
2188 len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen, &security_level);
2189 if (len < 0) {
2190 return 0;
2191 }
2192 p += len;
2193 caplen -= len;
2194 } else {
2195 security_level = 0;
2196 }
2197
2198 switch (security_level) {
2199 case 0: /*FALLTHOUGH */
2200 case 4:
2201 miclen = 0;
2202 break;
2203 case 1: /*FALLTHOUGH */
2204 case 5:
2205 miclen = 4;
2206 break;
2207 case 2: /*FALLTHOUGH */
2208 case 6:
2209 miclen = 8;
2210 break;
2211 case 3: /*FALLTHOUGH */
2212 case 7:
2213 miclen = 16;
2214 break;
2215 }
2216
2217 /* Remove MIC */
2218 if (miclen > 0) {
2219 if (caplen < (u_int) miclen) {
2220 ND_PRINT((ndo, "[ERROR: Truncated before MIC]"));
2221 return 0;
2222 }
2223 caplen -= miclen;
2224 mic_start = p + caplen;
2225 }
2226
2227 /* Parse Information elements if present */
2228 if (ie_present) {
2229 /* Yes we have those. */
2230 len = ieee802_15_4_print_header_ie_list(ndo, p, caplen,
2231 &payload_ie_present);
2232 if (len < 0) {
2233 return 0;
2234 }
2235 p += len;
2236 caplen -= len;
2237 }
2238
2239 if (payload_ie_present) {
2240 if (security_level >= 4) {
2241 ND_PRINT((ndo, "Payload IEs present, but encrypted, cannot print "));
2242 } else {
2243 len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen);
2244 if (len < 0) {
2245 return 0;
2246 }
2247 p += len;
2248 caplen -= len;
2249 }
2250 }
2251
2252 /* Print MIC */
2253 if (ndo->ndo_vflag > 2 && miclen != 0) {
2254 ND_PRINT((ndo, "\n\tMIC "));
2255
2256 for(len = 0; len < miclen; len += 4) {
2257 ND_PRINT((ndo, "%08x", EXTRACT_32BITS(mic_start + len)));
2258 }
2259 ND_PRINT((ndo, " "));
2260 }
2261
2262
2263 /* Print FCS */
2264 if (ndo->ndo_vflag > 2) {
2265 if (crc_check == fcs) {
2266 ND_PRINT((ndo, "FCS %04x ", fcs));
2267 } else {
2268 ND_PRINT((ndo, "wrong FCS %04x vs %04x (assume no FCS stored) ",
2269 fcs, crc_check));
2270 }
2271 }
2272
2273 if (!ndo->ndo_suppress_default_print)
2274 ND_DEFAULTPRINT(p, caplen);
2275
2276 return 1;
2277 }
2278
2279 /*
2280 * Print frag frame.
2281 *
2282 * Returns FALSE in case of error.
2283 */
2284 static u_int
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)))
2289 {
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. */
2294 return 0;
2295 }
2296
2297 /*
2298 * Interal call to dissector taking packet + len instead of pcap_pkthdr.
2299 *
2300 * Returns FALSE in case of error.
2301 */
2302 u_int
2303 ieee802_15_4_print(netdissect_options *ndo,
2304 const u_char *p, u_int caplen)
2305 {
2306 int frame_type;
2307 uint16_t fc;
2308
2309 if (caplen < 3) {
2310 ND_PRINT((ndo, "[|802.15.4] %x", caplen));
2311 return 0;
2312 }
2313
2314 fc = EXTRACT_LE_16BITS(p);
2315
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.
2318 */
2319
2320 frame_type = fc & 0x7;
2321 ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[frame_type]));
2322
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);
2329 break;
2330 case 0x04: /* Reserved */
2331 return 0;
2332 break;
2333 case 0x05: /* Multipurpose */
2334 return ieee802_15_4_mp_frame(ndo, p, caplen, fc);
2335 break;
2336 case 0x06: /* Fragment or Frak */
2337 return ieee802_15_4_frag_frame(ndo, p, caplen, fc);
2338 break;
2339 case 0x07: /* Extended */
2340 return 0;
2341 break;
2342 }
2343 return 0;
2344 }
2345
2346 /*
2347 * Main function to print packets.
2348 */
2349
2350 u_int
2351 ieee802_15_4_if_print(netdissect_options *ndo,
2352 const struct pcap_pkthdr *h, const u_char *p)
2353 {
2354 u_int caplen = h->caplen;
2355 return ieee802_15_4_print(ndo, p, caplen);
2356 }
2357
2358