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