1 /*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * Alternatively, this software may be distributed under the terms of the 18 * GNU General Public License ("GPL") version 2 as published by the Free 19 * Software Foundation. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include "opt_inet.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/mbuf.h> 41 #include <sys/malloc.h> 42 #include <sys/kernel.h> 43 #include <sys/socket.h> 44 #include <sys/sockio.h> 45 #include <sys/endian.h> 46 #include <sys/errno.h> 47 #include <sys/bus.h> 48 #include <sys/proc.h> 49 #include <sys/sysctl.h> 50 51 #include <machine/atomic.h> 52 53 #include <net/if.h> 54 #include <net/if_dl.h> 55 #include <net/if_media.h> 56 #include <net/if_arp.h> 57 #include <net/ethernet.h> 58 #include <net/if_llc.h> 59 60 #include <net80211/ieee80211_var.h> 61 62 #include <net/bpf.h> 63 64 #ifdef INET 65 #include <netinet/in.h> 66 #include <netinet/if_ether.h> 67 #endif 68 69 /* 70 * Process a received frame. The node associated with the sender 71 * should be supplied. If nothing was found in the node table then 72 * the caller is assumed to supply a reference to ic_bss instead. 73 * The RSSI and a timestamp are also supplied. The RSSI data is used 74 * during AP scanning to select a AP to associate with; it can have 75 * any units so long as values have consistent units and higher values 76 * mean ``better signal''. The receive timestamp is currently not used 77 * by the 802.11 layer. 78 */ 79 void 80 ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni, 81 int rssi, u_int32_t rstamp) 82 { 83 struct ieee80211com *ic = (void *)ifp; 84 struct ieee80211_frame *wh; 85 struct ether_header *eh; 86 struct mbuf *m1; 87 int len; 88 u_int8_t dir, type, subtype; 89 u_int8_t *bssid; 90 u_int16_t rxseq; 91 92 KASSERT(ni != NULL, ("null node")); 93 94 /* trim CRC here so WEP can find its own CRC at the end of packet. */ 95 if (m->m_flags & M_HASFCS) { 96 m_adj(m, -IEEE80211_CRC_LEN); 97 m->m_flags &= ~M_HASFCS; 98 } 99 KASSERT(m->m_pkthdr.len >= sizeof(struct ieee80211_frame_min), 100 ("frame length too short: %u", m->m_pkthdr.len)); 101 102 /* 103 * In monitor mode, send everything directly to bpf. 104 * XXX may want to include the CRC 105 */ 106 if (ic->ic_opmode == IEEE80211_M_MONITOR) 107 goto out; 108 109 wh = mtod(m, struct ieee80211_frame *); 110 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 111 IEEE80211_FC0_VERSION_0) { 112 if (ifp->if_flags & IFF_DEBUG) 113 if_printf(ifp, "receive packet with wrong version: %x\n", 114 wh->i_fc[0]); 115 ieee80211_unref_node(&ni); 116 goto err; 117 } 118 119 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 120 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 121 /* 122 * NB: We are not yet prepared to handle control frames, 123 * but permitting drivers to send them to us allows 124 * them to go through bpf tapping at the 802.11 layer. 125 */ 126 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { 127 /* XXX statistic */ 128 goto out; /* XXX */ 129 } 130 if (ic->ic_state != IEEE80211_S_SCAN) { 131 switch (ic->ic_opmode) { 132 case IEEE80211_M_STA: 133 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { 134 IEEE80211_DPRINTF2(("%s: discard frame from " 135 "bss %s\n", __func__, 136 ether_sprintf(wh->i_addr2))); 137 /* not interested in */ 138 goto out; 139 } 140 break; 141 case IEEE80211_M_IBSS: 142 case IEEE80211_M_AHDEMO: 143 case IEEE80211_M_HOSTAP: 144 if (dir == IEEE80211_FC1_DIR_NODS) 145 bssid = wh->i_addr3; 146 else 147 bssid = wh->i_addr1; 148 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) && 149 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { 150 /* not interested in */ 151 IEEE80211_DPRINTF2(("%s: other bss %s\n", 152 __func__, ether_sprintf(wh->i_addr3))); 153 goto out; 154 } 155 break; 156 case IEEE80211_M_MONITOR: 157 goto out; 158 default: 159 /* XXX catch bad values */ 160 break; 161 } 162 ni->ni_rssi = rssi; 163 ni->ni_rstamp = rstamp; 164 rxseq = ni->ni_rxseq; 165 ni->ni_rxseq = 166 le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; 167 /* TODO: fragment */ 168 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && 169 rxseq == ni->ni_rxseq) { 170 /* duplicate, silently discarded */ 171 goto out; 172 } 173 ni->ni_inact = 0; 174 } 175 176 switch (type) { 177 case IEEE80211_FC0_TYPE_DATA: 178 switch (ic->ic_opmode) { 179 case IEEE80211_M_STA: 180 if (dir != IEEE80211_FC1_DIR_FROMDS) 181 goto out; 182 if ((ifp->if_flags & IFF_SIMPLEX) && 183 IEEE80211_IS_MULTICAST(wh->i_addr1) && 184 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) { 185 /* 186 * In IEEE802.11 network, multicast packet 187 * sent from me is broadcasted from AP. 188 * It should be silently discarded for 189 * SIMPLEX interface. 190 */ 191 goto out; 192 } 193 break; 194 case IEEE80211_M_IBSS: 195 case IEEE80211_M_AHDEMO: 196 if (dir != IEEE80211_FC1_DIR_NODS) 197 goto out; 198 break; 199 case IEEE80211_M_HOSTAP: 200 if (dir != IEEE80211_FC1_DIR_TODS) 201 goto out; 202 /* check if source STA is associated */ 203 if (ni == ic->ic_bss) { 204 IEEE80211_DPRINTF(("%s: data from unknown src " 205 "%s\n", __func__, 206 ether_sprintf(wh->i_addr2))); 207 /* NB: caller deals with reference */ 208 ni = ieee80211_dup_bss(ic, wh->i_addr2); 209 if (ni != NULL) { 210 IEEE80211_SEND_MGMT(ic, ni, 211 IEEE80211_FC0_SUBTYPE_DEAUTH, 212 IEEE80211_REASON_NOT_AUTHED); 213 ieee80211_free_node(ic, ni); 214 } 215 goto err; 216 } 217 if (ni->ni_associd == 0) { 218 IEEE80211_DPRINTF(("ieee80211_input: " 219 "data from unassoc src %s\n", 220 ether_sprintf(wh->i_addr2))); 221 IEEE80211_SEND_MGMT(ic, ni, 222 IEEE80211_FC0_SUBTYPE_DISASSOC, 223 IEEE80211_REASON_NOT_ASSOCED); 224 ieee80211_unref_node(&ni); 225 goto err; 226 } 227 break; 228 case IEEE80211_M_MONITOR: 229 break; 230 } 231 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 232 if (ic->ic_flags & IEEE80211_F_WEPON) { 233 m = ieee80211_wep_crypt(ifp, m, 0); 234 if (m == NULL) 235 goto err; 236 wh = mtod(m, struct ieee80211_frame *); 237 } else 238 goto out; 239 } 240 /* copy to listener after decrypt */ 241 if (ic->ic_rawbpf) 242 bpf_mtap(ic->ic_rawbpf, m); 243 m = ieee80211_decap(ifp, m); 244 if (m == NULL) 245 goto err; 246 ifp->if_ipackets++; 247 248 /* perform as a bridge within the AP */ 249 m1 = NULL; 250 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 251 eh = mtod(m, struct ether_header *); 252 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 253 m1 = m_copypacket(m, M_DONTWAIT); 254 if (m1 == NULL) 255 ifp->if_oerrors++; 256 else 257 m1->m_flags |= M_MCAST; 258 } else { 259 ni = ieee80211_find_node(ic, eh->ether_dhost); 260 if (ni != NULL) { 261 if (ni->ni_associd != 0) { 262 m1 = m; 263 m = NULL; 264 } 265 ieee80211_unref_node(&ni); 266 } 267 } 268 if (m1 != NULL) { 269 #ifdef ALTQ 270 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 271 altq_etherclassify(&ifp->if_snd, m1, 272 &pktattr); 273 #endif 274 len = m1->m_pkthdr.len; 275 IF_ENQUEUE(&ifp->if_snd, m1); 276 if (m != NULL) 277 ifp->if_omcasts++; 278 ifp->if_obytes += len; 279 } 280 } 281 if (m != NULL) 282 (*ifp->if_input)(ifp, m); 283 return; 284 285 case IEEE80211_FC0_TYPE_MGT: 286 if (dir != IEEE80211_FC1_DIR_NODS) 287 goto err; 288 if (ic->ic_opmode == IEEE80211_M_AHDEMO) 289 goto out; 290 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 291 292 /* drop frames without interest */ 293 if (ic->ic_state == IEEE80211_S_SCAN) { 294 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON && 295 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) 296 goto out; 297 } else { 298 if (ic->ic_opmode != IEEE80211_M_IBSS && 299 subtype == IEEE80211_FC0_SUBTYPE_BEACON) 300 goto out; 301 } 302 303 if (ifp->if_flags & IFF_DEBUG) { 304 /* avoid to print too many frames */ 305 int doprint = 0; 306 307 switch (subtype) { 308 case IEEE80211_FC0_SUBTYPE_BEACON: 309 if (ic->ic_state == IEEE80211_S_SCAN) 310 doprint = 1; 311 break; 312 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 313 if (ic->ic_opmode == IEEE80211_M_IBSS) 314 doprint = 1; 315 break; 316 default: 317 doprint = 1; 318 break; 319 } 320 #ifdef IEEE80211_DEBUG 321 doprint += ieee80211_debug; 322 #endif 323 if (doprint) 324 if_printf(ifp, "received %s from %s rssi %d\n", 325 ieee80211_mgt_subtype_name[subtype 326 >> IEEE80211_FC0_SUBTYPE_SHIFT], 327 ether_sprintf(wh->i_addr2), rssi); 328 } 329 if (ic->ic_rawbpf) 330 bpf_mtap(ic->ic_rawbpf, m); 331 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 332 m_freem(m); 333 return; 334 335 case IEEE80211_FC0_TYPE_CTL: 336 goto out; 337 default: 338 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, type)); 339 /* should not come here */ 340 break; 341 } 342 err: 343 ifp->if_ierrors++; 344 out: 345 if (m != NULL) { 346 if (ic->ic_rawbpf) 347 bpf_mtap(ic->ic_rawbpf, m); 348 m_freem(m); 349 } 350 } 351 352 struct mbuf * 353 ieee80211_decap(struct ifnet *ifp, struct mbuf *m) 354 { 355 struct ether_header *eh; 356 struct ieee80211_frame wh; 357 struct llc *llc; 358 359 if (m->m_len < sizeof(wh) + sizeof(*llc)) { 360 m = m_pullup(m, sizeof(wh) + sizeof(*llc)); 361 if (m == NULL) 362 return NULL; 363 } 364 memcpy(&wh, mtod(m, caddr_t), sizeof(wh)); 365 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh)); 366 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 367 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 368 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 369 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh)); 370 llc = NULL; 371 } else { 372 m_adj(m, sizeof(wh) - sizeof(*eh)); 373 } 374 eh = mtod(m, struct ether_header *); 375 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 376 case IEEE80211_FC1_DIR_NODS: 377 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 378 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 379 break; 380 case IEEE80211_FC1_DIR_TODS: 381 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 382 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 383 break; 384 case IEEE80211_FC1_DIR_FROMDS: 385 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 386 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 387 break; 388 case IEEE80211_FC1_DIR_DSTODS: 389 /* not yet supported */ 390 IEEE80211_DPRINTF(("%s: DS to DS\n", __func__)); 391 m_freem(m); 392 return NULL; 393 } 394 #ifdef ALIGNED_POINTER 395 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) { 396 struct mbuf *n, *n0, **np; 397 caddr_t newdata; 398 int off, pktlen; 399 400 n0 = NULL; 401 np = &n0; 402 off = 0; 403 pktlen = m->m_pkthdr.len; 404 while (pktlen > off) { 405 if (n0 == NULL) { 406 MGETHDR(n, M_DONTWAIT, MT_DATA); 407 if (n == NULL) { 408 m_freem(m); 409 return NULL; 410 } 411 M_MOVE_PKTHDR(n, m); 412 n->m_len = MHLEN; 413 } else { 414 MGET(n, M_DONTWAIT, MT_DATA); 415 if (n == NULL) { 416 m_freem(m); 417 m_freem(n0); 418 return NULL; 419 } 420 n->m_len = MLEN; 421 } 422 if (pktlen - off >= MINCLSIZE) { 423 MCLGET(n, M_DONTWAIT); 424 if (n->m_flags & M_EXT) 425 n->m_len = n->m_ext.ext_size; 426 } 427 if (n0 == NULL) { 428 newdata = 429 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) - 430 sizeof(*eh); 431 n->m_len -= newdata - n->m_data; 432 n->m_data = newdata; 433 } 434 if (n->m_len > pktlen - off) 435 n->m_len = pktlen - off; 436 m_copydata(m, off, n->m_len, mtod(n, caddr_t)); 437 off += n->m_len; 438 *np = n; 439 np = &n->m_next; 440 } 441 m_freem(m); 442 m = n0; 443 } 444 #endif /* ALIGNED_POINTER */ 445 if (llc != NULL) { 446 eh = mtod(m, struct ether_header *); 447 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 448 } 449 return m; 450 } 451 452 /* 453 * Install received rate set information in the node's state block. 454 */ 455 static int 456 ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni, 457 u_int8_t *rates, u_int8_t *xrates, int flags) 458 { 459 struct ieee80211_rateset *rs = &ni->ni_rates; 460 461 memset(rs, 0, sizeof(*rs)); 462 rs->rs_nrates = rates[1]; 463 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 464 if (xrates != NULL) { 465 u_int8_t nxrates; 466 /* 467 * Tack on 11g extended supported rate element. 468 */ 469 nxrates = xrates[1]; 470 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 471 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 472 IEEE80211_DPRINTF(("%s: extended rate set too large;" 473 " only using %u of %u rates\n", 474 __func__, nxrates, xrates[1])); 475 } 476 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 477 rs->rs_nrates += nxrates; 478 } 479 return ieee80211_fix_rate(ic, ni, flags); 480 } 481 482 /* XXX statistics */ 483 /* Verify the existence and length of __elem or get out. */ 484 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 485 if ((__elem) == NULL) { \ 486 IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \ 487 __func__, ieee80211_mgt_subtype_name[subtype >> \ 488 IEEE80211_FC0_SUBTYPE_SHIFT])); \ 489 return; \ 490 } \ 491 if ((__elem)[1] > (__maxlen)) { \ 492 IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s " \ 493 "frame from %s\n", __func__, (__elem)[1], \ 494 ieee80211_mgt_subtype_name[subtype >> \ 495 IEEE80211_FC0_SUBTYPE_SHIFT], \ 496 ether_sprintf(wh->i_addr2))); \ 497 return; \ 498 } \ 499 } while (0) 500 501 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 502 if ((_len) < (_minlen)) { \ 503 IEEE80211_DPRINTF(("%s: %s frame too short from %s\n", \ 504 __func__, \ 505 ieee80211_mgt_subtype_name[subtype >> \ 506 IEEE80211_FC0_SUBTYPE_SHIFT], \ 507 ether_sprintf(wh->i_addr2))); \ 508 return; \ 509 } \ 510 } while (0) 511 512 void 513 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 514 struct ieee80211_node *ni, 515 int subtype, int rssi, u_int32_t rstamp) 516 { 517 #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 518 struct ifnet *ifp = &ic->ic_if; 519 struct ieee80211_frame *wh; 520 u_int8_t *frm, *efrm; 521 u_int8_t *ssid, *rates, *xrates; 522 int reassoc, resp, newassoc, allocbs; 523 524 wh = mtod(m0, struct ieee80211_frame *); 525 frm = (u_int8_t *)&wh[1]; 526 efrm = mtod(m0, u_int8_t *) + m0->m_len; 527 switch (subtype) { 528 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 529 case IEEE80211_FC0_SUBTYPE_BEACON: { 530 u_int8_t *tstamp, *bintval, *capinfo, *country; 531 u_int8_t chan, bchan, fhindex, erp; 532 u_int16_t fhdwell; 533 534 if (ic->ic_opmode != IEEE80211_M_IBSS && 535 ic->ic_state != IEEE80211_S_SCAN) { 536 /* XXX: may be useful for background scan */ 537 return; 538 } 539 540 /* 541 * beacon/probe response frame format 542 * [8] time stamp 543 * [2] beacon interval 544 * [2] capability information 545 * [tlv] ssid 546 * [tlv] supported rates 547 * [tlv] country information 548 * [tlv] parameter set (FH/DS) 549 * [tlv] erp information 550 * [tlv] extended supported rates 551 */ 552 IEEE80211_VERIFY_LENGTH(efrm - frm, 12); 553 tstamp = frm; frm += 8; 554 bintval = frm; frm += 2; 555 capinfo = frm; frm += 2; 556 ssid = rates = xrates = country = NULL; 557 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 558 chan = bchan; 559 fhdwell = 0; 560 fhindex = 0; 561 erp = 0; 562 while (frm < efrm) { 563 switch (*frm) { 564 case IEEE80211_ELEMID_SSID: 565 ssid = frm; 566 break; 567 case IEEE80211_ELEMID_RATES: 568 rates = frm; 569 break; 570 case IEEE80211_ELEMID_COUNTRY: 571 country = frm; 572 break; 573 case IEEE80211_ELEMID_FHPARMS: 574 if (ic->ic_phytype == IEEE80211_T_FH) { 575 fhdwell = (frm[3] << 8) | frm[2]; 576 chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 577 fhindex = frm[6]; 578 } 579 break; 580 case IEEE80211_ELEMID_DSPARMS: 581 /* 582 * XXX hack this since depending on phytype 583 * is problematic for multi-mode devices. 584 */ 585 if (ic->ic_phytype != IEEE80211_T_FH) 586 chan = frm[2]; 587 break; 588 case IEEE80211_ELEMID_TIM: 589 break; 590 case IEEE80211_ELEMID_XRATES: 591 xrates = frm; 592 break; 593 case IEEE80211_ELEMID_ERP: 594 if (frm[1] != 1) { 595 IEEE80211_DPRINTF(("%s: invalid ERP " 596 "element; length %u, expecting " 597 "1\n", __func__, frm[1])); 598 break; 599 } 600 erp = frm[2]; 601 break; 602 default: 603 IEEE80211_DPRINTF(("%s: element id %u/len %u " 604 "ignored\n", __func__, *frm, frm[1])); 605 break; 606 } 607 frm += frm[1] + 2; 608 } 609 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 610 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 611 if ( 612 #if IEEE80211_CHAN_MAX < 255 613 chan > IEEE80211_CHAN_MAX || 614 #endif 615 isclr(ic->ic_chan_active, chan)) { 616 IEEE80211_DPRINTF(("%s: ignore %s with invalid channel " 617 "%u\n", __func__, 618 ISPROBE(subtype) ? "probe response" : "beacon", 619 chan)); 620 return; 621 } 622 if (chan != bchan) { 623 /* 624 * Frame was received on a channel different from the 625 * one indicated in the DS/FH params element id; 626 * silently discard it. 627 * 628 * NB: this can happen due to signal leakage. 629 */ 630 IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked " 631 "for channel %u\n", __func__, 632 ISPROBE(subtype) ? "probe response" : "beacon", 633 bchan, chan)); 634 /* XXX statistic */ 635 return; 636 } 637 638 /* 639 * Use mac and channel for lookup so we collect all 640 * potential AP's when scanning. Otherwise we may 641 * see the same AP on multiple channels and will only 642 * record the last one. We could filter APs here based 643 * on rssi, etc. but leave that to the end of the scan 644 * so we can keep the selection criteria in one spot. 645 * This may result in a bloat of the scanned AP list but 646 * it shouldn't be too much. 647 */ 648 ni = ieee80211_lookup_node(ic, wh->i_addr2, 649 &ic->ic_channels[chan]); 650 #ifdef IEEE80211_DEBUG 651 if (ieee80211_debug && 652 (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) { 653 printf("%s: %s%s on chan %u (bss chan %u) ", 654 __func__, (ni == NULL ? "new " : ""), 655 ISPROBE(subtype) ? "probe response" : "beacon", 656 chan, bchan); 657 ieee80211_print_essid(ssid + 2, ssid[1]); 658 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 659 printf("%s: caps 0x%x bintval %u erp 0x%x\n", 660 __func__, le16toh(*(u_int16_t *)capinfo), 661 le16toh(*(u_int16_t *)bintval), erp); 662 if (country) 663 printf("%s: country info %*D\n", 664 __func__, country[1], country+2, " "); 665 } 666 #endif 667 if (ni == NULL) { 668 ni = ieee80211_alloc_node(ic, wh->i_addr2); 669 if (ni == NULL) 670 return; 671 ni->ni_esslen = ssid[1]; 672 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 673 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 674 } else if (ssid[1] != 0 && ISPROBE(subtype)) { 675 /* 676 * Update ESSID at probe response to adopt hidden AP by 677 * Lucent/Cisco, which announces null ESSID in beacon. 678 */ 679 ni->ni_esslen = ssid[1]; 680 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 681 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 682 } 683 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 684 ni->ni_rssi = rssi; 685 ni->ni_rstamp = rstamp; 686 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); 687 ni->ni_intval = le16toh(*(u_int16_t *)bintval); 688 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo); 689 /* XXX validate channel # */ 690 ni->ni_chan = &ic->ic_channels[chan]; 691 ni->ni_fhdwell = fhdwell; 692 ni->ni_fhindex = fhindex; 693 ni->ni_erp = erp; 694 /* NB: must be after ni_chan is setup */ 695 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); 696 ieee80211_unref_node(&ni); 697 break; 698 } 699 700 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: { 701 u_int8_t rate; 702 703 if (ic->ic_opmode == IEEE80211_M_STA) 704 return; 705 if (ic->ic_state != IEEE80211_S_RUN) 706 return; 707 708 /* 709 * prreq frame format 710 * [tlv] ssid 711 * [tlv] supported rates 712 * [tlv] extended supported rates 713 */ 714 ssid = rates = xrates = NULL; 715 while (frm < efrm) { 716 switch (*frm) { 717 case IEEE80211_ELEMID_SSID: 718 ssid = frm; 719 break; 720 case IEEE80211_ELEMID_RATES: 721 rates = frm; 722 break; 723 case IEEE80211_ELEMID_XRATES: 724 xrates = frm; 725 break; 726 } 727 frm += frm[1] + 2; 728 } 729 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 730 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 731 if (ssid[1] != 0 && 732 (ssid[1] != ic->ic_bss->ni_esslen || 733 memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) { 734 #ifdef IEEE80211_DEBUG 735 if (ieee80211_debug) { 736 printf("%s: ssid unmatch ", __func__); 737 ieee80211_print_essid(ssid + 2, ssid[1]); 738 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 739 } 740 #endif 741 return; 742 } 743 744 if (ni == ic->ic_bss) { 745 ni = ieee80211_dup_bss(ic, wh->i_addr2); 746 if (ni == NULL) 747 return; 748 IEEE80211_DPRINTF(("%s: new req from %s\n", 749 __func__, ether_sprintf(wh->i_addr2))); 750 allocbs = 1; 751 } else 752 allocbs = 0; 753 ni->ni_rssi = rssi; 754 ni->ni_rstamp = rstamp; 755 rate = ieee80211_setup_rates(ic, ni, rates, xrates, 756 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 757 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 758 if (rate & IEEE80211_RATE_BASIC) { 759 IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n", 760 __func__,ether_sprintf(wh->i_addr2))); 761 } else { 762 IEEE80211_SEND_MGMT(ic, ni, 763 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0); 764 } 765 if (allocbs) { 766 /* XXX just use free? */ 767 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 768 ieee80211_free_node(ic, ni); 769 else 770 ieee80211_unref_node(&ni); 771 } 772 break; 773 } 774 775 case IEEE80211_FC0_SUBTYPE_AUTH: { 776 u_int16_t algo, seq, status; 777 /* 778 * auth frame format 779 * [2] algorithm 780 * [2] sequence 781 * [2] status 782 * [tlv*] challenge 783 */ 784 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 785 algo = le16toh(*(u_int16_t *)frm); 786 seq = le16toh(*(u_int16_t *)(frm + 2)); 787 status = le16toh(*(u_int16_t *)(frm + 4)); 788 if (algo != IEEE80211_AUTH_ALG_OPEN) { 789 /* TODO: shared key auth */ 790 IEEE80211_DPRINTF(("%s: unsupported auth %d from %s\n", 791 __func__, algo, ether_sprintf(wh->i_addr2))); 792 return; 793 } 794 switch (ic->ic_opmode) { 795 case IEEE80211_M_IBSS: 796 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 797 return; 798 ieee80211_new_state(ic, IEEE80211_S_AUTH, 799 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 800 break; 801 802 case IEEE80211_M_AHDEMO: 803 /* should not come here */ 804 break; 805 806 case IEEE80211_M_HOSTAP: 807 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 808 return; 809 if (ni == ic->ic_bss) { 810 ni = ieee80211_alloc_node(ic, wh->i_addr2); 811 if (ni == NULL) 812 return; 813 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 814 ni->ni_rssi = rssi; 815 ni->ni_rstamp = rstamp; 816 ni->ni_chan = ic->ic_bss->ni_chan; 817 allocbs = 1; 818 } else 819 allocbs = 0; 820 IEEE80211_SEND_MGMT(ic, ni, 821 IEEE80211_FC0_SUBTYPE_AUTH, 2); 822 if (ifp->if_flags & IFF_DEBUG) 823 if_printf(ifp, "station %s %s authenticated\n", 824 (allocbs ? "newly" : "already"), 825 ether_sprintf(ni->ni_macaddr)); 826 break; 827 828 case IEEE80211_M_STA: 829 if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) 830 return; 831 if (status != 0) { 832 if_printf(&ic->ic_if, 833 "authentication failed (reason %d) for %s\n", 834 status, 835 ether_sprintf(wh->i_addr3)); 836 if (ni != ic->ic_bss) 837 ni->ni_fails++; 838 return; 839 } 840 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 841 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 842 break; 843 case IEEE80211_M_MONITOR: 844 break; 845 } 846 break; 847 } 848 849 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 850 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { 851 u_int16_t capinfo, bintval; 852 853 if (ic->ic_opmode != IEEE80211_M_HOSTAP || 854 (ic->ic_state != IEEE80211_S_RUN)) 855 return; 856 857 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 858 reassoc = 1; 859 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 860 } else { 861 reassoc = 0; 862 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 863 } 864 /* 865 * asreq frame format 866 * [2] capability information 867 * [2] listen interval 868 * [6*] current AP address (reassoc only) 869 * [tlv] ssid 870 * [tlv] supported rates 871 * [tlv] extended supported rates 872 */ 873 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 874 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 875 IEEE80211_DPRINTF(("%s: ignore other bss from %s\n", 876 __func__, ether_sprintf(wh->i_addr2))); 877 return; 878 } 879 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 880 bintval = le16toh(*(u_int16_t *)frm); frm += 2; 881 if (reassoc) 882 frm += 6; /* ignore current AP info */ 883 ssid = rates = xrates = NULL; 884 while (frm < efrm) { 885 switch (*frm) { 886 case IEEE80211_ELEMID_SSID: 887 ssid = frm; 888 break; 889 case IEEE80211_ELEMID_RATES: 890 rates = frm; 891 break; 892 case IEEE80211_ELEMID_XRATES: 893 xrates = frm; 894 break; 895 } 896 frm += frm[1] + 2; 897 } 898 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 899 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 900 if (ssid[1] != ic->ic_bss->ni_esslen || 901 memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) { 902 #ifdef IEEE80211_DEBUG 903 if (ieee80211_debug) { 904 printf("%s: ssid unmatch ", __func__); 905 ieee80211_print_essid(ssid + 2, ssid[1]); 906 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 907 } 908 #endif 909 return; 910 } 911 if (ni == ic->ic_bss) { 912 IEEE80211_DPRINTF(("%s: not authenticated for %s\n", 913 __func__, ether_sprintf(wh->i_addr2))); 914 ni = ieee80211_dup_bss(ic, wh->i_addr2); 915 if (ni != NULL) { 916 IEEE80211_SEND_MGMT(ic, ni, 917 IEEE80211_FC0_SUBTYPE_DEAUTH, 918 IEEE80211_REASON_ASSOC_NOT_AUTHED); 919 ieee80211_free_node(ic, ni); 920 } 921 return; 922 } 923 /* XXX per-node cipher suite */ 924 /* XXX some stations use the privacy bit for handling APs 925 that suport both encrypted and unencrypted traffic */ 926 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 927 (capinfo & IEEE80211_CAPINFO_PRIVACY) != 928 ((ic->ic_flags & IEEE80211_F_WEPON) ? 929 IEEE80211_CAPINFO_PRIVACY : 0)) { 930 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n", 931 __func__, capinfo, ether_sprintf(wh->i_addr2))); 932 ni->ni_associd = 0; 933 IEEE80211_SEND_MGMT(ic, ni, resp, 934 IEEE80211_STATUS_CAPINFO); 935 return; 936 } 937 ieee80211_setup_rates(ic, ni, rates, xrates, 938 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 939 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 940 if (ni->ni_rates.rs_nrates == 0) { 941 IEEE80211_DPRINTF(("%s: rate unmatch for %s\n", 942 __func__, ether_sprintf(wh->i_addr2))); 943 ni->ni_associd = 0; 944 IEEE80211_SEND_MGMT(ic, ni, resp, 945 IEEE80211_STATUS_BASIC_RATE); 946 return; 947 } 948 ni->ni_rssi = rssi; 949 ni->ni_rstamp = rstamp; 950 ni->ni_intval = bintval; 951 ni->ni_capinfo = capinfo; 952 ni->ni_chan = ic->ic_bss->ni_chan; 953 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 954 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 955 if (ni->ni_associd == 0) { 956 /* XXX handle rollover at 2007 */ 957 /* XXX guarantee uniqueness */ 958 ni->ni_associd = 0xc000 | ic->ic_bss->ni_associd++; 959 newassoc = 1; 960 } else 961 newassoc = 0; 962 /* XXX for 11g must turn off short slot time if long 963 slot time sta associates */ 964 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); 965 if (ifp->if_flags & IFF_DEBUG) 966 if_printf(ifp, "station %s %s associated\n", 967 (newassoc ? "newly" : "already"), 968 ether_sprintf(ni->ni_macaddr)); 969 /* give driver a chance to setup state like ni_txrate */ 970 if (ic->ic_newassoc) 971 (*ic->ic_newassoc)(ic, ni, newassoc); 972 break; 973 } 974 975 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 976 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 977 u_int16_t status; 978 979 if (ic->ic_opmode != IEEE80211_M_STA || 980 ic->ic_state != IEEE80211_S_ASSOC) 981 return; 982 983 /* 984 * asresp frame format 985 * [2] capability information 986 * [2] status 987 * [2] association ID 988 * [tlv] supported rates 989 * [tlv] extended supported rates 990 */ 991 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 992 ni = ic->ic_bss; 993 ni->ni_capinfo = le16toh(*(u_int16_t *)frm); 994 frm += 2; 995 996 status = le16toh(*(u_int16_t *)frm); 997 frm += 2; 998 if (status != 0) { 999 if_printf(ifp, "association failed (reason %d) for %s\n", 1000 status, ether_sprintf(wh->i_addr3)); 1001 if (ni != ic->ic_bss) 1002 ni->ni_fails++; 1003 return; 1004 } 1005 ni->ni_associd = le16toh(*(u_int16_t *)frm); 1006 frm += 2; 1007 1008 rates = xrates = NULL; 1009 while (frm < efrm) { 1010 switch (*frm) { 1011 case IEEE80211_ELEMID_RATES: 1012 rates = frm; 1013 break; 1014 case IEEE80211_ELEMID_XRATES: 1015 xrates = frm; 1016 break; 1017 } 1018 frm += frm[1] + 2; 1019 } 1020 1021 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 1022 ieee80211_setup_rates(ic, ni, rates, xrates, 1023 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 1024 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 1025 if (ni->ni_rates.rs_nrates != 0) 1026 ieee80211_new_state(ic, IEEE80211_S_RUN, 1027 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1028 break; 1029 } 1030 1031 case IEEE80211_FC0_SUBTYPE_DEAUTH: { 1032 u_int16_t reason; 1033 /* 1034 * deauth frame format 1035 * [2] reason 1036 */ 1037 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1038 reason = le16toh(*(u_int16_t *)frm); 1039 switch (ic->ic_opmode) { 1040 case IEEE80211_M_STA: 1041 ieee80211_new_state(ic, IEEE80211_S_AUTH, 1042 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1043 break; 1044 case IEEE80211_M_HOSTAP: 1045 if (ni != ic->ic_bss) { 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 /* node will be free'd on return */ 1051 ieee80211_unref_node(&ni); 1052 } 1053 break; 1054 default: 1055 break; 1056 } 1057 break; 1058 } 1059 1060 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 1061 u_int16_t reason; 1062 /* 1063 * disassoc frame format 1064 * [2] reason 1065 */ 1066 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1067 reason = le16toh(*(u_int16_t *)frm); 1068 switch (ic->ic_opmode) { 1069 case IEEE80211_M_STA: 1070 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1071 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1072 break; 1073 case IEEE80211_M_HOSTAP: 1074 if (ni != ic->ic_bss) { 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 /* XXX node reclaimed how? */ 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 1097