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