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