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