1 /* $FreeBSD$ */ 2 /* 3 * Copyright (c) 2001 4 * Fortress Technologies, Inc. All rights reserved. 5 * Charlie Lenahan (clenahan@fortresstech.com) 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #ifndef lint 25 static const char rcsid[] _U_ = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.31.2.15 2007/07/22 23:14:14 guy Exp $ (LBL)"; 27 #endif 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #include <tcpdump-stdinc.h> 34 35 #include <stdio.h> 36 #include <pcap.h> 37 #include <string.h> 38 39 #include "interface.h" 40 #include "addrtoname.h" 41 #include "ethertype.h" 42 43 #include "extract.h" 44 45 #include "cpack.h" 46 47 #include "ieee802_11.h" 48 #include "ieee802_11_radio.h" 49 50 #define PRINT_SSID(p) \ 51 switch (p.ssid_status) { \ 52 case TRUNCATED: \ 53 return 0; \ 54 case PRESENT: \ 55 printf(" ("); \ 56 fn_print(p.ssid.ssid, NULL); \ 57 printf(")"); \ 58 break; \ 59 case NOT_PRESENT: \ 60 break; \ 61 } 62 63 #define PRINT_RATE(_sep, _r, _suf) \ 64 printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf) 65 #define PRINT_RATES(p) \ 66 switch (p.rates_status) { \ 67 case TRUNCATED: \ 68 return 0; \ 69 case PRESENT: \ 70 do { \ 71 int z; \ 72 const char *sep = " ["; \ 73 for (z = 0; z < p.rates.length ; z++) { \ 74 PRINT_RATE(sep, p.rates.rate[z], \ 75 (p.rates.rate[z] & 0x80 ? "*" : "")); \ 76 sep = " "; \ 77 } \ 78 if (p.rates.length != 0) \ 79 printf(" Mbit]"); \ 80 } while (0); \ 81 break; \ 82 case NOT_PRESENT: \ 83 break; \ 84 } 85 86 #define PRINT_DS_CHANNEL(p) \ 87 switch (p.ds_status) { \ 88 case TRUNCATED: \ 89 return 0; \ 90 case PRESENT: \ 91 printf(" CH: %u", p.ds.channel); \ 92 break; \ 93 case NOT_PRESENT: \ 94 break; \ 95 } \ 96 printf("%s", \ 97 CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" ); 98 99 static const int ieee80211_htrates[16] = { 100 13, /* IFM_IEEE80211_MCS0 */ 101 26, /* IFM_IEEE80211_MCS1 */ 102 39, /* IFM_IEEE80211_MCS2 */ 103 52, /* IFM_IEEE80211_MCS3 */ 104 78, /* IFM_IEEE80211_MCS4 */ 105 104, /* IFM_IEEE80211_MCS5 */ 106 117, /* IFM_IEEE80211_MCS6 */ 107 130, /* IFM_IEEE80211_MCS7 */ 108 26, /* IFM_IEEE80211_MCS8 */ 109 52, /* IFM_IEEE80211_MCS9 */ 110 78, /* IFM_IEEE80211_MCS10 */ 111 104, /* IFM_IEEE80211_MCS11 */ 112 156, /* IFM_IEEE80211_MCS12 */ 113 208, /* IFM_IEEE80211_MCS13 */ 114 234, /* IFM_IEEE80211_MCS14 */ 115 260, /* IFM_IEEE80211_MCS15 */ 116 }; 117 #define PRINT_HT_RATE(_sep, _r, _suf) \ 118 printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf) 119 120 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"}; 121 #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0]) 122 123 static const char *status_text[] = { 124 "Succesful", /* 0 */ 125 "Unspecified failure", /* 1 */ 126 "Reserved", /* 2 */ 127 "Reserved", /* 3 */ 128 "Reserved", /* 4 */ 129 "Reserved", /* 5 */ 130 "Reserved", /* 6 */ 131 "Reserved", /* 7 */ 132 "Reserved", /* 8 */ 133 "Reserved", /* 9 */ 134 "Cannot Support all requested capabilities in the Capability Information field", /* 10 */ 135 "Reassociation denied due to inability to confirm that association exists", /* 11 */ 136 "Association denied due to reason outside the scope of the standard", /* 12 */ 137 "Responding station does not support the specified authentication algorithm ", /* 13 */ 138 "Received an Authentication frame with authentication transaction " \ 139 "sequence number out of expected sequence", /* 14 */ 140 "Authentication rejected because of challenge failure", /* 15 */ 141 "Authentication rejected due to timeout waiting for next frame in sequence", /* 16 */ 142 "Association denied because AP is unable to handle additional associated stations", /* 17 */ 143 "Association denied due to requesting station not supporting all of the " \ 144 "data rates in BSSBasicRateSet parameter", /* 18 */ 145 }; 146 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0]) 147 148 static const char *reason_text[] = { 149 "Reserved", /* 0 */ 150 "Unspecified reason", /* 1 */ 151 "Previous authentication no longer valid", /* 2 */ 152 "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */ 153 "Disassociated due to inactivity", /* 4 */ 154 "Disassociated because AP is unable to handle all currently associated stations", /* 5 */ 155 "Class 2 frame received from nonauthenticated station", /* 6 */ 156 "Class 3 frame received from nonassociated station", /* 7 */ 157 "Disassociated because sending station is leaving (or has left) BSS", /* 8 */ 158 "Station requesting (re)association is not authenticated with responding station", /* 9 */ 159 }; 160 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0]) 161 162 static int 163 wep_print(const u_char *p) 164 { 165 u_int32_t iv; 166 167 if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN)) 168 return 0; 169 iv = EXTRACT_LE_32BITS(p); 170 171 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), 172 IV_KEYID(iv)); 173 174 return 1; 175 } 176 177 static void 178 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset) 179 { 180 /* 181 * We haven't seen any elements yet. 182 */ 183 pbody->challenge_status = NOT_PRESENT; 184 pbody->ssid_status = NOT_PRESENT; 185 pbody->rates_status = NOT_PRESENT; 186 pbody->ds_status = NOT_PRESENT; 187 pbody->cf_status = NOT_PRESENT; 188 pbody->tim_status = NOT_PRESENT; 189 190 for (;;) { 191 if (!TTEST2(*(p + offset), 1)) 192 return; 193 switch (*(p + offset)) { 194 case E_SSID: 195 /* Present, possibly truncated */ 196 pbody->ssid_status = TRUNCATED; 197 if (!TTEST2(*(p + offset), 2)) 198 return; 199 memcpy(&pbody->ssid, p + offset, 2); 200 offset += 2; 201 if (pbody->ssid.length != 0) { 202 if (pbody->ssid.length > 203 sizeof(pbody->ssid.ssid) - 1) 204 return; 205 if (!TTEST2(*(p + offset), pbody->ssid.length)) 206 return; 207 memcpy(&pbody->ssid.ssid, p + offset, 208 pbody->ssid.length); 209 offset += pbody->ssid.length; 210 } 211 pbody->ssid.ssid[pbody->ssid.length] = '\0'; 212 /* Present and not truncated */ 213 pbody->ssid_status = PRESENT; 214 break; 215 case E_CHALLENGE: 216 /* Present, possibly truncated */ 217 pbody->challenge_status = TRUNCATED; 218 if (!TTEST2(*(p + offset), 2)) 219 return; 220 memcpy(&pbody->challenge, p + offset, 2); 221 offset += 2; 222 if (pbody->challenge.length != 0) { 223 if (pbody->challenge.length > 224 sizeof(pbody->challenge.text) - 1) 225 return; 226 if (!TTEST2(*(p + offset), pbody->challenge.length)) 227 return; 228 memcpy(&pbody->challenge.text, p + offset, 229 pbody->challenge.length); 230 offset += pbody->challenge.length; 231 } 232 pbody->challenge.text[pbody->challenge.length] = '\0'; 233 /* Present and not truncated */ 234 pbody->challenge_status = PRESENT; 235 break; 236 case E_RATES: 237 /* Present, possibly truncated */ 238 pbody->rates_status = TRUNCATED; 239 if (!TTEST2(*(p + offset), 2)) 240 return; 241 memcpy(&(pbody->rates), p + offset, 2); 242 offset += 2; 243 if (pbody->rates.length != 0) { 244 if (pbody->rates.length > sizeof pbody->rates.rate) 245 return; 246 if (!TTEST2(*(p + offset), pbody->rates.length)) 247 return; 248 memcpy(&pbody->rates.rate, p + offset, 249 pbody->rates.length); 250 offset += pbody->rates.length; 251 } 252 /* Present and not truncated */ 253 pbody->rates_status = PRESENT; 254 break; 255 case E_DS: 256 /* Present, possibly truncated */ 257 pbody->ds_status = TRUNCATED; 258 if (!TTEST2(*(p + offset), 3)) 259 return; 260 memcpy(&pbody->ds, p + offset, 3); 261 offset += 3; 262 /* Present and not truncated */ 263 pbody->ds_status = PRESENT; 264 break; 265 case E_CF: 266 /* Present, possibly truncated */ 267 pbody->cf_status = TRUNCATED; 268 if (!TTEST2(*(p + offset), 8)) 269 return; 270 memcpy(&pbody->cf, p + offset, 8); 271 offset += 8; 272 /* Present and not truncated */ 273 pbody->cf_status = PRESENT; 274 break; 275 case E_TIM: 276 /* Present, possibly truncated */ 277 pbody->tim_status = TRUNCATED; 278 if (!TTEST2(*(p + offset), 2)) 279 return; 280 memcpy(&pbody->tim, p + offset, 2); 281 offset += 2; 282 if (!TTEST2(*(p + offset), 3)) 283 return; 284 memcpy(&pbody->tim.count, p + offset, 3); 285 offset += 3; 286 287 if (pbody->tim.length <= 3) 288 break; 289 if (pbody->tim.length - 3 > sizeof pbody->tim.bitmap) 290 return; 291 if (!TTEST2(*(p + offset), pbody->tim.length - 3)) 292 return; 293 memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3), 294 (pbody->tim.length - 3)); 295 offset += pbody->tim.length - 3; 296 /* Present and not truncated */ 297 pbody->tim_status = PRESENT; 298 break; 299 default: 300 #if 0 301 printf("(1) unhandled element_id (%d) ", 302 *(p + offset) ); 303 #endif 304 if (!TTEST2(*(p + offset), 2)) 305 return; 306 if (!TTEST2(*(p + offset + 2), *(p + offset + 1))) 307 return; 308 offset += *(p + offset + 1) + 2; 309 break; 310 } 311 } 312 } 313 314 /********************************************************************************* 315 * Print Handle functions for the management frame types 316 *********************************************************************************/ 317 318 static int 319 handle_beacon(const u_char *p) 320 { 321 struct mgmt_body_t pbody; 322 int offset = 0; 323 324 memset(&pbody, 0, sizeof(pbody)); 325 326 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + 327 IEEE802_11_CAPINFO_LEN)) 328 return 0; 329 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); 330 offset += IEEE802_11_TSTAMP_LEN; 331 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); 332 offset += IEEE802_11_BCNINT_LEN; 333 pbody.capability_info = EXTRACT_LE_16BITS(p+offset); 334 offset += IEEE802_11_CAPINFO_LEN; 335 336 parse_elements(&pbody, p, offset); 337 338 PRINT_SSID(pbody); 339 PRINT_RATES(pbody); 340 printf(" %s", 341 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"); 342 PRINT_DS_CHANNEL(pbody); 343 344 return 1; 345 } 346 347 static int 348 handle_assoc_request(const u_char *p) 349 { 350 struct mgmt_body_t pbody; 351 int offset = 0; 352 353 memset(&pbody, 0, sizeof(pbody)); 354 355 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)) 356 return 0; 357 pbody.capability_info = EXTRACT_LE_16BITS(p); 358 offset += IEEE802_11_CAPINFO_LEN; 359 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); 360 offset += IEEE802_11_LISTENINT_LEN; 361 362 parse_elements(&pbody, p, offset); 363 364 PRINT_SSID(pbody); 365 PRINT_RATES(pbody); 366 return 1; 367 } 368 369 static int 370 handle_assoc_response(const u_char *p) 371 { 372 struct mgmt_body_t pbody; 373 int offset = 0; 374 375 memset(&pbody, 0, sizeof(pbody)); 376 377 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + 378 IEEE802_11_AID_LEN)) 379 return 0; 380 pbody.capability_info = EXTRACT_LE_16BITS(p); 381 offset += IEEE802_11_CAPINFO_LEN; 382 pbody.status_code = EXTRACT_LE_16BITS(p+offset); 383 offset += IEEE802_11_STATUS_LEN; 384 pbody.aid = EXTRACT_LE_16BITS(p+offset); 385 offset += IEEE802_11_AID_LEN; 386 387 parse_elements(&pbody, p, offset); 388 389 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 , 390 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "", 391 (pbody.status_code < NUM_STATUSES 392 ? status_text[pbody.status_code] 393 : "n/a")); 394 395 return 1; 396 } 397 398 static int 399 handle_reassoc_request(const u_char *p) 400 { 401 struct mgmt_body_t pbody; 402 int offset = 0; 403 404 memset(&pbody, 0, sizeof(pbody)); 405 406 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + 407 IEEE802_11_AP_LEN)) 408 return 0; 409 pbody.capability_info = EXTRACT_LE_16BITS(p); 410 offset += IEEE802_11_CAPINFO_LEN; 411 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); 412 offset += IEEE802_11_LISTENINT_LEN; 413 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN); 414 offset += IEEE802_11_AP_LEN; 415 416 parse_elements(&pbody, p, offset); 417 418 PRINT_SSID(pbody); 419 printf(" AP : %s", etheraddr_string( pbody.ap )); 420 421 return 1; 422 } 423 424 static int 425 handle_reassoc_response(const u_char *p) 426 { 427 /* Same as a Association Reponse */ 428 return handle_assoc_response(p); 429 } 430 431 static int 432 handle_probe_request(const u_char *p) 433 { 434 struct mgmt_body_t pbody; 435 int offset = 0; 436 437 memset(&pbody, 0, sizeof(pbody)); 438 439 parse_elements(&pbody, p, offset); 440 441 PRINT_SSID(pbody); 442 PRINT_RATES(pbody); 443 444 return 1; 445 } 446 447 static int 448 handle_probe_response(const u_char *p) 449 { 450 struct mgmt_body_t pbody; 451 int offset = 0; 452 453 memset(&pbody, 0, sizeof(pbody)); 454 455 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + 456 IEEE802_11_CAPINFO_LEN)) 457 return 0; 458 459 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); 460 offset += IEEE802_11_TSTAMP_LEN; 461 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); 462 offset += IEEE802_11_BCNINT_LEN; 463 pbody.capability_info = EXTRACT_LE_16BITS(p+offset); 464 offset += IEEE802_11_CAPINFO_LEN; 465 466 parse_elements(&pbody, p, offset); 467 468 PRINT_SSID(pbody); 469 PRINT_RATES(pbody); 470 PRINT_DS_CHANNEL(pbody); 471 472 return 1; 473 } 474 475 static int 476 handle_atim(void) 477 { 478 /* the frame body for ATIM is null. */ 479 return 1; 480 } 481 482 static int 483 handle_disassoc(const u_char *p) 484 { 485 struct mgmt_body_t pbody; 486 487 memset(&pbody, 0, sizeof(pbody)); 488 489 if (!TTEST2(*p, IEEE802_11_REASON_LEN)) 490 return 0; 491 pbody.reason_code = EXTRACT_LE_16BITS(p); 492 493 printf(": %s", 494 (pbody.reason_code < NUM_REASONS) 495 ? reason_text[pbody.reason_code] 496 : "Reserved" ); 497 498 return 1; 499 } 500 501 static int 502 handle_auth(const u_char *p) 503 { 504 struct mgmt_body_t pbody; 505 int offset = 0; 506 507 memset(&pbody, 0, sizeof(pbody)); 508 509 if (!TTEST2(*p, 6)) 510 return 0; 511 pbody.auth_alg = EXTRACT_LE_16BITS(p); 512 offset += 2; 513 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset); 514 offset += 2; 515 pbody.status_code = EXTRACT_LE_16BITS(p + offset); 516 offset += 2; 517 518 parse_elements(&pbody, p, offset); 519 520 if ((pbody.auth_alg == 1) && 521 ((pbody.auth_trans_seq_num == 2) || 522 (pbody.auth_trans_seq_num == 3))) { 523 printf(" (%s)-%x [Challenge Text] %s", 524 (pbody.auth_alg < NUM_AUTH_ALGS) 525 ? auth_alg_text[pbody.auth_alg] 526 : "Reserved", 527 pbody.auth_trans_seq_num, 528 ((pbody.auth_trans_seq_num % 2) 529 ? ((pbody.status_code < NUM_STATUSES) 530 ? status_text[pbody.status_code] 531 : "n/a") : "")); 532 return 1; 533 } 534 printf(" (%s)-%x: %s", 535 (pbody.auth_alg < NUM_AUTH_ALGS) 536 ? auth_alg_text[pbody.auth_alg] 537 : "Reserved", 538 pbody.auth_trans_seq_num, 539 (pbody.auth_trans_seq_num % 2) 540 ? ((pbody.status_code < NUM_STATUSES) 541 ? status_text[pbody.status_code] 542 : "n/a") 543 : ""); 544 545 return 1; 546 } 547 548 static int 549 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p) 550 { 551 struct mgmt_body_t pbody; 552 int offset = 0; 553 const char *reason = NULL; 554 555 memset(&pbody, 0, sizeof(pbody)); 556 557 if (!TTEST2(*p, IEEE802_11_REASON_LEN)) 558 return 0; 559 pbody.reason_code = EXTRACT_LE_16BITS(p); 560 offset += IEEE802_11_REASON_LEN; 561 562 reason = (pbody.reason_code < NUM_REASONS) 563 ? reason_text[pbody.reason_code] 564 : "Reserved"; 565 566 if (eflag) { 567 printf(": %s", reason); 568 } else { 569 printf(" (%s): %s", etheraddr_string(pmh->sa), reason); 570 } 571 return 1; 572 } 573 574 575 /********************************************************************************* 576 * Print Body funcs 577 *********************************************************************************/ 578 579 580 static int 581 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh, 582 const u_char *p) 583 { 584 switch (FC_SUBTYPE(fc)) { 585 case ST_ASSOC_REQUEST: 586 printf("Assoc Request"); 587 return handle_assoc_request(p); 588 case ST_ASSOC_RESPONSE: 589 printf("Assoc Response"); 590 return handle_assoc_response(p); 591 case ST_REASSOC_REQUEST: 592 printf("ReAssoc Request"); 593 return handle_reassoc_request(p); 594 case ST_REASSOC_RESPONSE: 595 printf("ReAssoc Response"); 596 return handle_reassoc_response(p); 597 case ST_PROBE_REQUEST: 598 printf("Probe Request"); 599 return handle_probe_request(p); 600 case ST_PROBE_RESPONSE: 601 printf("Probe Response"); 602 return handle_probe_response(p); 603 case ST_BEACON: 604 printf("Beacon"); 605 return handle_beacon(p); 606 case ST_ATIM: 607 printf("ATIM"); 608 return handle_atim(); 609 case ST_DISASSOC: 610 printf("Disassociation"); 611 return handle_disassoc(p); 612 case ST_AUTH: 613 printf("Authentication"); 614 if (!TTEST2(*p, 3)) 615 return 0; 616 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) { 617 printf("Authentication (Shared-Key)-3 "); 618 return wep_print(p); 619 } 620 return handle_auth(p); 621 case ST_DEAUTH: 622 printf("DeAuthentication"); 623 return handle_deauth(pmh, p); 624 break; 625 default: 626 printf("Unhandled Management subtype(%x)", 627 FC_SUBTYPE(fc)); 628 return 1; 629 } 630 } 631 632 633 /********************************************************************************* 634 * Handles printing all the control frame types 635 *********************************************************************************/ 636 637 static int 638 ctrl_body_print(u_int16_t fc, const u_char *p) 639 { 640 switch (FC_SUBTYPE(fc)) { 641 case CTRL_BAR: 642 printf("BAR"); 643 if (!TTEST2(*p, CTRL_BAR_HDRLEN)) 644 return 0; 645 if (!eflag) 646 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", 647 etheraddr_string(((const struct ctrl_bar_t *)p)->ra), 648 etheraddr_string(((const struct ctrl_bar_t *)p)->ta), 649 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), 650 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); 651 break; 652 case CTRL_PS_POLL: 653 printf("Power Save-Poll"); 654 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN)) 655 return 0; 656 printf(" AID(%x)", 657 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid))); 658 break; 659 case CTRL_RTS: 660 printf("Request-To-Send"); 661 if (!TTEST2(*p, CTRL_RTS_HDRLEN)) 662 return 0; 663 if (!eflag) 664 printf(" TA:%s ", 665 etheraddr_string(((const struct ctrl_rts_t *)p)->ta)); 666 break; 667 case CTRL_CTS: 668 printf("Clear-To-Send"); 669 if (!TTEST2(*p, CTRL_CTS_HDRLEN)) 670 return 0; 671 if (!eflag) 672 printf(" RA:%s ", 673 etheraddr_string(((const struct ctrl_cts_t *)p)->ra)); 674 break; 675 case CTRL_ACK: 676 printf("Acknowledgment"); 677 if (!TTEST2(*p, CTRL_ACK_HDRLEN)) 678 return 0; 679 if (!eflag) 680 printf(" RA:%s ", 681 etheraddr_string(((const struct ctrl_ack_t *)p)->ra)); 682 break; 683 case CTRL_CF_END: 684 printf("CF-End"); 685 if (!TTEST2(*p, CTRL_END_HDRLEN)) 686 return 0; 687 if (!eflag) 688 printf(" RA:%s ", 689 etheraddr_string(((const struct ctrl_end_t *)p)->ra)); 690 break; 691 case CTRL_END_ACK: 692 printf("CF-End+CF-Ack"); 693 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN)) 694 return 0; 695 if (!eflag) 696 printf(" RA:%s ", 697 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra)); 698 break; 699 default: 700 printf("Unknown Ctrl Subtype"); 701 } 702 return 1; 703 } 704 705 /* 706 * Print Header funcs 707 */ 708 709 /* 710 * Data Frame - Address field contents 711 * 712 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4 713 * 0 | 0 | DA | SA | BSSID | n/a 714 * 0 | 1 | DA | BSSID | SA | n/a 715 * 1 | 0 | BSSID | SA | DA | n/a 716 * 1 | 1 | RA | TA | DA | SA 717 */ 718 719 static void 720 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, 721 const u_int8_t **dstp) 722 { 723 u_int subtype = FC_SUBTYPE(fc); 724 725 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) || 726 DATA_FRAME_IS_QOS(subtype)) { 727 printf("CF "); 728 if (DATA_FRAME_IS_CF_ACK(subtype)) { 729 if (DATA_FRAME_IS_CF_POLL(subtype)) 730 printf("Ack/Poll"); 731 else 732 printf("Ack"); 733 } else { 734 if (DATA_FRAME_IS_CF_POLL(subtype)) 735 printf("Poll"); 736 } 737 if (DATA_FRAME_IS_QOS(subtype)) 738 printf("+QoS"); 739 printf(" "); 740 } 741 742 #define ADDR1 (p + 4) 743 #define ADDR2 (p + 10) 744 #define ADDR3 (p + 16) 745 #define ADDR4 (p + 24) 746 747 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { 748 if (srcp != NULL) 749 *srcp = ADDR2; 750 if (dstp != NULL) 751 *dstp = ADDR1; 752 if (!eflag) 753 return; 754 printf("DA:%s SA:%s BSSID:%s ", 755 etheraddr_string(ADDR1), etheraddr_string(ADDR2), 756 etheraddr_string(ADDR3)); 757 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { 758 if (srcp != NULL) 759 *srcp = ADDR3; 760 if (dstp != NULL) 761 *dstp = ADDR1; 762 if (!eflag) 763 return; 764 printf("DA:%s BSSID:%s SA:%s ", 765 etheraddr_string(ADDR1), etheraddr_string(ADDR2), 766 etheraddr_string(ADDR3)); 767 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { 768 if (srcp != NULL) 769 *srcp = ADDR2; 770 if (dstp != NULL) 771 *dstp = ADDR3; 772 if (!eflag) 773 return; 774 printf("BSSID:%s SA:%s DA:%s ", 775 etheraddr_string(ADDR1), etheraddr_string(ADDR2), 776 etheraddr_string(ADDR3)); 777 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { 778 if (srcp != NULL) 779 *srcp = ADDR4; 780 if (dstp != NULL) 781 *dstp = ADDR3; 782 if (!eflag) 783 return; 784 printf("RA:%s TA:%s DA:%s SA:%s ", 785 etheraddr_string(ADDR1), etheraddr_string(ADDR2), 786 etheraddr_string(ADDR3), etheraddr_string(ADDR4)); 787 } 788 789 #undef ADDR1 790 #undef ADDR2 791 #undef ADDR3 792 #undef ADDR4 793 } 794 795 static void 796 mgmt_header_print(const u_char *p, const u_int8_t **srcp, 797 const u_int8_t **dstp) 798 { 799 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; 800 801 if (srcp != NULL) 802 *srcp = hp->sa; 803 if (dstp != NULL) 804 *dstp = hp->da; 805 if (!eflag) 806 return; 807 808 printf("BSSID:%s DA:%s SA:%s ", 809 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da), 810 etheraddr_string((hp)->sa)); 811 } 812 813 static void 814 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, 815 const u_int8_t **dstp) 816 { 817 if (srcp != NULL) 818 *srcp = NULL; 819 if (dstp != NULL) 820 *dstp = NULL; 821 if (!eflag) 822 return; 823 824 switch (FC_SUBTYPE(fc)) { 825 case CTRL_BAR: 826 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", 827 etheraddr_string(((const struct ctrl_bar_t *)p)->ra), 828 etheraddr_string(((const struct ctrl_bar_t *)p)->ta), 829 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), 830 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); 831 break; 832 case CTRL_PS_POLL: 833 printf("BSSID:%s TA:%s ", 834 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid), 835 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta)); 836 break; 837 case CTRL_RTS: 838 printf("RA:%s TA:%s ", 839 etheraddr_string(((const struct ctrl_rts_t *)p)->ra), 840 etheraddr_string(((const struct ctrl_rts_t *)p)->ta)); 841 break; 842 case CTRL_CTS: 843 printf("RA:%s ", 844 etheraddr_string(((const struct ctrl_cts_t *)p)->ra)); 845 break; 846 case CTRL_ACK: 847 printf("RA:%s ", 848 etheraddr_string(((const struct ctrl_ack_t *)p)->ra)); 849 break; 850 case CTRL_CF_END: 851 printf("RA:%s BSSID:%s ", 852 etheraddr_string(((const struct ctrl_end_t *)p)->ra), 853 etheraddr_string(((const struct ctrl_end_t *)p)->bssid)); 854 break; 855 case CTRL_END_ACK: 856 printf("RA:%s BSSID:%s ", 857 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra), 858 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid)); 859 break; 860 default: 861 printf("(H) Unknown Ctrl Subtype"); 862 break; 863 } 864 } 865 866 static int 867 extract_header_length(u_int16_t fc) 868 { 869 int len; 870 871 switch (FC_TYPE(fc)) { 872 case T_MGMT: 873 return MGMT_HDRLEN; 874 case T_CTRL: 875 switch (FC_SUBTYPE(fc)) { 876 case CTRL_BAR: 877 return CTRL_BAR_HDRLEN; 878 case CTRL_PS_POLL: 879 return CTRL_PS_POLL_HDRLEN; 880 case CTRL_RTS: 881 return CTRL_RTS_HDRLEN; 882 case CTRL_CTS: 883 return CTRL_CTS_HDRLEN; 884 case CTRL_ACK: 885 return CTRL_ACK_HDRLEN; 886 case CTRL_CF_END: 887 return CTRL_END_HDRLEN; 888 case CTRL_END_ACK: 889 return CTRL_END_ACK_HDRLEN; 890 default: 891 return 0; 892 } 893 case T_DATA: 894 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; 895 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) 896 len += 2; 897 return len; 898 default: 899 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc)); 900 return 0; 901 } 902 } 903 904 /* 905 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp" 906 * to point to the source and destination MAC addresses in any case if 907 * "srcp" and "dstp" aren't null. 908 */ 909 static inline void 910 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, 911 const u_int8_t **dstp) 912 { 913 if (vflag) { 914 if (FC_MORE_DATA(fc)) 915 printf("More Data "); 916 if (FC_MORE_FLAG(fc)) 917 printf("More Fragments "); 918 if (FC_POWER_MGMT(fc)) 919 printf("Pwr Mgmt "); 920 if (FC_RETRY(fc)) 921 printf("Retry "); 922 if (FC_ORDER(fc)) 923 printf("Strictly Ordered "); 924 if (FC_WEP(fc)) 925 printf("WEP Encrypted "); 926 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL) 927 printf("%dus ", 928 EXTRACT_LE_16BITS( 929 &((const struct mgmt_header_t *)p)->duration)); 930 } 931 932 switch (FC_TYPE(fc)) { 933 case T_MGMT: 934 mgmt_header_print(p, srcp, dstp); 935 break; 936 case T_CTRL: 937 ctrl_header_print(fc, p, srcp, dstp); 938 break; 939 case T_DATA: 940 data_header_print(fc, p, srcp, dstp); 941 break; 942 default: 943 printf("(header) unknown IEEE802.11 frame type (%d)", 944 FC_TYPE(fc)); 945 *srcp = NULL; 946 *dstp = NULL; 947 break; 948 } 949 } 950 951 #ifndef roundup2 952 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ 953 #endif 954 955 static u_int 956 ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad) 957 { 958 u_int16_t fc; 959 u_int hdrlen; 960 const u_int8_t *src, *dst; 961 u_short extracted_ethertype; 962 963 if (caplen < IEEE802_11_FC_LEN) { 964 printf("[|802.11]"); 965 return caplen; 966 } 967 968 fc = EXTRACT_LE_16BITS(p); 969 hdrlen = extract_header_length(fc); 970 if (pad) 971 hdrlen = roundup2(hdrlen, 4); 972 973 if (caplen < hdrlen) { 974 printf("[|802.11]"); 975 return hdrlen; 976 } 977 978 ieee_802_11_hdr_print(fc, p, &src, &dst); 979 980 /* 981 * Go past the 802.11 header. 982 */ 983 length -= hdrlen; 984 caplen -= hdrlen; 985 p += hdrlen; 986 987 switch (FC_TYPE(fc)) { 988 case T_MGMT: 989 if (!mgmt_body_print(fc, 990 (const struct mgmt_header_t *)(p - hdrlen), p)) { 991 printf("[|802.11]"); 992 return hdrlen; 993 } 994 break; 995 case T_CTRL: 996 if (!ctrl_body_print(fc, p - hdrlen)) { 997 printf("[|802.11]"); 998 return hdrlen; 999 } 1000 break; 1001 case T_DATA: 1002 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))) 1003 return hdrlen; /* no-data frame */ 1004 /* There may be a problem w/ AP not having this bit set */ 1005 if (FC_WEP(fc)) { 1006 if (!wep_print(p)) { 1007 printf("[|802.11]"); 1008 return hdrlen; 1009 } 1010 } else if (llc_print(p, length, caplen, dst, src, 1011 &extracted_ethertype) == 0) { 1012 /* 1013 * Some kinds of LLC packet we cannot 1014 * handle intelligently 1015 */ 1016 if (!eflag) 1017 ieee_802_11_hdr_print(fc, p - hdrlen, NULL, 1018 NULL); 1019 if (extracted_ethertype) 1020 printf("(LLC %s) ", 1021 etherproto_string( 1022 htons(extracted_ethertype))); 1023 if (!suppress_default_print) 1024 default_print(p, caplen); 1025 } 1026 break; 1027 default: 1028 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc)); 1029 break; 1030 } 1031 1032 return hdrlen; 1033 } 1034 1035 /* 1036 * This is the top level routine of the printer. 'p' points 1037 * to the 802.11 header of the packet, 'h->ts' is the timestamp, 1038 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 1039 * is the number of bytes actually captured. 1040 */ 1041 u_int 1042 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p) 1043 { 1044 return ieee802_11_print(p, h->len, h->caplen, 0); 1045 } 1046 1047 #define IEEE80211_CHAN_FHSS \ 1048 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) 1049 #define IEEE80211_CHAN_A \ 1050 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) 1051 #define IEEE80211_CHAN_B \ 1052 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) 1053 #define IEEE80211_CHAN_PUREG \ 1054 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) 1055 #define IEEE80211_CHAN_G \ 1056 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) 1057 1058 #define IS_CHAN_FHSS(flags) \ 1059 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) 1060 #define IS_CHAN_A(flags) \ 1061 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) 1062 #define IS_CHAN_B(flags) \ 1063 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) 1064 #define IS_CHAN_PUREG(flags) \ 1065 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) 1066 #define IS_CHAN_G(flags) \ 1067 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) 1068 #define IS_CHAN_ANYG(flags) \ 1069 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) 1070 1071 static void 1072 print_chaninfo(int freq, int flags) 1073 { 1074 printf("%u MHz", freq); 1075 if (IS_CHAN_FHSS(flags)) 1076 printf(" FHSS"); 1077 if (IS_CHAN_A(flags)) { 1078 if (flags & IEEE80211_CHAN_HALF) 1079 printf(" 11a/10Mhz"); 1080 else if (flags & IEEE80211_CHAN_QUARTER) 1081 printf(" 11a/5Mhz"); 1082 else 1083 printf(" 11a"); 1084 } 1085 if (IS_CHAN_ANYG(flags)) { 1086 if (flags & IEEE80211_CHAN_HALF) 1087 printf(" 11g/10Mhz"); 1088 else if (flags & IEEE80211_CHAN_QUARTER) 1089 printf(" 11g/5Mhz"); 1090 else 1091 printf(" 11g"); 1092 } else if (IS_CHAN_B(flags)) 1093 printf(" 11b"); 1094 if (flags & IEEE80211_CHAN_TURBO) 1095 printf(" Turbo"); 1096 if (flags & IEEE80211_CHAN_HT20) 1097 printf(" ht/20"); 1098 else if (flags & IEEE80211_CHAN_HT40D) 1099 printf(" ht/40-"); 1100 else if (flags & IEEE80211_CHAN_HT40U) 1101 printf(" ht/40+"); 1102 printf(" "); 1103 } 1104 1105 static int 1106 print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) 1107 { 1108 union { 1109 int8_t i8; 1110 u_int8_t u8; 1111 int16_t i16; 1112 u_int16_t u16; 1113 u_int32_t u32; 1114 u_int64_t u64; 1115 } u, u2, u3, u4; 1116 int rc; 1117 1118 switch (bit) { 1119 case IEEE80211_RADIOTAP_FLAGS: 1120 rc = cpack_uint8(s, &u.u8); 1121 if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD) 1122 *pad = 1; 1123 break; 1124 case IEEE80211_RADIOTAP_RATE: 1125 case IEEE80211_RADIOTAP_DB_ANTSIGNAL: 1126 case IEEE80211_RADIOTAP_DB_ANTNOISE: 1127 case IEEE80211_RADIOTAP_ANTENNA: 1128 rc = cpack_uint8(s, &u.u8); 1129 break; 1130 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: 1131 case IEEE80211_RADIOTAP_DBM_ANTNOISE: 1132 rc = cpack_int8(s, &u.i8); 1133 break; 1134 case IEEE80211_RADIOTAP_CHANNEL: 1135 rc = cpack_uint16(s, &u.u16); 1136 if (rc != 0) 1137 break; 1138 rc = cpack_uint16(s, &u2.u16); 1139 break; 1140 case IEEE80211_RADIOTAP_FHSS: 1141 case IEEE80211_RADIOTAP_LOCK_QUALITY: 1142 case IEEE80211_RADIOTAP_TX_ATTENUATION: 1143 rc = cpack_uint16(s, &u.u16); 1144 break; 1145 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: 1146 rc = cpack_uint8(s, &u.u8); 1147 break; 1148 case IEEE80211_RADIOTAP_DBM_TX_POWER: 1149 rc = cpack_int8(s, &u.i8); 1150 break; 1151 case IEEE80211_RADIOTAP_TSFT: 1152 rc = cpack_uint64(s, &u.u64); 1153 break; 1154 case IEEE80211_RADIOTAP_XCHANNEL: 1155 rc = cpack_uint32(s, &u.u32); 1156 if (rc != 0) 1157 break; 1158 rc = cpack_uint16(s, &u2.u16); 1159 if (rc != 0) 1160 break; 1161 rc = cpack_uint8(s, &u3.u8); 1162 if (rc != 0) 1163 break; 1164 rc = cpack_uint8(s, &u4.u8); 1165 break; 1166 default: 1167 /* this bit indicates a field whose 1168 * size we do not know, so we cannot 1169 * proceed. 1170 */ 1171 printf("[0x%08x] ", bit); 1172 return -1; 1173 } 1174 1175 if (rc != 0) { 1176 printf("[|802.11]"); 1177 return rc; 1178 } 1179 1180 switch (bit) { 1181 case IEEE80211_RADIOTAP_CHANNEL: 1182 print_chaninfo(u.u16, u2.u16); 1183 break; 1184 case IEEE80211_RADIOTAP_FHSS: 1185 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff); 1186 break; 1187 case IEEE80211_RADIOTAP_RATE: 1188 if (u.u8 & 0x80) 1189 PRINT_RATE("", u.u8, " Mb/s "); 1190 else 1191 PRINT_HT_RATE("", u.u8, " Mb/s "); 1192 break; 1193 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: 1194 printf("%ddB signal ", u.i8); 1195 break; 1196 case IEEE80211_RADIOTAP_DBM_ANTNOISE: 1197 printf("%ddB noise ", u.i8); 1198 break; 1199 case IEEE80211_RADIOTAP_DB_ANTSIGNAL: 1200 printf("%ddB signal ", u.u8); 1201 break; 1202 case IEEE80211_RADIOTAP_DB_ANTNOISE: 1203 printf("%ddB noise ", u.u8); 1204 break; 1205 case IEEE80211_RADIOTAP_LOCK_QUALITY: 1206 printf("%u sq ", u.u16); 1207 break; 1208 case IEEE80211_RADIOTAP_TX_ATTENUATION: 1209 printf("%d tx power ", -(int)u.u16); 1210 break; 1211 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: 1212 printf("%ddB tx power ", -(int)u.u8); 1213 break; 1214 case IEEE80211_RADIOTAP_DBM_TX_POWER: 1215 printf("%ddBm tx power ", u.i8); 1216 break; 1217 case IEEE80211_RADIOTAP_FLAGS: 1218 if (u.u8 & IEEE80211_RADIOTAP_F_CFP) 1219 printf("cfp "); 1220 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE) 1221 printf("short preamble "); 1222 if (u.u8 & IEEE80211_RADIOTAP_F_WEP) 1223 printf("wep "); 1224 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG) 1225 printf("fragmented "); 1226 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS) 1227 printf("bad-fcs "); 1228 break; 1229 case IEEE80211_RADIOTAP_ANTENNA: 1230 printf("antenna %d ", u.u8); 1231 break; 1232 case IEEE80211_RADIOTAP_TSFT: 1233 printf("%" PRIu64 "us tsft ", u.u64); 1234 break; 1235 case IEEE80211_RADIOTAP_XCHANNEL: 1236 print_chaninfo(u2.u16, u.u32); 1237 break; 1238 } 1239 return 0; 1240 } 1241 1242 static u_int 1243 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) 1244 { 1245 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) 1246 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) 1247 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) 1248 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) 1249 #define BITNO_2(x) (((x) & 2) ? 1 : 0) 1250 #define BIT(n) (1 << n) 1251 #define IS_EXTENDED(__p) \ 1252 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 1253 1254 struct cpack_state cpacker; 1255 struct ieee80211_radiotap_header *hdr; 1256 u_int32_t present, next_present; 1257 u_int32_t *presentp, *last_presentp; 1258 enum ieee80211_radiotap_type bit; 1259 int bit0; 1260 const u_char *iter; 1261 u_int len; 1262 int pad; 1263 1264 if (caplen < sizeof(*hdr)) { 1265 printf("[|802.11]"); 1266 return caplen; 1267 } 1268 1269 hdr = (struct ieee80211_radiotap_header *)p; 1270 1271 len = EXTRACT_LE_16BITS(&hdr->it_len); 1272 1273 if (caplen < len) { 1274 printf("[|802.11]"); 1275 return caplen; 1276 } 1277 for (last_presentp = &hdr->it_present; 1278 IS_EXTENDED(last_presentp) && 1279 (u_char*)(last_presentp + 1) <= p + len; 1280 last_presentp++); 1281 1282 /* are there more bitmap extensions than bytes in header? */ 1283 if (IS_EXTENDED(last_presentp)) { 1284 printf("[|802.11]"); 1285 return caplen; 1286 } 1287 1288 iter = (u_char*)(last_presentp + 1); 1289 1290 if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) { 1291 /* XXX */ 1292 printf("[|802.11]"); 1293 return caplen; 1294 } 1295 1296 /* Assume no Atheros padding between 802.11 header and body */ 1297 pad = 0; 1298 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp; 1299 presentp++, bit0 += 32) { 1300 for (present = EXTRACT_LE_32BITS(presentp); present; 1301 present = next_present) { 1302 /* clear the least significant bit that is set */ 1303 next_present = present & (present - 1); 1304 1305 /* extract the least significant bit that is set */ 1306 bit = (enum ieee80211_radiotap_type) 1307 (bit0 + BITNO_32(present ^ next_present)); 1308 1309 if (print_radiotap_field(&cpacker, bit, &pad) != 0) 1310 goto out; 1311 } 1312 } 1313 out: 1314 return len + ieee802_11_print(p + len, length - len, caplen - len, pad); 1315 #undef BITNO_32 1316 #undef BITNO_16 1317 #undef BITNO_8 1318 #undef BITNO_4 1319 #undef BITNO_2 1320 #undef BIT 1321 } 1322 1323 static u_int 1324 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen) 1325 { 1326 u_int32_t caphdr_len; 1327 1328 caphdr_len = EXTRACT_32BITS(p + 4); 1329 if (caphdr_len < 8) { 1330 /* 1331 * Yow! The capture header length is claimed not 1332 * to be large enough to include even the version 1333 * cookie or capture header length! 1334 */ 1335 printf("[|802.11]"); 1336 return caplen; 1337 } 1338 1339 if (caplen < caphdr_len) { 1340 printf("[|802.11]"); 1341 return caplen; 1342 } 1343 1344 return caphdr_len + ieee802_11_print(p + caphdr_len, 1345 length - caphdr_len, caplen - caphdr_len, 0); 1346 } 1347 1348 #define PRISM_HDR_LEN 144 1349 1350 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001 1351 1352 /* 1353 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header, 1354 * containing information such as radio information, which we 1355 * currently ignore. 1356 * 1357 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1, it's 1358 * really DLT_IEEE802_11_RADIO (currently, on Linux, there's no 1359 * ARPHRD_ type for DLT_IEEE802_11_RADIO, as there is a 1360 * ARPHRD_IEEE80211_PRISM for DLT_PRISM_HEADER, so 1361 * ARPHRD_IEEE80211_PRISM is used for DLT_IEEE802_11_RADIO, and 1362 * the first 4 bytes of the header are used to indicate which it is). 1363 */ 1364 u_int 1365 prism_if_print(const struct pcap_pkthdr *h, const u_char *p) 1366 { 1367 u_int caplen = h->caplen; 1368 u_int length = h->len; 1369 1370 if (caplen < 4) { 1371 printf("[|802.11]"); 1372 return caplen; 1373 } 1374 1375 if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1) 1376 return ieee802_11_avs_radio_print(p, length, caplen); 1377 1378 if (caplen < PRISM_HDR_LEN) { 1379 printf("[|802.11]"); 1380 return caplen; 1381 } 1382 1383 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN, 1384 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0); 1385 } 1386 1387 /* 1388 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra 1389 * header, containing information such as radio information, which we 1390 * currently ignore. 1391 */ 1392 u_int 1393 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p) 1394 { 1395 u_int caplen = h->caplen; 1396 u_int length = h->len; 1397 1398 if (caplen < 8) { 1399 printf("[|802.11]"); 1400 return caplen; 1401 } 1402 1403 return ieee802_11_radio_print(p, length, caplen); 1404 } 1405