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