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