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