1 /* $OpenBSD: print-802_11.c,v 1.40 2017/09/01 14:04:49 stsp Exp $ */ 2 3 /* 4 * Copyright (c) 2005 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/time.h> 20 #include <sys/socket.h> 21 #include <sys/file.h> 22 #include <sys/ioctl.h> 23 24 #include <net/if.h> 25 26 #include <netinet/in.h> 27 #include <netinet/if_ether.h> 28 29 #include <net80211/ieee80211.h> 30 #include <net80211/ieee80211_radiotap.h> 31 32 #include <ctype.h> 33 #include <pcap.h> 34 #include <stdio.h> 35 #include <string.h> 36 37 #include "addrtoname.h" 38 #include "interface.h" 39 40 const char *ieee80211_ctl_subtype_name[] = { 41 "reserved#0", 42 "reserved#1", 43 "reserved#2", 44 "reserved#3", 45 "reserved#4", 46 "reserved#5", 47 "reserved#6", 48 "wrapper", 49 "block ack request", 50 "block ack", 51 "ps poll", 52 "rts", 53 "cts", 54 "ack", 55 "cf-end", 56 "cf-end-ack", 57 }; 58 59 const char *ieee80211_mgt_subtype_name[] = { 60 "association request", 61 "association response", 62 "reassociation request", 63 "reassociation response", 64 "probe request", 65 "probe response", 66 "reserved#6", 67 "reserved#7", 68 "beacon", 69 "atim", 70 "disassociation", 71 "authentication", 72 "deauthentication", 73 "action", 74 "action noack", 75 "reserved#15" 76 }; 77 78 const char *ieee80211_data_subtype_name[] = { 79 "data", 80 "data cf ack", 81 "data cf poll", 82 "data cf poll ack", 83 "no-data", 84 "no-data cf poll", 85 "no-data cf ack", 86 "no-data cf poll ack", 87 "QoS data", 88 "QoS data cf ack", 89 "QoS data cf poll", 90 "QoS data cf poll ack", 91 "QoS no-data", 92 "QoS no-data cf poll", 93 "QoS no-data cf ack", 94 "QoS no-data cf poll ack" 95 }; 96 97 int ieee80211_hdr(struct ieee80211_frame *); 98 int ieee80211_data(struct ieee80211_frame *, u_int); 99 void ieee80211_print_element(u_int8_t *, u_int); 100 void ieee80211_print_essid(u_int8_t *, u_int); 101 void ieee80211_print_country(u_int8_t *, u_int); 102 void ieee80211_print_htcaps(u_int8_t *, u_int); 103 void ieee80211_print_htop(u_int8_t *, u_int); 104 void ieee80211_print_rsncipher(u_int8_t []); 105 void ieee80211_print_akm(u_int8_t []); 106 void ieee80211_print_rsn(u_int8_t *, u_int); 107 int ieee80211_print_beacon(struct ieee80211_frame *, u_int); 108 int ieee80211_print_assocreq(struct ieee80211_frame *, u_int); 109 int ieee80211_print_elements(uint8_t *); 110 int ieee80211_frame(struct ieee80211_frame *, u_int); 111 int ieee80211_print(struct ieee80211_frame *, u_int); 112 u_int ieee80211_any2ieee(u_int, u_int); 113 void ieee80211_reason(u_int16_t); 114 115 #define TCARR(a) TCHECK2(*a, sizeof(a)) 116 117 int ieee80211_encap = 0; 118 119 int 120 ieee80211_hdr(struct ieee80211_frame *wh) 121 { 122 struct ieee80211_frame_addr4 *w4; 123 124 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { 125 case IEEE80211_FC1_DIR_NODS: 126 TCARR(wh->i_addr2); 127 printf("%s", etheraddr_string(wh->i_addr2)); 128 TCARR(wh->i_addr1); 129 printf(" > %s", etheraddr_string(wh->i_addr1)); 130 TCARR(wh->i_addr3); 131 printf(", bssid %s", etheraddr_string(wh->i_addr3)); 132 break; 133 case IEEE80211_FC1_DIR_TODS: 134 TCARR(wh->i_addr2); 135 printf("%s", etheraddr_string(wh->i_addr2)); 136 TCARR(wh->i_addr3); 137 printf(" > %s", etheraddr_string(wh->i_addr3)); 138 TCARR(wh->i_addr1); 139 printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1)); 140 break; 141 case IEEE80211_FC1_DIR_FROMDS: 142 TCARR(wh->i_addr3); 143 printf("%s", etheraddr_string(wh->i_addr3)); 144 TCARR(wh->i_addr1); 145 printf(" > %s", etheraddr_string(wh->i_addr1)); 146 TCARR(wh->i_addr2); 147 printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2)); 148 break; 149 case IEEE80211_FC1_DIR_DSTODS: 150 w4 = (struct ieee80211_frame_addr4 *) wh; 151 TCARR(w4->i_addr4); 152 printf("%s", etheraddr_string(w4->i_addr4)); 153 TCARR(w4->i_addr3); 154 printf(" > %s", etheraddr_string(w4->i_addr3)); 155 TCARR(w4->i_addr2); 156 printf(", bssid %s", etheraddr_string(w4->i_addr2)); 157 TCARR(w4->i_addr1); 158 printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1)); 159 break; 160 } 161 if (vflag) { 162 u_int16_t seq; 163 TCARR(wh->i_seq); 164 bcopy(wh->i_seq, &seq, sizeof(u_int16_t)); 165 printf(" (seq %u): ", letoh16(seq)); 166 } else 167 printf(": "); 168 169 return (0); 170 171 trunc: 172 /* Truncated elements in frame */ 173 return (1); 174 } 175 176 int 177 ieee80211_data(struct ieee80211_frame *wh, u_int len) 178 { 179 u_int8_t *t = (u_int8_t *)wh; 180 u_int datalen; 181 int data = !(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_NODATA); 182 int hasqos = ((wh->i_fc[0] & 183 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == 184 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)); 185 u_char *esrc = NULL, *edst = NULL; 186 187 if (hasqos) { 188 struct ieee80211_qosframe *wq; 189 190 wq = (struct ieee80211_qosframe *) wh; 191 TCHECK(*wq); 192 t += sizeof(*wq); 193 datalen = len - sizeof(*wq); 194 } else { 195 TCHECK(*wh); 196 t += sizeof(*wh); 197 datalen = len - sizeof(*wh); 198 } 199 200 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { 201 case IEEE80211_FC1_DIR_TODS: 202 esrc = wh->i_addr2; 203 edst = wh->i_addr3; 204 break; 205 case IEEE80211_FC1_DIR_FROMDS: 206 esrc = wh->i_addr3; 207 edst = wh->i_addr1; 208 break; 209 case IEEE80211_FC1_DIR_NODS: 210 esrc = wh->i_addr2; 211 edst = wh->i_addr1; 212 break; 213 case IEEE80211_FC1_DIR_DSTODS: 214 if (hasqos) { 215 struct ieee80211_qosframe_addr4 *w4; 216 217 w4 = (struct ieee80211_qosframe_addr4 *) wh; 218 TCHECK(*w4); 219 t = (u_int8_t *) (w4 + 1); 220 datalen = len - sizeof(*w4); 221 esrc = w4->i_addr4; 222 edst = w4->i_addr3; 223 } else { 224 struct ieee80211_frame_addr4 *w4; 225 226 w4 = (struct ieee80211_frame_addr4 *) wh; 227 TCHECK(*w4); 228 t = (u_int8_t *) (w4 + 1); 229 datalen = len - sizeof(*w4); 230 esrc = w4->i_addr4; 231 edst = w4->i_addr3; 232 } 233 break; 234 } 235 236 if (data && esrc) 237 llc_print(t, datalen, datalen, esrc, edst); 238 else if (eflag && esrc) 239 printf("%s > %s", 240 etheraddr_string(esrc), etheraddr_string(edst)); 241 242 return (0); 243 244 trunc: 245 /* Truncated elements in frame */ 246 return (1); 247 } 248 249 /* Caller checks len */ 250 void 251 ieee80211_print_element(u_int8_t *data, u_int len) 252 { 253 u_int8_t *p; 254 int i; 255 256 printf(" 0x"); 257 for (i = 0, p = data; i < len; i++, p++) 258 printf("%02x", *p); 259 } 260 261 /* Caller checks len */ 262 void 263 ieee80211_print_essid(u_int8_t *essid, u_int len) 264 { 265 u_int8_t *p; 266 int i; 267 268 if (len > IEEE80211_NWID_LEN) 269 len = IEEE80211_NWID_LEN; 270 271 /* determine printable or not */ 272 for (i = 0, p = essid; i < len; i++, p++) { 273 if (*p < ' ' || *p > 0x7e) 274 break; 275 } 276 if (i == len) { 277 printf(" ("); 278 for (i = 0, p = essid; i < len; i++, p++) 279 putchar(*p); 280 putchar(')'); 281 } else 282 ieee80211_print_element(essid, len); 283 } 284 285 /* Caller checks len */ 286 void 287 ieee80211_print_country(u_int8_t *data, u_int len) 288 { 289 u_int8_t first_chan, nchan, maxpower; 290 291 if (len < 6) 292 return; 293 294 /* country string */ 295 printf((isprint(data[0]) ? " '%c" : " '\\%03o"), data[0]); 296 printf((isprint(data[1]) ? "%c" : "\\%03o"), data[1]); 297 printf((isprint(data[2]) ? "%c'" : "\\%03o'"), data[2]); 298 299 len -= 3; 300 data += 3; 301 302 /* channels and corresponding TX power limits */ 303 while (len >= 3) { 304 /* no pretty-printing for nonsensical zero values, 305 * nor for operating extension IDs (values >= 201) */ 306 if (data[0] == 0 || data[1] == 0 || 307 data[0] >= 201 || data[1] >= 201) { 308 printf(", %d %d %d", data[0], data[1], data[2]); 309 len -= 3; 310 data += 3; 311 continue; 312 } 313 314 first_chan = data[0]; 315 nchan = data[1]; 316 maxpower = data[2]; 317 318 printf(", channel%s %d", nchan == 1 ? "" : "s", first_chan); 319 if (nchan > 1) 320 printf("-%d", first_chan + nchan - 1); 321 printf(" limit %ddB", maxpower); 322 323 len -= 3; 324 data += 3; 325 } 326 } 327 328 /* Caller checks len */ 329 void 330 ieee80211_print_htcaps(u_int8_t *data, u_int len) 331 { 332 uint16_t htcaps, rxrate; 333 int smps, rxstbc; 334 uint8_t ampdu, txmcs; 335 int i; 336 uint8_t *rxmcs; 337 338 if (len < 2) { 339 ieee80211_print_element(data, len); 340 return; 341 } 342 343 htcaps = (data[0]) | (data[1] << 8); 344 printf("=<"); 345 346 /* channel width */ 347 if (htcaps & IEEE80211_HTCAP_CBW20_40) 348 printf("20/40MHz"); 349 else 350 printf("20MHz"); 351 352 /* LDPC coding */ 353 if (htcaps & IEEE80211_HTCAP_LDPC) 354 printf(",LDPC"); 355 356 /* spatial multiplexing power save mode */ 357 smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK) 358 >> IEEE80211_HTCAP_SMPS_SHIFT; 359 if (smps == 0) 360 printf(",SMPS static"); 361 else if (smps == 1) 362 printf(",SMPS dynamic"); 363 364 /* 11n greenfield mode */ 365 if (htcaps & IEEE80211_HTCAP_GF) 366 printf(",greenfield"); 367 368 /* short guard interval */ 369 if (htcaps & IEEE80211_HTCAP_SGI20) 370 printf(",SGI@20MHz"); 371 if (htcaps & IEEE80211_HTCAP_SGI40) 372 printf(",SGI@40MHz"); 373 374 /* space-time block coding */ 375 if (htcaps & IEEE80211_HTCAP_TXSTBC) 376 printf(",TXSTBC"); 377 rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK) 378 >> IEEE80211_HTCAP_RXSTBC_SHIFT; 379 if (rxstbc > 0 && rxstbc < 4) 380 printf(",RXSTBC %d stream", rxstbc); 381 382 /* delayed block-ack */ 383 if (htcaps & IEEE80211_HTCAP_DELAYEDBA) 384 printf(",delayed BA"); 385 386 /* max A-MSDU length */ 387 if (htcaps & IEEE80211_HTCAP_AMSDU7935) 388 printf(",A-MSDU 7935"); 389 else 390 printf(",A-MSDU 3839"); 391 392 /* DSSS/CCK in 40MHz mode */ 393 if (htcaps & IEEE80211_HTCAP_DSSSCCK40) 394 printf(",DSSS/CCK@40MHz"); 395 396 /* 40MHz intolerant */ 397 if (htcaps & IEEE80211_HTCAP_40INTOLERANT) 398 printf(",40MHz intolerant"); 399 400 /* L-SIG TXOP protection */ 401 if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT) 402 printf(",L-SIG TXOP prot"); 403 404 if (len < 3) { 405 printf(">"); 406 return; 407 } 408 409 /* A-MPDU parameters. */ 410 ampdu = data[2]; 411 412 /* A-MPDU length exponent */ 413 if ((ampdu & IEEE80211_AMPDU_PARAM_LE) >= 0 && 414 (ampdu & IEEE80211_AMPDU_PARAM_LE) <= 3) 415 printf(",A-MPDU max %d", 416 (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE))) - 1); 417 418 /* A-MPDU start spacing */ 419 if (ampdu & IEEE80211_AMPDU_PARAM_SS) { 420 float ss; 421 422 switch ((ampdu & IEEE80211_AMPDU_PARAM_SS) >> 2) { 423 case 1: 424 ss = 0.25; 425 break; 426 case 2: 427 ss = 0.5; 428 break; 429 case 3: 430 ss = 1; 431 break; 432 case 4: 433 ss = 2; 434 break; 435 case 5: 436 ss = 4; 437 break; 438 case 6: 439 ss = 8; 440 break; 441 case 7: 442 ss = 16; 443 break; 444 default: 445 ss = 0; 446 break; 447 } 448 if (ss != 0) 449 printf(",A-MPDU spacing %.2fus", ss); 450 } 451 452 if (len < 21) { 453 printf(">"); 454 return; 455 } 456 457 /* Supported MCS set. */ 458 printf(",RxMCS 0x"); 459 rxmcs = &data[3]; 460 for (i = 0; i < 10; i++) 461 printf("%02x", rxmcs[i]); 462 463 /* Max MCS Rx rate (a value of 0 means "not specified"). */ 464 rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH); 465 if (rxrate) 466 printf(",RxMaxrate %huMb/s", rxrate); 467 468 /* Tx MCS Set */ 469 txmcs = data[15]; 470 if (txmcs & IEEE80211_TX_MCS_SET_DEFINED) { 471 if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL) { 472 /* Number of spatial Tx streams. */ 473 printf(",%d Tx streams", 474 1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS) >> 2)); 475 /* Transmit unequal modulation supported. */ 476 if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION) 477 printf(",UEQM"); 478 } 479 } 480 481 printf(">"); 482 } 483 484 /* Caller checks len */ 485 void 486 ieee80211_print_htop(u_int8_t *data, u_int len) 487 { 488 u_int8_t primary_chan; 489 u_int8_t htopinfo[5]; 490 u_int8_t basic_mcs[16]; 491 int sco, htprot, i; 492 493 if (len < sizeof(primary_chan) + sizeof(htopinfo) + sizeof(basic_mcs)) { 494 ieee80211_print_element(data, len); 495 return; 496 } 497 498 htopinfo[0] = data[1]; 499 500 printf("=<"); 501 502 /* primary channel and secondary channel offset */ 503 primary_chan = data[0]; 504 sco = ((htopinfo[0] & IEEE80211_HTOP0_SCO_MASK) 505 >> IEEE80211_HTOP0_SCO_SHIFT); 506 if (sco == 0) /* no secondary channel */ 507 printf("20MHz chan %d", primary_chan); 508 else if (sco == 1) { /* secondary channel above */ 509 if (primary_chan >= 1 && primary_chan <= 13) /* 2GHz */ 510 printf("40MHz chan %d:%d", primary_chan, 511 primary_chan + 1); 512 else if (primary_chan >= 34) /* 5GHz */ 513 printf("40MHz chan %d:%d", primary_chan, 514 primary_chan + 4); 515 else 516 printf("[invalid 40MHz chan %d+]", primary_chan); 517 } else if (sco == 3) { /* secondary channel below */ 518 if (primary_chan >= 2 && primary_chan <= 14) /* 2GHz */ 519 printf("40MHz chan %d:%d", primary_chan, 520 primary_chan - 1); 521 else if (primary_chan >= 40) /* 5GHz */ 522 printf("40MHz chan %d:%d", primary_chan, 523 primary_chan - 4); 524 else 525 printf("[invalid 40MHz chan %d-]", primary_chan); 526 } else 527 printf("chan %d [invalid secondary channel offset %d]", 528 primary_chan, sco); 529 530 /* STA channel width */ 531 if ((htopinfo[0] & IEEE80211_HTOP0_CHW) == 0) 532 printf(",STA chanw 20MHz"); 533 534 /* reduced interframe space (RIFS) permitted */ 535 if (htopinfo[0] & IEEE80211_HTOP0_RIFS) 536 printf(",RIFS"); 537 538 htopinfo[1] = data[2]; 539 540 /* protection requirements for HT transmissions */ 541 htprot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK) 542 >> IEEE80211_HTOP1_PROT_SHIFT); 543 switch (htprot) { 544 case IEEE80211_HTPROT_NONE: 545 printf(",htprot none"); 546 break; 547 case IEEE80211_HTPROT_NONMEMBER: 548 printf(",htprot non-member"); 549 break; 550 case IEEE80211_HTPROT_20MHZ: 551 printf(",htprot 20MHz"); 552 break; 553 case IEEE80211_HTPROT_NONHT_MIXED: 554 printf(",htprot non-HT-mixed"); 555 break; 556 default: 557 printf(",htprot %d", htprot); 558 break; 559 } 560 561 /* non-greenfield STA present */ 562 if (htopinfo[1] & IEEE80211_HTOP1_NONGF_STA) 563 printf(",non-greenfield STA"); 564 565 /* non-HT STA present */ 566 if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA) 567 printf(",non-HT STA"); 568 569 htopinfo[3] = data[4]; 570 571 /* dual-beacon */ 572 if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON) 573 printf(",dualbeacon"); 574 575 /* dual CTS protection */ 576 if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT) 577 printf(",dualctsprot"); 578 579 htopinfo[4] = data[5]; 580 581 /* space-time block coding (STBC) beacon */ 582 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON) 583 printf(",STBC beacon"); 584 585 /* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */ 586 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP) 587 printf(",lsigtxprot"); 588 589 /* phased-coexistence operation (PCO) active */ 590 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE) { 591 /* PCO phase */ 592 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE40) 593 printf(",pco40MHz"); 594 else 595 printf(",pco20MHz"); 596 } 597 598 /* basic MCS set */ 599 memcpy(basic_mcs, &data[6], sizeof(basic_mcs)); 600 printf(",basic MCS set 0x"); 601 for (i = 0; i < sizeof(basic_mcs) / sizeof(basic_mcs[0]); i++) 602 printf("%x", basic_mcs[i]); 603 604 printf(">"); 605 } 606 607 void 608 ieee80211_print_rsncipher(uint8_t selector[4]) 609 { 610 if (memcmp(selector, MICROSOFT_OUI, 3) != 0 && 611 memcmp(selector, IEEE80211_OUI, 3) != 0) { 612 printf("0x%x%x%x%x", selector[0], selector[1], selector[2], 613 selector[3]); 614 return; 615 } 616 617 /* See 802.11-2012 Table 8-99 */ 618 switch (selector[3]) { 619 case 0: /* use group data cipher suite */ 620 printf("usegroup"); 621 break; 622 case 1: /* WEP-40 */ 623 printf("wep40"); 624 break; 625 case 2: /* TKIP */ 626 printf("tkip"); 627 break; 628 case 4: /* CCMP (RSNA default) */ 629 printf("ccmp"); 630 break; 631 case 5: /* WEP-104 */ 632 printf("wep104"); 633 break; 634 case 6: /* BIP */ 635 printf("bip"); 636 break; 637 default: 638 printf("%d", selector[3]); 639 break; 640 } 641 } 642 643 void 644 ieee80211_print_akm(uint8_t selector[4]) 645 { 646 if (memcmp(selector, MICROSOFT_OUI, 3) != 0 && 647 memcmp(selector, IEEE80211_OUI, 3) != 0) { 648 printf("0x%x%x%x%x", selector[0], selector[1], selector[2], 649 selector[3]); 650 return; 651 } 652 653 switch (selector[3]) { 654 case 1: 655 printf("802.1x"); 656 break; 657 case 2: 658 printf("PSK"); 659 break; 660 case 5: 661 printf("SHA256-802.1x"); 662 break; 663 case 6: 664 printf("SHA256-PSK"); 665 break; 666 default: 667 printf("%d", selector[3]); 668 break; 669 } 670 } 671 672 /* Caller checks len */ 673 void 674 ieee80211_print_rsn(u_int8_t *data, u_int len) 675 { 676 uint16_t version, nciphers, nakms, rsncap, npmk; 677 int i, j; 678 uint8_t selector[4]; 679 680 if (len < 2) { 681 ieee80211_print_element(data, len); 682 return; 683 } 684 685 version = (data[0]) | (data[1] << 8); 686 printf("=<version %d", version); 687 688 if (len < 6) { 689 printf(">"); 690 return; 691 } 692 693 data += 2; 694 printf(",groupcipher "); 695 for (i = 0; i < 4; i++) 696 selector[i] = data[i]; 697 ieee80211_print_rsncipher(selector); 698 699 if (len < 8) { 700 printf(">"); 701 return; 702 } 703 704 data += 4; 705 nciphers = (data[0]) | ((data[1]) << 8); 706 data += 2; 707 708 if (len < 8 + (nciphers * 4)) { 709 printf(">"); 710 return; 711 } 712 713 printf(",cipher%s ", nciphers > 1 ? "s" : ""); 714 for (i = 0; i < nciphers; i++) { 715 for (j = 0; j < 4; j++) 716 selector[j] = data[i + j]; 717 ieee80211_print_rsncipher(selector); 718 if (i < nciphers - 1) 719 printf(" "); 720 data += 4; 721 } 722 723 if (len < 8 + (nciphers * 4) + 2) { 724 printf(">"); 725 return; 726 } 727 728 nakms = (data[0]) | ((data[1]) << 8); 729 data += 2; 730 731 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4)) { 732 printf(">"); 733 return; 734 } 735 736 printf(",akm%s ", nakms > 1 ? "s" : ""); 737 for (i = 0; i < nciphers; i++) { 738 for (j = 0; j < 4; j++) 739 selector[j] = data[i + j]; 740 ieee80211_print_akm(selector); 741 if (i < nciphers - 1) 742 printf(" "); 743 data += 4; 744 } 745 746 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2) { 747 printf(">"); 748 return; 749 } 750 751 rsncap = (data[0]) | ((data[1]) << 8); 752 printf(",rsncap 0x%x", rsncap); 753 data += 2; 754 755 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2) { 756 printf(">"); 757 return; 758 } 759 760 npmk = (data[0]) | ((data[1]) << 8); 761 data += 2; 762 763 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 + 764 (npmk * IEEE80211_PMKID_LEN)) { 765 printf(">"); 766 return; 767 } 768 769 if (npmk >= 1) 770 printf(",pmkid%s ", npmk > 1 ? "s" : ""); 771 for (i = 0; i < npmk; i++) { 772 printf("0x"); 773 for (j = 0; j < IEEE80211_PMKID_LEN; j++) 774 printf("%x", data[i + j]); 775 if (i < npmk - 1) 776 printf(" "); 777 data += IEEE80211_PMKID_LEN; 778 } 779 780 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 + 781 (npmk * IEEE80211_PMKID_LEN) + 4) { 782 printf(">"); 783 return; 784 } 785 786 printf(",integrity-groupcipher "); 787 for (i = 0; i < 4; i++) 788 selector[i] = data[i]; 789 ieee80211_print_rsncipher(selector); 790 791 printf(">"); 792 } 793 794 int 795 ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len) 796 { 797 uint64_t tstamp; 798 uint16_t bintval, capinfo; 799 uint8_t *frm; 800 801 if (len < sizeof(tstamp) + sizeof(bintval) + sizeof(capinfo)) 802 return 1; /* truncated */ 803 804 frm = (u_int8_t *)&wh[1]; 805 806 bcopy(frm, &tstamp, sizeof(u_int64_t)); 807 frm += 8; 808 if (vflag > 1) 809 printf(", timestamp %llu", letoh64(tstamp)); 810 811 bcopy(frm, &bintval, sizeof(u_int16_t)); 812 frm += 2; 813 if (vflag > 1) 814 printf(", interval %u", letoh16(bintval)); 815 816 bcopy(frm, &capinfo, sizeof(u_int16_t)); 817 frm += 2; 818 if (vflag) 819 printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS); 820 821 return ieee80211_print_elements(frm); 822 } 823 824 int 825 ieee80211_print_assocreq(struct ieee80211_frame *wh, u_int len) 826 { 827 uint8_t subtype; 828 uint16_t capinfo, lintval; 829 uint8_t *frm; 830 831 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 832 833 if (len < sizeof(capinfo) + sizeof(lintval) + 834 (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ? 835 IEEE80211_ADDR_LEN : 0)) 836 return 1; /* truncated */ 837 838 frm = (u_int8_t *)&wh[1]; 839 840 bcopy(frm, &capinfo, sizeof(u_int16_t)); 841 frm += 2; 842 if (vflag) 843 printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS); 844 845 bcopy(frm, &lintval, sizeof(u_int16_t)); 846 frm += 2; 847 if (vflag > 1) 848 printf(", listen interval %u", letoh16(lintval)); 849 850 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 851 if (vflag) 852 printf(", AP %s", etheraddr_string(frm)); 853 frm += IEEE80211_ADDR_LEN; 854 } 855 856 return ieee80211_print_elements(frm); 857 } 858 859 int 860 ieee80211_print_elements(uint8_t *frm) 861 { 862 int i; 863 864 while (TTEST2(*frm, 2)) { 865 u_int len = frm[1]; 866 u_int8_t *data = frm + 2; 867 868 if (!TTEST2(*data, len)) 869 break; 870 871 #define ELEM_CHECK(l) if (len != l) goto trunc 872 873 switch (*frm) { 874 case IEEE80211_ELEMID_SSID: 875 printf(", ssid"); 876 ieee80211_print_essid(data, len); 877 break; 878 case IEEE80211_ELEMID_RATES: 879 printf(", rates"); 880 if (!vflag) 881 break; 882 for (i = len; i > 0; i--, data++) 883 printf(" %uM%s", 884 (data[0] & IEEE80211_RATE_VAL) / 2, 885 (data[0] & IEEE80211_RATE_BASIC 886 ? "*" : "")); 887 break; 888 case IEEE80211_ELEMID_FHPARMS: 889 ELEM_CHECK(5); 890 printf(", fh (dwell %u, chan %u, index %u)", 891 (data[1] << 8) | data[0], 892 (data[2] - 1) * 80 + data[3], /* FH_CHAN */ 893 data[4]); 894 break; 895 case IEEE80211_ELEMID_DSPARMS: 896 ELEM_CHECK(1); 897 printf(", ds"); 898 if (vflag) 899 printf(" (chan %u)", data[0]); 900 break; 901 case IEEE80211_ELEMID_CFPARMS: 902 printf(", cf"); 903 if (vflag) 904 ieee80211_print_element(data, len); 905 break; 906 case IEEE80211_ELEMID_TIM: 907 printf(", tim"); 908 if (vflag) 909 ieee80211_print_element(data, len); 910 break; 911 case IEEE80211_ELEMID_IBSSPARMS: 912 printf(", ibss"); 913 if (vflag) 914 ieee80211_print_element(data, len); 915 break; 916 case IEEE80211_ELEMID_COUNTRY: 917 printf(", country"); 918 if (vflag) 919 ieee80211_print_country(data, len); 920 break; 921 case IEEE80211_ELEMID_CHALLENGE: 922 printf(", challenge"); 923 if (vflag) 924 ieee80211_print_element(data, len); 925 break; 926 case IEEE80211_ELEMID_CSA: 927 ELEM_CHECK(3); 928 printf(", csa (chan %u count %u%s)", data[1], data[2], 929 (data[0] == 1) ? " noTX" : ""); 930 break; 931 case IEEE80211_ELEMID_ERP: 932 printf(", erp"); 933 if (vflag) 934 ieee80211_print_element(data, len); 935 break; 936 case IEEE80211_ELEMID_RSN: 937 printf(", rsn"); 938 if (vflag) 939 ieee80211_print_rsn(data, len); 940 break; 941 case IEEE80211_ELEMID_XRATES: 942 printf(", xrates"); 943 if (!vflag) 944 break; 945 for (i = len; i > 0; i--, data++) 946 printf(" %uM", 947 (data[0] & IEEE80211_RATE_VAL) / 2); 948 break; 949 case IEEE80211_ELEMID_TPC_REPORT: 950 printf(", tpcreport"); 951 if (vflag) 952 ieee80211_print_element(data, len); 953 break; 954 case IEEE80211_ELEMID_TPC_REQUEST: 955 printf(", tpcrequest"); 956 if (vflag) 957 ieee80211_print_element(data, len); 958 break; 959 case IEEE80211_ELEMID_HTCAPS: 960 printf(", htcaps"); 961 if (vflag) 962 ieee80211_print_htcaps(data, len); 963 break; 964 case IEEE80211_ELEMID_HTOP: 965 printf(", htop"); 966 if (vflag) 967 ieee80211_print_htop(data, len); 968 break; 969 case IEEE80211_ELEMID_POWER_CONSTRAINT: 970 ELEM_CHECK(1); 971 printf(", power constraint %udB", data[0]); 972 break; 973 case IEEE80211_ELEMID_QBSS_LOAD: 974 ELEM_CHECK(5); 975 printf(", %u stations, %d%% utilization, " 976 "admission capacity %uus/s", 977 (data[0] | data[1] << 8), 978 (data[2] * 100) / 255, 979 (data[3] | data[4] << 8) / 32); 980 break; 981 case IEEE80211_ELEMID_VENDOR: 982 printf(", vendor"); 983 if (vflag) 984 ieee80211_print_element(data, len); 985 break; 986 default: 987 printf(", %u:%u", (u_int) *frm, len); 988 if (vflag) 989 ieee80211_print_element(data, len); 990 break; 991 } 992 frm += len + 2; 993 994 if (frm >= snapend) 995 break; 996 } 997 998 #undef ELEM_CHECK 999 1000 return (0); 1001 1002 trunc: 1003 /* Truncated elements in frame */ 1004 return (1); 1005 } 1006 1007 int 1008 ieee80211_frame(struct ieee80211_frame *wh, u_int len) 1009 { 1010 u_int8_t subtype, type, *frm; 1011 1012 TCARR(wh->i_fc); 1013 1014 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 1015 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 1016 1017 frm = (u_int8_t *)&wh[1]; 1018 1019 if (vflag) 1020 printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS); 1021 1022 switch (type) { 1023 case IEEE80211_FC0_TYPE_DATA: 1024 printf(": %s: ", ieee80211_data_subtype_name[ 1025 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]); 1026 ieee80211_data(wh, len); 1027 break; 1028 case IEEE80211_FC0_TYPE_MGT: 1029 printf(": %s", ieee80211_mgt_subtype_name[ 1030 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]); 1031 switch (subtype) { 1032 case IEEE80211_FC0_SUBTYPE_BEACON: 1033 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 1034 if (ieee80211_print_beacon(wh, len) != 0) 1035 goto trunc; 1036 break; 1037 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 1038 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: 1039 if (ieee80211_print_assocreq(wh, len) != 0) 1040 goto trunc; 1041 break; 1042 case IEEE80211_FC0_SUBTYPE_AUTH: 1043 TCHECK2(*frm, 2); /* Auth Algorithm */ 1044 switch (IEEE80211_AUTH_ALGORITHM(frm)) { 1045 case IEEE80211_AUTH_ALG_OPEN: 1046 TCHECK2(*frm, 4); /* Auth Transaction */ 1047 switch (IEEE80211_AUTH_TRANSACTION(frm)) { 1048 case IEEE80211_AUTH_OPEN_REQUEST: 1049 printf(" request"); 1050 break; 1051 case IEEE80211_AUTH_OPEN_RESPONSE: 1052 printf(" response"); 1053 break; 1054 } 1055 break; 1056 case IEEE80211_AUTH_ALG_SHARED: 1057 TCHECK2(*frm, 4); /* Auth Transaction */ 1058 switch (IEEE80211_AUTH_TRANSACTION(frm)) { 1059 case IEEE80211_AUTH_SHARED_REQUEST: 1060 printf(" request"); 1061 break; 1062 case IEEE80211_AUTH_SHARED_CHALLENGE: 1063 printf(" challenge"); 1064 break; 1065 case IEEE80211_AUTH_SHARED_RESPONSE: 1066 printf(" response"); 1067 break; 1068 case IEEE80211_AUTH_SHARED_PASS: 1069 printf(" pass"); 1070 break; 1071 } 1072 break; 1073 case IEEE80211_AUTH_ALG_LEAP: 1074 printf(" (leap)"); 1075 break; 1076 } 1077 break; 1078 case IEEE80211_FC0_SUBTYPE_DEAUTH: 1079 case IEEE80211_FC0_SUBTYPE_DISASSOC: 1080 TCHECK2(*frm, 2); /* Reason Code */ 1081 ieee80211_reason(frm[0] | (frm[1] << 8)); 1082 break; 1083 } 1084 break; 1085 case IEEE80211_FC0_TYPE_CTL: { 1086 u_int8_t *t = (u_int8_t *) wh; 1087 1088 printf(": %s", ieee80211_ctl_subtype_name[ 1089 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]); 1090 if (!vflag) 1091 break; 1092 1093 /* See 802.11 2012 "8.3.1 Control frames". */ 1094 t += 2; /* skip Frame Control */ 1095 switch (subtype) { 1096 case IEEE80211_FC0_SUBTYPE_RTS: 1097 case IEEE80211_FC0_SUBTYPE_BAR: 1098 case IEEE80211_FC0_SUBTYPE_BA: 1099 TCHECK2(*t, 2); /* Duration */ 1100 printf(", duration %dus", (t[0] | t[1] << 8)); 1101 t += 2; 1102 TCHECK2(*t, 6); /* RA */ 1103 printf(", ra %s", etheraddr_string(t)); 1104 t += 6; 1105 TCHECK2(*t, 6); /* TA */ 1106 printf(", ta %s", etheraddr_string(t)); 1107 if (subtype == IEEE80211_FC0_SUBTYPE_BAR || 1108 subtype == IEEE80211_FC0_SUBTYPE_BA) { 1109 u_int16_t ctrl; 1110 1111 t += 6; 1112 TCHECK2(*t, 2); /* BAR/BA control */ 1113 ctrl = t[0] | (t[1] << 8); 1114 if (ctrl & IEEE80211_BA_ACK_POLICY) 1115 printf(", no ack"); 1116 else 1117 printf(", normal ack"); 1118 if ((ctrl & IEEE80211_BA_MULTI_TID) == 0 && 1119 (ctrl & IEEE80211_BA_COMPRESSED) == 0) 1120 printf(", basic variant"); 1121 else if ((ctrl & IEEE80211_BA_MULTI_TID) && 1122 (ctrl & IEEE80211_BA_COMPRESSED)) 1123 printf(", multi-tid variant"); 1124 else if (ctrl & IEEE80211_BA_COMPRESSED) 1125 printf(", compressed variant"); 1126 } 1127 break; 1128 case IEEE80211_FC0_SUBTYPE_CTS: 1129 case IEEE80211_FC0_SUBTYPE_ACK: 1130 TCHECK2(*t, 2); /* Duration */ 1131 printf(", duration %dus", (t[0] | t[1] << 8)); 1132 t += 2; 1133 TCHECK2(*t, 6); /* RA */ 1134 printf(", ra %s", etheraddr_string(t)); 1135 break; 1136 case IEEE80211_FC0_SUBTYPE_PS_POLL: 1137 TCHECK2(*t, 2); /* AID */ 1138 printf(", aid 0x%x", (t[0] | t[1] << 8)); 1139 t += 2; 1140 TCHECK2(*t, 6); /* BSSID(RA) */ 1141 printf(", ra %s", etheraddr_string(t)); 1142 t += 6; 1143 TCHECK2(*t, 6); /* TA */ 1144 printf(", ta %s", etheraddr_string(t)); 1145 break; 1146 } 1147 break; 1148 } 1149 default: 1150 printf(": type#%d", type); 1151 break; 1152 } 1153 1154 return (0); 1155 1156 trunc: 1157 /* Truncated 802.11 frame */ 1158 return (1); 1159 } 1160 1161 u_int 1162 ieee80211_any2ieee(u_int freq, u_int flags) 1163 { 1164 if (flags & IEEE80211_CHAN_2GHZ) { 1165 if (freq == 2484) 1166 return 14; 1167 if (freq < 2484) 1168 return (freq - 2407) / 5; 1169 else 1170 return 15 + ((freq - 2512) / 20); 1171 } else if (flags & IEEE80211_CHAN_5GHZ) { 1172 return (freq - 5000) / 5; 1173 } else { 1174 /* Assume channel is already an IEEE number */ 1175 return (freq); 1176 } 1177 } 1178 1179 int 1180 ieee80211_print(struct ieee80211_frame *wh, u_int len) 1181 { 1182 if (eflag) 1183 if (ieee80211_hdr(wh)) 1184 return (1); 1185 1186 printf("802.11"); 1187 1188 return (ieee80211_frame(wh, len)); 1189 } 1190 1191 void 1192 ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h, 1193 const u_char *p) 1194 { 1195 struct ieee80211_frame *wh = (struct ieee80211_frame*)p; 1196 1197 if (!ieee80211_encap) 1198 ts_print(&h->ts); 1199 1200 packetp = p; 1201 snapend = p + h->caplen; 1202 1203 if (ieee80211_print(wh, (u_int)h->len) != 0) 1204 printf("[|802.11]"); 1205 1206 if (!ieee80211_encap) { 1207 if (xflag) 1208 default_print(p, (u_int)h->len); 1209 putchar('\n'); 1210 } 1211 } 1212 1213 void 1214 ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h, 1215 const u_char *p) 1216 { 1217 struct ieee80211_radiotap_header *rh = 1218 (struct ieee80211_radiotap_header*)p; 1219 struct ieee80211_frame *wh; 1220 u_int8_t *t; 1221 u_int32_t present; 1222 u_int len, rh_len; 1223 u_int16_t tmp; 1224 1225 if (!ieee80211_encap) 1226 ts_print(&h->ts); 1227 1228 packetp = p; 1229 snapend = p + h->caplen; 1230 1231 TCHECK(*rh); 1232 1233 len = h->len; 1234 rh_len = letoh16(rh->it_len); 1235 if (rh->it_version != 0) { 1236 printf("[?radiotap + 802.11 v:%u]", rh->it_version); 1237 goto out; 1238 } 1239 1240 wh = (struct ieee80211_frame *)(p + rh_len); 1241 if (len <= rh_len || ieee80211_print(wh, len - rh_len)) 1242 printf("[|802.11]"); 1243 1244 t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header); 1245 1246 if ((present = letoh32(rh->it_present)) == 0) 1247 goto out; 1248 1249 printf(", <radiotap v%u", rh->it_version); 1250 1251 #define RADIOTAP(_x) \ 1252 (present & (1 << IEEE80211_RADIOTAP_##_x)) 1253 1254 if (RADIOTAP(TSFT)) { 1255 u_int64_t tsf; 1256 1257 TCHECK2(*t, 8); 1258 bcopy(t, &tsf, sizeof(u_int64_t)); 1259 if (vflag > 1) 1260 printf(", tsf %llu", letoh64(tsf)); 1261 t += 8; 1262 } 1263 1264 if (RADIOTAP(FLAGS)) { 1265 u_int8_t flags = *(u_int8_t*)t; 1266 TCHECK2(*t, 1); 1267 1268 if (flags & IEEE80211_RADIOTAP_F_CFP) 1269 printf(", CFP"); 1270 if (flags & IEEE80211_RADIOTAP_F_SHORTPRE) 1271 printf(", SHORTPRE"); 1272 if (flags & IEEE80211_RADIOTAP_F_WEP) 1273 printf(", WEP"); 1274 if (flags & IEEE80211_RADIOTAP_F_FRAG) 1275 printf(", FRAG"); 1276 t += 1; 1277 } 1278 1279 if (RADIOTAP(RATE)) { 1280 TCHECK2(*t, 1); 1281 if (vflag) { 1282 uint8_t rate = *(u_int8_t*)t; 1283 if (rate & 0x80) 1284 printf(", MCS %u", rate & 0x7f); 1285 else 1286 printf(", %uMbit/s", rate / 2); 1287 } 1288 t += 1; 1289 } 1290 1291 if (RADIOTAP(CHANNEL)) { 1292 u_int16_t freq, flags; 1293 TCHECK2(*t, 2); 1294 1295 bcopy(t, &freq, sizeof(u_int16_t)); 1296 freq = letoh16(freq); 1297 t += 2; 1298 TCHECK2(*t, 2); 1299 bcopy(t, &flags, sizeof(u_int16_t)); 1300 flags = letoh16(flags); 1301 t += 2; 1302 1303 printf(", chan %u", ieee80211_any2ieee(freq, flags)); 1304 1305 if (flags & IEEE80211_CHAN_HT) 1306 printf(", 11n"); 1307 else if (flags & IEEE80211_CHAN_DYN && 1308 flags & IEEE80211_CHAN_2GHZ) 1309 printf(", 11g"); 1310 else if (flags & IEEE80211_CHAN_CCK && 1311 flags & IEEE80211_CHAN_2GHZ) 1312 printf(", 11b"); 1313 else if (flags & IEEE80211_CHAN_OFDM && 1314 flags & IEEE80211_CHAN_2GHZ) 1315 printf(", 11G"); 1316 else if (flags & IEEE80211_CHAN_OFDM && 1317 flags & IEEE80211_CHAN_5GHZ) 1318 printf(", 11a"); 1319 1320 if (flags & IEEE80211_CHAN_XR) 1321 printf(", XR"); 1322 } 1323 1324 if (RADIOTAP(FHSS)) { 1325 TCHECK2(*t, 2); 1326 printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1); 1327 t += 2; 1328 } 1329 1330 if (RADIOTAP(DBM_ANTSIGNAL)) { 1331 TCHECK(*t); 1332 printf(", sig %ddBm", *(int8_t*)t); 1333 t += 1; 1334 } 1335 1336 if (RADIOTAP(DBM_ANTNOISE)) { 1337 TCHECK(*t); 1338 printf(", noise %ddBm", *(int8_t*)t); 1339 t += 1; 1340 } 1341 1342 if (RADIOTAP(LOCK_QUALITY)) { 1343 TCHECK2(*t, 2); 1344 if (vflag) { 1345 bcopy(t, &tmp, sizeof(u_int16_t)); 1346 printf(", quality %u", letoh16(tmp)); 1347 } 1348 t += 2; 1349 } 1350 1351 if (RADIOTAP(TX_ATTENUATION)) { 1352 TCHECK2(*t, 2); 1353 if (vflag) { 1354 bcopy(t, &tmp, sizeof(u_int16_t)); 1355 printf(", txatt %u", letoh16(tmp)); 1356 } 1357 t += 2; 1358 } 1359 1360 if (RADIOTAP(DB_TX_ATTENUATION)) { 1361 TCHECK2(*t, 2); 1362 if (vflag) { 1363 bcopy(t, &tmp, sizeof(u_int16_t)); 1364 printf(", txatt %udB", letoh16(tmp)); 1365 } 1366 t += 2; 1367 } 1368 1369 if (RADIOTAP(DBM_TX_POWER)) { 1370 TCHECK(*t); 1371 printf(", txpower %ddBm", *(int8_t*)t); 1372 t += 1; 1373 } 1374 1375 if (RADIOTAP(ANTENNA)) { 1376 TCHECK(*t); 1377 if (vflag) 1378 printf(", antenna %u", *(u_int8_t*)t); 1379 t += 1; 1380 } 1381 1382 if (RADIOTAP(DB_ANTSIGNAL)) { 1383 TCHECK(*t); 1384 printf(", signal %udB", *(u_int8_t*)t); 1385 t += 1; 1386 } 1387 1388 if (RADIOTAP(DB_ANTNOISE)) { 1389 TCHECK(*t); 1390 printf(", noise %udB", *(u_int8_t*)t); 1391 t += 1; 1392 } 1393 1394 if (RADIOTAP(FCS)) { 1395 TCHECK2(*t, 4); 1396 if (vflag) { 1397 u_int32_t fcs; 1398 bcopy(t, &fcs, sizeof(u_int32_t)); 1399 printf(", fcs %08x", letoh32(fcs)); 1400 } 1401 t += 4; 1402 } 1403 1404 if (RADIOTAP(RSSI)) { 1405 u_int8_t rssi, max_rssi; 1406 TCHECK(*t); 1407 rssi = *(u_int8_t*)t; 1408 t += 1; 1409 TCHECK(*t); 1410 max_rssi = *(u_int8_t*)t; 1411 t += 1; 1412 1413 printf(", rssi %u/%u", rssi, max_rssi); 1414 } 1415 1416 #undef RADIOTAP 1417 1418 putchar('>'); 1419 goto out; 1420 1421 trunc: 1422 /* Truncated frame */ 1423 printf("[|radiotap + 802.11]"); 1424 1425 out: 1426 if (!ieee80211_encap) { 1427 if (xflag) 1428 default_print(p, h->len); 1429 putchar('\n'); 1430 } 1431 } 1432 1433 void 1434 ieee80211_reason(u_int16_t reason) 1435 { 1436 if (!vflag) 1437 return; 1438 1439 switch (reason) { 1440 case IEEE80211_REASON_UNSPECIFIED: 1441 printf(", unspecified failure"); 1442 break; 1443 case IEEE80211_REASON_AUTH_EXPIRE: 1444 printf(", authentication expired"); 1445 break; 1446 case IEEE80211_REASON_AUTH_LEAVE: 1447 printf(", deauth - station left"); 1448 break; 1449 case IEEE80211_REASON_ASSOC_EXPIRE: 1450 printf(", association expired"); 1451 break; 1452 case IEEE80211_REASON_ASSOC_TOOMANY: 1453 printf(", too many associated stations"); 1454 break; 1455 case IEEE80211_REASON_NOT_AUTHED: 1456 printf(", not authenticated"); 1457 break; 1458 case IEEE80211_REASON_NOT_ASSOCED: 1459 printf(", not associated"); 1460 break; 1461 case IEEE80211_REASON_ASSOC_LEAVE: 1462 printf(", disassociated - station left"); 1463 break; 1464 case IEEE80211_REASON_ASSOC_NOT_AUTHED: 1465 printf(", association but not authenticated"); 1466 break; 1467 case IEEE80211_REASON_RSN_REQUIRED: 1468 printf(", rsn required"); 1469 break; 1470 case IEEE80211_REASON_RSN_INCONSISTENT: 1471 printf(", rsn inconsistent"); 1472 break; 1473 case IEEE80211_REASON_IE_INVALID: 1474 printf(", ie invalid"); 1475 break; 1476 case IEEE80211_REASON_MIC_FAILURE: 1477 printf(", mic failure"); 1478 break; 1479 default: 1480 printf(", unknown reason %u", reason); 1481 } 1482 } 1483