1 /* $NetBSD: ieee80211_input.c,v 1.41 2005/06/26 04:31:51 dyoung Exp $ */ 2 /*- 3 * Copyright (c) 2001 Atsushi Onoe 4 * Copyright (c) 2002-2005 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.33 2005/02/23 04:52:30 sam Exp $"); 37 #endif 38 #ifdef __NetBSD__ 39 __KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.41 2005/06/26 04:31:51 dyoung Exp $"); 40 #endif 41 42 #include "opt_inet.h" 43 44 #ifdef __NetBSD__ 45 #include "bpfilter.h" 46 #endif /* __NetBSD__ */ 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/mbuf.h> 51 #include <sys/malloc.h> 52 #include <sys/endian.h> 53 #include <sys/kernel.h> 54 55 #include <sys/socket.h> 56 #include <sys/sockio.h> 57 #include <sys/endian.h> 58 #include <sys/errno.h> 59 #include <sys/proc.h> 60 #include <sys/sysctl.h> 61 62 #include <net/if.h> 63 #include <net/if_media.h> 64 #include <net/if_arp.h> 65 #include <net/if_ether.h> 66 #include <net/if_llc.h> 67 68 #include <net80211/ieee80211_netbsd.h> 69 #include <net80211/ieee80211_var.h> 70 71 #if NBPFILTER > 0 72 #include <net/bpf.h> 73 #endif 74 75 #ifdef INET 76 #include <netinet/in.h> 77 #include <net/if_ether.h> 78 #endif 79 80 const struct timeval ieee80211_merge_print_intvl = {.tv_sec = 1, .tv_usec = 0}; 81 82 #ifdef IEEE80211_DEBUG 83 #include <machine/stdarg.h> 84 85 /* 86 * Decide if a received management frame should be 87 * printed when debugging is enabled. This filters some 88 * of the less interesting frames that come frequently 89 * (e.g. beacons). 90 */ 91 static __inline int 92 doprint(struct ieee80211com *ic, int subtype) 93 { 94 switch (subtype) { 95 case IEEE80211_FC0_SUBTYPE_BEACON: 96 return (ic->ic_flags & IEEE80211_F_SCAN); 97 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 98 return (ic->ic_opmode == IEEE80211_M_IBSS); 99 } 100 return 1; 101 } 102 103 /* 104 * Emit a debug message about discarding a frame or information 105 * element. One format is for extracting the mac address from 106 * the frame header; the other is for when a header is not 107 * available or otherwise appropriate. 108 */ 109 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) do { \ 110 if ((_ic)->ic_debug & (_m)) \ 111 ieee80211_discard_frame(_ic, _wh, _type, _fmt, __VA_ARGS__);\ 112 } while (0) 113 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) do { \ 114 if ((_ic)->ic_debug & (_m)) \ 115 ieee80211_discard_ie(_ic, _wh, _type, _fmt, __VA_ARGS__);\ 116 } while (0) 117 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) do { \ 118 if ((_ic)->ic_debug & (_m)) \ 119 ieee80211_discard_mac(_ic, _mac, _type, _fmt, __VA_ARGS__);\ 120 } while (0) 121 122 static const u_int8_t *ieee80211_getbssid(struct ieee80211com *, 123 const struct ieee80211_frame *); 124 static void ieee80211_discard_frame(struct ieee80211com *, 125 const struct ieee80211_frame *, const char *type, const char *fmt, ...); 126 static void ieee80211_discard_ie(struct ieee80211com *, 127 const struct ieee80211_frame *, const char *type, const char *fmt, ...); 128 static void ieee80211_discard_mac(struct ieee80211com *, 129 const u_int8_t mac[IEEE80211_ADDR_LEN], const char *type, 130 const char *fmt, ...); 131 #else 132 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) 133 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) 134 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) 135 #endif /* IEEE80211_DEBUG */ 136 137 static struct mbuf *ieee80211_defrag(struct ieee80211com *, 138 struct ieee80211_node *, struct mbuf *); 139 static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *); 140 #ifndef IEEE80211_NO_HOSTAP 141 static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable); 142 static void ieee80211_recv_pspoll(struct ieee80211com *, 143 struct ieee80211_node *, struct mbuf *); 144 #endif /* !IEEE80211_NO_HOSTAP */ 145 146 /* 147 * Process a received frame. The node associated with the sender 148 * should be supplied. If nothing was found in the node table then 149 * the caller is assumed to supply a reference to ic_bss instead. 150 * The RSSI and a timestamp are also supplied. The RSSI data is used 151 * during AP scanning to select a AP to associate with; it can have 152 * any units so long as values have consistent units and higher values 153 * mean ``better signal''. The receive timestamp is currently not used 154 * by the 802.11 layer. 155 */ 156 int 157 ieee80211_input(struct ieee80211com *ic, struct mbuf *m, 158 struct ieee80211_node *ni, int rssi, u_int32_t rstamp) 159 { 160 #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 161 #define HAS_SEQ(type) ((type & 0x4) == 0) 162 struct ifnet *ifp = ic->ic_ifp; 163 struct ieee80211_frame *wh; 164 struct ieee80211_key *key; 165 struct ether_header *eh; 166 int hdrsize, off; 167 u_int8_t dir, type, subtype; 168 u_int8_t *bssid; 169 u_int16_t rxseq; 170 ALTQ_DECL(struct altq_pktattr pktattr;) 171 172 IASSERT(ni != NULL, ("null node")); 173 ni->ni_inact = ni->ni_inact_reload; 174 175 /* trim CRC here so WEP can find its own CRC at the end of packet. */ 176 if (m->m_flags & M_HASFCS) { 177 m_adj(m, -IEEE80211_CRC_LEN); 178 m->m_flags &= ~M_HASFCS; 179 } 180 181 type = -1; /* undefined */ 182 /* 183 * In monitor mode, send everything directly to bpf. 184 * XXX may want to include the CRC 185 */ 186 if (ic->ic_opmode == IEEE80211_M_MONITOR) 187 goto out; 188 189 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { 190 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, 191 ni->ni_macaddr, NULL, 192 "too short (1): len %u", m->m_pkthdr.len); 193 ic->ic_stats.is_rx_tooshort++; 194 goto out; 195 } 196 /* 197 * Bit of a cheat here, we use a pointer for a 3-address 198 * frame format but don't reference fields past outside 199 * ieee80211_frame_min w/o first validating the data is 200 * present. 201 */ 202 wh = mtod(m, struct ieee80211_frame *); 203 204 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 205 IEEE80211_FC0_VERSION_0) { 206 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, 207 ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]); 208 ic->ic_stats.is_rx_badversion++; 209 goto err; 210 } 211 212 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 213 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 214 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 215 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { 216 switch (ic->ic_opmode) { 217 case IEEE80211_M_STA: 218 bssid = wh->i_addr2; 219 if (!IEEE80211_ADDR_EQ(bssid, ni->ni_bssid)) { 220 /* not interested in */ 221 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 222 bssid, NULL, "%s", "not to bss"); 223 ic->ic_stats.is_rx_wrongbss++; 224 goto out; 225 } 226 break; 227 case IEEE80211_M_IBSS: 228 case IEEE80211_M_AHDEMO: 229 case IEEE80211_M_HOSTAP: 230 if (dir != IEEE80211_FC1_DIR_NODS) 231 bssid = wh->i_addr1; 232 else if (type == IEEE80211_FC0_TYPE_CTL) 233 bssid = wh->i_addr1; 234 else { 235 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { 236 IEEE80211_DISCARD_MAC(ic, 237 IEEE80211_MSG_ANY, ni->ni_macaddr, 238 NULL, "too short (2): len %u", 239 m->m_pkthdr.len); 240 ic->ic_stats.is_rx_tooshort++; 241 goto out; 242 } 243 bssid = wh->i_addr3; 244 } 245 if (type != IEEE80211_FC0_TYPE_DATA) 246 break; 247 /* 248 * Data frame, validate the bssid. 249 */ 250 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) && 251 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { 252 /* not interested in */ 253 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 254 bssid, NULL, "%s", "not to bss"); 255 ic->ic_stats.is_rx_wrongbss++; 256 goto out; 257 } 258 /* 259 * For adhoc mode we cons up a node when it doesn't 260 * exist. This should probably done after an ACL check. 261 */ 262 if (ni == ic->ic_bss && 263 ic->ic_opmode != IEEE80211_M_HOSTAP) { 264 /* 265 * Fake up a node for this newly 266 * discovered member of the IBSS. 267 */ 268 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, 269 wh->i_addr2); 270 if (ni == NULL) { 271 /* NB: stat kept for alloc failure */ 272 goto err; 273 } 274 } 275 break; 276 default: 277 goto out; 278 } 279 ni->ni_rssi = rssi; 280 ni->ni_rstamp = rstamp; 281 if (HAS_SEQ(type)) { 282 u_int8_t tid; 283 if (IEEE80211_QOS_HAS_SEQ(wh)) { 284 tid = ((struct ieee80211_qosframe *)wh)-> 285 i_qos[0] & IEEE80211_QOS_TID; 286 if (tid >= WME_AC_VI) 287 ic->ic_wme.wme_hipri_traffic++; 288 tid++; 289 } else 290 tid = 0; 291 rxseq = le16toh(*(u_int16_t *)wh->i_seq); 292 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && 293 SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) { 294 /* duplicate, discard */ 295 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 296 bssid, "duplicate", 297 "seqno <%u,%u> fragno <%u,%u> tid %u", 298 rxseq >> IEEE80211_SEQ_SEQ_SHIFT, 299 ni->ni_rxseqs[tid] >> 300 IEEE80211_SEQ_SEQ_SHIFT, 301 rxseq & IEEE80211_SEQ_FRAG_MASK, 302 ni->ni_rxseqs[tid] & 303 IEEE80211_SEQ_FRAG_MASK, 304 tid); 305 ic->ic_stats.is_rx_dup++; 306 IEEE80211_NODE_STAT(ni, rx_dup); 307 goto out; 308 } 309 ni->ni_rxseqs[tid] = rxseq; 310 } 311 } 312 313 switch (type) { 314 case IEEE80211_FC0_TYPE_DATA: 315 hdrsize = ieee80211_hdrsize(wh); 316 if (ic->ic_flags & IEEE80211_F_DATAPAD) 317 hdrsize = roundup(hdrsize, sizeof(u_int32_t)); 318 if (m->m_len < hdrsize && 319 (m = m_pullup(m, hdrsize)) == NULL) { 320 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, 321 ni->ni_macaddr, NULL, 322 "data too short: expecting %u", hdrsize); 323 ic->ic_stats.is_rx_tooshort++; 324 goto out; /* XXX */ 325 } 326 if (subtype & IEEE80211_FC0_SUBTYPE_QOS) { 327 /* XXX discard if node w/o IEEE80211_NODE_QOS? */ 328 /* 329 * Strip QoS control and any padding so only a 330 * stock 802.11 header is at the front. 331 */ 332 /* XXX 4-address QoS frame */ 333 off = hdrsize - sizeof(struct ieee80211_frame); 334 ovbcopy(mtod(m, u_int8_t *), mtod(m, u_int8_t *) + off, 335 hdrsize - off); 336 m_adj(m, off); 337 wh = mtod(m, struct ieee80211_frame *); 338 wh->i_fc[0] &= ~IEEE80211_FC0_SUBTYPE_QOS; 339 } else { 340 /* XXX copy up for 4-address frames w/ padding */ 341 } 342 switch (ic->ic_opmode) { 343 case IEEE80211_M_STA: 344 if (dir != IEEE80211_FC1_DIR_FROMDS) { 345 ic->ic_stats.is_rx_wrongdir++; 346 goto out; 347 } 348 if (ic->ic_state != IEEE80211_S_SCAN && 349 !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { 350 /* Source address is not our BSS. */ 351 IEEE80211_DPRINTF(ic, IEEE80211_MSG_INPUT, 352 "%s: discard frame from SA %s\n", 353 __func__, ether_sprintf(wh->i_addr2)); 354 ic->ic_stats.is_rx_wrongbss++; 355 goto out; 356 } 357 if ((ifp->if_flags & IFF_SIMPLEX) && 358 IEEE80211_IS_MULTICAST(wh->i_addr1) && 359 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) { 360 /* 361 * In IEEE802.11 network, multicast packet 362 * sent from me is broadcasted from AP. 363 * It should be silently discarded for 364 * SIMPLEX interface. 365 */ 366 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 367 wh, NULL, "%s", "multicast echo"); 368 ic->ic_stats.is_rx_mcastecho++; 369 goto out; 370 } 371 break; 372 case IEEE80211_M_IBSS: 373 case IEEE80211_M_AHDEMO: 374 if (dir != IEEE80211_FC1_DIR_NODS) { 375 ic->ic_stats.is_rx_wrongdir++; 376 goto out; 377 } 378 /* XXX no power-save support */ 379 break; 380 case IEEE80211_M_HOSTAP: 381 #ifndef IEEE80211_NO_HOSTAP 382 if (dir != IEEE80211_FC1_DIR_TODS) { 383 ic->ic_stats.is_rx_wrongdir++; 384 goto out; 385 } 386 if (ic->ic_state != IEEE80211_S_SCAN && 387 !IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_bss->ni_bssid) && 388 !IEEE80211_ADDR_EQ(wh->i_addr1, ifp->if_broadcastaddr)) { 389 /* BSS is not us or broadcast. */ 390 IEEE80211_DPRINTF(ic, IEEE80211_MSG_INPUT, 391 "%s: discard data frame to BSS %s\n", 392 __func__, ether_sprintf(wh->i_addr1)); 393 ic->ic_stats.is_rx_wrongbss++; 394 goto out; 395 } 396 /* check if source STA is associated */ 397 if (ni == ic->ic_bss) { 398 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 399 wh, "data", "%s", "unknown src"); 400 /* NB: caller deals with reference */ 401 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 402 if (ni != NULL) { 403 IEEE80211_SEND_MGMT(ic, ni, 404 IEEE80211_FC0_SUBTYPE_DEAUTH, 405 IEEE80211_REASON_NOT_AUTHED); 406 ieee80211_free_node(ni); 407 } 408 ic->ic_stats.is_rx_notassoc++; 409 goto err; 410 } 411 if (ni->ni_associd == 0) { 412 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 413 wh, "data", "%s", "unassoc src"); 414 IEEE80211_SEND_MGMT(ic, ni, 415 IEEE80211_FC0_SUBTYPE_DISASSOC, 416 IEEE80211_REASON_NOT_ASSOCED); 417 ic->ic_stats.is_rx_notassoc++; 418 goto err; 419 } 420 421 /* 422 * Check for power save state change. 423 */ 424 if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^ 425 (ni->ni_flags & IEEE80211_NODE_PWR_MGT))) 426 ieee80211_node_pwrsave(ni, 427 wh->i_fc[1] & IEEE80211_FC1_PWR_MGT); 428 #endif /* !IEEE80211_NO_HOSTAP */ 429 break; 430 default: 431 /* XXX here to keep compiler happy */ 432 goto out; 433 } 434 435 /* 436 * Handle privacy requirements. Note that we 437 * must not be preempted from here until after 438 * we (potentially) call ieee80211_crypto_demic; 439 * otherwise we may violate assumptions in the 440 * crypto cipher modules used to do delayed update 441 * of replay sequence numbers. 442 */ 443 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 444 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 445 /* 446 * Discard encrypted frames when privacy is off. 447 */ 448 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 449 wh, "WEP", "%s", "PRIVACY off"); 450 ic->ic_stats.is_rx_noprivacy++; 451 IEEE80211_NODE_STAT(ni, rx_noprivacy); 452 goto out; 453 } 454 key = ieee80211_crypto_decap(ic, ni, m); 455 if (key == NULL) { 456 /* NB: stats+msgs handled in crypto_decap */ 457 IEEE80211_NODE_STAT(ni, rx_wepfail); 458 goto out; 459 } 460 wh = mtod(m, struct ieee80211_frame *); 461 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 462 } else { 463 key = NULL; 464 } 465 466 /* 467 * Next up, any fragmentation. 468 */ 469 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 470 m = ieee80211_defrag(ic, ni, m); 471 if (m == NULL) { 472 /* Fragment dropped or frame not complete yet */ 473 goto out; 474 } 475 } 476 wh = NULL; /* no longer valid, catch any uses */ 477 478 /* 479 * Next strip any MSDU crypto bits. 480 */ 481 if (key != NULL && !ieee80211_crypto_demic(ic, key, m)) { 482 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 483 ni->ni_macaddr, "data", "%s", "demic error"); 484 IEEE80211_NODE_STAT(ni, rx_demicfail); 485 goto out; 486 } 487 488 #if NBPFILTER > 0 489 /* copy to listener after decrypt */ 490 if (ic->ic_rawbpf) 491 bpf_mtap(ic->ic_rawbpf, m); 492 #endif 493 494 /* 495 * Finally, strip the 802.11 header. 496 */ 497 m = ieee80211_decap(ic, m); 498 if (m == NULL) { 499 /* don't count Null data frames as errors */ 500 if (subtype == IEEE80211_FC0_SUBTYPE_NODATA) 501 goto out; 502 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 503 ni->ni_macaddr, "data", "%s", "decap error"); 504 ic->ic_stats.is_rx_decap++; 505 IEEE80211_NODE_STAT(ni, rx_decap); 506 goto err; 507 } 508 eh = mtod(m, struct ether_header *); 509 if (!ieee80211_node_is_authorized(ni)) { 510 /* 511 * Deny any non-PAE frames received prior to 512 * authorization. For open/shared-key 513 * authentication the port is mark authorized 514 * after authentication completes. For 802.1x 515 * the port is not marked authorized by the 516 * authenticator until the handshake has completed. 517 */ 518 if (eh->ether_type != htons(ETHERTYPE_PAE)) { 519 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 520 eh->ether_shost, "data", 521 "unauthorized port: ether type 0x%x len %u", 522 eh->ether_type, m->m_pkthdr.len); 523 ic->ic_stats.is_rx_unauth++; 524 IEEE80211_NODE_STAT(ni, rx_unauth); 525 goto err; 526 } 527 } else { 528 /* 529 * When denying unencrypted frames, discard 530 * any non-PAE frames received without encryption. 531 */ 532 if ((ic->ic_flags & IEEE80211_F_DROPUNENC) && 533 key == NULL && 534 eh->ether_type != htons(ETHERTYPE_PAE)) { 535 /* 536 * Drop unencrypted frames. 537 */ 538 ic->ic_stats.is_rx_unencrypted++; 539 IEEE80211_NODE_STAT(ni, rx_unencrypted); 540 goto out; 541 } 542 } 543 ifp->if_ipackets++; 544 IEEE80211_NODE_STAT(ni, rx_data); 545 IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); 546 547 #ifndef IEEE80211_NO_HOSTAP 548 /* perform as a bridge within the AP */ 549 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 550 (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) { 551 struct mbuf *m1 = NULL; 552 553 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 554 m1 = m_copypacket(m, M_DONTWAIT); 555 if (m1 == NULL) 556 ifp->if_oerrors++; 557 else 558 m1->m_flags |= M_MCAST; 559 } else { 560 /* XXX this dups work done in ieee80211_encap */ 561 /* check if destination is associated */ 562 struct ieee80211_node *ni1 = 563 ieee80211_find_node(&ic->ic_sta, 564 eh->ether_dhost); 565 if (ni1 != NULL) { 566 /* XXX check if authorized */ 567 if (ni1->ni_associd != 0) { 568 m1 = m; 569 m = NULL; 570 } 571 /* XXX statistic? */ 572 ieee80211_free_node(ni1); 573 } 574 } 575 if (m1 != NULL) { 576 int len = m1->m_pkthdr.len; 577 IF_ENQUEUE(&ifp->if_snd, m1); 578 if (m != NULL) 579 ifp->if_omcasts++; 580 ifp->if_obytes += len; 581 } 582 } 583 #endif /* !IEEE80211_NO_HOSTAP */ 584 if (m != NULL) { 585 #if NBPFILTER > 0 586 /* 587 * XXX If we forward packet into transmitter of the AP, 588 * we don't need to duplicate for DLT_EN10MB. 589 */ 590 if (ifp->if_bpf) 591 bpf_mtap(ifp->if_bpf, m); 592 #endif 593 if (ni->ni_vlan != 0) { 594 /* attach vlan tag */ 595 /* XXX goto err? */ 596 VLAN_INPUT_TAG(ifp, m, ni->ni_vlan, goto out); 597 } 598 (*ifp->if_input)(ifp, m); 599 } 600 return IEEE80211_FC0_TYPE_DATA; 601 602 case IEEE80211_FC0_TYPE_MGT: 603 IEEE80211_NODE_STAT(ni, rx_mgmt); 604 if (dir != IEEE80211_FC1_DIR_NODS) { 605 ic->ic_stats.is_rx_wrongdir++; 606 goto err; 607 } 608 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { 609 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, 610 ni->ni_macaddr, "mgt", "too short: len %u", 611 m->m_pkthdr.len); 612 ic->ic_stats.is_rx_tooshort++; 613 goto out; 614 } 615 #ifdef IEEE80211_DEBUG 616 if ((ieee80211_msg_debug(ic) && doprint(ic, subtype)) || 617 ieee80211_msg_dumppkts(ic)) { 618 if_printf(ic->ic_ifp, "received %s from %s rssi %d\n", 619 ieee80211_mgt_subtype_name[subtype >> 620 IEEE80211_FC0_SUBTYPE_SHIFT], 621 ether_sprintf(wh->i_addr2), rssi); 622 } 623 #endif 624 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 625 if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) { 626 /* 627 * Only shared key auth frames with a challenge 628 * should be encrypted, discard all others. 629 */ 630 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 631 wh, ieee80211_mgt_subtype_name[subtype >> 632 IEEE80211_FC0_SUBTYPE_SHIFT], 633 "%s", "WEP set but not permitted"); 634 ic->ic_stats.is_rx_mgtdiscard++; /* XXX */ 635 goto out; 636 } 637 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 638 /* 639 * Discard encrypted frames when privacy is off. 640 */ 641 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 642 wh, "mgt", "%s", "WEP set but PRIVACY off"); 643 ic->ic_stats.is_rx_noprivacy++; 644 goto out; 645 } 646 key = ieee80211_crypto_decap(ic, ni, m); 647 if (key == NULL) { 648 /* NB: stats+msgs handled in crypto_decap */ 649 goto out; 650 } 651 wh = mtod(m, struct ieee80211_frame *); 652 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 653 } 654 #if NBPFILTER > 0 655 if (ic->ic_rawbpf) 656 bpf_mtap(ic->ic_rawbpf, m); 657 #endif 658 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 659 m_freem(m); 660 return type; 661 662 case IEEE80211_FC0_TYPE_CTL: 663 IEEE80211_NODE_STAT(ni, rx_ctrl); 664 ic->ic_stats.is_rx_ctl++; 665 #ifndef IEEE80211_NO_HOSTAP 666 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 667 switch (subtype) { 668 case IEEE80211_FC0_SUBTYPE_PS_POLL: 669 ieee80211_recv_pspoll(ic, ni, m); 670 break; 671 } 672 } 673 #endif /* !IEEE80211_NO_HOSTAP */ 674 goto out; 675 default: 676 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 677 wh, NULL, "bad frame type 0x%x", type); 678 /* should not come here */ 679 break; 680 } 681 err: 682 ifp->if_ierrors++; 683 out: 684 if (m != NULL) { 685 #if NBPFILTER > 0 686 if (ic->ic_rawbpf) 687 bpf_mtap(ic->ic_rawbpf, m); 688 #endif 689 m_freem(m); 690 } 691 return type; 692 #undef SEQ_LEQ 693 } 694 695 /* 696 * This function reassemble fragments. 697 */ 698 static struct mbuf * 699 ieee80211_defrag(struct ieee80211com *ic, struct ieee80211_node *ni, 700 struct mbuf *m) 701 { 702 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); 703 struct ieee80211_frame *lwh; 704 u_int16_t rxseq; 705 u_int8_t fragno; 706 u_int8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG; 707 struct mbuf *mfrag; 708 709 IASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?")); 710 711 rxseq = le16toh(*(u_int16_t *)wh->i_seq); 712 fragno = rxseq & IEEE80211_SEQ_FRAG_MASK; 713 714 /* Quick way out, if there's nothing to defragment */ 715 if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL) 716 return m; 717 718 /* 719 * Remove frag to insure it doesn't get reaped by timer. 720 */ 721 if (ni->ni_table == NULL) { 722 /* 723 * Should never happen. If the node is orphaned (not in 724 * the table) then input packets should not reach here. 725 * Otherwise, a concurrent request that yanks the table 726 * should be blocked by other interlocking and/or by first 727 * shutting the driver down. Regardless, be defensive 728 * here and just bail 729 */ 730 /* XXX need msg+stat */ 731 m_freem(m); 732 return NULL; 733 } 734 IEEE80211_NODE_LOCK(ni->ni_table); 735 mfrag = ni->ni_rxfrag[0]; 736 ni->ni_rxfrag[0] = NULL; 737 IEEE80211_NODE_UNLOCK(ni->ni_table); 738 739 /* 740 * Validate new fragment is in order and 741 * related to the previous ones. 742 */ 743 if (mfrag != NULL) { 744 u_int16_t last_rxseq; 745 746 lwh = mtod(mfrag, struct ieee80211_frame *); 747 last_rxseq = le16toh(*(u_int16_t *)lwh->i_seq); 748 /* NB: check seq # and frag together */ 749 if (rxseq != last_rxseq+1 || 750 !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) || 751 !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) { 752 /* 753 * Unrelated fragment or no space for it, 754 * clear current fragments. 755 */ 756 m_freem(mfrag); 757 mfrag = NULL; 758 } 759 } 760 761 if (mfrag == NULL) { 762 if (fragno != 0) { /* !first fragment, discard */ 763 IEEE80211_NODE_STAT(ni, rx_defrag); 764 m_freem(m); 765 return NULL; 766 } 767 mfrag = m; 768 } else { /* concatenate */ 769 m_cat(mfrag, m); 770 /* NB: m_cat doesn't update the packet header */ 771 mfrag->m_pkthdr.len += m->m_pkthdr.len; 772 /* track last seqnum and fragno */ 773 lwh = mtod(mfrag, struct ieee80211_frame *); 774 *(u_int16_t *) lwh->i_seq = *(u_int16_t *) wh->i_seq; 775 } 776 if (more_frag) { /* more to come, save */ 777 ni->ni_rxfragstamp = ticks; 778 ni->ni_rxfrag[0] = mfrag; 779 mfrag = NULL; 780 } 781 return mfrag; 782 } 783 784 static struct mbuf * 785 ieee80211_decap(struct ieee80211com *ic, struct mbuf *m) 786 { 787 struct ieee80211_frame wh; /* NB: QoS stripped above */ 788 struct ether_header *eh; 789 struct llc *llc; 790 791 if (m->m_len < sizeof(wh) + sizeof(*llc) && 792 (m = m_pullup(m, sizeof(wh) + sizeof(*llc))) == NULL) { 793 /* XXX stat, msg */ 794 return NULL; 795 } 796 memcpy(&wh, mtod(m, caddr_t), sizeof(wh)); 797 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh)); 798 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 799 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 800 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 801 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh)); 802 llc = NULL; 803 } else { 804 m_adj(m, sizeof(wh) - sizeof(*eh)); 805 } 806 eh = mtod(m, struct ether_header *); 807 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 808 case IEEE80211_FC1_DIR_NODS: 809 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 810 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 811 break; 812 case IEEE80211_FC1_DIR_TODS: 813 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 814 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 815 break; 816 case IEEE80211_FC1_DIR_FROMDS: 817 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 818 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 819 break; 820 case IEEE80211_FC1_DIR_DSTODS: 821 /* not yet supported */ 822 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 823 &wh, "data", "%s", "DS to DS not supported"); 824 m_freem(m); 825 return NULL; 826 } 827 #ifdef ALIGNED_POINTER 828 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) { 829 struct mbuf *n, *n0, **np; 830 caddr_t newdata; 831 int off, pktlen; 832 833 n0 = NULL; 834 np = &n0; 835 off = 0; 836 pktlen = m->m_pkthdr.len; 837 while (pktlen > off) { 838 if (n0 == NULL) { 839 MGETHDR(n, M_DONTWAIT, MT_DATA); 840 if (n == NULL) { 841 m_freem(m); 842 return NULL; 843 } 844 M_COPY_PKTHDR(n, m); 845 n->m_len = MHLEN; 846 } else { 847 MGET(n, M_DONTWAIT, MT_DATA); 848 if (n == NULL) { 849 m_freem(m); 850 m_freem(n0); 851 return NULL; 852 } 853 n->m_len = MLEN; 854 } 855 if (pktlen - off >= MINCLSIZE) { 856 MCLGET(n, M_DONTWAIT); 857 if (n->m_flags & M_EXT) 858 n->m_len = n->m_ext.ext_size; 859 } 860 if (n0 == NULL) { 861 newdata = 862 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) - 863 sizeof(*eh); 864 n->m_len -= newdata - n->m_data; 865 n->m_data = newdata; 866 } 867 if (n->m_len > pktlen - off) 868 n->m_len = pktlen - off; 869 m_copydata(m, off, n->m_len, mtod(n, caddr_t)); 870 off += n->m_len; 871 *np = n; 872 np = &n->m_next; 873 } 874 m_freem(m); 875 m = n0; 876 } 877 #endif /* ALIGNED_POINTER */ 878 if (llc != NULL) { 879 eh = mtod(m, struct ether_header *); 880 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 881 } 882 return m; 883 } 884 885 /* 886 * Install received rate set information in the node's state block. 887 */ 888 static int 889 ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni, 890 u_int8_t *rates, u_int8_t *xrates, int flags) 891 { 892 struct ieee80211_rateset *rs = &ni->ni_rates; 893 894 memset(rs, 0, sizeof(*rs)); 895 rs->rs_nrates = rates[1]; 896 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 897 if (xrates != NULL) { 898 u_int8_t nxrates; 899 /* 900 * Tack on 11g extended supported rate element. 901 */ 902 nxrates = xrates[1]; 903 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 904 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 905 IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE, 906 "[%s] extended rate set too large;" 907 " only using %u of %u rates\n", 908 ether_sprintf(ni->ni_macaddr), nxrates, xrates[1]); 909 ic->ic_stats.is_rx_rstoobig++; 910 } 911 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 912 rs->rs_nrates += nxrates; 913 } 914 return ieee80211_fix_rate(ic, ni, flags); 915 } 916 917 static void 918 ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh, 919 struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq, 920 u_int16_t status) 921 { 922 923 switch (ic->ic_opmode) { 924 case IEEE80211_M_IBSS: 925 if (ic->ic_state != IEEE80211_S_RUN || 926 seq != IEEE80211_AUTH_OPEN_REQUEST) { 927 ic->ic_stats.is_rx_bad_auth++; 928 return; 929 } 930 ieee80211_new_state(ic, IEEE80211_S_AUTH, 931 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 932 break; 933 934 case IEEE80211_M_AHDEMO: 935 /* should not come here */ 936 break; 937 938 case IEEE80211_M_HOSTAP: 939 #ifndef IEEE80211_NO_HOSTAP 940 if (ic->ic_state != IEEE80211_S_RUN || 941 seq != IEEE80211_AUTH_OPEN_REQUEST) { 942 ic->ic_stats.is_rx_bad_auth++; 943 return; 944 } 945 /* always accept open authentication requests */ 946 if (ni == ic->ic_bss) { 947 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 948 if (ni == NULL) 949 return; 950 } else 951 (void) ieee80211_ref_node(ni); 952 IEEE80211_SEND_MGMT(ic, ni, 953 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 954 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 955 "[%s] station authenticated (open)\n", 956 ether_sprintf(ni->ni_macaddr)); 957 #endif /* !IEEE80211_NO_HOSTAP */ 958 break; 959 960 case IEEE80211_M_STA: 961 if (ic->ic_state != IEEE80211_S_AUTH || 962 seq != IEEE80211_AUTH_OPEN_RESPONSE) { 963 ic->ic_stats.is_rx_bad_auth++; 964 return; 965 } 966 if (status != 0) { 967 IEEE80211_DPRINTF(ic, 968 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 969 "[%s] open auth failed (reason %d)\n", 970 ether_sprintf(ni->ni_macaddr), status); 971 /* XXX can this happen? */ 972 if (ni != ic->ic_bss) 973 ni->ni_fails++; 974 ic->ic_stats.is_rx_auth_fail++; 975 return; 976 } 977 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 978 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 979 break; 980 case IEEE80211_M_MONITOR: 981 break; 982 } 983 } 984 985 static int 986 alloc_challenge(struct ieee80211com *ic, struct ieee80211_node *ni) 987 { 988 if (ni->ni_challenge == NULL) 989 MALLOC(ni->ni_challenge, u_int32_t*, IEEE80211_CHALLENGE_LEN, 990 M_DEVBUF, M_NOWAIT); 991 if (ni->ni_challenge == NULL) { 992 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 993 "[%s] shared key challenge alloc failed\n", 994 ether_sprintf(ni->ni_macaddr)); 995 /* XXX statistic */ 996 } 997 return (ni->ni_challenge != NULL); 998 } 999 1000 /* XXX TODO: add statistics */ 1001 static void 1002 ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh, 1003 u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi, 1004 u_int32_t rstamp, u_int16_t seq, u_int16_t status) 1005 { 1006 u_int8_t *challenge; 1007 int estatus; 1008 1009 /* 1010 * NB: this can happen as we allow pre-shared key 1011 * authentication to be enabled w/o wep being turned 1012 * on so that configuration of these can be done 1013 * in any order. It may be better to enforce the 1014 * ordering in which case this check would just be 1015 * for sanity/consistency. 1016 */ 1017 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 1018 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1019 ni->ni_macaddr, "shared key auth", 1020 "%s", " PRIVACY is disabled"); 1021 estatus = IEEE80211_STATUS_ALG; 1022 goto bad; 1023 } 1024 /* 1025 * Pre-shared key authentication is evil; accept 1026 * it only if explicitly configured (it is supported 1027 * mainly for compatibility with clients like OS X). 1028 */ 1029 if (ni->ni_authmode != IEEE80211_AUTH_AUTO && 1030 ni->ni_authmode != IEEE80211_AUTH_SHARED) { 1031 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1032 ni->ni_macaddr, "shared key auth", 1033 "bad sta auth mode %u", ni->ni_authmode); 1034 ic->ic_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ 1035 estatus = IEEE80211_STATUS_ALG; 1036 goto bad; 1037 } 1038 1039 challenge = NULL; 1040 if (frm + 1 < efrm) { 1041 if ((frm[1] + 2) > (efrm - frm)) { 1042 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1043 ni->ni_macaddr, "shared key auth", 1044 "ie %d/%d too long", 1045 frm[0], (frm[1] + 2) - (efrm - frm)); 1046 ic->ic_stats.is_rx_bad_auth++; 1047 estatus = IEEE80211_STATUS_CHALLENGE; 1048 goto bad; 1049 } 1050 if (*frm == IEEE80211_ELEMID_CHALLENGE) 1051 challenge = frm; 1052 frm += frm[1] + 2; 1053 } 1054 switch (seq) { 1055 case IEEE80211_AUTH_SHARED_CHALLENGE: 1056 case IEEE80211_AUTH_SHARED_RESPONSE: 1057 if (challenge == NULL) { 1058 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1059 ni->ni_macaddr, "shared key auth", 1060 "%s", "no challenge"); 1061 ic->ic_stats.is_rx_bad_auth++; 1062 estatus = IEEE80211_STATUS_CHALLENGE; 1063 goto bad; 1064 } 1065 if (challenge[1] != IEEE80211_CHALLENGE_LEN) { 1066 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1067 ni->ni_macaddr, "shared key auth", 1068 "bad challenge len %d", challenge[1]); 1069 ic->ic_stats.is_rx_bad_auth++; 1070 estatus = IEEE80211_STATUS_CHALLENGE; 1071 goto bad; 1072 } 1073 default: 1074 break; 1075 } 1076 switch (ic->ic_opmode) { 1077 case IEEE80211_M_MONITOR: 1078 case IEEE80211_M_AHDEMO: 1079 case IEEE80211_M_IBSS: 1080 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1081 ni->ni_macaddr, "shared key auth", 1082 "bad operating mode %u", ic->ic_opmode); 1083 return; 1084 case IEEE80211_M_HOSTAP: 1085 #ifndef IEEE80211_NO_HOSTAP 1086 { 1087 int allocbs; 1088 if (ic->ic_state != IEEE80211_S_RUN) { 1089 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1090 ni->ni_macaddr, "shared key auth", 1091 "bad state %u", ic->ic_state); 1092 estatus = IEEE80211_STATUS_ALG; /* XXX */ 1093 goto bad; 1094 } 1095 switch (seq) { 1096 case IEEE80211_AUTH_SHARED_REQUEST: 1097 if (ni == ic->ic_bss) { 1098 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 1099 if (ni == NULL) { 1100 /* NB: no way to return an error */ 1101 return; 1102 } 1103 allocbs = 1; 1104 } else { 1105 (void) ieee80211_ref_node(ni); 1106 allocbs = 0; 1107 } 1108 ni->ni_rssi = rssi; 1109 ni->ni_rstamp = rstamp; 1110 if (!alloc_challenge(ic, ni)) { 1111 /* NB: don't return error so they rexmit */ 1112 return; 1113 } 1114 get_random_bytes(ni->ni_challenge, 1115 IEEE80211_CHALLENGE_LEN); 1116 IEEE80211_DPRINTF(ic, 1117 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1118 "[%s] shared key %sauth request\n", 1119 ether_sprintf(ni->ni_macaddr), 1120 allocbs ? "" : "re"); 1121 break; 1122 case IEEE80211_AUTH_SHARED_RESPONSE: 1123 if (ni == ic->ic_bss) { 1124 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1125 ni->ni_macaddr, "shared key response", 1126 "%s", "unknown station"); 1127 /* NB: don't send a response */ 1128 return; 1129 } 1130 if (ni->ni_challenge == NULL) { 1131 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1132 ni->ni_macaddr, "shared key response", 1133 "%s", "no challenge recorded"); 1134 ic->ic_stats.is_rx_bad_auth++; 1135 estatus = IEEE80211_STATUS_CHALLENGE; 1136 goto bad; 1137 } 1138 if (memcmp(ni->ni_challenge, &challenge[2], 1139 challenge[1]) != 0) { 1140 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1141 ni->ni_macaddr, "shared key response", 1142 "%s", "challenge mismatch"); 1143 ic->ic_stats.is_rx_auth_fail++; 1144 estatus = IEEE80211_STATUS_CHALLENGE; 1145 goto bad; 1146 } 1147 IEEE80211_DPRINTF(ic, 1148 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1149 "[%s] station authenticated (shared key)\n", 1150 ether_sprintf(ni->ni_macaddr)); 1151 break; 1152 default: 1153 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1154 ni->ni_macaddr, "shared key auth", 1155 "bad seq %d", seq); 1156 ic->ic_stats.is_rx_bad_auth++; 1157 estatus = IEEE80211_STATUS_SEQUENCE; 1158 goto bad; 1159 } 1160 IEEE80211_SEND_MGMT(ic, ni, 1161 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 1162 } 1163 #endif /* !IEEE80211_NO_HOSTAP */ 1164 break; 1165 1166 case IEEE80211_M_STA: 1167 if (ic->ic_state != IEEE80211_S_AUTH) 1168 return; 1169 switch (seq) { 1170 case IEEE80211_AUTH_SHARED_PASS: 1171 if (ni->ni_challenge != NULL) { 1172 FREE(ni->ni_challenge, M_DEVBUF); 1173 ni->ni_challenge = NULL; 1174 } 1175 if (status != 0) { 1176 IEEE80211_DPRINTF(ic, 1177 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1178 "[%s] shared key auth failed (reason %d)\n", 1179 ether_sprintf(ieee80211_getbssid(ic, wh)), 1180 status); 1181 /* XXX can this happen? */ 1182 if (ni != ic->ic_bss) 1183 ni->ni_fails++; 1184 ic->ic_stats.is_rx_auth_fail++; 1185 return; 1186 } 1187 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1188 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1189 break; 1190 case IEEE80211_AUTH_SHARED_CHALLENGE: 1191 if (!alloc_challenge(ic, ni)) 1192 return; 1193 /* XXX could optimize by passing recvd challenge */ 1194 memcpy(ni->ni_challenge, &challenge[2], challenge[1]); 1195 IEEE80211_SEND_MGMT(ic, ni, 1196 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 1197 break; 1198 default: 1199 IEEE80211_DISCARD(ic, IEEE80211_MSG_AUTH, 1200 wh, "shared key auth", "bad seq %d", seq); 1201 ic->ic_stats.is_rx_bad_auth++; 1202 return; 1203 } 1204 break; 1205 } 1206 return; 1207 bad: 1208 #ifndef IEEE80211_NO_HOSTAP 1209 /* 1210 * Send an error response; but only when operating as an AP. 1211 */ 1212 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1213 /* XXX hack to workaround calling convention */ 1214 IEEE80211_SEND_MGMT(ic, ni, 1215 IEEE80211_FC0_SUBTYPE_AUTH, 1216 (seq + 1) | (estatus<<16)); 1217 } 1218 #else 1219 ; 1220 #endif /* !IEEE80211_NO_HOSTAP */ 1221 } 1222 1223 /* Verify the existence and length of __elem or get out. */ 1224 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 1225 if ((__elem) == NULL) { \ 1226 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 1227 wh, ieee80211_mgt_subtype_name[subtype >> \ 1228 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1229 "%s", "no " #__elem ); \ 1230 ic->ic_stats.is_rx_elem_missing++; \ 1231 return; \ 1232 } \ 1233 if ((__elem)[1] > (__maxlen)) { \ 1234 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 1235 wh, ieee80211_mgt_subtype_name[subtype >> \ 1236 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1237 "bad " #__elem " len %d", (__elem)[1]); \ 1238 ic->ic_stats.is_rx_elem_toobig++; \ 1239 return; \ 1240 } \ 1241 } while (0) 1242 1243 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 1244 if ((_len) < (_minlen)) { \ 1245 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 1246 wh, ieee80211_mgt_subtype_name[subtype >> \ 1247 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1248 "%s", "ie too short"); \ 1249 ic->ic_stats.is_rx_elem_toosmall++; \ 1250 return; \ 1251 } \ 1252 } while (0) 1253 1254 #ifdef IEEE80211_DEBUG 1255 static void 1256 ieee80211_ssid_mismatch(struct ieee80211com *ic, const char *tag, 1257 u_int8_t mac[IEEE80211_ADDR_LEN], u_int8_t *ssid) 1258 { 1259 printf("[%s] discard %s frame, ssid mismatch: ", 1260 ether_sprintf(mac), tag); 1261 ieee80211_print_essid(ssid + 2, ssid[1]); 1262 printf("\n"); 1263 } 1264 1265 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \ 1266 if ((_ssid)[1] != 0 && \ 1267 ((_ssid)[1] != (_ni)->ni_esslen || \ 1268 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 1269 if (ieee80211_msg_input(ic)) \ 1270 ieee80211_ssid_mismatch(ic, \ 1271 ieee80211_mgt_subtype_name[subtype >> \ 1272 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1273 wh->i_addr2, _ssid); \ 1274 ic->ic_stats.is_rx_ssidmismatch++; \ 1275 return; \ 1276 } \ 1277 } while (0) 1278 #else /* !IEEE80211_DEBUG */ 1279 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \ 1280 if ((_ssid)[1] != 0 && \ 1281 ((_ssid)[1] != (_ni)->ni_esslen || \ 1282 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 1283 ic->ic_stats.is_rx_ssidmismatch++; \ 1284 return; \ 1285 } \ 1286 } while (0) 1287 #endif /* !IEEE80211_DEBUG */ 1288 1289 /* unalligned little endian access */ 1290 #define LE_READ_2(p) \ 1291 ((u_int16_t) \ 1292 ((((const u_int8_t *)(p))[0] ) | \ 1293 (((const u_int8_t *)(p))[1] << 8))) 1294 #define LE_READ_4(p) \ 1295 ((u_int32_t) \ 1296 ((((const u_int8_t *)(p))[0] ) | \ 1297 (((const u_int8_t *)(p))[1] << 8) | \ 1298 (((const u_int8_t *)(p))[2] << 16) | \ 1299 (((const u_int8_t *)(p))[3] << 24))) 1300 1301 static int __inline 1302 iswpaoui(const u_int8_t *frm) 1303 { 1304 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); 1305 } 1306 1307 static int __inline 1308 iswmeoui(const u_int8_t *frm) 1309 { 1310 return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); 1311 } 1312 1313 static int __inline 1314 iswmeparam(const u_int8_t *frm) 1315 { 1316 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && 1317 frm[6] == WME_PARAM_OUI_SUBTYPE; 1318 } 1319 1320 static int __inline 1321 iswmeinfo(const u_int8_t *frm) 1322 { 1323 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && 1324 frm[6] == WME_INFO_OUI_SUBTYPE; 1325 } 1326 1327 static int __inline 1328 isatherosoui(const u_int8_t *frm) 1329 { 1330 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); 1331 } 1332 1333 /* 1334 * Convert a WPA cipher selector OUI to an internal 1335 * cipher algorithm. Where appropriate we also 1336 * record any key length. 1337 */ 1338 static int 1339 wpa_cipher(u_int8_t *sel, u_int8_t *keylen) 1340 { 1341 #define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1342 u_int32_t w = LE_READ_4(sel); 1343 1344 switch (w) { 1345 case WPA_SEL(WPA_CSE_NULL): 1346 return IEEE80211_CIPHER_NONE; 1347 case WPA_SEL(WPA_CSE_WEP40): 1348 if (keylen) 1349 *keylen = 40 / NBBY; 1350 return IEEE80211_CIPHER_WEP; 1351 case WPA_SEL(WPA_CSE_WEP104): 1352 if (keylen) 1353 *keylen = 104 / NBBY; 1354 return IEEE80211_CIPHER_WEP; 1355 case WPA_SEL(WPA_CSE_TKIP): 1356 return IEEE80211_CIPHER_TKIP; 1357 case WPA_SEL(WPA_CSE_CCMP): 1358 return IEEE80211_CIPHER_AES_CCM; 1359 } 1360 return 32; /* NB: so 1<< is discarded */ 1361 #undef WPA_SEL 1362 } 1363 1364 /* 1365 * Convert a WPA key management/authentication algorithm 1366 * to an internal code. 1367 */ 1368 static int 1369 wpa_keymgmt(u_int8_t *sel) 1370 { 1371 #define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1372 u_int32_t w = LE_READ_4(sel); 1373 1374 switch (w) { 1375 case WPA_SEL(WPA_ASE_8021X_UNSPEC): 1376 return WPA_ASE_8021X_UNSPEC; 1377 case WPA_SEL(WPA_ASE_8021X_PSK): 1378 return WPA_ASE_8021X_PSK; 1379 case WPA_SEL(WPA_ASE_NONE): 1380 return WPA_ASE_NONE; 1381 } 1382 return 0; /* NB: so is discarded */ 1383 #undef WPA_SEL 1384 } 1385 1386 /* 1387 * Parse a WPA information element to collect parameters 1388 * and validate the parameters against what has been 1389 * configured for the system. 1390 */ 1391 static int 1392 ieee80211_parse_wpa(struct ieee80211com *ic, u_int8_t *frm, 1393 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1394 { 1395 u_int8_t len = frm[1]; 1396 u_int32_t w; 1397 int n; 1398 1399 /* 1400 * Check the length once for fixed parts: OUI, type, 1401 * version, mcast cipher, and 2 selector counts. 1402 * Other, variable-length data, must be checked separately. 1403 */ 1404 IASSERT(ic->ic_flags & IEEE80211_F_WPA1, 1405 ("not WPA, flags 0x%x", ic->ic_flags)); 1406 if (len < 14) { 1407 IEEE80211_DISCARD_IE(ic, 1408 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1409 wh, "WPA", "too short, len %u", len); 1410 return IEEE80211_REASON_IE_INVALID; 1411 } 1412 frm += 6, len -= 4; /* NB: len is payload only */ 1413 /* NB: iswapoui already validated the OUI and type */ 1414 w = LE_READ_2(frm); 1415 if (w != WPA_VERSION) { 1416 IEEE80211_DISCARD_IE(ic, 1417 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1418 wh, "WPA", "bad version %u", w); 1419 return IEEE80211_REASON_IE_INVALID; 1420 } 1421 frm += 2, len -= 2; 1422 1423 /* multicast/group cipher */ 1424 w = wpa_cipher(frm, &rsn->rsn_mcastkeylen); 1425 if (w != rsn->rsn_mcastcipher) { 1426 IEEE80211_DISCARD_IE(ic, 1427 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1428 wh, "WPA", "mcast cipher mismatch; got %u, expected %u", 1429 w, rsn->rsn_mcastcipher); 1430 return IEEE80211_REASON_IE_INVALID; 1431 } 1432 frm += 4, len -= 4; 1433 1434 /* unicast ciphers */ 1435 n = LE_READ_2(frm); 1436 frm += 2, len -= 2; 1437 if (len < n*4+2) { 1438 IEEE80211_DISCARD_IE(ic, 1439 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1440 wh, "WPA", "ucast cipher data too short; len %u, n %u", 1441 len, n); 1442 return IEEE80211_REASON_IE_INVALID; 1443 } 1444 w = 0; 1445 for (; n > 0; n--) { 1446 w |= 1<<wpa_cipher(frm, &rsn->rsn_ucastkeylen); 1447 frm += 4, len -= 4; 1448 } 1449 w &= rsn->rsn_ucastcipherset; 1450 if (w == 0) { 1451 IEEE80211_DISCARD_IE(ic, 1452 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1453 wh, "WPA", "%s", "ucast cipher set empty"); 1454 return IEEE80211_REASON_IE_INVALID; 1455 } 1456 if (w & (1<<IEEE80211_CIPHER_TKIP)) 1457 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1458 else 1459 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1460 1461 /* key management algorithms */ 1462 n = LE_READ_2(frm); 1463 frm += 2, len -= 2; 1464 if (len < n*4) { 1465 IEEE80211_DISCARD_IE(ic, 1466 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1467 wh, "WPA", "key mgmt alg data too short; len %u, n %u", 1468 len, n); 1469 return IEEE80211_REASON_IE_INVALID; 1470 } 1471 w = 0; 1472 for (; n > 0; n--) { 1473 w |= wpa_keymgmt(frm); 1474 frm += 4, len -= 4; 1475 } 1476 w &= rsn->rsn_keymgmtset; 1477 if (w == 0) { 1478 IEEE80211_DISCARD_IE(ic, 1479 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1480 wh, "WPA", "%s", "no acceptable key mgmt alg"); 1481 return IEEE80211_REASON_IE_INVALID; 1482 } 1483 if (w & WPA_ASE_8021X_UNSPEC) 1484 rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC; 1485 else 1486 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK; 1487 1488 if (len > 2) /* optional capabilities */ 1489 rsn->rsn_caps = LE_READ_2(frm); 1490 1491 return 0; 1492 } 1493 1494 /* 1495 * Convert an RSN cipher selector OUI to an internal 1496 * cipher algorithm. Where appropriate we also 1497 * record any key length. 1498 */ 1499 static int 1500 rsn_cipher(u_int8_t *sel, u_int8_t *keylen) 1501 { 1502 #define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1503 u_int32_t w = LE_READ_4(sel); 1504 1505 switch (w) { 1506 case RSN_SEL(RSN_CSE_NULL): 1507 return IEEE80211_CIPHER_NONE; 1508 case RSN_SEL(RSN_CSE_WEP40): 1509 if (keylen) 1510 *keylen = 40 / NBBY; 1511 return IEEE80211_CIPHER_WEP; 1512 case RSN_SEL(RSN_CSE_WEP104): 1513 if (keylen) 1514 *keylen = 104 / NBBY; 1515 return IEEE80211_CIPHER_WEP; 1516 case RSN_SEL(RSN_CSE_TKIP): 1517 return IEEE80211_CIPHER_TKIP; 1518 case RSN_SEL(RSN_CSE_CCMP): 1519 return IEEE80211_CIPHER_AES_CCM; 1520 case RSN_SEL(RSN_CSE_WRAP): 1521 return IEEE80211_CIPHER_AES_OCB; 1522 } 1523 return 32; /* NB: so 1<< is discarded */ 1524 #undef WPA_SEL 1525 } 1526 1527 /* 1528 * Convert an RSN key management/authentication algorithm 1529 * to an internal code. 1530 */ 1531 static int 1532 rsn_keymgmt(u_int8_t *sel) 1533 { 1534 #define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1535 u_int32_t w = LE_READ_4(sel); 1536 1537 switch (w) { 1538 case RSN_SEL(RSN_ASE_8021X_UNSPEC): 1539 return RSN_ASE_8021X_UNSPEC; 1540 case RSN_SEL(RSN_ASE_8021X_PSK): 1541 return RSN_ASE_8021X_PSK; 1542 case RSN_SEL(RSN_ASE_NONE): 1543 return RSN_ASE_NONE; 1544 } 1545 return 0; /* NB: so is discarded */ 1546 #undef RSN_SEL 1547 } 1548 1549 /* 1550 * Parse a WPA/RSN information element to collect parameters 1551 * and validate the parameters against what has been 1552 * configured for the system. 1553 */ 1554 static int 1555 ieee80211_parse_rsn(struct ieee80211com *ic, u_int8_t *frm, 1556 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1557 { 1558 u_int8_t len = frm[1]; 1559 u_int32_t w; 1560 int n; 1561 1562 /* 1563 * Check the length once for fixed parts: 1564 * version, mcast cipher, and 2 selector counts. 1565 * Other, variable-length data, must be checked separately. 1566 */ 1567 IASSERT(ic->ic_flags & IEEE80211_F_WPA2, 1568 ("not RSN, flags 0x%x", ic->ic_flags)); 1569 if (len < 10) { 1570 IEEE80211_DISCARD_IE(ic, 1571 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1572 wh, "RSN", "too short, len %u", len); 1573 return IEEE80211_REASON_IE_INVALID; 1574 } 1575 frm += 2; 1576 w = LE_READ_2(frm); 1577 if (w != RSN_VERSION) { 1578 IEEE80211_DISCARD_IE(ic, 1579 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1580 wh, "RSN", "bad version %u", w); 1581 return IEEE80211_REASON_IE_INVALID; 1582 } 1583 frm += 2, len -= 2; 1584 1585 /* multicast/group cipher */ 1586 w = rsn_cipher(frm, &rsn->rsn_mcastkeylen); 1587 if (w != rsn->rsn_mcastcipher) { 1588 IEEE80211_DISCARD_IE(ic, 1589 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1590 wh, "RSN", "mcast cipher mismatch; got %u, expected %u", 1591 w, rsn->rsn_mcastcipher); 1592 return IEEE80211_REASON_IE_INVALID; 1593 } 1594 frm += 4, len -= 4; 1595 1596 /* unicast ciphers */ 1597 n = LE_READ_2(frm); 1598 frm += 2, len -= 2; 1599 if (len < n*4+2) { 1600 IEEE80211_DISCARD_IE(ic, 1601 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1602 wh, "RSN", "ucast cipher data too short; len %u, n %u", 1603 len, n); 1604 return IEEE80211_REASON_IE_INVALID; 1605 } 1606 w = 0; 1607 for (; n > 0; n--) { 1608 w |= 1<<rsn_cipher(frm, &rsn->rsn_ucastkeylen); 1609 frm += 4, len -= 4; 1610 } 1611 w &= rsn->rsn_ucastcipherset; 1612 if (w == 0) { 1613 IEEE80211_DISCARD_IE(ic, 1614 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1615 wh, "RSN", "%s", "ucast cipher set empty"); 1616 return IEEE80211_REASON_IE_INVALID; 1617 } 1618 if (w & (1<<IEEE80211_CIPHER_TKIP)) 1619 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1620 else 1621 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1622 1623 /* key management algorithms */ 1624 n = LE_READ_2(frm); 1625 frm += 2, len -= 2; 1626 if (len < n*4) { 1627 IEEE80211_DISCARD_IE(ic, 1628 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1629 wh, "RSN", "key mgmt alg data too short; len %u, n %u", 1630 len, n); 1631 return IEEE80211_REASON_IE_INVALID; 1632 } 1633 w = 0; 1634 for (; n > 0; n--) { 1635 w |= rsn_keymgmt(frm); 1636 frm += 4, len -= 4; 1637 } 1638 w &= rsn->rsn_keymgmtset; 1639 if (w == 0) { 1640 IEEE80211_DISCARD_IE(ic, 1641 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1642 wh, "RSN", "%s", "no acceptable key mgmt alg"); 1643 return IEEE80211_REASON_IE_INVALID; 1644 } 1645 if (w & RSN_ASE_8021X_UNSPEC) 1646 rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC; 1647 else 1648 rsn->rsn_keymgmt = RSN_ASE_8021X_PSK; 1649 1650 /* optional RSN capabilities */ 1651 if (len > 2) 1652 rsn->rsn_caps = LE_READ_2(frm); 1653 /* XXXPMKID */ 1654 1655 return 0; 1656 } 1657 1658 static int 1659 ieee80211_parse_wmeparams(struct ieee80211com *ic, u_int8_t *frm, 1660 const struct ieee80211_frame *wh) 1661 { 1662 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 1663 struct ieee80211_wme_state *wme = &ic->ic_wme; 1664 u_int len = frm[1], qosinfo; 1665 int i; 1666 1667 if (len < sizeof(struct ieee80211_wme_param)-2) { 1668 IEEE80211_DISCARD_IE(ic, 1669 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME, 1670 wh, "WME", "too short, len %u", len); 1671 return -1; 1672 } 1673 qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)]; 1674 qosinfo &= WME_QOSINFO_COUNT; 1675 /* XXX do proper check for wraparound */ 1676 if (qosinfo == wme->wme_wmeChanParams.cap_info) 1677 return 0; 1678 frm += __offsetof(struct ieee80211_wme_param, params_acParams); 1679 for (i = 0; i < WME_NUM_AC; i++) { 1680 struct wmeParams *wmep = 1681 &wme->wme_wmeChanParams.cap_wmeParams[i]; 1682 /* NB: ACI not used */ 1683 wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM); 1684 wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN); 1685 wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN); 1686 wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX); 1687 wmep->wmep_txopLimit = LE_READ_2(frm+2); 1688 frm += 4; 1689 } 1690 wme->wme_wmeChanParams.cap_info = qosinfo; 1691 return 1; 1692 #undef MS 1693 } 1694 1695 static void 1696 ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie) 1697 { 1698 u_int ielen = ie[1]+2; 1699 /* 1700 * Record information element for later use. 1701 */ 1702 if (*iep == NULL || (*iep)[1] != ie[1]) { 1703 if (*iep != NULL) 1704 FREE(*iep, M_DEVBUF); 1705 MALLOC(*iep, void*, ielen, M_DEVBUF, M_NOWAIT); 1706 } 1707 if (*iep != NULL) 1708 memcpy(*iep, ie, ielen); 1709 /* XXX note failure */ 1710 } 1711 1712 #ifdef IEEE80211_DEBUG 1713 static void 1714 dump_probe_beacon(u_int8_t subtype, int isnew, 1715 const u_int8_t mac[IEEE80211_ADDR_LEN], 1716 u_int8_t chan, u_int8_t bchan, u_int16_t capinfo, u_int16_t bintval, 1717 u_int8_t erp, u_int8_t *ssid, u_int8_t *country) 1718 { 1719 printf("[%s] %s%s on chan %u (bss chan %u) ", 1720 ether_sprintf(mac), isnew ? "new " : "", 1721 ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT], 1722 chan, bchan); 1723 ieee80211_print_essid(ssid + 2, ssid[1]); 1724 printf("\n"); 1725 1726 if (isnew) { 1727 printf("[%s] caps 0x%x bintval %u erp 0x%x", 1728 ether_sprintf(mac), capinfo, bintval, erp); 1729 if (country) { 1730 #ifdef __FreeBSD__ 1731 printf(" country info %*D", country[1], country+2, " "); 1732 #else 1733 int i; 1734 printf(" country info"); 1735 for (i = 0; i < country[1]; i++) 1736 printf(" %02x", country[i+2]); 1737 #endif 1738 } 1739 printf("\n"); 1740 } 1741 } 1742 #endif /* IEEE80211_DEBUG */ 1743 1744 void 1745 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 1746 struct ieee80211_node *ni, 1747 int subtype, int rssi, u_int32_t rstamp) 1748 { 1749 #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 1750 #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) 1751 struct ieee80211_frame *wh; 1752 u_int8_t *frm, *efrm; 1753 u_int8_t *ssid, *rates, *xrates, *wpa, *wme; 1754 int reassoc, resp, allocbs; 1755 1756 wh = mtod(m0, struct ieee80211_frame *); 1757 frm = (u_int8_t *)&wh[1]; 1758 efrm = mtod(m0, u_int8_t *) + m0->m_len; 1759 switch (subtype) { 1760 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 1761 case IEEE80211_FC0_SUBTYPE_BEACON: { 1762 u_int8_t *tstamp, *country; 1763 u_int8_t chan, bchan, fhindex, erp; 1764 u_int16_t capinfo, bintval, timoff; 1765 u_int16_t fhdwell; 1766 1767 /* 1768 * We process beacon/probe response frames: 1769 * o when scanning, or 1770 * o station mode when associated (to collect state 1771 * updates such as 802.11g slot time), or 1772 * o adhoc mode (to discover neighbors) 1773 * Frames otherwise received are discarded. 1774 */ 1775 if (!((ic->ic_flags & IEEE80211_F_SCAN) || 1776 (ic->ic_opmode == IEEE80211_M_STA && ni->ni_associd) || 1777 ic->ic_opmode == IEEE80211_M_IBSS)) { 1778 ic->ic_stats.is_rx_mgtdiscard++; 1779 return; 1780 } 1781 /* 1782 * beacon/probe response frame format 1783 * [8] time stamp 1784 * [2] beacon interval 1785 * [2] capability information 1786 * [tlv] ssid 1787 * [tlv] supported rates 1788 * [tlv] country information 1789 * [tlv] parameter set (FH/DS) 1790 * [tlv] erp information 1791 * [tlv] extended supported rates 1792 * [tlv] WME 1793 * [tlv] WPA or RSN 1794 */ 1795 IEEE80211_VERIFY_LENGTH(efrm - frm, 12); 1796 tstamp = frm; frm += 8; 1797 bintval = le16toh(*(u_int16_t *)frm); frm += 2; 1798 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 1799 ssid = rates = xrates = country = wpa = wme = NULL; 1800 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 1801 chan = bchan; 1802 fhdwell = 0; 1803 fhindex = 0; 1804 erp = 0; 1805 timoff = 0; 1806 while (frm < efrm) { 1807 switch (*frm) { 1808 case IEEE80211_ELEMID_SSID: 1809 ssid = frm; 1810 break; 1811 case IEEE80211_ELEMID_RATES: 1812 rates = frm; 1813 break; 1814 case IEEE80211_ELEMID_COUNTRY: 1815 country = frm; 1816 break; 1817 case IEEE80211_ELEMID_FHPARMS: 1818 if (ic->ic_phytype == IEEE80211_T_FH) { 1819 fhdwell = LE_READ_2(&frm[2]); 1820 chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 1821 fhindex = frm[6]; 1822 } 1823 break; 1824 case IEEE80211_ELEMID_DSPARMS: 1825 /* 1826 * XXX hack this since depending on phytype 1827 * is problematic for multi-mode devices. 1828 */ 1829 if (ic->ic_phytype != IEEE80211_T_FH) 1830 chan = frm[2]; 1831 break; 1832 case IEEE80211_ELEMID_TIM: 1833 /* XXX ATIM? */ 1834 timoff = frm - mtod(m0, u_int8_t *); 1835 break; 1836 case IEEE80211_ELEMID_IBSSPARMS: 1837 break; 1838 case IEEE80211_ELEMID_XRATES: 1839 xrates = frm; 1840 break; 1841 case IEEE80211_ELEMID_ERP: 1842 if (frm[1] != 1) { 1843 IEEE80211_DISCARD_IE(ic, 1844 IEEE80211_MSG_ELEMID, wh, "ERP", 1845 "bad len %u", frm[1]); 1846 ic->ic_stats.is_rx_elem_toobig++; 1847 break; 1848 } 1849 erp = frm[2]; 1850 break; 1851 case IEEE80211_ELEMID_RSN: 1852 wpa = frm; 1853 break; 1854 case IEEE80211_ELEMID_VENDOR: 1855 if (iswpaoui(frm)) 1856 wpa = frm; 1857 else if (iswmeparam(frm) || iswmeinfo(frm)) 1858 wme = frm; 1859 /* XXX Atheros OUI support */ 1860 break; 1861 default: 1862 IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID, 1863 wh, "unhandled", 1864 "id %u, len %u", *frm, frm[1]); 1865 ic->ic_stats.is_rx_elem_unknown++; 1866 break; 1867 } 1868 frm += frm[1] + 2; 1869 } 1870 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 1871 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 1872 if ( 1873 #if IEEE80211_CHAN_MAX < 255 1874 chan > IEEE80211_CHAN_MAX || 1875 #endif 1876 isclr(ic->ic_chan_active, chan)) { 1877 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, 1878 wh, ieee80211_mgt_subtype_name[subtype >> 1879 IEEE80211_FC0_SUBTYPE_SHIFT], 1880 "invalid channel %u", chan); 1881 ic->ic_stats.is_rx_badchan++; 1882 return; 1883 } 1884 if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) { 1885 /* 1886 * Frame was received on a channel different from the 1887 * one indicated in the DS params element id; 1888 * silently discard it. 1889 * 1890 * NB: this can happen due to signal leakage. 1891 * But we should take it for FH phy because 1892 * the rssi value should be correct even for 1893 * different hop pattern in FH. 1894 */ 1895 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, 1896 wh, ieee80211_mgt_subtype_name[subtype >> 1897 IEEE80211_FC0_SUBTYPE_SHIFT], 1898 "for off-channel %u", chan); 1899 ic->ic_stats.is_rx_chanmismatch++; 1900 return; 1901 } 1902 1903 /* 1904 * Count frame now that we know it's to be processed. 1905 */ 1906 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { 1907 ic->ic_stats.is_rx_beacon++; /* XXX remove */ 1908 IEEE80211_NODE_STAT(ni, rx_beacons); 1909 } else 1910 IEEE80211_NODE_STAT(ni, rx_proberesp); 1911 1912 /* 1913 * When operating in station mode, check for state updates. 1914 * Be careful to ignore beacons received while doing a 1915 * background scan. We consider only 11g/WMM stuff right now. 1916 */ 1917 if (ni != ic->ic_bss) { 1918 ni = ieee80211_refine_node_for_beacon(ic, ni, 1919 &ic->ic_channels[chan], ssid); 1920 } 1921 if (ic->ic_opmode == IEEE80211_M_STA && 1922 ni->ni_associd != 0 && 1923 ((ic->ic_flags & IEEE80211_F_SCAN) == 0 || 1924 IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) { 1925 if (ni->ni_erp != erp) { 1926 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1927 "[%s] erp change: was 0x%x, now 0x%x\n", 1928 ether_sprintf(wh->i_addr2), 1929 ni->ni_erp, erp); 1930 if (erp & IEEE80211_ERP_USE_PROTECTION) 1931 ic->ic_flags |= IEEE80211_F_USEPROT; 1932 else 1933 ic->ic_flags &= ~IEEE80211_F_USEPROT; 1934 ni->ni_erp = erp; 1935 /* XXX statistic */ 1936 } 1937 if ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) { 1938 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1939 "[%s] capabilities change: before 0x%x," 1940 " now 0x%x\n", 1941 ether_sprintf(wh->i_addr2), 1942 ni->ni_capinfo, capinfo); 1943 /* 1944 * NB: we assume short preamble doesn't 1945 * change dynamically 1946 */ 1947 ieee80211_set_shortslottime(ic, 1948 ic->ic_curmode == IEEE80211_MODE_11A || 1949 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); 1950 ni->ni_capinfo = capinfo; 1951 /* XXX statistic */ 1952 } 1953 if (wme != NULL && 1954 ieee80211_parse_wmeparams(ic, wme, wh) > 0) 1955 ieee80211_wme_updateparams(ic); 1956 /* NB: don't need the rest of this */ 1957 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) 1958 return; 1959 } 1960 1961 if (ni == ic->ic_bss) { 1962 #ifdef IEEE80211_DEBUG 1963 if (ieee80211_msg_scan(ic)) 1964 dump_probe_beacon(subtype, 1, 1965 wh->i_addr2, chan, bchan, capinfo, 1966 bintval, erp, ssid, country); 1967 #endif 1968 /* 1969 * Create a new entry. If scanning the entry goes 1970 * in the scan cache. Otherwise, be particular when 1971 * operating in adhoc mode--only take nodes marked 1972 * as ibss participants so we don't populate our 1973 * neighbor table with unintersting sta's. 1974 */ 1975 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { 1976 if ((capinfo & IEEE80211_CAPINFO_IBSS) == 0) 1977 return; 1978 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, 1979 wh->i_addr2); 1980 } else 1981 ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2); 1982 if (ni == NULL) 1983 return; 1984 ni->ni_esslen = ssid[1]; 1985 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 1986 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 1987 } else if (ssid[1] != 0 && 1988 (ISPROBE(subtype) || ni->ni_esslen == 0)) { 1989 /* 1990 * Update ESSID at probe response to adopt 1991 * hidden AP by Lucent/Cisco, which announces 1992 * null ESSID in beacon. 1993 */ 1994 #ifdef IEEE80211_DEBUG 1995 if (ieee80211_msg_scan(ic) || 1996 ieee80211_msg_debug(ic)) 1997 dump_probe_beacon(subtype, 0, 1998 wh->i_addr2, chan, bchan, capinfo, 1999 bintval, erp, ssid, country); 2000 #endif 2001 ni->ni_esslen = ssid[1]; 2002 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 2003 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 2004 } 2005 ni->ni_scangen = ic->ic_scan.nt_scangen; 2006 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 2007 ni->ni_rssi = rssi; 2008 ni->ni_rstamp = rstamp; 2009 memcpy(ni->ni_tstamp.data, tstamp, sizeof(ni->ni_tstamp)); 2010 ni->ni_intval = bintval; 2011 ni->ni_capinfo = capinfo; 2012 ni->ni_chan = &ic->ic_channels[chan]; 2013 ni->ni_fhdwell = fhdwell; 2014 ni->ni_fhindex = fhindex; 2015 ni->ni_erp = erp; 2016 /* 2017 * Record the byte offset from the mac header to 2018 * the start of the TIM information element for 2019 * use by hardware and/or to speedup software 2020 * processing of beacon frames. 2021 */ 2022 ni->ni_timoff = timoff; 2023 /* 2024 * Record optional information elements that might be 2025 * used by applications or drivers. 2026 */ 2027 if (wme != NULL) 2028 ieee80211_saveie(&ni->ni_wme_ie, wme); 2029 if (wpa != NULL) 2030 ieee80211_saveie(&ni->ni_wpa_ie, wpa); 2031 /* NB: must be after ni_chan is setup */ 2032 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); 2033 break; 2034 } 2035 2036 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: { 2037 u_int8_t rate; 2038 2039 if (ic->ic_opmode == IEEE80211_M_STA || 2040 ic->ic_state != IEEE80211_S_RUN) { 2041 ic->ic_stats.is_rx_mgtdiscard++; 2042 return; 2043 } 2044 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { 2045 /* frame must be directed */ 2046 ic->ic_stats.is_rx_mgtdiscard++; /* XXX stat */ 2047 return; 2048 } 2049 2050 /* 2051 * prreq frame format 2052 * [tlv] ssid 2053 * [tlv] supported rates 2054 * [tlv] extended supported rates 2055 */ 2056 ssid = rates = xrates = NULL; 2057 while (frm < efrm) { 2058 switch (*frm) { 2059 case IEEE80211_ELEMID_SSID: 2060 ssid = frm; 2061 break; 2062 case IEEE80211_ELEMID_RATES: 2063 rates = frm; 2064 break; 2065 case IEEE80211_ELEMID_XRATES: 2066 xrates = frm; 2067 break; 2068 } 2069 frm += frm[1] + 2; 2070 } 2071 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2072 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 2073 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid); 2074 if ((ic->ic_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { 2075 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 2076 wh, ieee80211_mgt_subtype_name[subtype >> 2077 IEEE80211_FC0_SUBTYPE_SHIFT], 2078 "%s", "no ssid with ssid suppression enabled"); 2079 ic->ic_stats.is_rx_ssidmismatch++; /*XXX*/ 2080 return; 2081 } 2082 2083 if (ni == ic->ic_bss) { 2084 if (ic->ic_opmode == IEEE80211_M_IBSS) { 2085 /* 2086 * XXX Cannot tell if the sender is operating 2087 * in ibss mode. But we need a new node to 2088 * send the response so blindly add them to the 2089 * neighbor table. 2090 */ 2091 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, 2092 wh->i_addr2); 2093 } else 2094 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 2095 if (ni == NULL) 2096 return; 2097 allocbs = 1; 2098 } else 2099 allocbs = 0; 2100 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2101 "[%s] recv probe req\n", ether_sprintf(wh->i_addr2)); 2102 ni->ni_rssi = rssi; 2103 ni->ni_rstamp = rstamp; 2104 rate = ieee80211_setup_rates(ic, ni, rates, xrates, 2105 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 2106 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 2107 if (rate & IEEE80211_RATE_BASIC) { 2108 IEEE80211_DISCARD(ic, IEEE80211_MSG_XRATE, 2109 wh, ieee80211_mgt_subtype_name[subtype >> 2110 IEEE80211_FC0_SUBTYPE_SHIFT], 2111 "%s", "recv'd rate set invalid"); 2112 } else { 2113 IEEE80211_SEND_MGMT(ic, ni, 2114 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0); 2115 } 2116 if (allocbs && ic->ic_opmode != IEEE80211_M_IBSS) { 2117 /* reclaim immediately */ 2118 ieee80211_free_node(ni); 2119 } 2120 break; 2121 } 2122 2123 case IEEE80211_FC0_SUBTYPE_AUTH: { 2124 u_int16_t algo, seq, status; 2125 /* 2126 * auth frame format 2127 * [2] algorithm 2128 * [2] sequence 2129 * [2] status 2130 * [tlv*] challenge 2131 */ 2132 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 2133 algo = le16toh(*(u_int16_t *)frm); 2134 seq = le16toh(*(u_int16_t *)(frm + 2)); 2135 status = le16toh(*(u_int16_t *)(frm + 4)); 2136 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, 2137 "[%s] recv auth frame with algorithm %d seq %d\n", 2138 ether_sprintf(wh->i_addr2), algo, seq); 2139 /* 2140 * Consult the ACL policy module if setup. 2141 */ 2142 if (ic->ic_acl != NULL && 2143 !ic->ic_acl->iac_check(ic, wh->i_addr2)) { 2144 IEEE80211_DISCARD(ic, IEEE80211_MSG_ACL, 2145 wh, "auth", "%s", "disallowed by ACL"); 2146 ic->ic_stats.is_rx_acl++; 2147 return; 2148 } 2149 if (ic->ic_flags & IEEE80211_F_COUNTERM) { 2150 IEEE80211_DISCARD(ic, 2151 IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO, 2152 wh, "auth", "%s", "TKIP countermeasures enabled"); 2153 ic->ic_stats.is_rx_auth_countermeasures++; 2154 #ifndef IEEE80211_NO_HOSTAP 2155 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2156 IEEE80211_SEND_MGMT(ic, ni, 2157 IEEE80211_FC0_SUBTYPE_AUTH, 2158 IEEE80211_REASON_MIC_FAILURE); 2159 } 2160 #endif /* !IEEE80211_NO_HOSTAP */ 2161 return; 2162 } 2163 if (algo == IEEE80211_AUTH_ALG_SHARED) 2164 ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi, 2165 rstamp, seq, status); 2166 else if (algo == IEEE80211_AUTH_ALG_OPEN) 2167 ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq, 2168 status); 2169 else { 2170 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2171 wh, "auth", "unsupported alg %d", algo); 2172 ic->ic_stats.is_rx_auth_unsupported++; 2173 #ifndef IEEE80211_NO_HOSTAP 2174 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2175 /* XXX not right */ 2176 IEEE80211_SEND_MGMT(ic, ni, 2177 IEEE80211_FC0_SUBTYPE_AUTH, 2178 (seq+1) | (IEEE80211_STATUS_ALG<<16)); 2179 } 2180 #endif /* !IEEE80211_NO_HOSTAP */ 2181 return; 2182 } 2183 break; 2184 } 2185 2186 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2187 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { 2188 u_int16_t capinfo, bintval; 2189 struct ieee80211_rsnparms rsn; 2190 u_int8_t reason; 2191 2192 if (ic->ic_opmode != IEEE80211_M_HOSTAP || 2193 ic->ic_state != IEEE80211_S_RUN) { 2194 ic->ic_stats.is_rx_mgtdiscard++; 2195 return; 2196 } 2197 2198 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 2199 reassoc = 1; 2200 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 2201 } else { 2202 reassoc = 0; 2203 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 2204 } 2205 /* 2206 * asreq frame format 2207 * [2] capability information 2208 * [2] listen interval 2209 * [6*] current AP address (reassoc only) 2210 * [tlv] ssid 2211 * [tlv] supported rates 2212 * [tlv] extended supported rates 2213 * [tlv] WPA or RSN 2214 */ 2215 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 2216 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 2217 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2218 wh, ieee80211_mgt_subtype_name[subtype >> 2219 IEEE80211_FC0_SUBTYPE_SHIFT], 2220 "%s", "wrong bssid"); 2221 ic->ic_stats.is_rx_assoc_bss++; 2222 return; 2223 } 2224 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 2225 bintval = le16toh(*(u_int16_t *)frm); frm += 2; 2226 if (reassoc) 2227 frm += 6; /* ignore current AP info */ 2228 ssid = rates = xrates = wpa = wme = NULL; 2229 while (frm < efrm) { 2230 switch (*frm) { 2231 case IEEE80211_ELEMID_SSID: 2232 ssid = frm; 2233 break; 2234 case IEEE80211_ELEMID_RATES: 2235 rates = frm; 2236 break; 2237 case IEEE80211_ELEMID_XRATES: 2238 xrates = frm; 2239 break; 2240 /* XXX verify only one of RSN and WPA ie's? */ 2241 case IEEE80211_ELEMID_RSN: 2242 wpa = frm; 2243 break; 2244 case IEEE80211_ELEMID_VENDOR: 2245 if (iswpaoui(frm)) { 2246 if (ic->ic_flags & IEEE80211_F_WPA1) 2247 wpa = frm; 2248 } else if (iswmeinfo(frm)) 2249 wme = frm; 2250 /* XXX Atheros OUI support */ 2251 break; 2252 } 2253 frm += frm[1] + 2; 2254 } 2255 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2256 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 2257 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid); 2258 2259 if (ni == ic->ic_bss) { 2260 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2261 "[%s] deny %s request, sta not authenticated\n", 2262 ether_sprintf(wh->i_addr2), 2263 reassoc ? "reassoc" : "assoc"); 2264 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 2265 if (ni != NULL) { 2266 IEEE80211_SEND_MGMT(ic, ni, 2267 IEEE80211_FC0_SUBTYPE_DEAUTH, 2268 IEEE80211_REASON_ASSOC_NOT_AUTHED); 2269 ieee80211_free_node(ni); 2270 } 2271 ic->ic_stats.is_rx_assoc_notauth++; 2272 return; 2273 } 2274 /* assert right associstion security credentials */ 2275 if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) { 2276 IEEE80211_DPRINTF(ic, 2277 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 2278 "[%s] no WPA/RSN IE in association request\n", 2279 ether_sprintf(wh->i_addr2)); 2280 IEEE80211_SEND_MGMT(ic, ni, 2281 IEEE80211_FC0_SUBTYPE_DEAUTH, 2282 IEEE80211_REASON_RSN_REQUIRED); 2283 ieee80211_node_leave(ic, ni); 2284 /* XXX distinguish WPA/RSN? */ 2285 ic->ic_stats.is_rx_assoc_badwpaie++; 2286 return; 2287 } 2288 if (wpa != NULL) { 2289 /* 2290 * Parse WPA information element. Note that 2291 * we initialize the param block from the node 2292 * state so that information in the IE overrides 2293 * our defaults. The resulting parameters are 2294 * installed below after the association is assured. 2295 */ 2296 rsn = ni->ni_rsn; 2297 if (wpa[0] != IEEE80211_ELEMID_RSN) 2298 reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh); 2299 else 2300 reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh); 2301 if (reason != 0) { 2302 IEEE80211_SEND_MGMT(ic, ni, 2303 IEEE80211_FC0_SUBTYPE_DEAUTH, reason); 2304 ieee80211_node_leave(ic, ni); 2305 /* XXX distinguish WPA/RSN? */ 2306 ic->ic_stats.is_rx_assoc_badwpaie++; 2307 return; 2308 } 2309 IEEE80211_DPRINTF(ic, 2310 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 2311 "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n", 2312 ether_sprintf(wh->i_addr2), 2313 wpa[0] != IEEE80211_ELEMID_RSN ? "WPA" : "RSN", 2314 rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen, 2315 rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen, 2316 rsn.rsn_keymgmt, rsn.rsn_caps); 2317 } 2318 /* discard challenge after association */ 2319 if (ni->ni_challenge != NULL) { 2320 FREE(ni->ni_challenge, M_DEVBUF); 2321 ni->ni_challenge = NULL; 2322 } 2323 /* XXX some stations use the privacy bit for handling APs 2324 that suport both encrypted and unencrypted traffic */ 2325 /* NB: PRIVACY flag bits are assumed to match */ 2326 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 2327 (capinfo & IEEE80211_CAPINFO_PRIVACY) ^ 2328 (ic->ic_flags & IEEE80211_F_PRIVACY)) { 2329 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2330 "[%s] deny %s request, capability mismatch 0x%x\n", 2331 ether_sprintf(wh->i_addr2), 2332 reassoc ? "reassoc" : "assoc", capinfo); 2333 IEEE80211_SEND_MGMT(ic, ni, resp, 2334 IEEE80211_STATUS_CAPINFO); 2335 ieee80211_node_leave(ic, ni); 2336 ic->ic_stats.is_rx_assoc_capmismatch++; 2337 return; 2338 } 2339 ieee80211_setup_rates(ic, ni, rates, xrates, 2340 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 2341 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 2342 if (ni->ni_rates.rs_nrates == 0) { 2343 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2344 "[%s] deny %s request, rate set mismatch\n", 2345 ether_sprintf(wh->i_addr2), 2346 reassoc ? "reassoc" : "assoc"); 2347 IEEE80211_SEND_MGMT(ic, ni, resp, 2348 IEEE80211_STATUS_BASIC_RATE); 2349 ieee80211_node_leave(ic, ni); 2350 ic->ic_stats.is_rx_assoc_norate++; 2351 return; 2352 } 2353 ni->ni_rssi = rssi; 2354 ni->ni_rstamp = rstamp; 2355 ni->ni_intval = bintval; 2356 ni->ni_capinfo = capinfo; 2357 ni->ni_chan = ic->ic_bss->ni_chan; 2358 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 2359 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 2360 if (wpa != NULL) { 2361 /* 2362 * Record WPA/RSN parameters for station, mark 2363 * node as using WPA and record information element 2364 * for applications that require it. 2365 */ 2366 ni->ni_rsn = rsn; 2367 ieee80211_saveie(&ni->ni_wpa_ie, wpa); 2368 } else if (ni->ni_wpa_ie != NULL) { 2369 /* 2370 * Flush any state from a previous association. 2371 */ 2372 FREE(ni->ni_wpa_ie, M_DEVBUF); 2373 ni->ni_wpa_ie = NULL; 2374 } 2375 if (wme != NULL) { 2376 /* 2377 * Record WME parameters for station, mark node 2378 * as capable of QoS and record information 2379 * element for applications that require it. 2380 */ 2381 ieee80211_saveie(&ni->ni_wme_ie, wme); 2382 ni->ni_flags |= IEEE80211_NODE_QOS; 2383 } else if (ni->ni_wme_ie != NULL) { 2384 /* 2385 * Flush any state from a previous association. 2386 */ 2387 FREE(ni->ni_wme_ie, M_DEVBUF); 2388 ni->ni_wme_ie = NULL; 2389 ni->ni_flags &= ~IEEE80211_NODE_QOS; 2390 } 2391 ieee80211_node_join(ic, ni, resp); 2392 break; 2393 } 2394 2395 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2396 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 2397 u_int16_t capinfo, associd; 2398 u_int16_t status; 2399 2400 if (ic->ic_opmode != IEEE80211_M_STA || 2401 ic->ic_state != IEEE80211_S_ASSOC) { 2402 ic->ic_stats.is_rx_mgtdiscard++; 2403 return; 2404 } 2405 2406 /* 2407 * asresp frame format 2408 * [2] capability information 2409 * [2] status 2410 * [2] association ID 2411 * [tlv] supported rates 2412 * [tlv] extended supported rates 2413 * [tlv] WME 2414 */ 2415 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 2416 ni = ic->ic_bss; 2417 capinfo = le16toh(*(u_int16_t *)frm); 2418 frm += 2; 2419 status = le16toh(*(u_int16_t *)frm); 2420 frm += 2; 2421 if (status != 0) { 2422 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2423 "[%s] %sassoc failed (reason %d)\n", 2424 ether_sprintf(wh->i_addr2), 2425 ISREASSOC(subtype) ? "re" : "", status); 2426 if (ni != ic->ic_bss) /* XXX never true? */ 2427 ni->ni_fails++; 2428 ic->ic_stats.is_rx_auth_fail++; /* XXX */ 2429 return; 2430 } 2431 associd = le16toh(*(u_int16_t *)frm); 2432 frm += 2; 2433 2434 rates = xrates = wpa = wme = NULL; 2435 while (frm < efrm) { 2436 switch (*frm) { 2437 case IEEE80211_ELEMID_RATES: 2438 rates = frm; 2439 break; 2440 case IEEE80211_ELEMID_XRATES: 2441 xrates = frm; 2442 break; 2443 case IEEE80211_ELEMID_VENDOR: 2444 if (iswmeoui(frm)) 2445 wme = frm; 2446 /* XXX Atheros OUI support */ 2447 break; 2448 } 2449 frm += frm[1] + 2; 2450 } 2451 2452 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2453 ieee80211_setup_rates(ic, ni, rates, xrates, 2454 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 2455 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 2456 if (ni->ni_rates.rs_nrates == 0) { 2457 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2458 "[%s] %sassoc failed (rate set mismatch)\n", 2459 ether_sprintf(wh->i_addr2), 2460 ISREASSOC(subtype) ? "re" : ""); 2461 if (ni != ic->ic_bss) /* XXX never true? */ 2462 ni->ni_fails++; 2463 ic->ic_stats.is_rx_assoc_norate++; 2464 return; 2465 } 2466 2467 ni->ni_capinfo = capinfo; 2468 ni->ni_associd = associd; 2469 if (wme != NULL && 2470 ieee80211_parse_wmeparams(ic, wme, wh) >= 0) { 2471 ni->ni_flags |= IEEE80211_NODE_QOS; 2472 ieee80211_wme_updateparams(ic); 2473 } else 2474 ni->ni_flags &= ~IEEE80211_NODE_QOS; 2475 /* 2476 * Configure state now that we are associated. 2477 * 2478 * XXX may need different/additional driver callbacks? 2479 */ 2480 if (ic->ic_curmode == IEEE80211_MODE_11A || 2481 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { 2482 ic->ic_flags |= IEEE80211_F_SHPREAMBLE; 2483 ic->ic_flags &= ~IEEE80211_F_USEBARKER; 2484 } else { 2485 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; 2486 ic->ic_flags |= IEEE80211_F_USEBARKER; 2487 } 2488 ieee80211_set_shortslottime(ic, 2489 ic->ic_curmode == IEEE80211_MODE_11A || 2490 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); 2491 /* 2492 * Honor ERP protection. 2493 * 2494 * NB: ni_erp should zero for non-11g operation. 2495 * XXX check ic_curmode anyway? 2496 */ 2497 if (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION) 2498 ic->ic_flags |= IEEE80211_F_USEPROT; 2499 else 2500 ic->ic_flags &= ~IEEE80211_F_USEPROT; 2501 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2502 "[%s] %sassoc success: %s preamble, %s slot time%s%s\n", 2503 ether_sprintf(wh->i_addr2), 2504 ISREASSOC(subtype) ? "re" : "", 2505 ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", 2506 ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", 2507 ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "", 2508 ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "" 2509 ); 2510 ieee80211_new_state(ic, IEEE80211_S_RUN, subtype); 2511 break; 2512 } 2513 2514 case IEEE80211_FC0_SUBTYPE_DEAUTH: { 2515 u_int16_t reason; 2516 2517 if (ic->ic_state == IEEE80211_S_SCAN) { 2518 ic->ic_stats.is_rx_mgtdiscard++; 2519 return; 2520 } 2521 /* 2522 * deauth frame format 2523 * [2] reason 2524 */ 2525 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 2526 reason = le16toh(*(u_int16_t *)frm); 2527 ic->ic_stats.is_rx_deauth++; 2528 IEEE80211_NODE_STAT(ni, rx_deauth); 2529 switch (ic->ic_opmode) { 2530 case IEEE80211_M_STA: 2531 ieee80211_new_state(ic, IEEE80211_S_AUTH, 2532 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 2533 break; 2534 case IEEE80211_M_HOSTAP: 2535 #ifndef IEEE80211_NO_HOSTAP 2536 if (ni != ic->ic_bss) { 2537 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, 2538 "station %s deauthenticated by peer " 2539 "(reason %d)\n", 2540 ether_sprintf(ni->ni_macaddr), reason); 2541 ieee80211_node_leave(ic, ni); 2542 } 2543 #endif /* !IEEE80211_NO_HOSTAP */ 2544 break; 2545 default: 2546 ic->ic_stats.is_rx_mgtdiscard++; 2547 break; 2548 } 2549 break; 2550 } 2551 2552 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 2553 u_int16_t reason; 2554 2555 if (ic->ic_state != IEEE80211_S_RUN && 2556 ic->ic_state != IEEE80211_S_AUTH) { 2557 ic->ic_stats.is_rx_mgtdiscard++; 2558 return; 2559 } 2560 /* 2561 * disassoc frame format 2562 * [2] reason 2563 */ 2564 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 2565 reason = le16toh(*(u_int16_t *)frm); 2566 ic->ic_stats.is_rx_disassoc++; 2567 IEEE80211_NODE_STAT(ni, rx_disassoc); 2568 switch (ic->ic_opmode) { 2569 case IEEE80211_M_STA: 2570 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 2571 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 2572 break; 2573 case IEEE80211_M_HOSTAP: 2574 #ifndef IEEE80211_NO_HOSTAP 2575 if (ni != ic->ic_bss) { 2576 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2577 "[%s] sta disassociated by peer (reason %d)\n", 2578 ether_sprintf(ni->ni_macaddr), reason); 2579 ieee80211_node_leave(ic, ni); 2580 } 2581 #endif /* !IEEE80211_NO_HOSTAP */ 2582 break; 2583 default: 2584 ic->ic_stats.is_rx_mgtdiscard++; 2585 break; 2586 } 2587 break; 2588 } 2589 default: 2590 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2591 wh, "mgt", "subtype 0x%x not handled", subtype); 2592 ic->ic_stats.is_rx_badsubtype++; 2593 break; 2594 } 2595 #undef ISREASSOC 2596 #undef ISPROBE 2597 } 2598 #undef IEEE80211_VERIFY_LENGTH 2599 #undef IEEE80211_VERIFY_ELEMENT 2600 2601 #ifndef IEEE80211_NO_HOSTAP 2602 /* 2603 * Handle station power-save state change. 2604 */ 2605 static void 2606 ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) 2607 { 2608 struct ieee80211com *ic = ni->ni_ic; 2609 struct mbuf *m; 2610 2611 if (enable) { 2612 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) 2613 ic->ic_ps_sta++; 2614 ni->ni_flags |= IEEE80211_NODE_PWR_MGT; 2615 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2616 "[%s] power save mode on, %u sta's in ps mode\n", 2617 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta); 2618 return; 2619 } 2620 2621 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) 2622 ic->ic_ps_sta--; 2623 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; 2624 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2625 "[%s] power save mode off, %u sta's in ps mode\n", 2626 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta); 2627 /* XXX if no stations in ps mode, flush mc frames */ 2628 2629 /* 2630 * Flush queued unicast frames. 2631 */ 2632 if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) { 2633 ic->ic_set_tim(ic, ni, 0); /* just in case */ 2634 return; 2635 } 2636 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2637 "[%s] flush ps queue, %u packets queued\n", 2638 ether_sprintf(ni->ni_macaddr), IEEE80211_NODE_SAVEQ_QLEN(ni)); 2639 for (;;) { 2640 int qlen; 2641 2642 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen); 2643 if (m == NULL) 2644 break; 2645 /* 2646 * If this is the last packet, turn off the TIM bit. 2647 * If there are more packets, set the more packets bit 2648 * in the packet dispatched to the station. 2649 */ 2650 if (qlen != 0) { 2651 struct ieee80211_frame_min *wh = 2652 mtod(m, struct ieee80211_frame_min *); 2653 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; 2654 } 2655 /* XXX need different driver interface */ 2656 /* XXX bypasses q max */ 2657 IF_ENQUEUE(&ic->ic_ifp->if_snd, m); 2658 } 2659 } 2660 2661 /* 2662 * Process a received ps-poll frame. 2663 */ 2664 static void 2665 ieee80211_recv_pspoll(struct ieee80211com *ic, 2666 struct ieee80211_node *ni, struct mbuf *m0) 2667 { 2668 struct ieee80211_frame_min *wh; 2669 struct mbuf *m; 2670 u_int16_t aid; 2671 int qlen; 2672 2673 wh = mtod(m0, struct ieee80211_frame_min *); 2674 if (ni->ni_associd == 0) { 2675 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 2676 (struct ieee80211_frame *) wh, "ps-poll", 2677 "%s", "unassociated station"); 2678 ic->ic_stats.is_ps_unassoc++; 2679 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 2680 IEEE80211_REASON_NOT_ASSOCED); 2681 return; 2682 } 2683 2684 aid = le16toh(*(u_int16_t *)wh->i_dur); 2685 if (aid != ni->ni_associd) { 2686 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 2687 (struct ieee80211_frame *) wh, "ps-poll", 2688 "aid mismatch: sta aid 0x%x poll aid 0x%x", 2689 ni->ni_associd, aid); 2690 ic->ic_stats.is_ps_badaid++; 2691 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 2692 IEEE80211_REASON_NOT_ASSOCED); 2693 return; 2694 } 2695 2696 /* Okay, take the first queued packet and put it out... */ 2697 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen); 2698 if (m == NULL) { 2699 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2700 "[%s] recv ps-poll, but queue empty\n", 2701 ether_sprintf(wh->i_addr2)); 2702 ieee80211_send_nulldata(ic, ni); 2703 ic->ic_stats.is_ps_qempty++; /* XXX node stat */ 2704 ic->ic_set_tim(ic, ni, 0); /* just in case */ 2705 return; 2706 } 2707 /* 2708 * If there are more packets, set the more packets bit 2709 * in the packet dispatched to the station; otherwise 2710 * turn off the TIM bit. 2711 */ 2712 if (qlen != 0) { 2713 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2714 "[%s] recv ps-poll, send packet, %u still queued\n", 2715 ether_sprintf(ni->ni_macaddr), qlen); 2716 wh = mtod(m, struct ieee80211_frame_min *); 2717 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; 2718 } else { 2719 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2720 "[%s] recv ps-poll, send packet, queue empty\n", 2721 ether_sprintf(ni->ni_macaddr)); 2722 ic->ic_set_tim(ic, ni, 0); 2723 } 2724 m->m_flags |= M_PWR_SAV; /* bypass PS handling */ 2725 IF_ENQUEUE(&ic->ic_ifp->if_snd, m); 2726 } 2727 #endif /* !IEEE80211_NO_HOSTAP */ 2728 2729 #ifdef IEEE80211_DEBUG 2730 /* 2731 * Debugging support. 2732 */ 2733 2734 /* 2735 * Return the bssid of a frame. 2736 */ 2737 static const u_int8_t * 2738 ieee80211_getbssid(struct ieee80211com *ic, const struct ieee80211_frame *wh) 2739 { 2740 if (ic->ic_opmode == IEEE80211_M_STA) 2741 return wh->i_addr2; 2742 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS) 2743 return wh->i_addr1; 2744 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) 2745 return wh->i_addr1; 2746 return wh->i_addr3; 2747 } 2748 2749 static void 2750 ieee80211_discard_frame(struct ieee80211com *ic, 2751 const struct ieee80211_frame *wh, 2752 const char *type, const char *fmt, ...) 2753 { 2754 va_list ap; 2755 2756 printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh))); 2757 if (type != NULL) 2758 printf(" %s frame, ", type); 2759 else 2760 printf(" frame, "); 2761 va_start(ap, fmt); 2762 vprintf(fmt, ap); 2763 va_end(ap); 2764 printf("\n"); 2765 } 2766 2767 static void 2768 ieee80211_discard_ie(struct ieee80211com *ic, 2769 const struct ieee80211_frame *wh, 2770 const char *type, const char *fmt, ...) 2771 { 2772 va_list ap; 2773 2774 printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh))); 2775 if (type != NULL) 2776 printf(" %s information element, ", type); 2777 else 2778 printf(" information element, "); 2779 va_start(ap, fmt); 2780 vprintf(fmt, ap); 2781 va_end(ap); 2782 printf("\n"); 2783 } 2784 2785 static void 2786 ieee80211_discard_mac(struct ieee80211com *ic, 2787 const u_int8_t mac[IEEE80211_ADDR_LEN], 2788 const char *type, const char *fmt, ...) 2789 { 2790 va_list ap; 2791 2792 printf("[%s] discard ", ether_sprintf(mac)); 2793 if (type != NULL) 2794 printf(" %s frame, ", type); 2795 else 2796 printf(" frame, "); 2797 va_start(ap, fmt); 2798 vprintf(fmt, ap); 2799 va_end(ap); 2800 printf("\n"); 2801 } 2802 #endif /* IEEE80211_DEBUG */ 2803