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