215 } 216 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 217 if (ic->ic_flags & IEEE80211_F_WEPON) { 218 m = ieee80211_wep_crypt(ifp, m, 0); 219 if (m == NULL) 220 goto err; 221 wh = mtod(m, struct ieee80211_frame *); 222 } else 223 goto out; 224 } 225 /* copy to listener after decrypt */ 226 if (ic->ic_rawbpf) 227 bpf_mtap(ic->ic_rawbpf, m); 228 m = ieee80211_decap(ifp, m); 229 if (m == NULL) 230 goto err; 231 ifp->if_ipackets++; 232 233 /* perform as a bridge within the AP */ 234 m1 = NULL; 235 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 236 eh = mtod(m, struct ether_header *); 237 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 238 m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 239 if (m1 == NULL) 240 ifp->if_oerrors++; 241 else 242 m1->m_flags |= M_MCAST; 243 } else { 244 ni = ieee80211_find_node(ic, eh->ether_dhost); 245 if (ni != NULL) { 246 if (ni->ni_associd != 0) { 247 m1 = m; 248 m = NULL; 249 } 250 ieee80211_unref_node(&ni); 251 } 252 } 253 if (m1 != NULL) { 254#ifdef ALTQ 255 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 256 altq_etherclassify(&ifp->if_snd, m1, 257 &pktattr); 258#endif 259 len = m1->m_pkthdr.len; 260 IF_ENQUEUE(&ifp->if_snd, m1); 261 if (m != NULL) 262 ifp->if_omcasts++; 263 ifp->if_obytes += len; 264 } 265 } 266 if (m != NULL) 267 (*ifp->if_input)(ifp, m); 268 return; 269 270 case IEEE80211_FC0_TYPE_MGT: 271 if (dir != IEEE80211_FC1_DIR_NODS) 272 goto err; 273 if (ic->ic_opmode == IEEE80211_M_AHDEMO) 274 goto out; 275 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 276 277 /* drop frames without interest */ 278 if (ic->ic_state == IEEE80211_S_SCAN) { 279 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON && 280 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) 281 goto out; 282 } else { 283 if (ic->ic_opmode != IEEE80211_M_IBSS && 284 subtype == IEEE80211_FC0_SUBTYPE_BEACON) 285 goto out; 286 } 287 288 if (ifp->if_flags & IFF_DEBUG) { 289 /* avoid to print too many frames */ 290 int doprint = 0; 291 292 switch (subtype) { 293 case IEEE80211_FC0_SUBTYPE_BEACON: 294 if (ic->ic_state == IEEE80211_S_SCAN) 295 doprint = 1; 296 break; 297 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 298 if (ic->ic_opmode == IEEE80211_M_IBSS) 299 doprint = 1; 300 break; 301 default: 302 doprint = 1; 303 break; 304 } 305#ifdef IEEE80211_DEBUG 306 doprint += ieee80211_debug; 307#endif 308 if (doprint) 309 if_printf(ifp, "received %s from %s rssi %d\n", 310 ieee80211_mgt_subtype_name[subtype 311 >> IEEE80211_FC0_SUBTYPE_SHIFT], 312 ether_sprintf(wh->i_addr2), rssi); 313 } 314 if (ic->ic_rawbpf) 315 bpf_mtap(ic->ic_rawbpf, m); 316 (*ic->ic_recv_mgmt)(ic, m, subtype, rssi, rstamp, rantenna); 317 m_freem(m); 318 return; 319 320 case IEEE80211_FC0_TYPE_CTL: 321 default: 322 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, wh->i_fc[0])); 323 /* should not come here */ 324 break; 325 } 326 err: 327 ifp->if_ierrors++; 328 out: 329 if (m != NULL) { 330 if (ic->ic_rawbpf) 331 bpf_mtap(ic->ic_rawbpf, m); 332 m_freem(m); 333 } 334} 335 336struct mbuf * 337ieee80211_decap(struct ifnet *ifp, struct mbuf *m) 338{ 339 struct ether_header *eh; 340 struct ieee80211_frame wh; 341 struct llc *llc; 342 343 if (m->m_len < sizeof(wh) + sizeof(*llc)) { 344 m = m_pullup(m, sizeof(wh) + sizeof(*llc)); 345 if (m == NULL) 346 return NULL; 347 } 348 memcpy(&wh, mtod(m, caddr_t), sizeof(wh)); 349 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh)); 350 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 351 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 352 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 353 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh)); 354 llc = NULL; 355 } else { 356 m_adj(m, sizeof(wh) - sizeof(*eh)); 357 } 358 eh = mtod(m, struct ether_header *); 359 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 360 case IEEE80211_FC1_DIR_NODS: 361 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 362 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 363 break; 364 case IEEE80211_FC1_DIR_TODS: 365 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 366 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 367 break; 368 case IEEE80211_FC1_DIR_FROMDS: 369 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 370 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 371 break; 372 case IEEE80211_FC1_DIR_DSTODS: 373 /* not yet supported */ 374 IEEE80211_DPRINTF(("%s: DS to DS\n", __func__)); 375 m_freem(m); 376 return NULL; 377 } 378#ifdef ALIGNED_POINTER 379 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) { 380 struct mbuf *n, *n0, **np; 381 caddr_t newdata; 382 int off, pktlen; 383 384 n0 = NULL; 385 np = &n0; 386 off = 0; 387 pktlen = m->m_pkthdr.len; 388 while (pktlen > off) { 389 if (n0 == NULL) { 390 MGETHDR(n, M_DONTWAIT, MT_DATA); 391 if (n == NULL) { 392 m_freem(m); 393 return NULL; 394 } 395 M_MOVE_PKTHDR(n, m); 396 n->m_len = MHLEN; 397 } else { 398 MGET(n, M_DONTWAIT, MT_DATA); 399 if (n == NULL) { 400 m_freem(m); 401 m_freem(n0); 402 return NULL; 403 } 404 n->m_len = MLEN; 405 } 406 if (pktlen - off >= MINCLSIZE) { 407 MCLGET(n, M_DONTWAIT); 408 if (n->m_flags & M_EXT) 409 n->m_len = n->m_ext.ext_size; 410 } 411 if (n0 == NULL) { 412 newdata = 413 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) - 414 sizeof(*eh); 415 n->m_len -= newdata - n->m_data; 416 n->m_data = newdata; 417 } 418 if (n->m_len > pktlen - off) 419 n->m_len = pktlen - off; 420 m_copydata(m, off, n->m_len, mtod(n, caddr_t)); 421 off += n->m_len; 422 *np = n; 423 np = &n->m_next; 424 } 425 m_freem(m); 426 m = n0; 427 } 428#endif /* ALIGNED_POINTER */ 429 if (llc != NULL) { 430 eh = mtod(m, struct ether_header *); 431 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 432 } 433 return m; 434} 435 436/* 437 * Install received rate set information in the node's state block. 438 */ 439static int 440ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni, 441 u_int8_t *rates, u_int8_t *xrates, int flags) 442{ 443 struct ieee80211_rateset *rs = &ni->ni_rates; 444 445 memset(rs, 0, sizeof(*rs)); 446 rs->rs_nrates = rates[1]; 447 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 448 if (xrates != NULL) { 449 u_int8_t nxrates; 450 /* 451 * Tack on 11g extended supported rate element. 452 */ 453 nxrates = xrates[1]; 454 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 455 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 456 IEEE80211_DPRINTF(("%s: extended rate set too large;" 457 " only using %u of %u rates\n", 458 __func__, nxrates, xrates[1])); 459 } 460 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 461 rs->rs_nrates += nxrates; 462 } 463 return ieee80211_fix_rate(ic, ni, flags); 464} 465 466/* XXX statistics */ 467/* Verify the existence and length of __elem or get out. */ 468#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 469 if ((__elem) == NULL) { \ 470 IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \ 471 __func__, ieee80211_mgt_subtype_name[subtype >> \ 472 IEEE80211_FC0_SUBTYPE_SHIFT])); \ 473 return; \ 474 } \ 475 if ((__elem)[1] > (__maxlen)) { \ 476 IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s " \ 477 "frame from %s\n", __func__, (__elem)[1], \ 478 ieee80211_mgt_subtype_name[subtype >> \ 479 IEEE80211_FC0_SUBTYPE_SHIFT], \ 480 ether_sprintf(wh->i_addr2))); \ 481 return; \ 482 } \ 483} while (0) 484 485#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 486 if ((_len) < (_minlen)) { \ 487 IEEE80211_DPRINTF(("%s: %s frame too short from %s\n", \ 488 __func__, \ 489 ieee80211_mgt_subtype_name[subtype >> \ 490 IEEE80211_FC0_SUBTYPE_SHIFT], \ 491 ether_sprintf(wh->i_addr2))); \ 492 return; \ 493 } \ 494} while (0) 495 496void 497ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, 498 int rssi, u_int32_t rstamp, u_int rantenna) 499{ 500#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 501 struct ifnet *ifp = &ic->ic_if; 502 struct ieee80211_frame *wh; 503 struct ieee80211_node *ni; 504 u_int8_t *frm, *efrm; 505 u_int8_t *ssid, *rates, *xrates; 506 int reassoc, resp, newassoc, allocbs; 507 508 wh = mtod(m0, struct ieee80211_frame *); 509 frm = (u_int8_t *)&wh[1]; 510 efrm = mtod(m0, u_int8_t *) + m0->m_len; 511 switch (subtype) { 512 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 513 case IEEE80211_FC0_SUBTYPE_BEACON: { 514 u_int8_t *tstamp, *bintval, *capinfo, *country; 515 u_int8_t chan, bchan, fhindex, erp; 516 u_int16_t fhdwell; 517 518 if (ic->ic_opmode != IEEE80211_M_IBSS && 519 ic->ic_state != IEEE80211_S_SCAN) { 520 /* XXX: may be useful for background scan */ 521 return; 522 } 523 524 /* 525 * beacon/probe response frame format 526 * [8] time stamp 527 * [2] beacon interval 528 * [2] capability information 529 * [tlv] ssid 530 * [tlv] supported rates 531 * [tlv] country information 532 * [tlv] parameter set (FH/DS) 533 * [tlv] erp information 534 * [tlv] extended supported rates 535 */ 536 IEEE80211_VERIFY_LENGTH(efrm - frm, 12); 537 tstamp = frm; frm += 8; 538 bintval = frm; frm += 2; 539 capinfo = frm; frm += 2; 540 ssid = rates = xrates = country = NULL; 541 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 542 chan = bchan; 543 fhdwell = 0; 544 fhindex = 0; 545 erp = 0; 546 while (frm < efrm) { 547 switch (*frm) { 548 case IEEE80211_ELEMID_SSID: 549 ssid = frm; 550 break; 551 case IEEE80211_ELEMID_RATES: 552 rates = frm; 553 break; 554 case IEEE80211_ELEMID_COUNTRY: 555 country = frm; 556 break; 557 case IEEE80211_ELEMID_FHPARMS: 558 if (ic->ic_phytype == IEEE80211_T_FH) { 559 fhdwell = (frm[3] << 8) | frm[2]; 560 chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 561 fhindex = frm[6]; 562 } 563 break; 564 case IEEE80211_ELEMID_DSPARMS: 565 /* 566 * XXX hack this since depending on phytype 567 * is problematic for multi-mode devices. 568 */ 569 if (ic->ic_phytype != IEEE80211_T_FH) 570 chan = frm[2]; 571 break; 572 case IEEE80211_ELEMID_TIM: 573 break; 574 case IEEE80211_ELEMID_XRATES: 575 xrates = frm; 576 break; 577 case IEEE80211_ELEMID_ERP: 578 if (frm[1] != 1) { 579 IEEE80211_DPRINTF(("%s: invalid ERP " 580 "element; length %u, expecting " 581 "1\n", __func__, frm[1])); 582 break; 583 } 584 erp = frm[2]; 585 break; 586 default: 587 IEEE80211_DPRINTF(("%s: element id %u/len %u " 588 "ignored\n", __func__, *frm, frm[1])); 589 break; 590 } 591 frm += frm[1] + 2; 592 } 593 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 594 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 595 if ( 596#if IEEE80211_CHAN_MAX < 255 597 chan > IEEE80211_CHAN_MAX || 598#endif 599 isclr(ic->ic_chan_active, chan)) { 600 IEEE80211_DPRINTF(("%s: ignore %s with invalid channel " 601 "%u\n", __func__, 602 ISPROBE(subtype) ? "probe response" : "beacon", 603 chan)); 604 return; 605 } 606 if (chan != bchan) { 607 /* 608 * Frame was received on a channel different from the 609 * one indicated in the DS/FH params element id; 610 * silently discard it. 611 * 612 * NB: this can happen due to signal leakage. 613 */ 614 IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked " 615 "for channel %u\n", __func__, 616 ISPROBE(subtype) ? "probe response" : "beacon", 617 bchan, chan)); 618 /* XXX statistic */ 619 return; 620 } 621 622 /* 623 * Use mac and channel for lookup so we collect all 624 * potential AP's when scanning. Otherwise we may 625 * see the same AP on multiple channels and will only 626 * record the last one. We could filter APs here based 627 * on rssi, etc. but leave that to the end of the scan 628 * so we can keep the selection criteria in one spot. 629 * This may result in a bloat of the scanned AP list but 630 * it shouldn't be too much. 631 */ 632 ni = ieee80211_lookup_node(ic, wh->i_addr2, 633 &ic->ic_channels[chan]); 634#ifdef IEEE80211_DEBUG 635 if (ieee80211_debug && 636 (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) { 637 printf("%s: %s%s on chan %u (bss chan %u) ", 638 __func__, (ni == NULL ? "new " : ""), 639 ISPROBE(subtype) ? "probe response" : "beacon", 640 chan, bchan); 641 ieee80211_print_essid(ssid + 2, ssid[1]); 642 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 643 printf("%s: caps 0x%x bintval %u erp 0x%x\n", 644 __func__, le16toh(*(u_int16_t *)capinfo), 645 le16toh(*(u_int16_t *)bintval), erp); 646 if (country) 647 printf("%s: country info %*D\n", 648 __func__, country[1], country+2, " "); 649 } 650#endif 651 if (ni == NULL) { 652 ni = ieee80211_alloc_node(ic, wh->i_addr2); 653 if (ni == NULL) 654 return; 655 ni->ni_esslen = ssid[1]; 656 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 657 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 658 } else if (ssid[1] != 0 && ISPROBE(subtype)) { 659 /* 660 * Update ESSID at probe response to adopt hidden AP by 661 * Lucent/Cisco, which announces null ESSID in beacon. 662 */ 663 ni->ni_esslen = ssid[1]; 664 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 665 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 666 } 667 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 668 ni->ni_rssi = rssi; 669 ni->ni_rstamp = rstamp; 670 ni->ni_rantenna = rantenna; 671 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); 672 ni->ni_intval = le16toh(*(u_int16_t *)bintval); 673 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo); 674 /* XXX validate channel # */ 675 ni->ni_chan = &ic->ic_channels[chan]; 676 ni->ni_fhdwell = fhdwell; 677 ni->ni_fhindex = fhindex; 678 ni->ni_erp = erp; 679 /* NB: must be after ni_chan is setup */ 680 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); 681 ieee80211_unref_node(&ni); 682 break; 683 } 684 685 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: { 686 u_int8_t rate; 687 688 if (ic->ic_opmode == IEEE80211_M_STA) 689 return; 690 if (ic->ic_state != IEEE80211_S_RUN) 691 return; 692 693 /* 694 * prreq frame format 695 * [tlv] ssid 696 * [tlv] supported rates 697 * [tlv] extended supported rates 698 */ 699 ssid = rates = xrates = NULL; 700 while (frm < efrm) { 701 switch (*frm) { 702 case IEEE80211_ELEMID_SSID: 703 ssid = frm; 704 break; 705 case IEEE80211_ELEMID_RATES: 706 rates = frm; 707 break; 708 case IEEE80211_ELEMID_XRATES: 709 xrates = frm; 710 break; 711 } 712 frm += frm[1] + 2; 713 } 714 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 715 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 716 if (ssid[1] != 0 && 717 (ssid[1] != ic->ic_bss->ni_esslen || 718 memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) { 719#ifdef IEEE80211_DEBUG 720 if (ieee80211_debug) { 721 printf("%s: ssid unmatch ", __func__); 722 ieee80211_print_essid(ssid + 2, ssid[1]); 723 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 724 } 725#endif 726 return; 727 } 728 729 ni = ieee80211_find_node(ic, wh->i_addr2); 730 if (ni == NULL) { 731 ni = ieee80211_dup_bss(ic, wh->i_addr2); 732 if (ni == NULL) 733 return; 734 IEEE80211_DPRINTF(("%s: new req from %s\n", 735 __func__, ether_sprintf(wh->i_addr2))); 736 allocbs = 1; 737 } else 738 allocbs = 0; 739 ni->ni_rssi = rssi; 740 ni->ni_rstamp = rstamp; 741 ni->ni_rantenna = rantenna; 742 rate = ieee80211_setup_rates(ic, ni, rates, xrates, 743 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 744 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 745 if (rate & IEEE80211_RATE_BASIC) { 746 IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n", 747 __func__,ether_sprintf(wh->i_addr2))); 748 } else { 749 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 750 0); 751 } 752 if (allocbs && ic->ic_opmode == IEEE80211_M_HOSTAP) 753 ieee80211_free_node(ic, ni); 754 else 755 ieee80211_unref_node(&ni); 756 break; 757 } 758 759 case IEEE80211_FC0_SUBTYPE_AUTH: { 760 u_int16_t algo, seq, status; 761 /* 762 * auth frame format 763 * [2] algorithm 764 * [2] sequence 765 * [2] status 766 * [tlv*] challenge 767 */ 768 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 769 algo = le16toh(*(u_int16_t *)frm); 770 seq = le16toh(*(u_int16_t *)(frm + 2)); 771 status = le16toh(*(u_int16_t *)(frm + 4)); 772 if (algo != IEEE80211_AUTH_ALG_OPEN) { 773 /* TODO: shared key auth */ 774 IEEE80211_DPRINTF(("%s: unsupported auth %d from %s\n", 775 __func__, algo, ether_sprintf(wh->i_addr2))); 776 return; 777 } 778 switch (ic->ic_opmode) { 779 case IEEE80211_M_IBSS: 780 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 781 return; 782 ieee80211_new_state(ic, IEEE80211_S_AUTH, 783 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 784 break; 785 786 case IEEE80211_M_AHDEMO: 787 /* should not come here */ 788 break; 789 790 case IEEE80211_M_HOSTAP: 791 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 792 return; 793 allocbs = 0; 794 ni = ieee80211_find_node(ic, wh->i_addr2); 795 if (ni == NULL) { 796 ni = ieee80211_alloc_node(ic, wh->i_addr2); 797 if (ni == NULL) 798 return; 799 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 800 ni->ni_rssi = rssi; 801 ni->ni_rstamp = rstamp; 802 ni->ni_rantenna = rantenna; 803 ni->ni_chan = ic->ic_bss->ni_chan; 804 allocbs = 1; 805 } 806 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, 2); 807 if (ifp->if_flags & IFF_DEBUG) 808 if_printf(ifp, "station %s %s authenticated\n", 809 (allocbs ? "newly" : "already"), 810 ether_sprintf(ni->ni_macaddr)); 811 ieee80211_unref_node(&ni); 812 break; 813 814 case IEEE80211_M_STA: 815 if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) 816 return; 817 if (status != 0) { 818 if_printf(&ic->ic_if, 819 "authentication failed (reason %d) for %s\n", 820 status, 821 ether_sprintf(wh->i_addr3)); 822 ni = ieee80211_find_node(ic, wh->i_addr2); 823 if (ni != NULL) { 824 ni->ni_fails++; 825 ieee80211_unref_node(&ni); 826 } 827 return; 828 } 829 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 830 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 831 break;
| 220 } 221 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 222 if (ic->ic_flags & IEEE80211_F_WEPON) { 223 m = ieee80211_wep_crypt(ifp, m, 0); 224 if (m == NULL) 225 goto err; 226 wh = mtod(m, struct ieee80211_frame *); 227 } else 228 goto out; 229 } 230 /* copy to listener after decrypt */ 231 if (ic->ic_rawbpf) 232 bpf_mtap(ic->ic_rawbpf, m); 233 m = ieee80211_decap(ifp, m); 234 if (m == NULL) 235 goto err; 236 ifp->if_ipackets++; 237 238 /* perform as a bridge within the AP */ 239 m1 = NULL; 240 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 241 eh = mtod(m, struct ether_header *); 242 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 243 m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 244 if (m1 == NULL) 245 ifp->if_oerrors++; 246 else 247 m1->m_flags |= M_MCAST; 248 } else { 249 ni = ieee80211_find_node(ic, eh->ether_dhost); 250 if (ni != NULL) { 251 if (ni->ni_associd != 0) { 252 m1 = m; 253 m = NULL; 254 } 255 ieee80211_unref_node(&ni); 256 } 257 } 258 if (m1 != NULL) { 259#ifdef ALTQ 260 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 261 altq_etherclassify(&ifp->if_snd, m1, 262 &pktattr); 263#endif 264 len = m1->m_pkthdr.len; 265 IF_ENQUEUE(&ifp->if_snd, m1); 266 if (m != NULL) 267 ifp->if_omcasts++; 268 ifp->if_obytes += len; 269 } 270 } 271 if (m != NULL) 272 (*ifp->if_input)(ifp, m); 273 return; 274 275 case IEEE80211_FC0_TYPE_MGT: 276 if (dir != IEEE80211_FC1_DIR_NODS) 277 goto err; 278 if (ic->ic_opmode == IEEE80211_M_AHDEMO) 279 goto out; 280 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 281 282 /* drop frames without interest */ 283 if (ic->ic_state == IEEE80211_S_SCAN) { 284 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON && 285 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) 286 goto out; 287 } else { 288 if (ic->ic_opmode != IEEE80211_M_IBSS && 289 subtype == IEEE80211_FC0_SUBTYPE_BEACON) 290 goto out; 291 } 292 293 if (ifp->if_flags & IFF_DEBUG) { 294 /* avoid to print too many frames */ 295 int doprint = 0; 296 297 switch (subtype) { 298 case IEEE80211_FC0_SUBTYPE_BEACON: 299 if (ic->ic_state == IEEE80211_S_SCAN) 300 doprint = 1; 301 break; 302 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 303 if (ic->ic_opmode == IEEE80211_M_IBSS) 304 doprint = 1; 305 break; 306 default: 307 doprint = 1; 308 break; 309 } 310#ifdef IEEE80211_DEBUG 311 doprint += ieee80211_debug; 312#endif 313 if (doprint) 314 if_printf(ifp, "received %s from %s rssi %d\n", 315 ieee80211_mgt_subtype_name[subtype 316 >> IEEE80211_FC0_SUBTYPE_SHIFT], 317 ether_sprintf(wh->i_addr2), rssi); 318 } 319 if (ic->ic_rawbpf) 320 bpf_mtap(ic->ic_rawbpf, m); 321 (*ic->ic_recv_mgmt)(ic, m, subtype, rssi, rstamp, rantenna); 322 m_freem(m); 323 return; 324 325 case IEEE80211_FC0_TYPE_CTL: 326 default: 327 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, wh->i_fc[0])); 328 /* should not come here */ 329 break; 330 } 331 err: 332 ifp->if_ierrors++; 333 out: 334 if (m != NULL) { 335 if (ic->ic_rawbpf) 336 bpf_mtap(ic->ic_rawbpf, m); 337 m_freem(m); 338 } 339} 340 341struct mbuf * 342ieee80211_decap(struct ifnet *ifp, struct mbuf *m) 343{ 344 struct ether_header *eh; 345 struct ieee80211_frame wh; 346 struct llc *llc; 347 348 if (m->m_len < sizeof(wh) + sizeof(*llc)) { 349 m = m_pullup(m, sizeof(wh) + sizeof(*llc)); 350 if (m == NULL) 351 return NULL; 352 } 353 memcpy(&wh, mtod(m, caddr_t), sizeof(wh)); 354 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh)); 355 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 356 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 357 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 358 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh)); 359 llc = NULL; 360 } else { 361 m_adj(m, sizeof(wh) - sizeof(*eh)); 362 } 363 eh = mtod(m, struct ether_header *); 364 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 365 case IEEE80211_FC1_DIR_NODS: 366 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 367 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 368 break; 369 case IEEE80211_FC1_DIR_TODS: 370 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 371 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 372 break; 373 case IEEE80211_FC1_DIR_FROMDS: 374 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 375 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 376 break; 377 case IEEE80211_FC1_DIR_DSTODS: 378 /* not yet supported */ 379 IEEE80211_DPRINTF(("%s: DS to DS\n", __func__)); 380 m_freem(m); 381 return NULL; 382 } 383#ifdef ALIGNED_POINTER 384 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) { 385 struct mbuf *n, *n0, **np; 386 caddr_t newdata; 387 int off, pktlen; 388 389 n0 = NULL; 390 np = &n0; 391 off = 0; 392 pktlen = m->m_pkthdr.len; 393 while (pktlen > off) { 394 if (n0 == NULL) { 395 MGETHDR(n, M_DONTWAIT, MT_DATA); 396 if (n == NULL) { 397 m_freem(m); 398 return NULL; 399 } 400 M_MOVE_PKTHDR(n, m); 401 n->m_len = MHLEN; 402 } else { 403 MGET(n, M_DONTWAIT, MT_DATA); 404 if (n == NULL) { 405 m_freem(m); 406 m_freem(n0); 407 return NULL; 408 } 409 n->m_len = MLEN; 410 } 411 if (pktlen - off >= MINCLSIZE) { 412 MCLGET(n, M_DONTWAIT); 413 if (n->m_flags & M_EXT) 414 n->m_len = n->m_ext.ext_size; 415 } 416 if (n0 == NULL) { 417 newdata = 418 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) - 419 sizeof(*eh); 420 n->m_len -= newdata - n->m_data; 421 n->m_data = newdata; 422 } 423 if (n->m_len > pktlen - off) 424 n->m_len = pktlen - off; 425 m_copydata(m, off, n->m_len, mtod(n, caddr_t)); 426 off += n->m_len; 427 *np = n; 428 np = &n->m_next; 429 } 430 m_freem(m); 431 m = n0; 432 } 433#endif /* ALIGNED_POINTER */ 434 if (llc != NULL) { 435 eh = mtod(m, struct ether_header *); 436 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 437 } 438 return m; 439} 440 441/* 442 * Install received rate set information in the node's state block. 443 */ 444static int 445ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni, 446 u_int8_t *rates, u_int8_t *xrates, int flags) 447{ 448 struct ieee80211_rateset *rs = &ni->ni_rates; 449 450 memset(rs, 0, sizeof(*rs)); 451 rs->rs_nrates = rates[1]; 452 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 453 if (xrates != NULL) { 454 u_int8_t nxrates; 455 /* 456 * Tack on 11g extended supported rate element. 457 */ 458 nxrates = xrates[1]; 459 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 460 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 461 IEEE80211_DPRINTF(("%s: extended rate set too large;" 462 " only using %u of %u rates\n", 463 __func__, nxrates, xrates[1])); 464 } 465 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 466 rs->rs_nrates += nxrates; 467 } 468 return ieee80211_fix_rate(ic, ni, flags); 469} 470 471/* XXX statistics */ 472/* Verify the existence and length of __elem or get out. */ 473#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 474 if ((__elem) == NULL) { \ 475 IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \ 476 __func__, ieee80211_mgt_subtype_name[subtype >> \ 477 IEEE80211_FC0_SUBTYPE_SHIFT])); \ 478 return; \ 479 } \ 480 if ((__elem)[1] > (__maxlen)) { \ 481 IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s " \ 482 "frame from %s\n", __func__, (__elem)[1], \ 483 ieee80211_mgt_subtype_name[subtype >> \ 484 IEEE80211_FC0_SUBTYPE_SHIFT], \ 485 ether_sprintf(wh->i_addr2))); \ 486 return; \ 487 } \ 488} while (0) 489 490#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 491 if ((_len) < (_minlen)) { \ 492 IEEE80211_DPRINTF(("%s: %s frame too short from %s\n", \ 493 __func__, \ 494 ieee80211_mgt_subtype_name[subtype >> \ 495 IEEE80211_FC0_SUBTYPE_SHIFT], \ 496 ether_sprintf(wh->i_addr2))); \ 497 return; \ 498 } \ 499} while (0) 500 501void 502ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, 503 int rssi, u_int32_t rstamp, u_int rantenna) 504{ 505#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 506 struct ifnet *ifp = &ic->ic_if; 507 struct ieee80211_frame *wh; 508 struct ieee80211_node *ni; 509 u_int8_t *frm, *efrm; 510 u_int8_t *ssid, *rates, *xrates; 511 int reassoc, resp, newassoc, allocbs; 512 513 wh = mtod(m0, struct ieee80211_frame *); 514 frm = (u_int8_t *)&wh[1]; 515 efrm = mtod(m0, u_int8_t *) + m0->m_len; 516 switch (subtype) { 517 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 518 case IEEE80211_FC0_SUBTYPE_BEACON: { 519 u_int8_t *tstamp, *bintval, *capinfo, *country; 520 u_int8_t chan, bchan, fhindex, erp; 521 u_int16_t fhdwell; 522 523 if (ic->ic_opmode != IEEE80211_M_IBSS && 524 ic->ic_state != IEEE80211_S_SCAN) { 525 /* XXX: may be useful for background scan */ 526 return; 527 } 528 529 /* 530 * beacon/probe response frame format 531 * [8] time stamp 532 * [2] beacon interval 533 * [2] capability information 534 * [tlv] ssid 535 * [tlv] supported rates 536 * [tlv] country information 537 * [tlv] parameter set (FH/DS) 538 * [tlv] erp information 539 * [tlv] extended supported rates 540 */ 541 IEEE80211_VERIFY_LENGTH(efrm - frm, 12); 542 tstamp = frm; frm += 8; 543 bintval = frm; frm += 2; 544 capinfo = frm; frm += 2; 545 ssid = rates = xrates = country = NULL; 546 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 547 chan = bchan; 548 fhdwell = 0; 549 fhindex = 0; 550 erp = 0; 551 while (frm < efrm) { 552 switch (*frm) { 553 case IEEE80211_ELEMID_SSID: 554 ssid = frm; 555 break; 556 case IEEE80211_ELEMID_RATES: 557 rates = frm; 558 break; 559 case IEEE80211_ELEMID_COUNTRY: 560 country = frm; 561 break; 562 case IEEE80211_ELEMID_FHPARMS: 563 if (ic->ic_phytype == IEEE80211_T_FH) { 564 fhdwell = (frm[3] << 8) | frm[2]; 565 chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 566 fhindex = frm[6]; 567 } 568 break; 569 case IEEE80211_ELEMID_DSPARMS: 570 /* 571 * XXX hack this since depending on phytype 572 * is problematic for multi-mode devices. 573 */ 574 if (ic->ic_phytype != IEEE80211_T_FH) 575 chan = frm[2]; 576 break; 577 case IEEE80211_ELEMID_TIM: 578 break; 579 case IEEE80211_ELEMID_XRATES: 580 xrates = frm; 581 break; 582 case IEEE80211_ELEMID_ERP: 583 if (frm[1] != 1) { 584 IEEE80211_DPRINTF(("%s: invalid ERP " 585 "element; length %u, expecting " 586 "1\n", __func__, frm[1])); 587 break; 588 } 589 erp = frm[2]; 590 break; 591 default: 592 IEEE80211_DPRINTF(("%s: element id %u/len %u " 593 "ignored\n", __func__, *frm, frm[1])); 594 break; 595 } 596 frm += frm[1] + 2; 597 } 598 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 599 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 600 if ( 601#if IEEE80211_CHAN_MAX < 255 602 chan > IEEE80211_CHAN_MAX || 603#endif 604 isclr(ic->ic_chan_active, chan)) { 605 IEEE80211_DPRINTF(("%s: ignore %s with invalid channel " 606 "%u\n", __func__, 607 ISPROBE(subtype) ? "probe response" : "beacon", 608 chan)); 609 return; 610 } 611 if (chan != bchan) { 612 /* 613 * Frame was received on a channel different from the 614 * one indicated in the DS/FH params element id; 615 * silently discard it. 616 * 617 * NB: this can happen due to signal leakage. 618 */ 619 IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked " 620 "for channel %u\n", __func__, 621 ISPROBE(subtype) ? "probe response" : "beacon", 622 bchan, chan)); 623 /* XXX statistic */ 624 return; 625 } 626 627 /* 628 * Use mac and channel for lookup so we collect all 629 * potential AP's when scanning. Otherwise we may 630 * see the same AP on multiple channels and will only 631 * record the last one. We could filter APs here based 632 * on rssi, etc. but leave that to the end of the scan 633 * so we can keep the selection criteria in one spot. 634 * This may result in a bloat of the scanned AP list but 635 * it shouldn't be too much. 636 */ 637 ni = ieee80211_lookup_node(ic, wh->i_addr2, 638 &ic->ic_channels[chan]); 639#ifdef IEEE80211_DEBUG 640 if (ieee80211_debug && 641 (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) { 642 printf("%s: %s%s on chan %u (bss chan %u) ", 643 __func__, (ni == NULL ? "new " : ""), 644 ISPROBE(subtype) ? "probe response" : "beacon", 645 chan, bchan); 646 ieee80211_print_essid(ssid + 2, ssid[1]); 647 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 648 printf("%s: caps 0x%x bintval %u erp 0x%x\n", 649 __func__, le16toh(*(u_int16_t *)capinfo), 650 le16toh(*(u_int16_t *)bintval), erp); 651 if (country) 652 printf("%s: country info %*D\n", 653 __func__, country[1], country+2, " "); 654 } 655#endif 656 if (ni == NULL) { 657 ni = ieee80211_alloc_node(ic, wh->i_addr2); 658 if (ni == NULL) 659 return; 660 ni->ni_esslen = ssid[1]; 661 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 662 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 663 } else if (ssid[1] != 0 && ISPROBE(subtype)) { 664 /* 665 * Update ESSID at probe response to adopt hidden AP by 666 * Lucent/Cisco, which announces null ESSID in beacon. 667 */ 668 ni->ni_esslen = ssid[1]; 669 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 670 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 671 } 672 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 673 ni->ni_rssi = rssi; 674 ni->ni_rstamp = rstamp; 675 ni->ni_rantenna = rantenna; 676 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); 677 ni->ni_intval = le16toh(*(u_int16_t *)bintval); 678 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo); 679 /* XXX validate channel # */ 680 ni->ni_chan = &ic->ic_channels[chan]; 681 ni->ni_fhdwell = fhdwell; 682 ni->ni_fhindex = fhindex; 683 ni->ni_erp = erp; 684 /* NB: must be after ni_chan is setup */ 685 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); 686 ieee80211_unref_node(&ni); 687 break; 688 } 689 690 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: { 691 u_int8_t rate; 692 693 if (ic->ic_opmode == IEEE80211_M_STA) 694 return; 695 if (ic->ic_state != IEEE80211_S_RUN) 696 return; 697 698 /* 699 * prreq frame format 700 * [tlv] ssid 701 * [tlv] supported rates 702 * [tlv] extended supported rates 703 */ 704 ssid = rates = xrates = NULL; 705 while (frm < efrm) { 706 switch (*frm) { 707 case IEEE80211_ELEMID_SSID: 708 ssid = frm; 709 break; 710 case IEEE80211_ELEMID_RATES: 711 rates = frm; 712 break; 713 case IEEE80211_ELEMID_XRATES: 714 xrates = frm; 715 break; 716 } 717 frm += frm[1] + 2; 718 } 719 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 720 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 721 if (ssid[1] != 0 && 722 (ssid[1] != ic->ic_bss->ni_esslen || 723 memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) { 724#ifdef IEEE80211_DEBUG 725 if (ieee80211_debug) { 726 printf("%s: ssid unmatch ", __func__); 727 ieee80211_print_essid(ssid + 2, ssid[1]); 728 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 729 } 730#endif 731 return; 732 } 733 734 ni = ieee80211_find_node(ic, wh->i_addr2); 735 if (ni == NULL) { 736 ni = ieee80211_dup_bss(ic, wh->i_addr2); 737 if (ni == NULL) 738 return; 739 IEEE80211_DPRINTF(("%s: new req from %s\n", 740 __func__, ether_sprintf(wh->i_addr2))); 741 allocbs = 1; 742 } else 743 allocbs = 0; 744 ni->ni_rssi = rssi; 745 ni->ni_rstamp = rstamp; 746 ni->ni_rantenna = rantenna; 747 rate = ieee80211_setup_rates(ic, ni, rates, xrates, 748 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 749 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 750 if (rate & IEEE80211_RATE_BASIC) { 751 IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n", 752 __func__,ether_sprintf(wh->i_addr2))); 753 } else { 754 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 755 0); 756 } 757 if (allocbs && ic->ic_opmode == IEEE80211_M_HOSTAP) 758 ieee80211_free_node(ic, ni); 759 else 760 ieee80211_unref_node(&ni); 761 break; 762 } 763 764 case IEEE80211_FC0_SUBTYPE_AUTH: { 765 u_int16_t algo, seq, status; 766 /* 767 * auth frame format 768 * [2] algorithm 769 * [2] sequence 770 * [2] status 771 * [tlv*] challenge 772 */ 773 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 774 algo = le16toh(*(u_int16_t *)frm); 775 seq = le16toh(*(u_int16_t *)(frm + 2)); 776 status = le16toh(*(u_int16_t *)(frm + 4)); 777 if (algo != IEEE80211_AUTH_ALG_OPEN) { 778 /* TODO: shared key auth */ 779 IEEE80211_DPRINTF(("%s: unsupported auth %d from %s\n", 780 __func__, algo, ether_sprintf(wh->i_addr2))); 781 return; 782 } 783 switch (ic->ic_opmode) { 784 case IEEE80211_M_IBSS: 785 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 786 return; 787 ieee80211_new_state(ic, IEEE80211_S_AUTH, 788 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 789 break; 790 791 case IEEE80211_M_AHDEMO: 792 /* should not come here */ 793 break; 794 795 case IEEE80211_M_HOSTAP: 796 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 797 return; 798 allocbs = 0; 799 ni = ieee80211_find_node(ic, wh->i_addr2); 800 if (ni == NULL) { 801 ni = ieee80211_alloc_node(ic, wh->i_addr2); 802 if (ni == NULL) 803 return; 804 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 805 ni->ni_rssi = rssi; 806 ni->ni_rstamp = rstamp; 807 ni->ni_rantenna = rantenna; 808 ni->ni_chan = ic->ic_bss->ni_chan; 809 allocbs = 1; 810 } 811 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, 2); 812 if (ifp->if_flags & IFF_DEBUG) 813 if_printf(ifp, "station %s %s authenticated\n", 814 (allocbs ? "newly" : "already"), 815 ether_sprintf(ni->ni_macaddr)); 816 ieee80211_unref_node(&ni); 817 break; 818 819 case IEEE80211_M_STA: 820 if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) 821 return; 822 if (status != 0) { 823 if_printf(&ic->ic_if, 824 "authentication failed (reason %d) for %s\n", 825 status, 826 ether_sprintf(wh->i_addr3)); 827 ni = ieee80211_find_node(ic, wh->i_addr2); 828 if (ni != NULL) { 829 ni->ni_fails++; 830 ieee80211_unref_node(&ni); 831 } 832 return; 833 } 834 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 835 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 836 break;
|
832 } 833 break; 834 } 835 836 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 837 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { 838 u_int16_t capinfo, bintval; 839 840 if (ic->ic_opmode != IEEE80211_M_HOSTAP || 841 (ic->ic_state != IEEE80211_S_RUN)) 842 return; 843 844 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 845 reassoc = 1; 846 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 847 } else { 848 reassoc = 0; 849 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 850 } 851 /* 852 * asreq frame format 853 * [2] capability information 854 * [2] listen interval 855 * [6*] current AP address (reassoc only) 856 * [tlv] ssid 857 * [tlv] supported rates 858 * [tlv] extended supported rates 859 */ 860 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 861 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 862 IEEE80211_DPRINTF(("%s: ignore other bss from %s\n", 863 __func__, ether_sprintf(wh->i_addr2))); 864 return; 865 } 866 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 867 bintval = le16toh(*(u_int16_t *)frm); frm += 2; 868 if (reassoc) 869 frm += 6; /* ignore current AP info */ 870 ssid = rates = xrates = NULL; 871 while (frm < efrm) { 872 switch (*frm) { 873 case IEEE80211_ELEMID_SSID: 874 ssid = frm; 875 break; 876 case IEEE80211_ELEMID_RATES: 877 rates = frm; 878 break; 879 case IEEE80211_ELEMID_XRATES: 880 xrates = frm; 881 break; 882 } 883 frm += frm[1] + 2; 884 } 885 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 886 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 887 if (ssid[1] != ic->ic_bss->ni_esslen || 888 memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) { 889#ifdef IEEE80211_DEBUG 890 if (ieee80211_debug) { 891 printf("%s: ssid unmatch ", __func__); 892 ieee80211_print_essid(ssid + 2, ssid[1]); 893 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 894 } 895#endif 896 return; 897 } 898 ni = ieee80211_find_node(ic, wh->i_addr2); 899 if (ni == NULL) { 900 IEEE80211_DPRINTF(("%s: not authenticated for %s\n", 901 __func__, ether_sprintf(wh->i_addr2))); 902 ni = ieee80211_dup_bss(ic, wh->i_addr2); 903 if (ni == NULL) 904 return; 905 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 906 IEEE80211_REASON_ASSOC_NOT_AUTHED); 907 ieee80211_free_node(ic, ni); 908 return; 909 } 910 /* XXX per-node cipher suite */ 911 /* XXX some stations use the privacy bit for handling APs 912 that suport both encrypted and unencrypted traffic */ 913 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 914 (capinfo & IEEE80211_CAPINFO_PRIVACY) != 915 ((ic->ic_flags & IEEE80211_F_WEPON) ? 916 IEEE80211_CAPINFO_PRIVACY : 0)) { 917 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n", 918 __func__, capinfo, ether_sprintf(wh->i_addr2))); 919 ni->ni_associd = 0; 920 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_CAPINFO); 921 ieee80211_unref_node(&ni); 922 return; 923 } 924 ieee80211_setup_rates(ic, ni, rates, xrates, 925 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 926 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 927 if (ni->ni_rates.rs_nrates == 0) { 928 IEEE80211_DPRINTF(("%s: rate unmatch for %s\n", 929 __func__, ether_sprintf(wh->i_addr2))); 930 ni->ni_associd = 0; 931 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_BASIC_RATE); 932 ieee80211_unref_node(&ni); 933 return; 934 } 935 ni->ni_rssi = rssi; 936 ni->ni_rstamp = rstamp; 937 ni->ni_rantenna = rantenna; 938 ni->ni_intval = bintval; 939 ni->ni_capinfo = capinfo; 940 ni->ni_chan = ic->ic_bss->ni_chan; 941 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 942 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 943 if (ni->ni_associd == 0) { 944 /* XXX handle rollover at 2007 */ 945 /* XXX guarantee uniqueness */ 946 ni->ni_associd = 0xc000 | ic->ic_bss->ni_associd++; 947 newassoc = 1; 948 } else 949 newassoc = 0; 950 /* XXX for 11g must turn off short slot time if long 951 slot time sta associates */ 952 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); 953 if (ifp->if_flags & IFF_DEBUG) 954 if_printf(ifp, "station %s %s associated\n", 955 (newassoc ? "newly" : "already"), 956 ether_sprintf(ni->ni_macaddr)); 957 /* give driver a chance to setup state like ni_txrate */ 958 if (ic->ic_newassoc) 959 (*ic->ic_newassoc)(ic, ni, newassoc); 960 ieee80211_unref_node(&ni); 961 break; 962 } 963 964 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 965 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 966 u_int16_t status; 967 968 if (ic->ic_opmode != IEEE80211_M_STA || 969 ic->ic_state != IEEE80211_S_ASSOC) 970 return; 971 972 /* 973 * asresp frame format 974 * [2] capability information 975 * [2] status 976 * [2] association ID 977 * [tlv] supported rates 978 * [tlv] extended supported rates 979 */ 980 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 981 ni = ic->ic_bss; 982 ni->ni_capinfo = le16toh(*(u_int16_t *)frm); 983 frm += 2; 984 985 status = le16toh(*(u_int16_t *)frm); 986 frm += 2; 987 if (status != 0) { 988 if_printf(ifp, "association failed (reason %d) for %s\n", 989 status, ether_sprintf(wh->i_addr3)); 990 ni = ieee80211_find_node(ic, wh->i_addr2); 991 if (ni != NULL) { 992 ni->ni_fails++; 993 ieee80211_unref_node(&ni); 994 } 995 return; 996 } 997 ni->ni_associd = le16toh(*(u_int16_t *)frm); 998 frm += 2; 999 1000 rates = xrates = NULL; 1001 while (frm < efrm) { 1002 switch (*frm) { 1003 case IEEE80211_ELEMID_RATES: 1004 rates = frm; 1005 break; 1006 case IEEE80211_ELEMID_XRATES: 1007 xrates = frm; 1008 break; 1009 } 1010 frm += frm[1] + 2; 1011 } 1012 1013 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 1014 ieee80211_setup_rates(ic, ni, rates, xrates, 1015 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 1016 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 1017 if (ni->ni_rates.rs_nrates != 0) 1018 ieee80211_new_state(ic, IEEE80211_S_RUN, 1019 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1020 break; 1021 } 1022 1023 case IEEE80211_FC0_SUBTYPE_DEAUTH: { 1024 u_int16_t reason; 1025 /* 1026 * deauth frame format 1027 * [2] reason 1028 */ 1029 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1030 reason = le16toh(*(u_int16_t *)frm); 1031 switch (ic->ic_opmode) { 1032 case IEEE80211_M_STA: 1033 ieee80211_new_state(ic, IEEE80211_S_AUTH, 1034 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1035 break; 1036 case IEEE80211_M_HOSTAP: 1037 ni = ieee80211_find_node(ic, wh->i_addr2); 1038 if (ni != NULL) { 1039 if (ifp->if_flags & IFF_DEBUG) 1040 if_printf(ifp, "station %s deauthenticated" 1041 " by peer (reason %d)\n", 1042 ether_sprintf(ni->ni_macaddr), reason); 1043 ieee80211_free_node(ic, ni); 1044 } 1045 break; 1046 default: 1047 break; 1048 } 1049 break; 1050 } 1051 1052 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 1053 u_int16_t reason; 1054 /* 1055 * disassoc frame format 1056 * [2] reason 1057 */ 1058 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1059 reason = le16toh(*(u_int16_t *)frm); 1060 switch (ic->ic_opmode) { 1061 case IEEE80211_M_STA: 1062 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1063 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1064 break; 1065 case IEEE80211_M_HOSTAP: 1066 ni = ieee80211_find_node(ic, wh->i_addr2); 1067 if (ni != NULL) { 1068 if (ifp->if_flags & IFF_DEBUG) 1069 if_printf(ifp, "station %s disassociated" 1070 " by peer (reason %d)\n", 1071 ether_sprintf(ni->ni_macaddr), reason); 1072 ni->ni_associd = 0; 1073 ieee80211_unref_node(&ni); 1074 } 1075 break; 1076 default: 1077 break; 1078 } 1079 break; 1080 } 1081 default: 1082 IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not " 1083 "handled\n", __func__, subtype)); 1084 break; 1085 } 1086#undef ISPROBE 1087} 1088#undef IEEE80211_VERIFY_LENGTH 1089#undef IEEE80211_VERIFY_ELEMENT
| 839 } 840 break; 841 } 842 843 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 844 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { 845 u_int16_t capinfo, bintval; 846 847 if (ic->ic_opmode != IEEE80211_M_HOSTAP || 848 (ic->ic_state != IEEE80211_S_RUN)) 849 return; 850 851 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 852 reassoc = 1; 853 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 854 } else { 855 reassoc = 0; 856 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 857 } 858 /* 859 * asreq frame format 860 * [2] capability information 861 * [2] listen interval 862 * [6*] current AP address (reassoc only) 863 * [tlv] ssid 864 * [tlv] supported rates 865 * [tlv] extended supported rates 866 */ 867 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 868 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 869 IEEE80211_DPRINTF(("%s: ignore other bss from %s\n", 870 __func__, ether_sprintf(wh->i_addr2))); 871 return; 872 } 873 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 874 bintval = le16toh(*(u_int16_t *)frm); frm += 2; 875 if (reassoc) 876 frm += 6; /* ignore current AP info */ 877 ssid = rates = xrates = NULL; 878 while (frm < efrm) { 879 switch (*frm) { 880 case IEEE80211_ELEMID_SSID: 881 ssid = frm; 882 break; 883 case IEEE80211_ELEMID_RATES: 884 rates = frm; 885 break; 886 case IEEE80211_ELEMID_XRATES: 887 xrates = frm; 888 break; 889 } 890 frm += frm[1] + 2; 891 } 892 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 893 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 894 if (ssid[1] != ic->ic_bss->ni_esslen || 895 memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) { 896#ifdef IEEE80211_DEBUG 897 if (ieee80211_debug) { 898 printf("%s: ssid unmatch ", __func__); 899 ieee80211_print_essid(ssid + 2, ssid[1]); 900 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 901 } 902#endif 903 return; 904 } 905 ni = ieee80211_find_node(ic, wh->i_addr2); 906 if (ni == NULL) { 907 IEEE80211_DPRINTF(("%s: not authenticated for %s\n", 908 __func__, ether_sprintf(wh->i_addr2))); 909 ni = ieee80211_dup_bss(ic, wh->i_addr2); 910 if (ni == NULL) 911 return; 912 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 913 IEEE80211_REASON_ASSOC_NOT_AUTHED); 914 ieee80211_free_node(ic, ni); 915 return; 916 } 917 /* XXX per-node cipher suite */ 918 /* XXX some stations use the privacy bit for handling APs 919 that suport both encrypted and unencrypted traffic */ 920 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 921 (capinfo & IEEE80211_CAPINFO_PRIVACY) != 922 ((ic->ic_flags & IEEE80211_F_WEPON) ? 923 IEEE80211_CAPINFO_PRIVACY : 0)) { 924 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n", 925 __func__, capinfo, ether_sprintf(wh->i_addr2))); 926 ni->ni_associd = 0; 927 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_CAPINFO); 928 ieee80211_unref_node(&ni); 929 return; 930 } 931 ieee80211_setup_rates(ic, ni, rates, xrates, 932 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 933 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 934 if (ni->ni_rates.rs_nrates == 0) { 935 IEEE80211_DPRINTF(("%s: rate unmatch for %s\n", 936 __func__, ether_sprintf(wh->i_addr2))); 937 ni->ni_associd = 0; 938 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_BASIC_RATE); 939 ieee80211_unref_node(&ni); 940 return; 941 } 942 ni->ni_rssi = rssi; 943 ni->ni_rstamp = rstamp; 944 ni->ni_rantenna = rantenna; 945 ni->ni_intval = bintval; 946 ni->ni_capinfo = capinfo; 947 ni->ni_chan = ic->ic_bss->ni_chan; 948 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 949 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 950 if (ni->ni_associd == 0) { 951 /* XXX handle rollover at 2007 */ 952 /* XXX guarantee uniqueness */ 953 ni->ni_associd = 0xc000 | ic->ic_bss->ni_associd++; 954 newassoc = 1; 955 } else 956 newassoc = 0; 957 /* XXX for 11g must turn off short slot time if long 958 slot time sta associates */ 959 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); 960 if (ifp->if_flags & IFF_DEBUG) 961 if_printf(ifp, "station %s %s associated\n", 962 (newassoc ? "newly" : "already"), 963 ether_sprintf(ni->ni_macaddr)); 964 /* give driver a chance to setup state like ni_txrate */ 965 if (ic->ic_newassoc) 966 (*ic->ic_newassoc)(ic, ni, newassoc); 967 ieee80211_unref_node(&ni); 968 break; 969 } 970 971 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 972 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 973 u_int16_t status; 974 975 if (ic->ic_opmode != IEEE80211_M_STA || 976 ic->ic_state != IEEE80211_S_ASSOC) 977 return; 978 979 /* 980 * asresp frame format 981 * [2] capability information 982 * [2] status 983 * [2] association ID 984 * [tlv] supported rates 985 * [tlv] extended supported rates 986 */ 987 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 988 ni = ic->ic_bss; 989 ni->ni_capinfo = le16toh(*(u_int16_t *)frm); 990 frm += 2; 991 992 status = le16toh(*(u_int16_t *)frm); 993 frm += 2; 994 if (status != 0) { 995 if_printf(ifp, "association failed (reason %d) for %s\n", 996 status, ether_sprintf(wh->i_addr3)); 997 ni = ieee80211_find_node(ic, wh->i_addr2); 998 if (ni != NULL) { 999 ni->ni_fails++; 1000 ieee80211_unref_node(&ni); 1001 } 1002 return; 1003 } 1004 ni->ni_associd = le16toh(*(u_int16_t *)frm); 1005 frm += 2; 1006 1007 rates = xrates = NULL; 1008 while (frm < efrm) { 1009 switch (*frm) { 1010 case IEEE80211_ELEMID_RATES: 1011 rates = frm; 1012 break; 1013 case IEEE80211_ELEMID_XRATES: 1014 xrates = frm; 1015 break; 1016 } 1017 frm += frm[1] + 2; 1018 } 1019 1020 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); 1021 ieee80211_setup_rates(ic, ni, rates, xrates, 1022 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 1023 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 1024 if (ni->ni_rates.rs_nrates != 0) 1025 ieee80211_new_state(ic, IEEE80211_S_RUN, 1026 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1027 break; 1028 } 1029 1030 case IEEE80211_FC0_SUBTYPE_DEAUTH: { 1031 u_int16_t reason; 1032 /* 1033 * deauth frame format 1034 * [2] reason 1035 */ 1036 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1037 reason = le16toh(*(u_int16_t *)frm); 1038 switch (ic->ic_opmode) { 1039 case IEEE80211_M_STA: 1040 ieee80211_new_state(ic, IEEE80211_S_AUTH, 1041 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1042 break; 1043 case IEEE80211_M_HOSTAP: 1044 ni = ieee80211_find_node(ic, wh->i_addr2); 1045 if (ni != NULL) { 1046 if (ifp->if_flags & IFF_DEBUG) 1047 if_printf(ifp, "station %s deauthenticated" 1048 " by peer (reason %d)\n", 1049 ether_sprintf(ni->ni_macaddr), reason); 1050 ieee80211_free_node(ic, ni); 1051 } 1052 break; 1053 default: 1054 break; 1055 } 1056 break; 1057 } 1058 1059 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 1060 u_int16_t reason; 1061 /* 1062 * disassoc frame format 1063 * [2] reason 1064 */ 1065 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1066 reason = le16toh(*(u_int16_t *)frm); 1067 switch (ic->ic_opmode) { 1068 case IEEE80211_M_STA: 1069 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1070 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1071 break; 1072 case IEEE80211_M_HOSTAP: 1073 ni = ieee80211_find_node(ic, wh->i_addr2); 1074 if (ni != NULL) { 1075 if (ifp->if_flags & IFF_DEBUG) 1076 if_printf(ifp, "station %s disassociated" 1077 " by peer (reason %d)\n", 1078 ether_sprintf(ni->ni_macaddr), reason); 1079 ni->ni_associd = 0; 1080 ieee80211_unref_node(&ni); 1081 } 1082 break; 1083 default: 1084 break; 1085 } 1086 break; 1087 } 1088 default: 1089 IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not " 1090 "handled\n", __func__, subtype)); 1091 break; 1092 } 1093#undef ISPROBE 1094} 1095#undef IEEE80211_VERIFY_LENGTH 1096#undef IEEE80211_VERIFY_ELEMENT
|