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