1 /* $NetBSD: ieee80211_input.c,v 1.24 2004/05/31 11:12:24 dyoung Exp $ */ 2 /*- 3 * Copyright (c) 2001 Atsushi Onoe 4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * Alternatively, this software may be distributed under the terms of the 19 * GNU General Public License ("GPL") version 2 as published by the Free 20 * Software Foundation. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 #ifdef __FreeBSD__ 36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.20 2004/04/02 23:35:24 sam Exp $"); 37 #else 38 __KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.24 2004/05/31 11:12:24 dyoung Exp $"); 39 #endif 40 41 #include "opt_inet.h" 42 43 #ifdef __NetBSD__ 44 #include "bpfilter.h" 45 #endif /* __NetBSD__ */ 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/mbuf.h> 50 #include <sys/malloc.h> 51 #include <sys/kernel.h> 52 #include <sys/socket.h> 53 #include <sys/sockio.h> 54 #include <sys/endian.h> 55 #include <sys/errno.h> 56 #ifdef __FreeBSD__ 57 #include <sys/bus.h> 58 #endif 59 #include <sys/proc.h> 60 #include <sys/sysctl.h> 61 62 #ifdef __FreeBSD__ 63 #include <machine/atomic.h> 64 #endif 65 66 #include <net/if.h> 67 #include <net/if_dl.h> 68 #include <net/if_media.h> 69 #include <net/if_arp.h> 70 #ifdef __FreeBSD__ 71 #include <net/ethernet.h> 72 #else 73 #include <net/if_ether.h> 74 #endif 75 #include <net/if_llc.h> 76 77 #include <net80211/ieee80211_var.h> 78 #include <net80211/ieee80211_compat.h> 79 80 #if NBPFILTER > 0 81 #include <net/bpf.h> 82 #endif 83 84 #ifdef INET 85 #include <netinet/in.h> 86 #ifdef __FreeBSD__ 87 #include <netinet/if_ether.h> 88 #else 89 #include <net/if_ether.h> 90 #endif 91 #endif 92 93 static void ieee80211_recv_pspoll(struct ieee80211com *, 94 struct mbuf *, int, u_int32_t); 95 96 /* 97 * Process a received frame. The node associated with the sender 98 * should be supplied. If nothing was found in the node table then 99 * the caller is assumed to supply a reference to ic_bss instead. 100 * The RSSI and a timestamp are also supplied. The RSSI data is used 101 * during AP scanning to select a AP to associate with; it can have 102 * any units so long as values have consistent units and higher values 103 * mean ``better signal''. The receive timestamp is currently not used 104 * by the 802.11 layer. 105 */ 106 void 107 ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni, 108 int rssi, u_int32_t rstamp) 109 { 110 struct ieee80211com *ic = (void *)ifp; 111 struct ieee80211_frame *wh; 112 struct ether_header *eh; 113 struct mbuf *m1; 114 int len; 115 u_int8_t dir, type, subtype; 116 u_int8_t *bssid; 117 u_int16_t rxseq; 118 ALTQ_DECL(struct altq_pktattr pktattr;) 119 120 IASSERT(ni != NULL, ("null node")); 121 122 /* trim CRC here so WEP can find its own CRC at the end of packet. */ 123 if (m->m_flags & M_HASFCS) { 124 m_adj(m, -IEEE80211_CRC_LEN); 125 m->m_flags &= ~M_HASFCS; 126 } 127 128 /* 129 * In monitor mode, send everything directly to bpf. 130 * Also do not process frames w/o i_addr2 any further. 131 * XXX may want to include the CRC 132 */ 133 if (ic->ic_opmode == IEEE80211_M_MONITOR || 134 m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) 135 goto out; 136 137 wh = mtod(m, struct ieee80211_frame *); 138 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 139 IEEE80211_FC0_VERSION_0) { 140 if (ifp->if_flags & IFF_DEBUG) 141 if_printf(ifp, "receive packet with wrong version: %x\n", 142 wh->i_fc[0]); 143 ic->ic_stats.is_rx_badversion++; 144 goto err; 145 } 146 147 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 148 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 149 /* 150 * NB: We are not yet prepared to handle control frames, 151 * but permitting drivers to send them to us allows 152 * them to go through bpf tapping at the 802.11 layer. 153 */ 154 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { 155 /* XXX statistic */ 156 IEEE80211_DPRINTF2(("%s: frame too short, len %u\n", 157 __func__, m->m_pkthdr.len)); 158 ic->ic_stats.is_rx_tooshort++; 159 goto out; /* XXX */ 160 } 161 if (ic->ic_state != IEEE80211_S_SCAN) { 162 switch (ic->ic_opmode) { 163 case IEEE80211_M_STA: 164 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { 165 /* not interested in */ 166 IEEE80211_DPRINTF2(("%s: discard frame from " 167 "bss %s\n", __func__, 168 ether_sprintf(wh->i_addr2))); 169 ic->ic_stats.is_rx_wrongbss++; 170 goto out; 171 } 172 break; 173 case IEEE80211_M_IBSS: 174 case IEEE80211_M_AHDEMO: 175 case IEEE80211_M_HOSTAP: 176 if (dir == IEEE80211_FC1_DIR_NODS) 177 bssid = wh->i_addr3; 178 else 179 bssid = wh->i_addr1; 180 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) && 181 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr) && 182 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 183 IEEE80211_FC0_TYPE_DATA) { 184 /* not interested in */ 185 IEEE80211_DPRINTF2(("%s: discard frame from " 186 "bss %s\n", __func__, 187 ether_sprintf(bssid))); 188 ic->ic_stats.is_rx_wrongbss++; 189 goto out; 190 } 191 break; 192 case IEEE80211_M_MONITOR: 193 goto out; 194 default: 195 /* XXX catch bad values */ 196 break; 197 } 198 ni->ni_rssi = rssi; 199 ni->ni_rstamp = rstamp; 200 rxseq = ni->ni_rxseq; 201 ni->ni_rxseq = 202 le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; 203 /* TODO: fragment */ 204 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && 205 rxseq == ni->ni_rxseq) { 206 /* duplicate, silently discarded */ 207 ic->ic_stats.is_rx_dup++; /* XXX per-station stat */ 208 goto out; 209 } 210 ni->ni_inact = 0; 211 } 212 213 if (ic->ic_set_tim != NULL && 214 (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) 215 && ni->ni_pwrsave == 0) { 216 /* turn on power save mode */ 217 218 if (ifp->if_flags & IFF_DEBUG) 219 printf("%s: power save mode on for %s\n", 220 ifp->if_xname, ether_sprintf(wh->i_addr2)); 221 222 ni->ni_pwrsave = IEEE80211_PS_SLEEP; 223 } 224 if (ic->ic_set_tim != NULL && 225 (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) == 0 && 226 ni->ni_pwrsave != 0) { 227 /* turn off power save mode, dequeue stored packets */ 228 229 ni->ni_pwrsave = 0; 230 if (ic->ic_set_tim) 231 ic->ic_set_tim(ic, ni->ni_associd, 0); 232 233 if (ifp->if_flags & IFF_DEBUG) 234 printf("%s: power save mode off for %s\n", 235 ifp->if_xname, ether_sprintf(wh->i_addr2)); 236 237 while (!IF_IS_EMPTY(&ni->ni_savedq)) { 238 struct mbuf *m; 239 IF_DEQUEUE(&ni->ni_savedq, m); 240 IF_ENQUEUE(&ic->ic_pwrsaveq, m); 241 (*ifp->if_start)(ifp); 242 } 243 } 244 245 switch (type) { 246 case IEEE80211_FC0_TYPE_DATA: 247 switch (ic->ic_opmode) { 248 case IEEE80211_M_STA: 249 if (dir != IEEE80211_FC1_DIR_FROMDS) { 250 ic->ic_stats.is_rx_wrongdir++; 251 goto out; 252 } 253 if ((ifp->if_flags & IFF_SIMPLEX) && 254 IEEE80211_IS_MULTICAST(wh->i_addr1) && 255 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) { 256 /* 257 * In IEEE802.11 network, multicast packet 258 * sent from me is broadcasted from AP. 259 * It should be silently discarded for 260 * SIMPLEX interface. 261 */ 262 ic->ic_stats.is_rx_mcastecho++; 263 goto out; 264 } 265 break; 266 case IEEE80211_M_IBSS: 267 case IEEE80211_M_AHDEMO: 268 if (dir != IEEE80211_FC1_DIR_NODS) { 269 ic->ic_stats.is_rx_wrongdir++; 270 goto out; 271 } 272 break; 273 case IEEE80211_M_HOSTAP: 274 if (dir != IEEE80211_FC1_DIR_TODS) { 275 ic->ic_stats.is_rx_wrongdir++; 276 goto out; 277 } 278 /* check if source STA is associated */ 279 if (ni == ic->ic_bss) { 280 IEEE80211_DPRINTF(("%s: data from unknown src " 281 "%s\n", __func__, 282 ether_sprintf(wh->i_addr2))); 283 /* NB: caller deals with reference */ 284 ni = ieee80211_dup_bss(ic, wh->i_addr2); 285 if (ni != NULL) { 286 IEEE80211_SEND_MGMT(ic, ni, 287 IEEE80211_FC0_SUBTYPE_DEAUTH, 288 IEEE80211_REASON_NOT_AUTHED); 289 ieee80211_free_node(ic, ni); 290 } 291 ic->ic_stats.is_rx_notassoc++; 292 goto err; 293 } 294 if (ni->ni_associd == 0) { 295 IEEE80211_DPRINTF(("ieee80211_input: " 296 "data from unassoc src %s\n", 297 ether_sprintf(wh->i_addr2))); 298 IEEE80211_SEND_MGMT(ic, ni, 299 IEEE80211_FC0_SUBTYPE_DISASSOC, 300 IEEE80211_REASON_NOT_ASSOCED); 301 ieee80211_unref_node(&ni); 302 ic->ic_stats.is_rx_notassoc++; 303 goto err; 304 } 305 break; 306 case IEEE80211_M_MONITOR: 307 break; 308 } 309 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 310 if (ic->ic_flags & IEEE80211_F_WEPON) { 311 m = ieee80211_wep_crypt(ifp, m, 0); 312 if (m == NULL) { 313 ic->ic_stats.is_rx_wepfail++; 314 goto err; 315 } 316 wh = mtod(m, struct ieee80211_frame *); 317 } else { 318 ic->ic_stats.is_rx_nowep++; 319 goto out; 320 } 321 } 322 #if NBPFILTER > 0 323 /* copy to listener after decrypt */ 324 if (ic->ic_rawbpf) 325 bpf_mtap(ic->ic_rawbpf, m); 326 #endif 327 m = ieee80211_decap(ifp, m); 328 if (m == NULL) { 329 IEEE80211_DPRINTF(("ieee80211_input: " 330 "decapsulation error for src %s\n", 331 ether_sprintf(wh->i_addr2))); 332 ic->ic_stats.is_rx_decap++; 333 goto err; 334 } 335 ifp->if_ipackets++; 336 337 /* perform as a bridge within the AP */ 338 m1 = NULL; 339 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 340 eh = mtod(m, struct ether_header *); 341 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 342 m1 = m_copypacket(m, M_DONTWAIT); 343 if (m1 == NULL) 344 ifp->if_oerrors++; 345 else 346 m1->m_flags |= M_MCAST; 347 } else { 348 ni = ieee80211_find_node(ic, eh->ether_dhost); 349 if (ni != NULL) { 350 if (ni->ni_associd != 0) { 351 m1 = m; 352 m = NULL; 353 } 354 ieee80211_free_node(ic, ni); 355 } 356 } 357 if (m1 != NULL) { 358 #ifdef ALTQ 359 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 360 altq_etherclassify(&ifp->if_snd, m1, 361 &pktattr); 362 #endif 363 len = m1->m_pkthdr.len; 364 IF_ENQUEUE(&ifp->if_snd, m1); 365 if (m != NULL) 366 ifp->if_omcasts++; 367 ifp->if_obytes += len; 368 } 369 } 370 if (m != NULL) { 371 #if NBPFILTER > 0 372 /* 373 * If we forward packet into transmitter of the AP, 374 * we don't need to duplicate for DLT_EN10MB. 375 */ 376 if (ifp->if_bpf && m1 == NULL) 377 bpf_mtap(ifp->if_bpf, m); 378 #endif 379 (*ifp->if_input)(ifp, m); 380 } 381 return; 382 383 case IEEE80211_FC0_TYPE_MGT: 384 if (dir != IEEE80211_FC1_DIR_NODS) { 385 ic->ic_stats.is_rx_wrongdir++; 386 goto err; 387 } 388 if (ic->ic_opmode == IEEE80211_M_AHDEMO) { 389 ic->ic_stats.is_rx_ahdemo_mgt++; 390 goto out; 391 } 392 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 393 394 /* drop frames without interest */ 395 if (ic->ic_state == IEEE80211_S_SCAN) { 396 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON && 397 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) { 398 ic->ic_stats.is_rx_mgtdiscard++; 399 goto out; 400 } 401 } else { 402 if (ic->ic_opmode != IEEE80211_M_IBSS && 403 subtype == IEEE80211_FC0_SUBTYPE_BEACON) { 404 ic->ic_stats.is_rx_mgtdiscard++; 405 goto out; 406 } 407 } 408 409 if (ifp->if_flags & IFF_DEBUG) { 410 /* avoid to print too many frames */ 411 int doprint = 0; 412 413 switch (subtype) { 414 case IEEE80211_FC0_SUBTYPE_BEACON: 415 if (ic->ic_state == IEEE80211_S_SCAN) 416 doprint = 1; 417 break; 418 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 419 if (ic->ic_opmode == IEEE80211_M_IBSS) 420 doprint = 1; 421 break; 422 default: 423 doprint = 1; 424 break; 425 } 426 #ifdef IEEE80211_DEBUG 427 doprint += ieee80211_debug; 428 #endif 429 if (doprint) 430 if_printf(ifp, "received %s from %s rssi %d\n", 431 ieee80211_mgt_subtype_name[subtype 432 >> IEEE80211_FC0_SUBTYPE_SHIFT], 433 ether_sprintf(wh->i_addr2), rssi); 434 } 435 #if NBPFILTER > 0 436 if (ic->ic_rawbpf) 437 bpf_mtap(ic->ic_rawbpf, m); 438 #endif 439 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 440 m_freem(m); 441 return; 442 443 case IEEE80211_FC0_TYPE_CTL: 444 ic->ic_stats.is_rx_ctl++; 445 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 446 goto out; 447 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 448 if (subtype == IEEE80211_FC0_SUBTYPE_PS_POLL) { 449 /* XXX statistic */ 450 /* Dump out a single packet from the host */ 451 if (ifp->if_flags & IFF_DEBUG) 452 printf("%s: got power save probe from %s\n", 453 ifp->if_xname, 454 ether_sprintf(wh->i_addr2)); 455 ieee80211_recv_pspoll(ic, m, rssi, rstamp); 456 } 457 goto out; 458 459 default: 460 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, type)); 461 /* should not come here */ 462 break; 463 } 464 err: 465 ifp->if_ierrors++; 466 out: 467 if (m != NULL) { 468 #if NBPFILTER > 0 469 if (ic->ic_rawbpf) 470 bpf_mtap(ic->ic_rawbpf, m); 471 #endif 472 m_freem(m); 473 } 474 } 475 476 struct mbuf * 477 ieee80211_decap(struct ifnet *ifp, struct mbuf *m) 478 { 479 struct ether_header *eh; 480 struct ieee80211_frame wh; 481 struct llc *llc; 482 483 if (m->m_len < sizeof(wh) + sizeof(*llc)) { 484 m = m_pullup(m, sizeof(wh) + sizeof(*llc)); 485 if (m == NULL) 486 return NULL; 487 } 488 memcpy(&wh, mtod(m, caddr_t), sizeof(wh)); 489 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh)); 490 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 491 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 492 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 493 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh)); 494 llc = NULL; 495 } else { 496 m_adj(m, sizeof(wh) - sizeof(*eh)); 497 } 498 eh = mtod(m, struct ether_header *); 499 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 500 case IEEE80211_FC1_DIR_NODS: 501 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 502 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 503 break; 504 case IEEE80211_FC1_DIR_TODS: 505 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 506 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 507 break; 508 case IEEE80211_FC1_DIR_FROMDS: 509 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 510 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 511 break; 512 case IEEE80211_FC1_DIR_DSTODS: 513 /* not yet supported */ 514 IEEE80211_DPRINTF(("%s: DS to DS\n", __func__)); 515 m_freem(m); 516 return NULL; 517 } 518 #ifdef ALIGNED_POINTER 519 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) { 520 struct mbuf *n, *n0, **np; 521 caddr_t newdata; 522 int off, pktlen; 523 524 n0 = NULL; 525 np = &n0; 526 off = 0; 527 pktlen = m->m_pkthdr.len; 528 while (pktlen > off) { 529 if (n0 == NULL) { 530 MGETHDR(n, M_DONTWAIT, MT_DATA); 531 if (n == NULL) { 532 m_freem(m); 533 return NULL; 534 } 535 #ifdef __FreeBSD__ 536 M_MOVE_PKTHDR(n, m); 537 #else 538 M_COPY_PKTHDR(n, m); 539 #endif 540 n->m_len = MHLEN; 541 } else { 542 MGET(n, M_DONTWAIT, MT_DATA); 543 if (n == NULL) { 544 m_freem(m); 545 m_freem(n0); 546 return NULL; 547 } 548 n->m_len = MLEN; 549 } 550 if (pktlen - off >= MINCLSIZE) { 551 MCLGET(n, M_DONTWAIT); 552 if (n->m_flags & M_EXT) 553 n->m_len = n->m_ext.ext_size; 554 } 555 if (n0 == NULL) { 556 newdata = 557 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) - 558 sizeof(*eh); 559 n->m_len -= newdata - n->m_data; 560 n->m_data = newdata; 561 } 562 if (n->m_len > pktlen - off) 563 n->m_len = pktlen - off; 564 m_copydata(m, off, n->m_len, mtod(n, caddr_t)); 565 off += n->m_len; 566 *np = n; 567 np = &n->m_next; 568 } 569 m_freem(m); 570 m = n0; 571 } 572 #endif /* ALIGNED_POINTER */ 573 if (llc != NULL) { 574 eh = mtod(m, struct ether_header *); 575 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 576 } 577 return m; 578 } 579 580 /* 581 * Install received rate set information in the node's state block. 582 */ 583 static int 584 ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni, 585 u_int8_t *rates, u_int8_t *xrates, int flags) 586 { 587 struct ieee80211_rateset *rs = &ni->ni_rates; 588 589 memset(rs, 0, sizeof(*rs)); 590 rs->rs_nrates = rates[1]; 591 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 592 if (xrates != NULL) { 593 u_int8_t nxrates; 594 /* 595 * Tack on 11g extended supported rate element. 596 */ 597 nxrates = xrates[1]; 598 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 599 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 600 IEEE80211_DPRINTF(("%s: extended rate set too large;" 601 " only using %u of %u rates\n", 602 __func__, nxrates, xrates[1])); 603 ic->ic_stats.is_rx_rstoobig++; 604 } 605 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 606 rs->rs_nrates += nxrates; 607 } 608 return ieee80211_fix_rate(ic, ni, flags); 609 } 610 611 /* Verify the existence and length of __elem or get out. */ 612 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 613 if ((__elem) == NULL) { \ 614 IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \ 615 __func__, ieee80211_mgt_subtype_name[subtype >> \ 616 IEEE80211_FC0_SUBTYPE_SHIFT])); \ 617 ic->ic_stats.is_rx_elem_missing++; \ 618 return; \ 619 } \ 620 if ((__elem)[1] > (__maxlen)) { \ 621 IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s " \ 622 "frame from %s\n", __func__, (__elem)[1], \ 623 ieee80211_mgt_subtype_name[subtype >> \ 624 IEEE80211_FC0_SUBTYPE_SHIFT], \ 625 ether_sprintf(wh->i_addr2))); \ 626 ic->ic_stats.is_rx_elem_toobig++; \ 627 return; \ 628 } \ 629 } while (0) 630 631 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 632 if ((_len) < (_minlen)) { \ 633 IEEE80211_DPRINTF(("%s: %s frame too short from %s\n", \ 634 __func__, \ 635 ieee80211_mgt_subtype_name[subtype >> \ 636 IEEE80211_FC0_SUBTYPE_SHIFT], \ 637 ether_sprintf(wh->i_addr2))); \ 638 ic->ic_stats.is_rx_elem_toosmall++; \ 639 return; \ 640 } \ 641 } while (0) 642 643 static void 644 ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh, 645 struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq, 646 u_int16_t status) 647 { 648 struct ifnet *ifp = &ic->ic_if; 649 int allocbs; 650 switch (ic->ic_opmode) { 651 case IEEE80211_M_IBSS: 652 if (ic->ic_state != IEEE80211_S_RUN || 653 seq != IEEE80211_AUTH_OPEN_REQUEST) { 654 IEEE80211_DPRINTF(("%s: discard auth from %s; " 655 "state %u, seq %u\n", __func__, 656 ether_sprintf(wh->i_addr2), 657 ic->ic_state, seq)); 658 ic->ic_stats.is_rx_bad_auth++; 659 return; 660 } 661 ieee80211_new_state(ic, IEEE80211_S_AUTH, 662 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 663 break; 664 665 case IEEE80211_M_AHDEMO: 666 /* should not come here */ 667 break; 668 669 case IEEE80211_M_HOSTAP: 670 if (ic->ic_state != IEEE80211_S_RUN || 671 seq != IEEE80211_AUTH_OPEN_REQUEST) { 672 IEEE80211_DPRINTF(("%s: discard auth from %s; " 673 "state %u, seq %u\n", __func__, 674 ether_sprintf(wh->i_addr2), 675 ic->ic_state, seq)); 676 ic->ic_stats.is_rx_bad_auth++; 677 return; 678 } 679 if (ni == ic->ic_bss) { 680 ni = ieee80211_alloc_node(ic, wh->i_addr2); 681 if (ni == NULL) { 682 ic->ic_stats.is_rx_nodealloc++; 683 return; 684 } 685 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 686 ni->ni_rssi = rssi; 687 ni->ni_rstamp = rstamp; 688 ni->ni_chan = ic->ic_bss->ni_chan; 689 allocbs = 1; 690 } else 691 allocbs = 0; 692 IEEE80211_SEND_MGMT(ic, ni, 693 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 694 if (ifp->if_flags & IFF_DEBUG) 695 if_printf(ifp, "station %s %s authenticated (open)\n", 696 ether_sprintf(ni->ni_macaddr), 697 (allocbs ? "newly" : "already")); 698 break; 699 case IEEE80211_M_STA: 700 if (ic->ic_state != IEEE80211_S_AUTH || 701 seq != IEEE80211_AUTH_OPEN_RESPONSE) { 702 ic->ic_stats.is_rx_bad_auth++; 703 IEEE80211_DPRINTF(("%s: discard auth from %s; " 704 "state %u, seq %u\n", __func__, 705 ether_sprintf(wh->i_addr2), 706 ic->ic_state, seq)); 707 return; 708 } 709 if (status != 0) { 710 if_printf(&ic->ic_if, 711 "open authentication failed (reason %d) for %s\n", 712 status, 713 ether_sprintf(wh->i_addr3)); 714 if (ni != ic->ic_bss) 715 ni->ni_fails++; 716 ic->ic_stats.is_rx_auth_fail++; 717 return; 718 } 719 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 720 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 721 break; 722 case IEEE80211_M_MONITOR: 723 break; 724 } 725 } 726 727 /* TBD send appropriate responses on error? */ 728 static void 729 ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh, 730 u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi, 731 u_int32_t rstamp, u_int16_t seq, u_int16_t status) 732 { 733 struct ifnet *ifp = &ic->ic_if; 734 u_int8_t *challenge = NULL; 735 int allocbs, i; 736 737 if ((ic->ic_flags & IEEE80211_F_WEPON) == 0) { 738 IEEE80211_DPRINTF(("%s: WEP is off\n", __func__)); 739 return; 740 } 741 742 if (frm + 1 < efrm) { 743 if (frm[1] + 2 > efrm - frm) { 744 IEEE80211_DPRINTF(("elt %d %d bytes too long\n", 745 frm[0], (frm[1] + 2) - (int)(efrm - frm))); 746 ic->ic_stats.is_rx_bad_auth++; 747 return; 748 } 749 if (*frm == IEEE80211_ELEMID_CHALLENGE) 750 challenge = frm; 751 frm += frm[1] + 2; 752 } 753 switch (seq) { 754 case IEEE80211_AUTH_SHARED_CHALLENGE: 755 case IEEE80211_AUTH_SHARED_RESPONSE: 756 if (challenge == NULL) { 757 IEEE80211_DPRINTF(("%s: no challenge sent\n", 758 __func__)); 759 ic->ic_stats.is_rx_bad_auth++; 760 return; 761 } 762 if (challenge[1] != IEEE80211_CHALLENGE_LEN) { 763 IEEE80211_DPRINTF(("%s: bad challenge len %d\n", 764 __func__, challenge[1])); 765 ic->ic_stats.is_rx_bad_auth++; 766 return; 767 } 768 default: 769 break; 770 } 771 switch (ic->ic_opmode) { 772 case IEEE80211_M_MONITOR: 773 case IEEE80211_M_AHDEMO: 774 case IEEE80211_M_IBSS: 775 IEEE80211_DPRINTF(("%s: unexpected operating mode\n", 776 __func__)); 777 return; 778 case IEEE80211_M_HOSTAP: 779 if (ic->ic_state != IEEE80211_S_RUN) { 780 IEEE80211_DPRINTF(("%s: not running\n", __func__)); 781 return; 782 } 783 switch (seq) { 784 case IEEE80211_AUTH_SHARED_REQUEST: 785 if (ni == ic->ic_bss) { 786 ni = ieee80211_alloc_node(ic, wh->i_addr2); 787 if (ni == NULL) { 788 ic->ic_stats.is_rx_nodealloc++; 789 return; 790 } 791 IEEE80211_ADDR_COPY(ni->ni_bssid, 792 ic->ic_bss->ni_bssid); 793 ni->ni_rssi = rssi; 794 ni->ni_rstamp = rstamp; 795 ni->ni_chan = ic->ic_bss->ni_chan; 796 allocbs = 1; 797 } else 798 allocbs = 0; 799 if (ni->ni_challenge == NULL) 800 ni->ni_challenge = (u_int32_t*)malloc( 801 IEEE80211_CHALLENGE_LEN, M_DEVBUF, 802 M_NOWAIT); 803 if (ni->ni_challenge == NULL) { 804 IEEE80211_DPRINTF(("challenge alloc failed\n")); 805 /* XXX statistic */ 806 return; 807 } 808 for (i = IEEE80211_CHALLENGE_LEN / sizeof(u_int32_t); 809 --i >= 0; ) 810 ni->ni_challenge[i] = arc4random(); 811 if (ifp->if_flags & IFF_DEBUG) 812 if_printf(ifp, "station %s shared key " 813 "%sauthentication\n", 814 ether_sprintf(ni->ni_macaddr), 815 allocbs ? "" : "re"); 816 break; 817 case IEEE80211_AUTH_SHARED_RESPONSE: 818 if (ni == ic->ic_bss) { 819 IEEE80211_DPRINTF(("%s: unknown STA\n", 820 __func__)); 821 return; 822 } 823 if (ni->ni_challenge == NULL) { 824 IEEE80211_DPRINTF(( 825 "%s: no challenge recorded\n", __func__)); 826 ic->ic_stats.is_rx_bad_auth++; 827 return; 828 } 829 if (memcmp(ni->ni_challenge, &challenge[2], 830 challenge[1]) != 0) { 831 IEEE80211_DPRINTF(("%s: challenge mismatch\n", 832 __func__)); 833 ic->ic_stats.is_rx_auth_fail++; 834 return; 835 } 836 if (ifp->if_flags & IFF_DEBUG) 837 if_printf(ifp, "station %s authenticated " 838 "(shared key)\n", 839 ether_sprintf(ni->ni_macaddr)); 840 break; 841 default: 842 IEEE80211_DPRINTF(("%s: bad seq %d from %s\n", 843 __func__, seq, ether_sprintf(wh->i_addr2))); 844 ic->ic_stats.is_rx_bad_auth++; 845 return; 846 } 847 IEEE80211_SEND_MGMT(ic, ni, 848 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 849 break; 850 851 case IEEE80211_M_STA: 852 if (ic->ic_state != IEEE80211_S_AUTH) 853 return; 854 switch (seq) { 855 case IEEE80211_AUTH_SHARED_PASS: 856 if (ni->ni_challenge != NULL) { 857 FREE(ni->ni_challenge, M_DEVBUF); 858 ni->ni_challenge = NULL; 859 } 860 if (status != 0) { 861 if_printf(&ic->ic_if, 862 "%s: shared authentication failed " 863 "(reason %d) for %s\n", 864 __func__, status, 865 ether_sprintf(wh->i_addr3)); 866 if (ni != ic->ic_bss) 867 ni->ni_fails++; 868 ic->ic_stats.is_rx_auth_fail++; 869 return; 870 } 871 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 872 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 873 break; 874 case IEEE80211_AUTH_SHARED_CHALLENGE: 875 if (ni->ni_challenge == NULL) 876 ni->ni_challenge = (u_int32_t*)malloc( 877 challenge[1], M_DEVBUF, M_NOWAIT); 878 if (ni->ni_challenge == NULL) { 879 IEEE80211_DPRINTF(( 880 "%s: challenge alloc failed\n", __func__)); 881 /* XXX statistic */ 882 return; 883 } 884 memcpy(ni->ni_challenge, &challenge[2], challenge[1]); 885 IEEE80211_SEND_MGMT(ic, ni, 886 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 887 break; 888 default: 889 IEEE80211_DPRINTF(("%s: bad seq %d from %s\n", 890 __func__, seq, ether_sprintf(wh->i_addr2))); 891 ic->ic_stats.is_rx_bad_auth++; 892 return; 893 } 894 break; 895 } 896 } 897 898 void 899 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 900 struct ieee80211_node *ni, 901 int subtype, int rssi, u_int32_t rstamp) 902 { 903 struct ifnet *ifp = &ic->ic_if; 904 struct ieee80211_frame *wh; 905 u_int8_t *frm, *efrm; 906 u_int8_t *ssid, *rates, *xrates; 907 int reassoc, resp, newassoc, allocbs; 908 909 wh = mtod(m0, struct ieee80211_frame *); 910 frm = (u_int8_t *)&wh[1]; 911 efrm = mtod(m0, u_int8_t *) + m0->m_len; 912 switch (subtype) { 913 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 914 case IEEE80211_FC0_SUBTYPE_BEACON: { 915 u_int8_t *tstamp, *bintval, *capinfo, *country; 916 u_int8_t chan, bchan, fhindex, erp; 917 u_int16_t fhdwell; 918 int isprobe; 919 920 if (ic->ic_opmode != IEEE80211_M_IBSS && 921 ic->ic_state != IEEE80211_S_SCAN) { 922 /* XXX: may be useful for background scan */ 923 return; 924 } 925 isprobe = (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP); 926 927 /* 928 * beacon/probe response frame format 929 * [8] time stamp 930 * [2] beacon interval 931 * [2] capability information 932 * [tlv] ssid 933 * [tlv] supported rates 934 * [tlv] country information 935 * [tlv] parameter set (FH/DS) 936 * [tlv] erp information 937 * [tlv] extended supported rates 938 */ 939 IEEE80211_VERIFY_LENGTH(efrm - frm, 12); 940 tstamp = frm; frm += 8; 941 bintval = frm; frm += 2; 942 capinfo = frm; frm += 2; 943 ssid = rates = xrates = country = NULL; 944 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 945 chan = bchan; 946 fhdwell = 0; 947 fhindex = 0; 948 erp = 0; 949 while (frm < efrm) { 950 switch (*frm) { 951 case IEEE80211_ELEMID_SSID: 952 ssid = frm; 953 break; 954 case IEEE80211_ELEMID_RATES: 955 rates = frm; 956 break; 957 case IEEE80211_ELEMID_COUNTRY: 958 country = frm; 959 break; 960 case IEEE80211_ELEMID_FHPARMS: 961 if (ic->ic_phytype == IEEE80211_T_FH) { 962 fhdwell = (frm[3] << 8) | frm[2]; 963 chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 964 fhindex = frm[6]; 965 } 966 break; 967 case IEEE80211_ELEMID_DSPARMS: 968 /* 969 * XXX hack this since depending on phytype 970 * is problematic for multi-mode devices. 971 */ 972 if (ic->ic_phytype != IEEE80211_T_FH) 973 chan = frm[2]; 974 break; 975 case IEEE80211_ELEMID_TIM: 976 break; 977 case IEEE80211_ELEMID_IBSSPARMS: 978 break; 979 case IEEE80211_ELEMID_XRATES: 980 xrates = frm; 981 break; 982 case IEEE80211_ELEMID_ERP: 983 if (frm[1] != 1) { 984 IEEE80211_DPRINTF(("%s: invalid ERP " 985 "element; length %u, expecting " 986 "1\n", __func__, frm[1])); 987 ic->ic_stats.is_rx_elem_toobig++; 988 break; 989 } 990 erp = frm[2]; 991 break; 992 default: 993 IEEE80211_DPRINTF2(("%s: element id %u/len %u " 994 "ignored\n", __func__, *frm, frm[1])); 995 ic->ic_stats.is_rx_elem_unknown++; 996 break; 997 } 998 frm += frm[1] + 2; 999 } 1000 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 1001 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 1002 if ( 1003 #if IEEE80211_CHAN_MAX < 255 1004 chan > IEEE80211_CHAN_MAX || 1005 #endif 1006 isclr(ic->ic_chan_active, chan)) { 1007 IEEE80211_DPRINTF(("%s: ignore %s with invalid channel " 1008 "%u\n", __func__, 1009 isprobe ? "probe response" : "beacon", 1010 chan)); 1011 ic->ic_stats.is_rx_badchan++; 1012 return; 1013 } 1014 if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) { 1015 /* 1016 * Frame was received on a channel different from the 1017 * one indicated in the DS params element id; 1018 * silently discard it. 1019 * 1020 * NB: this can happen due to signal leakage. 1021 * But we should take it for FH phy because 1022 * the rssi value should be correct even for 1023 * different hop pattern in FH. 1024 */ 1025 IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked " 1026 "for channel %u\n", __func__, 1027 isprobe ? "probe response" : "beacon", 1028 bchan, chan)); 1029 ic->ic_stats.is_rx_chanmismatch++; 1030 return; 1031 } 1032 1033 /* 1034 * Use mac and channel for lookup so we collect all 1035 * potential AP's when scanning. Otherwise we may 1036 * see the same AP on multiple channels and will only 1037 * record the last one. We could filter APs here based 1038 * on rssi, etc. but leave that to the end of the scan 1039 * so we can keep the selection criteria in one spot. 1040 * This may result in a bloat of the scanned AP list but 1041 * it shouldn't be too much. 1042 */ 1043 ni = ieee80211_lookup_node(ic, wh->i_addr2, 1044 &ic->ic_channels[chan]); 1045 #ifdef IEEE80211_DEBUG 1046 if (ieee80211_debug && 1047 (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) { 1048 printf("%s: %s%s on chan %u (bss chan %u) ", 1049 __func__, (ni == NULL ? "new " : ""), 1050 isprobe ? "probe response" : "beacon", 1051 chan, bchan); 1052 ieee80211_print_essid(ssid + 2, ssid[1]); 1053 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 1054 printf("%s: caps 0x%x bintval %u erp 0x%x\n", 1055 __func__, le16toh(*(u_int16_t *)capinfo), 1056 le16toh(*(u_int16_t *)bintval), erp); 1057 if (country) { 1058 int i; 1059 printf("%s: country info", __func__); 1060 for (i = 0; i < country[1]; i++) 1061 printf(" %02x", country[i+2]); 1062 printf("\n"); 1063 } 1064 } 1065 #endif 1066 if (ni == NULL) { 1067 ni = ieee80211_alloc_node(ic, wh->i_addr2); 1068 if (ni == NULL) 1069 return; 1070 ni->ni_esslen = ssid[1]; 1071 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 1072 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 1073 allocbs = 1; 1074 } else if (ssid[1] != 0 && (isprobe || ni->ni_esslen == 0)) { 1075 /* 1076 * Update ESSID at probe response to adopt hidden AP by 1077 * Lucent/Cisco, which announces null ESSID in beacon. 1078 */ 1079 ni->ni_esslen = ssid[1]; 1080 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 1081 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 1082 allocbs = 0; 1083 } else 1084 allocbs = 0; 1085 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 1086 ni->ni_rssi = rssi; 1087 ni->ni_rstamp = rstamp; 1088 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); 1089 ni->ni_intval = le16toh(*(u_int16_t *)bintval); 1090 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo); 1091 /* XXX validate channel # */ 1092 ni->ni_chan = &ic->ic_channels[chan]; 1093 ni->ni_fhdwell = fhdwell; 1094 ni->ni_fhindex = fhindex; 1095 ni->ni_erp = erp; 1096 /* NB: must be after ni_chan is setup */ 1097 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); 1098 /* 1099 * When scanning we record results (nodes) with a zero 1100 * refcnt. Otherwise we want to hold the reference for 1101 * ibss neighbors so the nodes don't get released prematurely. 1102 * Anything else can be discarded (XXX and should be handled 1103 * above so we don't do so much work). 1104 */ 1105 if (ic->ic_state == IEEE80211_S_SCAN) 1106 ieee80211_unref_node(&ni); /* NB: do not free */ 1107 else if (ic->ic_opmode == IEEE80211_M_IBSS && 1108 allocbs && isprobe) { 1109 /* 1110 * Fake an association so the driver can setup it's 1111 * private state. The rate set has been setup above; 1112 * there is no handshake as in ap/station operation. 1113 */ 1114 if (ic->ic_newassoc) 1115 (*ic->ic_newassoc)(ic, ni, 1); 1116 /* NB: hold reference */ 1117 } else { 1118 /* XXX optimize to avoid work done above */ 1119 ieee80211_free_node(ic, ni); 1120 } 1121 break; 1122 } 1123 1124 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: { 1125 u_int8_t rate; 1126 1127 if (ic->ic_opmode == IEEE80211_M_STA) 1128 return; 1129 if (ic->ic_state != IEEE80211_S_RUN) 1130 return; 1131 1132 /* 1133 * prreq frame format 1134 * [tlv] ssid 1135 * [tlv] supported rates 1136 * [tlv] extended supported rates 1137 */ 1138 ssid = rates = xrates = NULL; 1139 while (frm < efrm) { 1140 switch (*frm) { 1141 case IEEE80211_ELEMID_SSID: 1142 ssid = frm; 1143 break; 1144 case IEEE80211_ELEMID_RATES: 1145 rates = frm; 1146 break; 1147 case IEEE80211_ELEMID_XRATES: 1148 xrates = frm; 1149 break; 1150 } 1151 frm += frm[1] + 2; 1152 } 1153 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 1154 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 1155 if (ssid[1] != 0 && 1156 (ssid[1] != ic->ic_bss->ni_esslen || 1157 memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) { 1158 #ifdef IEEE80211_DEBUG 1159 if (ieee80211_debug) { 1160 printf("%s: ssid mismatch ", __func__); 1161 ieee80211_print_essid(ssid + 2, ssid[1]); 1162 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 1163 } 1164 #endif 1165 ic->ic_stats.is_rx_ssidmismatch++; 1166 return; 1167 } 1168 1169 if (ni == ic->ic_bss) { 1170 ni = ieee80211_dup_bss(ic, wh->i_addr2); 1171 if (ni == NULL) 1172 return; 1173 IEEE80211_DPRINTF(("%s: new req from %s\n", 1174 __func__, ether_sprintf(wh->i_addr2))); 1175 allocbs = 1; 1176 } else 1177 allocbs = 0; 1178 ni->ni_rssi = rssi; 1179 ni->ni_rstamp = rstamp; 1180 rate = ieee80211_setup_rates(ic, ni, rates, xrates, 1181 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 1182 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 1183 if (rate & IEEE80211_RATE_BASIC) { 1184 IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n", 1185 __func__,ether_sprintf(wh->i_addr2))); 1186 } else { 1187 IEEE80211_SEND_MGMT(ic, ni, 1188 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0); 1189 } 1190 if (allocbs) 1191 ieee80211_free_node(ic, ni); 1192 break; 1193 } 1194 1195 case IEEE80211_FC0_SUBTYPE_AUTH: { 1196 u_int16_t algo, seq, status; 1197 /* 1198 * auth frame format 1199 * [2] algorithm 1200 * [2] sequence 1201 * [2] status 1202 * [tlv*] challenge 1203 */ 1204 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 1205 algo = le16toh(*(u_int16_t *)frm); 1206 seq = le16toh(*(u_int16_t *)(frm + 2)); 1207 status = le16toh(*(u_int16_t *)(frm + 4)); 1208 IEEE80211_DPRINTF(("%s: auth %d seq %d from %s\n", 1209 __func__, algo, seq, ether_sprintf(wh->i_addr2))); 1210 1211 if (algo == IEEE80211_AUTH_ALG_SHARED) 1212 ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi, 1213 rstamp, seq, status); 1214 else if (algo == IEEE80211_AUTH_ALG_OPEN) 1215 ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq, 1216 status); 1217 else { 1218 IEEE80211_DPRINTF(("%s: unsupported authentication " 1219 "algorithm %d from %s\n", 1220 __func__, algo, ether_sprintf(wh->i_addr2))); 1221 ic->ic_stats.is_rx_auth_unsupported++; 1222 return; 1223 } 1224 break; 1225 } 1226 1227 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 1228 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { 1229 u_int16_t capinfo, bintval; 1230 1231 if (ic->ic_opmode != IEEE80211_M_HOSTAP || 1232 (ic->ic_state != IEEE80211_S_RUN)) 1233 return; 1234 1235 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 1236 reassoc = 1; 1237 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 1238 } else { 1239 reassoc = 0; 1240 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 1241 } 1242 /* 1243 * asreq frame format 1244 * [2] capability information 1245 * [2] listen interval 1246 * [6*] current AP address (reassoc only) 1247 * [tlv] ssid 1248 * [tlv] supported rates 1249 * [tlv] extended supported rates 1250 */ 1251 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 1252 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 1253 IEEE80211_DPRINTF(("%s: ignore other bss from %s\n", 1254 __func__, ether_sprintf(wh->i_addr2))); 1255 ic->ic_stats.is_rx_assoc_bss++; 1256 return; 1257 } 1258 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 1259 bintval = le16toh(*(u_int16_t *)frm); frm += 2; 1260 if (reassoc) 1261 frm += 6; /* ignore current AP info */ 1262 ssid = rates = xrates = NULL; 1263 while (frm < efrm) { 1264 switch (*frm) { 1265 case IEEE80211_ELEMID_SSID: 1266 ssid = frm; 1267 break; 1268 case IEEE80211_ELEMID_RATES: 1269 rates = frm; 1270 break; 1271 case IEEE80211_ELEMID_XRATES: 1272 xrates = frm; 1273 break; 1274 } 1275 frm += frm[1] + 2; 1276 } 1277 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 1278 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 1279 if (ssid[1] != ic->ic_bss->ni_esslen || 1280 memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) { 1281 #ifdef IEEE80211_DEBUG 1282 if (ieee80211_debug) { 1283 printf("%s: ssid mismatch ", __func__); 1284 ieee80211_print_essid(ssid + 2, ssid[1]); 1285 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 1286 } 1287 #endif 1288 ic->ic_stats.is_rx_ssidmismatch++; 1289 return; 1290 } 1291 if (ni == ic->ic_bss) { 1292 IEEE80211_DPRINTF(("%s: not authenticated for %s\n", 1293 __func__, ether_sprintf(wh->i_addr2))); 1294 ni = ieee80211_dup_bss(ic, wh->i_addr2); 1295 if (ni != NULL) { 1296 IEEE80211_SEND_MGMT(ic, ni, 1297 IEEE80211_FC0_SUBTYPE_DEAUTH, 1298 IEEE80211_REASON_ASSOC_NOT_AUTHED); 1299 ieee80211_free_node(ic, ni); 1300 } 1301 ic->ic_stats.is_rx_assoc_notauth++; 1302 return; 1303 } 1304 /* discard challenge after association */ 1305 if (ni->ni_challenge != NULL) { 1306 FREE(ni->ni_challenge, M_DEVBUF); 1307 ni->ni_challenge = NULL; 1308 } 1309 /* XXX per-node cipher suite */ 1310 /* XXX some stations use the privacy bit for handling APs 1311 that suport both encrypted and unencrypted traffic */ 1312 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 1313 (capinfo & IEEE80211_CAPINFO_PRIVACY) != 1314 ((ic->ic_flags & IEEE80211_F_WEPON) ? 1315 IEEE80211_CAPINFO_PRIVACY : 0)) { 1316 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n", 1317 __func__, capinfo, ether_sprintf(wh->i_addr2))); 1318 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); 1319 ni->ni_associd = 0; 1320 IEEE80211_SEND_MGMT(ic, ni, resp, 1321 IEEE80211_STATUS_CAPINFO); 1322 ic->ic_stats.is_rx_assoc_capmismatch++; 1323 return; 1324 } 1325 ieee80211_setup_rates(ic, ni, rates, xrates, 1326 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 1327 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 1328 if (ni->ni_rates.rs_nrates == 0) { 1329 IEEE80211_DPRINTF(("%s: rate mismatch for %s\n", 1330 __func__, ether_sprintf(wh->i_addr2))); 1331 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); 1332 ni->ni_associd = 0; 1333 IEEE80211_SEND_MGMT(ic, ni, resp, 1334 IEEE80211_STATUS_BASIC_RATE); 1335 ic->ic_stats.is_rx_assoc_norate++; 1336 return; 1337 } 1338 ni->ni_rssi = rssi; 1339 ni->ni_rstamp = rstamp; 1340 ni->ni_intval = bintval; 1341 ni->ni_capinfo = capinfo; 1342 ni->ni_chan = ic->ic_bss->ni_chan; 1343 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 1344 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 1345 if (ni->ni_associd == 0) { 1346 u_int16_t aid; 1347 1348 /* 1349 * It would be clever to search the bitmap 1350 * more efficiently, but this will do for now. 1351 */ 1352 for (aid = 1; aid < ic->ic_max_aid; aid++) { 1353 if (!IEEE80211_AID_ISSET(aid, 1354 ic->ic_aid_bitmap)) 1355 break; 1356 } 1357 1358 if (ic->ic_bss->ni_associd >= ic->ic_max_aid) { 1359 IEEE80211_SEND_MGMT(ic, ni, resp, 1360 IEEE80211_REASON_ASSOC_TOOMANY); 1361 return; 1362 } else { 1363 ni->ni_associd = aid | 0xc000; 1364 IEEE80211_AID_SET(ni->ni_associd, 1365 ic->ic_aid_bitmap); 1366 newassoc = 1; 1367 } 1368 } else 1369 newassoc = 0; 1370 /* XXX for 11g must turn off short slot time if long 1371 slot time sta associates */ 1372 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); 1373 if (ifp->if_flags & IFF_DEBUG) 1374 if_printf(ifp, "station %s %s associated at aid %d\n", 1375 (newassoc ? "newly" : "already"), 1376 ether_sprintf(ni->ni_macaddr), 1377 ni->ni_associd & ~0xc000); 1378 /* give driver a chance to setup state like ni_txrate */ 1379 if (ic->ic_newassoc) 1380 (*ic->ic_newassoc)(ic, ni, newassoc); 1381 break; 1382 } 1383 1384 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 1385 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 1386 u_int16_t status; 1387 1388 if (ic->ic_opmode != IEEE80211_M_STA || 1389 ic->ic_state != IEEE80211_S_ASSOC) 1390 return; 1391 1392 /* 1393 * asresp frame format 1394 * [2] capability information 1395 * [2] status 1396 * [2] association ID 1397 * [tlv] supported rates 1398 * [tlv] extended supported rates 1399 */ 1400 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 1401 ni = ic->ic_bss; 1402 ni->ni_capinfo = le16toh(*(u_int16_t *)frm); 1403 frm += 2; 1404 1405 status = le16toh(*(u_int16_t *)frm); 1406 frm += 2; 1407 if (status != 0) { 1408 if (ifp->if_flags & IFF_DEBUG) 1409 if_printf(ifp, 1410 "association failed (reason %d) for %s\n", 1411 status, ether_sprintf(wh->i_addr3)); 1412 if (ni != ic->ic_bss) 1413 ni->ni_fails++; 1414 ic->ic_stats.is_rx_auth_fail++; 1415 return; 1416 } 1417 ni->ni_associd = le16toh(*(u_int16_t *)frm); 1418 frm += 2; 1419 1420 rates = xrates = NULL; 1421 while (frm < efrm) { 1422 switch (*frm) { 1423 case IEEE80211_ELEMID_RATES: 1424 rates = frm; 1425 break; 1426 case IEEE80211_ELEMID_XRATES: 1427 xrates = frm; 1428 break; 1429 } 1430 frm += frm[1] + 2; 1431 } 1432 1433 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 1434 ieee80211_setup_rates(ic, ni, rates, xrates, 1435 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 1436 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 1437 if (ni->ni_rates.rs_nrates != 0) 1438 ieee80211_new_state(ic, IEEE80211_S_RUN, 1439 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1440 break; 1441 } 1442 1443 case IEEE80211_FC0_SUBTYPE_DEAUTH: { 1444 u_int16_t reason; 1445 /* 1446 * deauth frame format 1447 * [2] reason 1448 */ 1449 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1450 reason = le16toh(*(u_int16_t *)frm); 1451 ic->ic_stats.is_rx_deauth++; 1452 switch (ic->ic_opmode) { 1453 case IEEE80211_M_STA: 1454 ieee80211_new_state(ic, IEEE80211_S_AUTH, 1455 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1456 break; 1457 case IEEE80211_M_HOSTAP: 1458 if (ni != ic->ic_bss) { 1459 if (ifp->if_flags & IFF_DEBUG) 1460 if_printf(ifp, "station %s deauthenticated" 1461 " by peer (reason %d)\n", 1462 ether_sprintf(ni->ni_macaddr), reason); 1463 /* node will be free'd on return */ 1464 ieee80211_unref_node(&ni); 1465 } 1466 break; 1467 default: 1468 break; 1469 } 1470 break; 1471 } 1472 1473 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 1474 u_int16_t reason; 1475 /* 1476 * disassoc frame format 1477 * [2] reason 1478 */ 1479 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1480 reason = le16toh(*(u_int16_t *)frm); 1481 ic->ic_stats.is_rx_disassoc++; 1482 switch (ic->ic_opmode) { 1483 case IEEE80211_M_STA: 1484 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1485 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1486 break; 1487 case IEEE80211_M_HOSTAP: 1488 if (ni != ic->ic_bss) { 1489 if (ifp->if_flags & IFF_DEBUG) 1490 if_printf(ifp, "station %s disassociated" 1491 " by peer (reason %d)\n", 1492 ether_sprintf(ni->ni_macaddr), reason); 1493 IEEE80211_AID_CLR(ni->ni_associd, 1494 ic->ic_aid_bitmap); 1495 ni->ni_associd = 0; 1496 /* XXX node reclaimed how? */ 1497 } 1498 break; 1499 default: 1500 break; 1501 } 1502 break; 1503 } 1504 default: 1505 IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not " 1506 "handled\n", __func__, subtype)); 1507 ic->ic_stats.is_rx_badsubtype++; 1508 break; 1509 } 1510 } 1511 1512 static void 1513 ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m0, int rssi, 1514 u_int32_t rstamp) 1515 { 1516 struct ifnet *ifp = &ic->ic_if; 1517 struct ieee80211_frame *wh; 1518 struct ieee80211_node *ni; 1519 struct mbuf *m; 1520 u_int16_t aid; 1521 1522 if (ic->ic_set_tim == NULL) /* No powersaving functionality */ 1523 return; 1524 1525 wh = mtod(m0, struct ieee80211_frame *); 1526 1527 if ((ni = ieee80211_find_node(ic, wh->i_addr2)) == NULL) { 1528 if (ifp->if_flags & IFF_DEBUG) 1529 printf("%s: station %s sent bogus power save poll\n", 1530 ifp->if_xname, ether_sprintf(wh->i_addr2)); 1531 return; 1532 } 1533 1534 memcpy(&aid, wh->i_dur, sizeof(wh->i_dur)); 1535 if ((aid & 0xc000) != 0xc000) { 1536 if (ifp->if_flags & IFF_DEBUG) 1537 printf("%s: station %s sent bogus aid %x\n", 1538 ifp->if_xname, ether_sprintf(wh->i_addr2), aid); 1539 return; 1540 } 1541 1542 if (aid != ni->ni_associd) { 1543 if (ifp->if_flags & IFF_DEBUG) 1544 printf("%s: station %s aid %x doesn't match pspoll " 1545 "aid %x\n", 1546 ifp->if_xname, ether_sprintf(wh->i_addr2), 1547 ni->ni_associd, aid); 1548 return; 1549 } 1550 1551 /* Okay, take the first queued packet and put it out... */ 1552 1553 IF_DEQUEUE(&ni->ni_savedq, m); 1554 if (m == NULL) { 1555 if (ifp->if_flags & IFF_DEBUG) 1556 printf("%s: station %s sent pspoll, " 1557 "but no packets are saved\n", 1558 ifp->if_xname, ether_sprintf(wh->i_addr2)); 1559 return; 1560 } 1561 wh = mtod(m, struct ieee80211_frame *); 1562 1563 /* 1564 * If this is the last packet, turn off the TIM fields. 1565 * If there are more packets, set the more packets bit. 1566 */ 1567 1568 if (IF_IS_EMPTY(&ni->ni_savedq)) { 1569 if (ic->ic_set_tim) 1570 ic->ic_set_tim(ic, ni->ni_associd, 0); 1571 } else { 1572 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; 1573 } 1574 1575 if (ifp->if_flags & IFF_DEBUG) 1576 printf("%s: enqueued power saving packet for station %s\n", 1577 ifp->if_xname, ether_sprintf(ni->ni_macaddr)); 1578 1579 IF_ENQUEUE(&ic->ic_pwrsaveq, m); 1580 (*ifp->if_start)(ifp); 1581 } 1582 #undef IEEE80211_VERIFY_LENGTH 1583 #undef IEEE80211_VERIFY_ELEMENT 1584