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