1 /* $OpenBSD: print-802_11.c,v 1.13 2013/01/17 02:53:07 claudio 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/param.h> 20 #include <sys/time.h> 21 #include <sys/socket.h> 22 #include <sys/file.h> 23 #include <sys/ioctl.h> 24 25 #include <net/if.h> 26 27 #include <netinet/in.h> 28 #include <netinet/in_systm.h> 29 #include <netinet/if_ether.h> 30 31 #include <net80211/ieee80211.h> 32 #include <net80211/ieee80211_radiotap.h> 33 34 #include <pcap.h> 35 #include <stdio.h> 36 #include <string.h> 37 38 #include "addrtoname.h" 39 #include "interface.h" 40 41 const char *ieee80211_mgt_subtype_name[] = { 42 "association request", 43 "association response", 44 "reassociation request", 45 "reassociation response", 46 "probe request", 47 "probe response", 48 "reserved#6", 49 "reserved#7", 50 "beacon", 51 "atim", 52 "disassociation", 53 "authentication", 54 "deauthentication", 55 "action", 56 "action noack", 57 "reserved#15" 58 }; 59 60 const char *ieee80211_data_subtype_name[] = { 61 "data", 62 "data cf ack", 63 "data cf poll", 64 "data cf poll ack", 65 "no-data", 66 "no-data cf poll", 67 "no-data cf ack", 68 "no-data cf poll ack", 69 "QoS data", 70 "QoS data cf ack", 71 "QoS data cf poll", 72 "QoS data cf poll ack", 73 "QoS no-data", 74 "QoS no-data cf poll", 75 "QoS no-data cf ack", 76 "QoS no-data cf poll ack" 77 }; 78 79 int ieee80211_hdr(struct ieee80211_frame *); 80 int ieee80211_data(struct ieee80211_frame *, u_int); 81 void ieee80211_print_element(u_int8_t *, u_int); 82 void ieee80211_print_essid(u_int8_t *, u_int); 83 int ieee80211_elements(struct ieee80211_frame *, u_int); 84 int ieee80211_frame(struct ieee80211_frame *, u_int); 85 int ieee80211_print(struct ieee80211_frame *, u_int); 86 u_int ieee80211_any2ieee(u_int, u_int); 87 void ieee80211_reason(u_int16_t); 88 89 #define TCARR(a) TCHECK2(*a, sizeof(a)) 90 91 int ieee80211_encap = 0; 92 93 int 94 ieee80211_hdr(struct ieee80211_frame *wh) 95 { 96 struct ieee80211_frame_addr4 *w4; 97 98 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { 99 case IEEE80211_FC1_DIR_NODS: 100 TCARR(wh->i_addr2); 101 printf("%s", etheraddr_string(wh->i_addr2)); 102 TCARR(wh->i_addr1); 103 printf(" > %s", etheraddr_string(wh->i_addr1)); 104 TCARR(wh->i_addr3); 105 printf(", bssid %s", etheraddr_string(wh->i_addr3)); 106 break; 107 case IEEE80211_FC1_DIR_TODS: 108 TCARR(wh->i_addr2); 109 printf("%s", etheraddr_string(wh->i_addr2)); 110 TCARR(wh->i_addr3); 111 printf(" > %s", etheraddr_string(wh->i_addr3)); 112 TCARR(wh->i_addr1); 113 printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1)); 114 break; 115 case IEEE80211_FC1_DIR_FROMDS: 116 TCARR(wh->i_addr3); 117 printf("%s", etheraddr_string(wh->i_addr3)); 118 TCARR(wh->i_addr1); 119 printf(" > %s", etheraddr_string(wh->i_addr1)); 120 TCARR(wh->i_addr2); 121 printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2)); 122 break; 123 case IEEE80211_FC1_DIR_DSTODS: 124 w4 = (struct ieee80211_frame_addr4 *) wh; 125 TCARR(w4->i_addr4); 126 printf("%s", etheraddr_string(w4->i_addr4)); 127 TCARR(w4->i_addr3); 128 printf(" > %s", etheraddr_string(w4->i_addr3)); 129 TCARR(w4->i_addr2); 130 printf(", bssid %s", etheraddr_string(w4->i_addr2)); 131 TCARR(w4->i_addr1); 132 printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1)); 133 break; 134 } 135 if (vflag) { 136 u_int16_t seq; 137 TCARR(wh->i_seq); 138 bcopy(wh->i_seq, &seq, sizeof(u_int16_t)); 139 printf(" (seq %u): ", letoh16(seq)); 140 } else 141 printf(": "); 142 143 return (0); 144 145 trunc: 146 /* Truncated elements in frame */ 147 return (1); 148 } 149 150 int 151 ieee80211_data(struct ieee80211_frame *wh, u_int len) 152 { 153 u_int8_t *t = (u_int8_t *)wh; 154 struct ieee80211_frame_addr4 *w4; 155 u_int datalen; 156 int data = !(wh->i_fc[1] & IEEE80211_FC0_SUBTYPE_NODATA); 157 u_char *esrc = NULL, *edst = NULL; 158 159 TCHECK(*wh); 160 t += sizeof(struct ieee80211_frame); 161 datalen = len - sizeof(struct ieee80211_frame); 162 163 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { 164 case IEEE80211_FC1_DIR_TODS: 165 esrc = wh->i_addr2; 166 edst = wh->i_addr3; 167 break; 168 case IEEE80211_FC1_DIR_FROMDS: 169 esrc = wh->i_addr3; 170 edst = wh->i_addr1; 171 break; 172 case IEEE80211_FC1_DIR_NODS: 173 esrc = wh->i_addr2; 174 edst = wh->i_addr1; 175 break; 176 case IEEE80211_FC1_DIR_DSTODS: 177 w4 = (struct ieee80211_frame_addr4 *) wh; 178 TCHECK(*w4); 179 t = (u_int8_t *) (w4 + 1); 180 datalen = len - sizeof(*w4); 181 esrc = w4->i_addr4; 182 edst = w4->i_addr3; 183 break; 184 } 185 186 if (data && esrc) 187 llc_print(t, datalen, datalen, esrc, edst); 188 else if (eflag && esrc) 189 printf("%s > %s", 190 etheraddr_string(esrc), etheraddr_string(edst)); 191 192 return (0); 193 194 trunc: 195 /* Truncated elements in frame */ 196 return (1); 197 } 198 199 /* Caller checks len */ 200 void 201 ieee80211_print_element(u_int8_t *data, u_int len) 202 { 203 u_int8_t *p; 204 int i; 205 206 printf(" 0x"); 207 for (i = 0, p = data; i < len; i++, p++) 208 printf("%02x", *p); 209 } 210 211 /* Caller checks len */ 212 void 213 ieee80211_print_essid(u_int8_t *essid, u_int len) 214 { 215 u_int8_t *p; 216 int i; 217 218 if (len > IEEE80211_NWID_LEN) 219 len = IEEE80211_NWID_LEN; 220 221 /* determine printable or not */ 222 for (i = 0, p = essid; i < len; i++, p++) { 223 if (*p < ' ' || *p > 0x7e) 224 break; 225 } 226 if (i == len) { 227 printf(" ("); 228 for (i = 0, p = essid; i < len; i++, p++) 229 putchar(*p); 230 putchar(')'); 231 } else 232 ieee80211_print_element(essid, len); 233 } 234 235 int 236 ieee80211_elements(struct ieee80211_frame *wh, u_int flen) 237 { 238 u_int8_t *buf, *frm; 239 u_int64_t tstamp; 240 u_int16_t bintval, capinfo; 241 int i; 242 243 buf = (u_int8_t *)wh; 244 frm = (u_int8_t *)&wh[1]; 245 246 TCHECK2(*frm, 8); 247 bcopy(frm, &tstamp, sizeof(u_int64_t)); 248 frm += 8; 249 250 if (vflag > 1) 251 printf(", timestamp %llu", letoh64(tstamp)); 252 253 TCHECK2(*frm, 2); 254 bcopy(frm, &bintval, sizeof(u_int16_t)); 255 frm += 2; 256 257 if (vflag > 1) 258 printf(", interval %u", letoh16(bintval)); 259 260 TCHECK2(*frm, 2); 261 bcopy(frm, &capinfo, sizeof(u_int16_t)); 262 frm += 2; 263 264 if (vflag) 265 printb(", caps", letoh16(capinfo), 266 IEEE80211_CAPINFO_BITS); 267 268 while (TTEST2(*frm, 2)) { 269 u_int len = frm[1]; 270 u_int8_t *data = frm + 2; 271 272 if (!TTEST2(*data, len)) 273 break; 274 275 #define ELEM_CHECK(l) if (len != l) break 276 277 switch (*frm) { 278 case IEEE80211_ELEMID_SSID: 279 printf(", ssid"); 280 ieee80211_print_essid(data, len); 281 break; 282 case IEEE80211_ELEMID_RATES: 283 printf(", rates"); 284 if (!vflag) 285 break; 286 for (i = len; i > 0; i--, data++) 287 printf(" %uM", 288 (data[0] & IEEE80211_RATE_VAL) / 2); 289 break; 290 case IEEE80211_ELEMID_FHPARMS: 291 ELEM_CHECK(5); 292 printf(", fh (dwell %u, chan %u, index %u)", 293 (data[1] << 8) | data[0], 294 (data[2] - 1) * 80 + data[3], /* FH_CHAN */ 295 data[4]); 296 break; 297 case IEEE80211_ELEMID_DSPARMS: 298 ELEM_CHECK(1); 299 printf(", ds"); 300 if (vflag) 301 printf(" (chan %u)", data[0]); 302 break; 303 case IEEE80211_ELEMID_CFPARMS: 304 printf(", cf"); 305 if (vflag) 306 ieee80211_print_element(data, len); 307 break; 308 case IEEE80211_ELEMID_TIM: 309 printf(", tim"); 310 if (vflag) 311 ieee80211_print_element(data, len); 312 break; 313 case IEEE80211_ELEMID_IBSSPARMS: 314 printf(", ibss"); 315 if (vflag) 316 ieee80211_print_element(data, len); 317 break; 318 case IEEE80211_ELEMID_COUNTRY: 319 printf(", country"); 320 for (i = len; i > 0; i--, data++) 321 printf(" %u", data[0]); 322 break; 323 case IEEE80211_ELEMID_CHALLENGE: 324 printf(", challenge"); 325 if (vflag) 326 ieee80211_print_element(data, len); 327 break; 328 case IEEE80211_ELEMID_ERP: 329 printf(", erp"); 330 if (vflag) 331 ieee80211_print_element(data, len); 332 break; 333 case IEEE80211_ELEMID_RSN: 334 printf(", rsn"); 335 if (vflag) 336 ieee80211_print_element(data, len); 337 break; 338 case IEEE80211_ELEMID_XRATES: 339 printf(", xrates"); 340 if (!vflag) 341 break; 342 for (i = len; i > 0; i--, data++) 343 printf(" %uM", 344 (data[0] & IEEE80211_RATE_VAL) / 2); 345 break; 346 case IEEE80211_ELEMID_TPC: 347 printf(", tpc"); 348 if (vflag) 349 ieee80211_print_element(data, len); 350 break; 351 case IEEE80211_ELEMID_CCKM: 352 printf(", cckm"); 353 if (vflag) 354 ieee80211_print_element(data, len); 355 break; 356 case IEEE80211_ELEMID_VENDOR: 357 printf(", vendor"); 358 if (vflag) 359 ieee80211_print_element(data, len); 360 break; 361 default: 362 printf(", %u:%u", (u_int) *frm, len); 363 if (vflag) 364 ieee80211_print_element(data, len); 365 break; 366 } 367 frm += len + 2; 368 369 if (frm >= snapend) 370 break; 371 } 372 373 #undef ELEM_CHECK 374 375 return (0); 376 377 trunc: 378 /* Truncated elements in frame */ 379 return (1); 380 } 381 382 int 383 ieee80211_frame(struct ieee80211_frame *wh, u_int len) 384 { 385 u_int8_t subtype, type, *frm; 386 387 TCARR(wh->i_fc); 388 389 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 390 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 391 392 frm = (u_int8_t *)&wh[1]; 393 394 if (vflag) 395 printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS); 396 397 switch (type) { 398 case IEEE80211_FC0_TYPE_DATA: 399 printf(": %s: ", ieee80211_data_subtype_name[ 400 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]); 401 ieee80211_data(wh, len); 402 break; 403 case IEEE80211_FC0_TYPE_MGT: 404 printf(": %s", ieee80211_mgt_subtype_name[ 405 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]); 406 switch (subtype) { 407 case IEEE80211_FC0_SUBTYPE_BEACON: 408 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 409 if (ieee80211_elements(wh, len) != 0) 410 goto trunc; 411 break; 412 case IEEE80211_FC0_SUBTYPE_AUTH: 413 TCHECK2(*frm, 2); /* Auth Algorithm */ 414 switch (IEEE80211_AUTH_ALGORITHM(frm)) { 415 case IEEE80211_AUTH_ALG_OPEN: 416 TCHECK2(*frm, 4); /* Auth Transaction */ 417 switch (IEEE80211_AUTH_TRANSACTION(frm)) { 418 case IEEE80211_AUTH_OPEN_REQUEST: 419 printf(" request"); 420 break; 421 case IEEE80211_AUTH_OPEN_RESPONSE: 422 printf(" response"); 423 break; 424 } 425 break; 426 case IEEE80211_AUTH_ALG_SHARED: 427 TCHECK2(*frm, 4); /* Auth Transaction */ 428 switch (IEEE80211_AUTH_TRANSACTION(frm)) { 429 case IEEE80211_AUTH_SHARED_REQUEST: 430 printf(" request"); 431 break; 432 case IEEE80211_AUTH_SHARED_CHALLENGE: 433 printf(" challenge"); 434 break; 435 case IEEE80211_AUTH_SHARED_RESPONSE: 436 printf(" response"); 437 break; 438 case IEEE80211_AUTH_SHARED_PASS: 439 printf(" pass"); 440 break; 441 } 442 break; 443 case IEEE80211_AUTH_ALG_LEAP: 444 printf(" (leap)"); 445 break; 446 } 447 break; 448 case IEEE80211_FC0_SUBTYPE_DEAUTH: 449 case IEEE80211_FC0_SUBTYPE_DISASSOC: 450 TCHECK2(*frm, 2); /* Reason Code */ 451 ieee80211_reason(frm[0] | (frm[1] << 8)); 452 break; 453 } 454 break; 455 default: 456 printf(": type#%d", type); 457 break; 458 } 459 460 return (0); 461 462 trunc: 463 /* Truncated 802.11 frame */ 464 return (1); 465 } 466 467 u_int 468 ieee80211_any2ieee(u_int freq, u_int flags) 469 { 470 if (flags & IEEE80211_CHAN_2GHZ) { 471 if (freq == 2484) 472 return 14; 473 if (freq < 2484) 474 return (freq - 2407) / 5; 475 else 476 return 15 + ((freq - 2512) / 20); 477 } else if (flags & IEEE80211_CHAN_5GHZ) { 478 return (freq - 5000) / 5; 479 } else { 480 /* Assume channel is already an IEEE number */ 481 return (freq); 482 } 483 } 484 485 int 486 ieee80211_print(struct ieee80211_frame *wh, u_int len) 487 { 488 if (eflag) 489 if (ieee80211_hdr(wh)) 490 return (1); 491 492 printf("802.11"); 493 494 return (ieee80211_frame(wh, len)); 495 } 496 497 void 498 ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h, 499 const u_char *p) 500 { 501 struct ieee80211_frame *wh = (struct ieee80211_frame*)p; 502 503 if (!ieee80211_encap) 504 ts_print(&h->ts); 505 506 packetp = p; 507 snapend = p + h->caplen; 508 509 if (ieee80211_print(wh, (u_int)h->len) != 0) 510 printf("[|802.11]"); 511 512 if (!ieee80211_encap) { 513 if (xflag) 514 default_print(p, (u_int)h->len); 515 putchar('\n'); 516 } 517 } 518 519 void 520 ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h, 521 const u_char *p) 522 { 523 struct ieee80211_radiotap_header *rh = 524 (struct ieee80211_radiotap_header*)p; 525 struct ieee80211_frame *wh; 526 u_int8_t *t; 527 u_int32_t present; 528 u_int len, rh_len; 529 u_int16_t tmp; 530 531 if (!ieee80211_encap) 532 ts_print(&h->ts); 533 534 packetp = p; 535 snapend = p + h->caplen; 536 537 TCHECK(*rh); 538 539 len = h->len; 540 rh_len = letoh16(rh->it_len); 541 if (rh->it_version != 0) { 542 printf("[?radiotap + 802.11 v:%u]", rh->it_version); 543 goto out; 544 } 545 546 wh = (struct ieee80211_frame *)(p + rh_len); 547 if (len <= rh_len || ieee80211_print(wh, len - rh_len)) 548 printf("[|802.11]"); 549 550 t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header); 551 552 if ((present = letoh32(rh->it_present)) == 0) 553 goto out; 554 555 printf(", <radiotap v%u", rh->it_version); 556 557 #define RADIOTAP(_x) \ 558 (present & (1 << IEEE80211_RADIOTAP_##_x)) 559 560 if (RADIOTAP(TSFT)) { 561 u_int64_t tsf; 562 563 TCHECK2(*t, 8); 564 bcopy(t, &tsf, sizeof(u_int64_t)); 565 if (vflag > 1) 566 printf(", tsf %llu", letoh64(tsf)); 567 t += 8; 568 } 569 570 if (RADIOTAP(FLAGS)) { 571 u_int8_t flags = *(u_int8_t*)t; 572 TCHECK2(*t, 1); 573 574 if (flags & IEEE80211_RADIOTAP_F_CFP) 575 printf(", CFP"); 576 if (flags & IEEE80211_RADIOTAP_F_SHORTPRE) 577 printf(", SHORTPRE"); 578 if (flags & IEEE80211_RADIOTAP_F_WEP) 579 printf(", WEP"); 580 if (flags & IEEE80211_RADIOTAP_F_FRAG) 581 printf(", FRAG"); 582 t += 1; 583 } 584 585 if (RADIOTAP(RATE)) { 586 TCHECK2(*t, 1); 587 if (vflag) 588 printf(", %uMbit/s", (*(u_int8_t*)t) / 2); 589 t += 1; 590 } 591 592 if (RADIOTAP(CHANNEL)) { 593 u_int16_t freq, flags; 594 TCHECK2(*t, 2); 595 596 bcopy(t, &freq, sizeof(u_int16_t)); 597 freq = letoh16(freq); 598 t += 2; 599 TCHECK2(*t, 2); 600 bcopy(t, &flags, sizeof(u_int16_t)); 601 flags = letoh16(flags); 602 t += 2; 603 604 printf(", chan %u", ieee80211_any2ieee(freq, flags)); 605 606 if (flags & IEEE80211_CHAN_DYN && 607 flags & IEEE80211_CHAN_2GHZ) 608 printf(", 11g"); 609 else if (flags & IEEE80211_CHAN_CCK && 610 flags & IEEE80211_CHAN_2GHZ) 611 printf(", 11b"); 612 else if (flags & IEEE80211_CHAN_OFDM && 613 flags & IEEE80211_CHAN_2GHZ) 614 printf(", 11G"); 615 else if (flags & IEEE80211_CHAN_OFDM && 616 flags & IEEE80211_CHAN_5GHZ) 617 printf(", 11a"); 618 619 if (flags & IEEE80211_CHAN_TURBO) 620 printf(", TURBO"); 621 if (flags & IEEE80211_CHAN_XR) 622 printf(", XR"); 623 } 624 625 if (RADIOTAP(FHSS)) { 626 TCHECK2(*t, 2); 627 printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1); 628 t += 2; 629 } 630 631 if (RADIOTAP(DBM_ANTSIGNAL)) { 632 TCHECK(*t); 633 printf(", sig %ddBm", *(int8_t*)t); 634 t += 1; 635 } 636 637 if (RADIOTAP(DBM_ANTNOISE)) { 638 TCHECK(*t); 639 printf(", noise %ddBm", *(int8_t*)t); 640 t += 1; 641 } 642 643 if (RADIOTAP(LOCK_QUALITY)) { 644 TCHECK2(*t, 2); 645 if (vflag) { 646 bcopy(t, &tmp, sizeof(u_int16_t)); 647 printf(", quality %u", letoh16(tmp)); 648 } 649 t += 2; 650 } 651 652 if (RADIOTAP(TX_ATTENUATION)) { 653 TCHECK2(*t, 2); 654 if (vflag) { 655 bcopy(t, &tmp, sizeof(u_int16_t)); 656 printf(", txatt %u", letoh16(tmp)); 657 } 658 t += 2; 659 } 660 661 if (RADIOTAP(DB_TX_ATTENUATION)) { 662 TCHECK2(*t, 2); 663 if (vflag) { 664 bcopy(t, &tmp, sizeof(u_int16_t)); 665 printf(", txatt %udB", letoh16(tmp)); 666 } 667 t += 2; 668 } 669 670 if (RADIOTAP(DBM_TX_POWER)) { 671 TCHECK(*t); 672 printf(", txpower %ddBm", *(int8_t*)t); 673 t += 1; 674 } 675 676 if (RADIOTAP(ANTENNA)) { 677 TCHECK(*t); 678 if (vflag) 679 printf(", antenna %u", *(u_int8_t*)t); 680 t += 1; 681 } 682 683 if (RADIOTAP(DB_ANTSIGNAL)) { 684 TCHECK(*t); 685 printf(", signal %udB", *(u_int8_t*)t); 686 t += 1; 687 } 688 689 if (RADIOTAP(DB_ANTNOISE)) { 690 TCHECK(*t); 691 printf(", noise %udB", *(u_int8_t*)t); 692 t += 1; 693 } 694 695 if (RADIOTAP(FCS)) { 696 TCHECK2(*t, 4); 697 if (vflag) { 698 u_int32_t fcs; 699 bcopy(t, &fcs, sizeof(u_int32_t)); 700 printf(", fcs %08x", letoh32(fcs)); 701 } 702 t += 4; 703 } 704 705 if (RADIOTAP(RSSI)) { 706 u_int8_t rssi, max_rssi; 707 TCHECK(*t); 708 rssi = *(u_int8_t*)t; 709 t += 1; 710 TCHECK(*t); 711 max_rssi = *(u_int8_t*)t; 712 t += 1; 713 714 printf(", rssi %u/%u", rssi, max_rssi); 715 } 716 717 #undef RADIOTAP 718 719 putchar('>'); 720 goto out; 721 722 trunc: 723 /* Truncated frame */ 724 printf("[|radiotap + 802.11]"); 725 726 out: 727 if (!ieee80211_encap) { 728 if (xflag) 729 default_print(p, h->len); 730 putchar('\n'); 731 } 732 } 733 734 void 735 ieee80211_reason(u_int16_t reason) 736 { 737 if (!vflag) 738 return; 739 740 switch (reason) { 741 case IEEE80211_REASON_UNSPECIFIED: 742 printf(", unspecified failure"); 743 break; 744 case IEEE80211_REASON_AUTH_EXPIRE: 745 printf(", authentication expired"); 746 break; 747 case IEEE80211_REASON_AUTH_LEAVE: 748 printf(", deauth - station left"); 749 break; 750 case IEEE80211_REASON_ASSOC_EXPIRE: 751 printf(", association expired"); 752 break; 753 case IEEE80211_REASON_ASSOC_TOOMANY: 754 printf(", too many associated stations"); 755 break; 756 case IEEE80211_REASON_NOT_AUTHED: 757 printf(", not authenticated"); 758 break; 759 case IEEE80211_REASON_NOT_ASSOCED: 760 printf(", not associated"); 761 break; 762 case IEEE80211_REASON_ASSOC_LEAVE: 763 printf(", disassociated - station left"); 764 break; 765 case IEEE80211_REASON_ASSOC_NOT_AUTHED: 766 printf(", association but not authenticated"); 767 break; 768 case IEEE80211_REASON_RSN_REQUIRED: 769 printf(", rsn required"); 770 break; 771 case IEEE80211_REASON_RSN_INCONSISTENT: 772 printf(", rsn inconsistent"); 773 break; 774 case IEEE80211_REASON_IE_INVALID: 775 printf(", ie invalid"); 776 break; 777 case IEEE80211_REASON_MIC_FAILURE: 778 printf(", mic failure"); 779 break; 780 default: 781 printf(", unknown reason %u", reason); 782 } 783 } 784