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