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 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 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 43 #include <sys/socket.h> 44 45 #include <net/if.h> 46 #include <net/if_media.h> 47 #include <net/ethernet.h> 48 #include <net/if_llc.h> 49 #include <net/if_vlan_var.h> 50 51 #include <net80211/ieee80211_var.h> 52 53 #include <net/bpf.h> 54 55 #ifdef IEEE80211_DEBUG 56 #include <machine/stdarg.h> 57 58 /* 59 * Decide if a received management frame should be 60 * printed when debugging is enabled. This filters some 61 * of the less interesting frames that come frequently 62 * (e.g. beacons). 63 */ 64 static __inline int 65 doprint(struct ieee80211com *ic, int subtype) 66 { 67 switch (subtype) { 68 case IEEE80211_FC0_SUBTYPE_BEACON: 69 return (ic->ic_flags & IEEE80211_F_SCAN); 70 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 71 return (ic->ic_opmode == IEEE80211_M_IBSS); 72 } 73 return 1; 74 } 75 76 /* 77 * Emit a debug message about discarding a frame or information 78 * element. One format is for extracting the mac address from 79 * the frame header; the other is for when a header is not 80 * available or otherwise appropriate. 81 */ 82 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) do { \ 83 if ((_ic)->ic_debug & (_m)) \ 84 ieee80211_discard_frame(_ic, _wh, _type, _fmt, __VA_ARGS__);\ 85 } while (0) 86 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) do { \ 87 if ((_ic)->ic_debug & (_m)) \ 88 ieee80211_discard_ie(_ic, _wh, _type, _fmt, __VA_ARGS__);\ 89 } while (0) 90 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) do { \ 91 if ((_ic)->ic_debug & (_m)) \ 92 ieee80211_discard_mac(_ic, _mac, _type, _fmt, __VA_ARGS__);\ 93 } while (0) 94 95 static const u_int8_t *ieee80211_getbssid(struct ieee80211com *, 96 const struct ieee80211_frame *); 97 static void ieee80211_discard_frame(struct ieee80211com *, 98 const struct ieee80211_frame *, const char *type, const char *fmt, ...); 99 static void ieee80211_discard_ie(struct ieee80211com *, 100 const struct ieee80211_frame *, const char *type, const char *fmt, ...); 101 static void ieee80211_discard_mac(struct ieee80211com *, 102 const u_int8_t mac[IEEE80211_ADDR_LEN], const char *type, 103 const char *fmt, ...); 104 #else 105 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) 106 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) 107 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) 108 #endif /* IEEE80211_DEBUG */ 109 110 static struct mbuf *ieee80211_defrag(struct ieee80211com *, 111 struct ieee80211_node *, struct mbuf *, int); 112 static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *, int); 113 static void ieee80211_send_error(struct ieee80211com *, struct ieee80211_node *, 114 const u_int8_t *mac, int subtype, int arg); 115 static void ieee80211_deliver_data(struct ieee80211com *, 116 struct ieee80211_node *, struct mbuf *); 117 static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable); 118 static void ieee80211_recv_pspoll(struct ieee80211com *, 119 struct ieee80211_node *, struct mbuf *); 120 121 /* 122 * Process a received frame. The node associated with the sender 123 * should be supplied. If nothing was found in the node table then 124 * the caller is assumed to supply a reference to ic_bss instead. 125 * The RSSI and a timestamp are also supplied. The RSSI data is used 126 * during AP scanning to select a AP to associate with; it can have 127 * any units so long as values have consistent units and higher values 128 * mean ``better signal''. The receive timestamp is currently not used 129 * by the 802.11 layer. 130 */ 131 int 132 ieee80211_input(struct ieee80211com *ic, struct mbuf *m, 133 struct ieee80211_node *ni, int rssi, u_int32_t rstamp) 134 { 135 #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 136 #define HAS_SEQ(type) ((type & 0x4) == 0) 137 struct ifnet *ifp = ic->ic_ifp; 138 struct ieee80211_frame *wh; 139 struct ieee80211_key *key; 140 struct ether_header *eh; 141 int hdrspace; 142 u_int8_t dir, type, subtype; 143 u_int8_t *bssid; 144 u_int16_t rxseq; 145 146 KASSERT(ni != NULL, ("null node")); 147 ni->ni_inact = ni->ni_inact_reload; 148 149 /* trim CRC here so WEP can find its own CRC at the end of packet. */ 150 if (m->m_flags & M_HASFCS) { 151 m_adj(m, -IEEE80211_CRC_LEN); 152 m->m_flags &= ~M_HASFCS; 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 u_int8_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(*(u_int16_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 %s rssi %d\n", 503 ieee80211_mgt_subtype_name[subtype >> 504 IEEE80211_FC0_SUBTYPE_SHIFT], 505 ether_sprintf(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 u_int16_t rxseq; 584 u_int8_t fragno; 585 u_int8_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(*(u_int16_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 IEEE80211_NODE_LOCK(ni->ni_table); 614 mfrag = ni->ni_rxfrag[0]; 615 ni->ni_rxfrag[0] = NULL; 616 IEEE80211_NODE_UNLOCK(ni->ni_table); 617 618 /* 619 * Validate new fragment is in order and 620 * related to the previous ones. 621 */ 622 if (mfrag != NULL) { 623 u_int16_t last_rxseq; 624 625 lwh = mtod(mfrag, struct ieee80211_frame *); 626 last_rxseq = le16toh(*(u_int16_t *)lwh->i_seq); 627 /* NB: check seq # and frag together */ 628 if (rxseq != last_rxseq+1 || 629 !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) || 630 !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) { 631 /* 632 * Unrelated fragment or no space for it, 633 * clear current fragments. 634 */ 635 m_freem(mfrag); 636 mfrag = NULL; 637 } 638 } 639 640 if (mfrag == NULL) { 641 if (fragno != 0) { /* !first fragment, discard */ 642 IEEE80211_NODE_STAT(ni, rx_defrag); 643 m_freem(m); 644 return NULL; 645 } 646 mfrag = m; 647 } else { /* concatenate */ 648 m_adj(m, hdrspace); /* strip header */ 649 m_cat(mfrag, m); 650 /* NB: m_cat doesn't update the packet header */ 651 mfrag->m_pkthdr.len += m->m_pkthdr.len; 652 /* track last seqnum and fragno */ 653 lwh = mtod(mfrag, struct ieee80211_frame *); 654 *(u_int16_t *) lwh->i_seq = *(u_int16_t *) wh->i_seq; 655 } 656 if (more_frag) { /* more to come, save */ 657 ni->ni_rxfragstamp = ticks; 658 ni->ni_rxfrag[0] = mfrag; 659 mfrag = NULL; 660 } 661 return mfrag; 662 } 663 664 static void 665 ieee80211_deliver_data(struct ieee80211com *ic, 666 struct ieee80211_node *ni, struct mbuf *m) 667 { 668 struct ether_header *eh = mtod(m, struct ether_header *); 669 struct ifnet *ifp = ic->ic_ifp; 670 671 /* perform as a bridge within the AP */ 672 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 673 (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) { 674 struct mbuf *m1 = NULL; 675 676 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 677 m1 = m_copypacket(m, M_DONTWAIT); 678 if (m1 == NULL) 679 ifp->if_oerrors++; 680 else 681 m1->m_flags |= M_MCAST; 682 } else { 683 /* 684 * Check if the destination is known; if so 685 * and the port is authorized dispatch directly. 686 */ 687 struct ieee80211_node *sta = 688 ieee80211_find_node(&ic->ic_sta, eh->ether_dhost); 689 if (sta != NULL) { 690 if (ieee80211_node_is_authorized(sta)) { 691 /* 692 * Beware of sending to ourself; this 693 * needs to happen via the normal 694 * input path. 695 */ 696 if (sta != ic->ic_bss) { 697 m1 = m; 698 m = NULL; 699 } 700 } else { 701 ic->ic_stats.is_rx_unauth++; 702 IEEE80211_NODE_STAT(sta, rx_unauth); 703 } 704 ieee80211_free_node(sta); 705 } 706 } 707 if (m1 != NULL) 708 IF_HANDOFF(&ifp->if_snd, m1, ifp); 709 } 710 if (m != NULL) { 711 if (ni->ni_vlan != 0) { 712 /* attach vlan tag */ 713 /* XXX goto err? */ 714 VLAN_INPUT_TAG(ifp, m, ni->ni_vlan, goto out); 715 } 716 (*ifp->if_input)(ifp, m); 717 } 718 return; 719 out: 720 if (m != NULL) { 721 if (ic->ic_rawbpf) 722 bpf_mtap(ic->ic_rawbpf, m); 723 m_freem(m); 724 } 725 } 726 727 static struct mbuf * 728 ieee80211_decap(struct ieee80211com *ic, struct mbuf *m, int hdrlen) 729 { 730 struct ieee80211_qosframe_addr4 wh; /* Max size address frames */ 731 struct ether_header *eh; 732 struct llc *llc; 733 734 if (m->m_len < hdrlen + sizeof(*llc) && 735 (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) { 736 /* XXX stat, msg */ 737 return NULL; 738 } 739 memcpy(&wh, mtod(m, caddr_t), hdrlen); 740 llc = (struct llc *)(mtod(m, caddr_t) + hdrlen); 741 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 742 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 743 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 744 m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); 745 llc = NULL; 746 } else { 747 m_adj(m, hdrlen - sizeof(*eh)); 748 } 749 eh = mtod(m, struct ether_header *); 750 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 751 case IEEE80211_FC1_DIR_NODS: 752 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 753 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 754 break; 755 case IEEE80211_FC1_DIR_TODS: 756 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 757 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 758 break; 759 case IEEE80211_FC1_DIR_FROMDS: 760 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 761 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 762 break; 763 case IEEE80211_FC1_DIR_DSTODS: 764 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 765 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4); 766 break; 767 } 768 #ifdef ALIGNED_POINTER 769 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) { 770 struct mbuf *n, *n0, **np; 771 caddr_t newdata; 772 int off, pktlen; 773 774 n0 = NULL; 775 np = &n0; 776 off = 0; 777 pktlen = m->m_pkthdr.len; 778 while (pktlen > off) { 779 if (n0 == NULL) { 780 MGETHDR(n, M_DONTWAIT, MT_DATA); 781 if (n == NULL) { 782 m_freem(m); 783 return NULL; 784 } 785 M_MOVE_PKTHDR(n, m); 786 n->m_len = MHLEN; 787 } else { 788 MGET(n, M_DONTWAIT, MT_DATA); 789 if (n == NULL) { 790 m_freem(m); 791 m_freem(n0); 792 return NULL; 793 } 794 n->m_len = MLEN; 795 } 796 if (pktlen - off >= MINCLSIZE) { 797 MCLGET(n, M_DONTWAIT); 798 if (n->m_flags & M_EXT) 799 n->m_len = n->m_ext.ext_size; 800 } 801 if (n0 == NULL) { 802 newdata = 803 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) - 804 sizeof(*eh); 805 n->m_len -= newdata - n->m_data; 806 n->m_data = newdata; 807 } 808 if (n->m_len > pktlen - off) 809 n->m_len = pktlen - off; 810 m_copydata(m, off, n->m_len, mtod(n, caddr_t)); 811 off += n->m_len; 812 *np = n; 813 np = &n->m_next; 814 } 815 m_freem(m); 816 m = n0; 817 } 818 #endif /* ALIGNED_POINTER */ 819 if (llc != NULL) { 820 eh = mtod(m, struct ether_header *); 821 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 822 } 823 return m; 824 } 825 826 /* 827 * Install received rate set information in the node's state block. 828 */ 829 int 830 ieee80211_setup_rates(struct ieee80211_node *ni, 831 const u_int8_t *rates, const u_int8_t *xrates, int flags) 832 { 833 struct ieee80211com *ic = ni->ni_ic; 834 struct ieee80211_rateset *rs = &ni->ni_rates; 835 836 memset(rs, 0, sizeof(*rs)); 837 rs->rs_nrates = rates[1]; 838 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 839 if (xrates != NULL) { 840 u_int8_t nxrates; 841 /* 842 * Tack on 11g extended supported rate element. 843 */ 844 nxrates = xrates[1]; 845 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 846 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 847 IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE, 848 "[%s] extended rate set too large;" 849 " only using %u of %u rates\n", 850 ether_sprintf(ni->ni_macaddr), nxrates, xrates[1]); 851 ic->ic_stats.is_rx_rstoobig++; 852 } 853 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 854 rs->rs_nrates += nxrates; 855 } 856 return ieee80211_fix_rate(ni, flags); 857 } 858 859 static void 860 ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh, 861 struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq, 862 u_int16_t status) 863 { 864 865 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { 866 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 867 ni->ni_macaddr, "open auth", 868 "bad sta auth mode %u", ni->ni_authmode); 869 ic->ic_stats.is_rx_bad_auth++; /* XXX */ 870 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 871 /* XXX hack to workaround calling convention */ 872 ieee80211_send_error(ic, ni, wh->i_addr2, 873 IEEE80211_FC0_SUBTYPE_AUTH, 874 (seq + 1) | (IEEE80211_STATUS_ALG<<16)); 875 } 876 return; 877 } 878 switch (ic->ic_opmode) { 879 case IEEE80211_M_IBSS: 880 case IEEE80211_M_AHDEMO: 881 case IEEE80211_M_MONITOR: 882 /* should not come here */ 883 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 884 ni->ni_macaddr, "open auth", 885 "bad operating mode %u", ic->ic_opmode); 886 break; 887 888 case IEEE80211_M_HOSTAP: 889 if (ic->ic_state != IEEE80211_S_RUN || 890 seq != IEEE80211_AUTH_OPEN_REQUEST) { 891 ic->ic_stats.is_rx_bad_auth++; 892 return; 893 } 894 /* always accept open authentication requests */ 895 if (ni == ic->ic_bss) { 896 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 897 if (ni == NULL) 898 return; 899 } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 900 (void) ieee80211_ref_node(ni); 901 /* 902 * Mark the node as referenced to reflect that it's 903 * reference count has been bumped to insure it remains 904 * after the transaction completes. 905 */ 906 ni->ni_flags |= IEEE80211_NODE_AREF; 907 908 IEEE80211_SEND_MGMT(ic, ni, 909 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 910 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 911 "[%s] station authenticated (open)\n", 912 ether_sprintf(ni->ni_macaddr)); 913 /* 914 * When 802.1x is not in use mark the port 915 * authorized at this point so traffic can flow. 916 */ 917 if (ni->ni_authmode != IEEE80211_AUTH_8021X) 918 ieee80211_node_authorize(ni); 919 break; 920 921 case IEEE80211_M_STA: 922 if (ic->ic_state != IEEE80211_S_AUTH || 923 seq != IEEE80211_AUTH_OPEN_RESPONSE) { 924 ic->ic_stats.is_rx_bad_auth++; 925 return; 926 } 927 if (status != 0) { 928 IEEE80211_DPRINTF(ic, 929 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 930 "[%s] open auth failed (reason %d)\n", 931 ether_sprintf(ni->ni_macaddr), status); 932 /* XXX can this happen? */ 933 if (ni != ic->ic_bss) 934 ni->ni_fails++; 935 ic->ic_stats.is_rx_auth_fail++; 936 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 937 } else 938 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 939 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 940 break; 941 } 942 } 943 944 /* 945 * Send a management frame error response to the specified 946 * station. If ni is associated with the station then use 947 * it; otherwise allocate a temporary node suitable for 948 * transmitting the frame and then free the reference so 949 * it will go away as soon as the frame has been transmitted. 950 */ 951 static void 952 ieee80211_send_error(struct ieee80211com *ic, struct ieee80211_node *ni, 953 const u_int8_t *mac, int subtype, int arg) 954 { 955 int istmp; 956 957 if (ni == ic->ic_bss) { 958 ni = ieee80211_tmp_node(ic, mac); 959 if (ni == NULL) { 960 /* XXX msg */ 961 return; 962 } 963 istmp = 1; 964 } else 965 istmp = 0; 966 IEEE80211_SEND_MGMT(ic, ni, subtype, arg); 967 if (istmp) 968 ieee80211_free_node(ni); 969 } 970 971 static int 972 alloc_challenge(struct ieee80211com *ic, struct ieee80211_node *ni) 973 { 974 if (ni->ni_challenge == NULL) 975 MALLOC(ni->ni_challenge, u_int32_t*, IEEE80211_CHALLENGE_LEN, 976 M_DEVBUF, M_NOWAIT); 977 if (ni->ni_challenge == NULL) { 978 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 979 "[%s] shared key challenge alloc failed\n", 980 ether_sprintf(ni->ni_macaddr)); 981 /* XXX statistic */ 982 } 983 return (ni->ni_challenge != NULL); 984 } 985 986 /* XXX TODO: add statistics */ 987 static void 988 ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh, 989 u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi, 990 u_int32_t rstamp, u_int16_t seq, u_int16_t status) 991 { 992 u_int8_t *challenge; 993 int allocbs, estatus; 994 995 /* 996 * NB: this can happen as we allow pre-shared key 997 * authentication to be enabled w/o wep being turned 998 * on so that configuration of these can be done 999 * in any order. It may be better to enforce the 1000 * ordering in which case this check would just be 1001 * for sanity/consistency. 1002 */ 1003 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 1004 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1005 ni->ni_macaddr, "shared key auth", 1006 "%s", " PRIVACY is disabled"); 1007 estatus = IEEE80211_STATUS_ALG; 1008 goto bad; 1009 } 1010 /* 1011 * Pre-shared key authentication is evil; accept 1012 * it only if explicitly configured (it is supported 1013 * mainly for compatibility with clients like OS X). 1014 */ 1015 if (ni->ni_authmode != IEEE80211_AUTH_AUTO && 1016 ni->ni_authmode != IEEE80211_AUTH_SHARED) { 1017 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1018 ni->ni_macaddr, "shared key auth", 1019 "bad sta auth mode %u", ni->ni_authmode); 1020 ic->ic_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ 1021 estatus = IEEE80211_STATUS_ALG; 1022 goto bad; 1023 } 1024 1025 challenge = NULL; 1026 if (frm + 1 < efrm) { 1027 if ((frm[1] + 2) > (efrm - frm)) { 1028 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1029 ni->ni_macaddr, "shared key auth", 1030 "ie %d/%d too long", 1031 frm[0], (frm[1] + 2) - (efrm - frm)); 1032 ic->ic_stats.is_rx_bad_auth++; 1033 estatus = IEEE80211_STATUS_CHALLENGE; 1034 goto bad; 1035 } 1036 if (*frm == IEEE80211_ELEMID_CHALLENGE) 1037 challenge = frm; 1038 frm += frm[1] + 2; 1039 } 1040 switch (seq) { 1041 case IEEE80211_AUTH_SHARED_CHALLENGE: 1042 case IEEE80211_AUTH_SHARED_RESPONSE: 1043 if (challenge == NULL) { 1044 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1045 ni->ni_macaddr, "shared key auth", 1046 "%s", "no challenge"); 1047 ic->ic_stats.is_rx_bad_auth++; 1048 estatus = IEEE80211_STATUS_CHALLENGE; 1049 goto bad; 1050 } 1051 if (challenge[1] != IEEE80211_CHALLENGE_LEN) { 1052 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1053 ni->ni_macaddr, "shared key auth", 1054 "bad challenge len %d", challenge[1]); 1055 ic->ic_stats.is_rx_bad_auth++; 1056 estatus = IEEE80211_STATUS_CHALLENGE; 1057 goto bad; 1058 } 1059 default: 1060 break; 1061 } 1062 switch (ic->ic_opmode) { 1063 case IEEE80211_M_MONITOR: 1064 case IEEE80211_M_AHDEMO: 1065 case IEEE80211_M_IBSS: 1066 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1067 ni->ni_macaddr, "shared key auth", 1068 "bad operating mode %u", ic->ic_opmode); 1069 return; 1070 case IEEE80211_M_HOSTAP: 1071 if (ic->ic_state != IEEE80211_S_RUN) { 1072 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1073 ni->ni_macaddr, "shared key auth", 1074 "bad state %u", ic->ic_state); 1075 estatus = IEEE80211_STATUS_ALG; /* XXX */ 1076 goto bad; 1077 } 1078 switch (seq) { 1079 case IEEE80211_AUTH_SHARED_REQUEST: 1080 if (ni == ic->ic_bss) { 1081 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 1082 if (ni == NULL) { 1083 /* NB: no way to return an error */ 1084 return; 1085 } 1086 allocbs = 1; 1087 } else { 1088 if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 1089 (void) ieee80211_ref_node(ni); 1090 allocbs = 0; 1091 } 1092 /* 1093 * Mark the node as referenced to reflect that it's 1094 * reference count has been bumped to insure it remains 1095 * after the transaction completes. 1096 */ 1097 ni->ni_flags |= IEEE80211_NODE_AREF; 1098 ni->ni_rssi = rssi; 1099 ni->ni_rstamp = rstamp; 1100 if (!alloc_challenge(ic, ni)) { 1101 /* NB: don't return error so they rexmit */ 1102 return; 1103 } 1104 get_random_bytes(ni->ni_challenge, 1105 IEEE80211_CHALLENGE_LEN); 1106 IEEE80211_DPRINTF(ic, 1107 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1108 "[%s] shared key %sauth request\n", 1109 ether_sprintf(ni->ni_macaddr), 1110 allocbs ? "" : "re"); 1111 break; 1112 case IEEE80211_AUTH_SHARED_RESPONSE: 1113 if (ni == ic->ic_bss) { 1114 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1115 ni->ni_macaddr, "shared key response", 1116 "%s", "unknown station"); 1117 /* NB: don't send a response */ 1118 return; 1119 } 1120 if (ni->ni_challenge == NULL) { 1121 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1122 ni->ni_macaddr, "shared key response", 1123 "%s", "no challenge recorded"); 1124 ic->ic_stats.is_rx_bad_auth++; 1125 estatus = IEEE80211_STATUS_CHALLENGE; 1126 goto bad; 1127 } 1128 if (memcmp(ni->ni_challenge, &challenge[2], 1129 challenge[1]) != 0) { 1130 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1131 ni->ni_macaddr, "shared key response", 1132 "%s", "challenge mismatch"); 1133 ic->ic_stats.is_rx_auth_fail++; 1134 estatus = IEEE80211_STATUS_CHALLENGE; 1135 goto bad; 1136 } 1137 IEEE80211_DPRINTF(ic, 1138 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1139 "[%s] station authenticated (shared key)\n", 1140 ether_sprintf(ni->ni_macaddr)); 1141 ieee80211_node_authorize(ni); 1142 break; 1143 default: 1144 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1145 ni->ni_macaddr, "shared key auth", 1146 "bad seq %d", seq); 1147 ic->ic_stats.is_rx_bad_auth++; 1148 estatus = IEEE80211_STATUS_SEQUENCE; 1149 goto bad; 1150 } 1151 IEEE80211_SEND_MGMT(ic, ni, 1152 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 1153 break; 1154 1155 case IEEE80211_M_STA: 1156 if (ic->ic_state != IEEE80211_S_AUTH) 1157 return; 1158 switch (seq) { 1159 case IEEE80211_AUTH_SHARED_PASS: 1160 if (ni->ni_challenge != NULL) { 1161 FREE(ni->ni_challenge, M_DEVBUF); 1162 ni->ni_challenge = NULL; 1163 } 1164 if (status != 0) { 1165 IEEE80211_DPRINTF(ic, 1166 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1167 "[%s] shared key auth failed (reason %d)\n", 1168 ether_sprintf(ieee80211_getbssid(ic, wh)), 1169 status); 1170 /* XXX can this happen? */ 1171 if (ni != ic->ic_bss) 1172 ni->ni_fails++; 1173 ic->ic_stats.is_rx_auth_fail++; 1174 return; 1175 } 1176 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1177 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1178 break; 1179 case IEEE80211_AUTH_SHARED_CHALLENGE: 1180 if (!alloc_challenge(ic, ni)) 1181 return; 1182 /* XXX could optimize by passing recvd challenge */ 1183 memcpy(ni->ni_challenge, &challenge[2], challenge[1]); 1184 IEEE80211_SEND_MGMT(ic, ni, 1185 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 1186 break; 1187 default: 1188 IEEE80211_DISCARD(ic, IEEE80211_MSG_AUTH, 1189 wh, "shared key auth", "bad seq %d", seq); 1190 ic->ic_stats.is_rx_bad_auth++; 1191 return; 1192 } 1193 break; 1194 } 1195 return; 1196 bad: 1197 /* 1198 * Send an error response; but only when operating as an AP. 1199 */ 1200 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1201 /* XXX hack to workaround calling convention */ 1202 ieee80211_send_error(ic, ni, wh->i_addr2, 1203 IEEE80211_FC0_SUBTYPE_AUTH, 1204 (seq + 1) | (estatus<<16)); 1205 } else if (ic->ic_opmode == IEEE80211_M_STA) { 1206 /* 1207 * Kick the state machine. This short-circuits 1208 * using the mgt frame timeout to trigger the 1209 * state transition. 1210 */ 1211 if (ic->ic_state == IEEE80211_S_AUTH) 1212 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 1213 } 1214 } 1215 1216 /* Verify the existence and length of __elem or get out. */ 1217 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 1218 if ((__elem) == NULL) { \ 1219 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 1220 wh, ieee80211_mgt_subtype_name[subtype >> \ 1221 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1222 "%s", "no " #__elem ); \ 1223 ic->ic_stats.is_rx_elem_missing++; \ 1224 return; \ 1225 } \ 1226 if ((__elem)[1] > (__maxlen)) { \ 1227 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 1228 wh, ieee80211_mgt_subtype_name[subtype >> \ 1229 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1230 "bad " #__elem " len %d", (__elem)[1]); \ 1231 ic->ic_stats.is_rx_elem_toobig++; \ 1232 return; \ 1233 } \ 1234 } while (0) 1235 1236 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 1237 if ((_len) < (_minlen)) { \ 1238 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 1239 wh, ieee80211_mgt_subtype_name[subtype >> \ 1240 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1241 "%s", "ie too short"); \ 1242 ic->ic_stats.is_rx_elem_toosmall++; \ 1243 return; \ 1244 } \ 1245 } while (0) 1246 1247 #ifdef IEEE80211_DEBUG 1248 static void 1249 ieee80211_ssid_mismatch(struct ieee80211com *ic, const char *tag, 1250 u_int8_t mac[IEEE80211_ADDR_LEN], u_int8_t *ssid) 1251 { 1252 printf("[%s] discard %s frame, ssid mismatch: ", 1253 ether_sprintf(mac), tag); 1254 ieee80211_print_essid(ssid + 2, ssid[1]); 1255 printf("\n"); 1256 } 1257 1258 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \ 1259 if ((_ssid)[1] != 0 && \ 1260 ((_ssid)[1] != (_ni)->ni_esslen || \ 1261 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 1262 if (ieee80211_msg_input(ic)) \ 1263 ieee80211_ssid_mismatch(ic, \ 1264 ieee80211_mgt_subtype_name[subtype >> \ 1265 IEEE80211_FC0_SUBTYPE_SHIFT], \ 1266 wh->i_addr2, _ssid); \ 1267 ic->ic_stats.is_rx_ssidmismatch++; \ 1268 return; \ 1269 } \ 1270 } while (0) 1271 #else /* !IEEE80211_DEBUG */ 1272 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \ 1273 if ((_ssid)[1] != 0 && \ 1274 ((_ssid)[1] != (_ni)->ni_esslen || \ 1275 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 1276 ic->ic_stats.is_rx_ssidmismatch++; \ 1277 return; \ 1278 } \ 1279 } while (0) 1280 #endif /* !IEEE80211_DEBUG */ 1281 1282 /* unalligned little endian access */ 1283 #define LE_READ_2(p) \ 1284 ((u_int16_t) \ 1285 ((((const u_int8_t *)(p))[0] ) | \ 1286 (((const u_int8_t *)(p))[1] << 8))) 1287 #define LE_READ_4(p) \ 1288 ((u_int32_t) \ 1289 ((((const u_int8_t *)(p))[0] ) | \ 1290 (((const u_int8_t *)(p))[1] << 8) | \ 1291 (((const u_int8_t *)(p))[2] << 16) | \ 1292 (((const u_int8_t *)(p))[3] << 24))) 1293 1294 static int __inline 1295 iswpaoui(const u_int8_t *frm) 1296 { 1297 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); 1298 } 1299 1300 static int __inline 1301 iswmeoui(const u_int8_t *frm) 1302 { 1303 return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); 1304 } 1305 1306 static int __inline 1307 iswmeparam(const u_int8_t *frm) 1308 { 1309 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && 1310 frm[6] == WME_PARAM_OUI_SUBTYPE; 1311 } 1312 1313 static int __inline 1314 iswmeinfo(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_INFO_OUI_SUBTYPE; 1318 } 1319 1320 static int __inline 1321 isatherosoui(const u_int8_t *frm) 1322 { 1323 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); 1324 } 1325 1326 /* 1327 * Convert a WPA cipher selector OUI to an internal 1328 * cipher algorithm. Where appropriate we also 1329 * record any key length. 1330 */ 1331 static int 1332 wpa_cipher(u_int8_t *sel, u_int8_t *keylen) 1333 { 1334 #define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1335 u_int32_t w = LE_READ_4(sel); 1336 1337 switch (w) { 1338 case WPA_SEL(WPA_CSE_NULL): 1339 return IEEE80211_CIPHER_NONE; 1340 case WPA_SEL(WPA_CSE_WEP40): 1341 if (keylen) 1342 *keylen = 40 / NBBY; 1343 return IEEE80211_CIPHER_WEP; 1344 case WPA_SEL(WPA_CSE_WEP104): 1345 if (keylen) 1346 *keylen = 104 / NBBY; 1347 return IEEE80211_CIPHER_WEP; 1348 case WPA_SEL(WPA_CSE_TKIP): 1349 return IEEE80211_CIPHER_TKIP; 1350 case WPA_SEL(WPA_CSE_CCMP): 1351 return IEEE80211_CIPHER_AES_CCM; 1352 } 1353 return 32; /* NB: so 1<< is discarded */ 1354 #undef WPA_SEL 1355 } 1356 1357 /* 1358 * Convert a WPA key management/authentication algorithm 1359 * to an internal code. 1360 */ 1361 static int 1362 wpa_keymgmt(u_int8_t *sel) 1363 { 1364 #define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1365 u_int32_t w = LE_READ_4(sel); 1366 1367 switch (w) { 1368 case WPA_SEL(WPA_ASE_8021X_UNSPEC): 1369 return WPA_ASE_8021X_UNSPEC; 1370 case WPA_SEL(WPA_ASE_8021X_PSK): 1371 return WPA_ASE_8021X_PSK; 1372 case WPA_SEL(WPA_ASE_NONE): 1373 return WPA_ASE_NONE; 1374 } 1375 return 0; /* NB: so is discarded */ 1376 #undef WPA_SEL 1377 } 1378 1379 /* 1380 * Parse a WPA information element to collect parameters 1381 * and validate the parameters against what has been 1382 * configured for the system. 1383 */ 1384 static int 1385 ieee80211_parse_wpa(struct ieee80211com *ic, u_int8_t *frm, 1386 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1387 { 1388 u_int8_t len = frm[1]; 1389 u_int32_t w; 1390 int n; 1391 1392 /* 1393 * Check the length once for fixed parts: OUI, type, 1394 * version, mcast cipher, and 2 selector counts. 1395 * Other, variable-length data, must be checked separately. 1396 */ 1397 if ((ic->ic_flags & IEEE80211_F_WPA1) == 0) { 1398 IEEE80211_DISCARD_IE(ic, 1399 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1400 wh, "WPA", "not WPA, flags 0x%x", ic->ic_flags); 1401 return IEEE80211_REASON_IE_INVALID; 1402 } 1403 if (len < 14) { 1404 IEEE80211_DISCARD_IE(ic, 1405 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1406 wh, "WPA", "too short, len %u", len); 1407 return IEEE80211_REASON_IE_INVALID; 1408 } 1409 frm += 6, len -= 4; /* NB: len is payload only */ 1410 /* NB: iswapoui already validated the OUI and type */ 1411 w = LE_READ_2(frm); 1412 if (w != WPA_VERSION) { 1413 IEEE80211_DISCARD_IE(ic, 1414 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1415 wh, "WPA", "bad version %u", w); 1416 return IEEE80211_REASON_IE_INVALID; 1417 } 1418 frm += 2, len -= 2; 1419 1420 /* multicast/group cipher */ 1421 w = wpa_cipher(frm, &rsn->rsn_mcastkeylen); 1422 if (w != rsn->rsn_mcastcipher) { 1423 IEEE80211_DISCARD_IE(ic, 1424 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1425 wh, "WPA", "mcast cipher mismatch; got %u, expected %u", 1426 w, rsn->rsn_mcastcipher); 1427 return IEEE80211_REASON_IE_INVALID; 1428 } 1429 frm += 4, len -= 4; 1430 1431 /* unicast ciphers */ 1432 n = LE_READ_2(frm); 1433 frm += 2, len -= 2; 1434 if (len < n*4+2) { 1435 IEEE80211_DISCARD_IE(ic, 1436 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1437 wh, "WPA", "ucast cipher data too short; len %u, n %u", 1438 len, n); 1439 return IEEE80211_REASON_IE_INVALID; 1440 } 1441 w = 0; 1442 for (; n > 0; n--) { 1443 w |= 1<<wpa_cipher(frm, &rsn->rsn_ucastkeylen); 1444 frm += 4, len -= 4; 1445 } 1446 w &= rsn->rsn_ucastcipherset; 1447 if (w == 0) { 1448 IEEE80211_DISCARD_IE(ic, 1449 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1450 wh, "WPA", "%s", "ucast cipher set empty"); 1451 return IEEE80211_REASON_IE_INVALID; 1452 } 1453 if (w & (1<<IEEE80211_CIPHER_TKIP)) 1454 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1455 else 1456 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1457 1458 /* key management algorithms */ 1459 n = LE_READ_2(frm); 1460 frm += 2, len -= 2; 1461 if (len < n*4) { 1462 IEEE80211_DISCARD_IE(ic, 1463 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1464 wh, "WPA", "key mgmt alg data too short; len %u, n %u", 1465 len, n); 1466 return IEEE80211_REASON_IE_INVALID; 1467 } 1468 w = 0; 1469 for (; n > 0; n--) { 1470 w |= wpa_keymgmt(frm); 1471 frm += 4, len -= 4; 1472 } 1473 w &= rsn->rsn_keymgmtset; 1474 if (w == 0) { 1475 IEEE80211_DISCARD_IE(ic, 1476 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1477 wh, "WPA", "%s", "no acceptable key mgmt alg"); 1478 return IEEE80211_REASON_IE_INVALID; 1479 } 1480 if (w & WPA_ASE_8021X_UNSPEC) 1481 rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC; 1482 else 1483 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK; 1484 1485 if (len > 2) /* optional capabilities */ 1486 rsn->rsn_caps = LE_READ_2(frm); 1487 1488 return 0; 1489 } 1490 1491 /* 1492 * Convert an RSN cipher selector OUI to an internal 1493 * cipher algorithm. Where appropriate we also 1494 * record any key length. 1495 */ 1496 static int 1497 rsn_cipher(u_int8_t *sel, u_int8_t *keylen) 1498 { 1499 #define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1500 u_int32_t w = LE_READ_4(sel); 1501 1502 switch (w) { 1503 case RSN_SEL(RSN_CSE_NULL): 1504 return IEEE80211_CIPHER_NONE; 1505 case RSN_SEL(RSN_CSE_WEP40): 1506 if (keylen) 1507 *keylen = 40 / NBBY; 1508 return IEEE80211_CIPHER_WEP; 1509 case RSN_SEL(RSN_CSE_WEP104): 1510 if (keylen) 1511 *keylen = 104 / NBBY; 1512 return IEEE80211_CIPHER_WEP; 1513 case RSN_SEL(RSN_CSE_TKIP): 1514 return IEEE80211_CIPHER_TKIP; 1515 case RSN_SEL(RSN_CSE_CCMP): 1516 return IEEE80211_CIPHER_AES_CCM; 1517 case RSN_SEL(RSN_CSE_WRAP): 1518 return IEEE80211_CIPHER_AES_OCB; 1519 } 1520 return 32; /* NB: so 1<< is discarded */ 1521 #undef WPA_SEL 1522 } 1523 1524 /* 1525 * Convert an RSN key management/authentication algorithm 1526 * to an internal code. 1527 */ 1528 static int 1529 rsn_keymgmt(u_int8_t *sel) 1530 { 1531 #define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1532 u_int32_t w = LE_READ_4(sel); 1533 1534 switch (w) { 1535 case RSN_SEL(RSN_ASE_8021X_UNSPEC): 1536 return RSN_ASE_8021X_UNSPEC; 1537 case RSN_SEL(RSN_ASE_8021X_PSK): 1538 return RSN_ASE_8021X_PSK; 1539 case RSN_SEL(RSN_ASE_NONE): 1540 return RSN_ASE_NONE; 1541 } 1542 return 0; /* NB: so is discarded */ 1543 #undef RSN_SEL 1544 } 1545 1546 /* 1547 * Parse a WPA/RSN information element to collect parameters 1548 * and validate the parameters against what has been 1549 * configured for the system. 1550 */ 1551 static int 1552 ieee80211_parse_rsn(struct ieee80211com *ic, u_int8_t *frm, 1553 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1554 { 1555 u_int8_t len = frm[1]; 1556 u_int32_t w; 1557 int n; 1558 1559 /* 1560 * Check the length once for fixed parts: 1561 * version, mcast cipher, and 2 selector counts. 1562 * Other, variable-length data, must be checked separately. 1563 */ 1564 if ((ic->ic_flags & IEEE80211_F_WPA2) == 0) { 1565 IEEE80211_DISCARD_IE(ic, 1566 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1567 wh, "WPA", "not RSN, flags 0x%x", ic->ic_flags); 1568 return IEEE80211_REASON_IE_INVALID; 1569 } 1570 if (len < 10) { 1571 IEEE80211_DISCARD_IE(ic, 1572 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1573 wh, "RSN", "too short, len %u", len); 1574 return IEEE80211_REASON_IE_INVALID; 1575 } 1576 frm += 2; 1577 w = LE_READ_2(frm); 1578 if (w != RSN_VERSION) { 1579 IEEE80211_DISCARD_IE(ic, 1580 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1581 wh, "RSN", "bad version %u", w); 1582 return IEEE80211_REASON_IE_INVALID; 1583 } 1584 frm += 2, len -= 2; 1585 1586 /* multicast/group cipher */ 1587 w = rsn_cipher(frm, &rsn->rsn_mcastkeylen); 1588 if (w != rsn->rsn_mcastcipher) { 1589 IEEE80211_DISCARD_IE(ic, 1590 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1591 wh, "RSN", "mcast cipher mismatch; got %u, expected %u", 1592 w, rsn->rsn_mcastcipher); 1593 return IEEE80211_REASON_IE_INVALID; 1594 } 1595 frm += 4, len -= 4; 1596 1597 /* unicast ciphers */ 1598 n = LE_READ_2(frm); 1599 frm += 2, len -= 2; 1600 if (len < n*4+2) { 1601 IEEE80211_DISCARD_IE(ic, 1602 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1603 wh, "RSN", "ucast cipher data too short; len %u, n %u", 1604 len, n); 1605 return IEEE80211_REASON_IE_INVALID; 1606 } 1607 w = 0; 1608 for (; n > 0; n--) { 1609 w |= 1<<rsn_cipher(frm, &rsn->rsn_ucastkeylen); 1610 frm += 4, len -= 4; 1611 } 1612 w &= rsn->rsn_ucastcipherset; 1613 if (w == 0) { 1614 IEEE80211_DISCARD_IE(ic, 1615 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1616 wh, "RSN", "%s", "ucast cipher set empty"); 1617 return IEEE80211_REASON_IE_INVALID; 1618 } 1619 if (w & (1<<IEEE80211_CIPHER_TKIP)) 1620 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1621 else 1622 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1623 1624 /* key management algorithms */ 1625 n = LE_READ_2(frm); 1626 frm += 2, len -= 2; 1627 if (len < n*4) { 1628 IEEE80211_DISCARD_IE(ic, 1629 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1630 wh, "RSN", "key mgmt alg data too short; len %u, n %u", 1631 len, n); 1632 return IEEE80211_REASON_IE_INVALID; 1633 } 1634 w = 0; 1635 for (; n > 0; n--) { 1636 w |= rsn_keymgmt(frm); 1637 frm += 4, len -= 4; 1638 } 1639 w &= rsn->rsn_keymgmtset; 1640 if (w == 0) { 1641 IEEE80211_DISCARD_IE(ic, 1642 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1643 wh, "RSN", "%s", "no acceptable key mgmt alg"); 1644 return IEEE80211_REASON_IE_INVALID; 1645 } 1646 if (w & RSN_ASE_8021X_UNSPEC) 1647 rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC; 1648 else 1649 rsn->rsn_keymgmt = RSN_ASE_8021X_PSK; 1650 1651 /* optional RSN capabilities */ 1652 if (len > 2) 1653 rsn->rsn_caps = LE_READ_2(frm); 1654 /* XXXPMKID */ 1655 1656 return 0; 1657 } 1658 1659 static int 1660 ieee80211_parse_wmeparams(struct ieee80211com *ic, u_int8_t *frm, 1661 const struct ieee80211_frame *wh) 1662 { 1663 #define MS(_v, _f) (((_v) & _f) >> _f##_S) 1664 struct ieee80211_wme_state *wme = &ic->ic_wme; 1665 u_int len = frm[1], qosinfo; 1666 int i; 1667 1668 if (len < sizeof(struct ieee80211_wme_param)-2) { 1669 IEEE80211_DISCARD_IE(ic, 1670 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME, 1671 wh, "WME", "too short, len %u", len); 1672 return -1; 1673 } 1674 qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)]; 1675 qosinfo &= WME_QOSINFO_COUNT; 1676 /* XXX do proper check for wraparound */ 1677 if (qosinfo == wme->wme_wmeChanParams.cap_info) 1678 return 0; 1679 frm += __offsetof(struct ieee80211_wme_param, params_acParams); 1680 for (i = 0; i < WME_NUM_AC; i++) { 1681 struct wmeParams *wmep = 1682 &wme->wme_wmeChanParams.cap_wmeParams[i]; 1683 /* NB: ACI not used */ 1684 wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM); 1685 wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN); 1686 wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN); 1687 wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX); 1688 wmep->wmep_txopLimit = LE_READ_2(frm+2); 1689 frm += 4; 1690 } 1691 wme->wme_wmeChanParams.cap_info = qosinfo; 1692 return 1; 1693 #undef MS 1694 } 1695 1696 void 1697 ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie) 1698 { 1699 u_int ielen = ie[1]+2; 1700 /* 1701 * Record information element for later use. 1702 */ 1703 if (*iep == NULL || (*iep)[1] != ie[1]) { 1704 if (*iep != NULL) 1705 FREE(*iep, M_DEVBUF); 1706 MALLOC(*iep, void*, ielen, M_DEVBUF, M_NOWAIT); 1707 } 1708 if (*iep != NULL) 1709 memcpy(*iep, ie, ielen); 1710 /* XXX note failure */ 1711 } 1712 1713 void 1714 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 1715 struct ieee80211_node *ni, 1716 int subtype, int rssi, u_int32_t rstamp) 1717 { 1718 #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 1719 #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) 1720 struct ieee80211_frame *wh; 1721 u_int8_t *frm, *efrm; 1722 u_int8_t *ssid, *rates, *xrates, *wpa, *wme; 1723 int reassoc, resp, allocbs; 1724 u_int8_t rate; 1725 1726 wh = mtod(m0, struct ieee80211_frame *); 1727 frm = (u_int8_t *)&wh[1]; 1728 efrm = mtod(m0, u_int8_t *) + m0->m_len; 1729 switch (subtype) { 1730 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 1731 case IEEE80211_FC0_SUBTYPE_BEACON: { 1732 struct ieee80211_scanparams scan; 1733 1734 /* 1735 * We process beacon/probe response frames: 1736 * o when scanning, or 1737 * o station mode when associated (to collect state 1738 * updates such as 802.11g slot time), or 1739 * o adhoc mode (to discover neighbors) 1740 * Frames otherwise received are discarded. 1741 */ 1742 if (!((ic->ic_flags & IEEE80211_F_SCAN) || 1743 (ic->ic_opmode == IEEE80211_M_STA && ni->ni_associd) || 1744 ic->ic_opmode == IEEE80211_M_IBSS)) { 1745 ic->ic_stats.is_rx_mgtdiscard++; 1746 return; 1747 } 1748 /* 1749 * beacon/probe response frame format 1750 * [8] time stamp 1751 * [2] beacon interval 1752 * [2] capability information 1753 * [tlv] ssid 1754 * [tlv] supported rates 1755 * [tlv] country information 1756 * [tlv] parameter set (FH/DS) 1757 * [tlv] erp information 1758 * [tlv] extended supported rates 1759 * [tlv] WME 1760 * [tlv] WPA or RSN 1761 */ 1762 IEEE80211_VERIFY_LENGTH(efrm - frm, 12); 1763 memset(&scan, 0, sizeof(scan)); 1764 scan.tstamp = frm; frm += 8; 1765 scan.bintval = le16toh(*(u_int16_t *)frm); frm += 2; 1766 scan.capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 1767 scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan); 1768 scan.chan = scan.bchan; 1769 1770 while (frm < efrm) { 1771 switch (*frm) { 1772 case IEEE80211_ELEMID_SSID: 1773 scan.ssid = frm; 1774 break; 1775 case IEEE80211_ELEMID_RATES: 1776 scan.rates = frm; 1777 break; 1778 case IEEE80211_ELEMID_COUNTRY: 1779 scan.country = frm; 1780 break; 1781 case IEEE80211_ELEMID_FHPARMS: 1782 if (ic->ic_phytype == IEEE80211_T_FH) { 1783 scan.fhdwell = LE_READ_2(&frm[2]); 1784 scan.chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 1785 scan.fhindex = frm[6]; 1786 } 1787 break; 1788 case IEEE80211_ELEMID_DSPARMS: 1789 /* 1790 * XXX hack this since depending on phytype 1791 * is problematic for multi-mode devices. 1792 */ 1793 if (ic->ic_phytype != IEEE80211_T_FH) 1794 scan.chan = frm[2]; 1795 break; 1796 case IEEE80211_ELEMID_TIM: 1797 /* XXX ATIM? */ 1798 scan.tim = frm; 1799 scan.timoff = frm - mtod(m0, u_int8_t *); 1800 break; 1801 case IEEE80211_ELEMID_IBSSPARMS: 1802 break; 1803 case IEEE80211_ELEMID_XRATES: 1804 scan.xrates = frm; 1805 break; 1806 case IEEE80211_ELEMID_ERP: 1807 if (frm[1] != 1) { 1808 IEEE80211_DISCARD_IE(ic, 1809 IEEE80211_MSG_ELEMID, wh, "ERP", 1810 "bad len %u", frm[1]); 1811 ic->ic_stats.is_rx_elem_toobig++; 1812 break; 1813 } 1814 scan.erp = frm[2]; 1815 break; 1816 case IEEE80211_ELEMID_RSN: 1817 scan.wpa = frm; 1818 break; 1819 case IEEE80211_ELEMID_VENDOR: 1820 if (iswpaoui(frm)) 1821 scan.wpa = frm; 1822 else if (iswmeparam(frm) || iswmeinfo(frm)) 1823 scan.wme = frm; 1824 /* XXX Atheros OUI support */ 1825 break; 1826 default: 1827 IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID, 1828 wh, "unhandled", 1829 "id %u, len %u", *frm, frm[1]); 1830 ic->ic_stats.is_rx_elem_unknown++; 1831 break; 1832 } 1833 frm += frm[1] + 2; 1834 } 1835 IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE); 1836 IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN); 1837 if ( 1838 #if IEEE80211_CHAN_MAX < 255 1839 scan.chan > IEEE80211_CHAN_MAX || 1840 #endif 1841 isclr(ic->ic_chan_active, scan.chan)) { 1842 IEEE80211_DISCARD(ic, 1843 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 1844 wh, ieee80211_mgt_subtype_name[subtype >> 1845 IEEE80211_FC0_SUBTYPE_SHIFT], 1846 "invalid channel %u", scan.chan); 1847 ic->ic_stats.is_rx_badchan++; 1848 return; 1849 } 1850 if (scan.chan != scan.bchan && 1851 ic->ic_phytype != IEEE80211_T_FH) { 1852 /* 1853 * Frame was received on a channel different from the 1854 * one indicated in the DS params element id; 1855 * silently discard it. 1856 * 1857 * NB: this can happen due to signal leakage. 1858 * But we should take it for FH phy because 1859 * the rssi value should be correct even for 1860 * different hop pattern in FH. 1861 */ 1862 IEEE80211_DISCARD(ic, 1863 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 1864 wh, ieee80211_mgt_subtype_name[subtype >> 1865 IEEE80211_FC0_SUBTYPE_SHIFT], 1866 "for off-channel %u", scan.chan); 1867 ic->ic_stats.is_rx_chanmismatch++; 1868 return; 1869 } 1870 if (!(IEEE80211_BINTVAL_MIN <= scan.bintval && 1871 scan.bintval <= IEEE80211_BINTVAL_MAX)) { 1872 IEEE80211_DISCARD(ic, 1873 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 1874 wh, ieee80211_mgt_subtype_name[subtype >> 1875 IEEE80211_FC0_SUBTYPE_SHIFT], 1876 "bogus beacon interval", scan.bintval); 1877 ic->ic_stats.is_rx_badbintval++; 1878 return; 1879 } 1880 1881 /* 1882 * Count frame now that we know it's to be processed. 1883 */ 1884 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { 1885 ic->ic_stats.is_rx_beacon++; /* XXX remove */ 1886 IEEE80211_NODE_STAT(ni, rx_beacons); 1887 } else 1888 IEEE80211_NODE_STAT(ni, rx_proberesp); 1889 1890 /* 1891 * When operating in station mode, check for state updates. 1892 * Be careful to ignore beacons received while doing a 1893 * background scan. We consider only 11g/WMM stuff right now. 1894 */ 1895 if (ic->ic_opmode == IEEE80211_M_STA && 1896 ni->ni_associd != 0 && 1897 ((ic->ic_flags & IEEE80211_F_SCAN) == 0 || 1898 IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) { 1899 /* record tsf of last beacon */ 1900 memcpy(ni->ni_tstamp.data, scan.tstamp, 1901 sizeof(ni->ni_tstamp)); 1902 if (ni->ni_erp != scan.erp) { 1903 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1904 "[%s] erp change: was 0x%x, now 0x%x\n", 1905 ether_sprintf(wh->i_addr2), 1906 ni->ni_erp, scan.erp); 1907 if (ic->ic_curmode == IEEE80211_MODE_11G && 1908 (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)) 1909 ic->ic_flags |= IEEE80211_F_USEPROT; 1910 else 1911 ic->ic_flags &= ~IEEE80211_F_USEPROT; 1912 ni->ni_erp = scan.erp; 1913 /* XXX statistic */ 1914 } 1915 if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) { 1916 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1917 "[%s] capabilities change: before 0x%x," 1918 " now 0x%x\n", 1919 ether_sprintf(wh->i_addr2), 1920 ni->ni_capinfo, scan.capinfo); 1921 /* 1922 * NB: we assume short preamble doesn't 1923 * change dynamically 1924 */ 1925 ieee80211_set_shortslottime(ic, 1926 ic->ic_curmode == IEEE80211_MODE_11A || 1927 (scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); 1928 ni->ni_capinfo = scan.capinfo; 1929 /* XXX statistic */ 1930 } 1931 if (scan.wme != NULL && 1932 (ni->ni_flags & IEEE80211_NODE_QOS) && 1933 ieee80211_parse_wmeparams(ic, scan.wme, wh) > 0) 1934 ieee80211_wme_updateparams(ic); 1935 if (scan.tim != NULL) { 1936 struct ieee80211_tim_ie *ie = 1937 (struct ieee80211_tim_ie *) scan.tim; 1938 1939 ni->ni_dtim_count = ie->tim_count; 1940 ni->ni_dtim_period = ie->tim_period; 1941 } 1942 if (ic->ic_flags & IEEE80211_F_SCAN) 1943 ieee80211_add_scan(ic, &scan, wh, 1944 subtype, rssi, rstamp); 1945 return; 1946 } 1947 /* 1948 * If scanning, just pass information to the scan module. 1949 */ 1950 if (ic->ic_flags & IEEE80211_F_SCAN) { 1951 ieee80211_add_scan(ic, &scan, wh, 1952 subtype, rssi, rstamp); 1953 return; 1954 } 1955 if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { 1956 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 1957 /* 1958 * Create a new entry in the neighbor table. 1959 */ 1960 ni = ieee80211_add_neighbor(ic, wh, &scan); 1961 } else if (ni->ni_capinfo == 0) { 1962 /* 1963 * Update faked node created on transmit. 1964 * Note this also updates the tsf. 1965 */ 1966 ieee80211_init_neighbor(ni, wh, &scan); 1967 } else { 1968 /* 1969 * Record tsf for potential resync. 1970 */ 1971 memcpy(ni->ni_tstamp.data, scan.tstamp, 1972 sizeof(ni->ni_tstamp)); 1973 } 1974 if (ni != NULL) { 1975 ni->ni_rssi = rssi; 1976 ni->ni_rstamp = rstamp; 1977 } 1978 } 1979 break; 1980 } 1981 1982 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 1983 if (ic->ic_opmode == IEEE80211_M_STA || 1984 ic->ic_state != IEEE80211_S_RUN) { 1985 ic->ic_stats.is_rx_mgtdiscard++; 1986 return; 1987 } 1988 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { 1989 /* frame must be directed */ 1990 ic->ic_stats.is_rx_mgtdiscard++; /* XXX stat */ 1991 return; 1992 } 1993 1994 /* 1995 * prreq frame format 1996 * [tlv] ssid 1997 * [tlv] supported rates 1998 * [tlv] extended supported rates 1999 */ 2000 ssid = rates = xrates = NULL; 2001 while (frm < efrm) { 2002 switch (*frm) { 2003 case IEEE80211_ELEMID_SSID: 2004 ssid = frm; 2005 break; 2006 case IEEE80211_ELEMID_RATES: 2007 rates = frm; 2008 break; 2009 case IEEE80211_ELEMID_XRATES: 2010 xrates = frm; 2011 break; 2012 } 2013 frm += frm[1] + 2; 2014 } 2015 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2016 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 2017 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid); 2018 if ((ic->ic_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { 2019 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 2020 wh, ieee80211_mgt_subtype_name[subtype >> 2021 IEEE80211_FC0_SUBTYPE_SHIFT], 2022 "%s", "no ssid with ssid suppression enabled"); 2023 ic->ic_stats.is_rx_ssidmismatch++; /*XXX*/ 2024 return; 2025 } 2026 2027 allocbs = 0; 2028 if (ni == ic->ic_bss) { 2029 if (ic->ic_opmode != IEEE80211_M_IBSS) { 2030 ni = ieee80211_tmp_node(ic, wh->i_addr2); 2031 allocbs = 1; 2032 } else if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 2033 /* 2034 * XXX Cannot tell if the sender is operating 2035 * in ibss mode. But we need a new node to 2036 * send the response so blindly add them to the 2037 * neighbor table. 2038 */ 2039 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, 2040 wh->i_addr2); 2041 } 2042 if (ni == NULL) 2043 return; 2044 } 2045 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2046 "[%s] recv probe req\n", ether_sprintf(wh->i_addr2)); 2047 ni->ni_rssi = rssi; 2048 ni->ni_rstamp = rstamp; 2049 rate = ieee80211_setup_rates(ni, rates, xrates, 2050 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 2051 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 2052 if (rate & IEEE80211_RATE_BASIC) { 2053 IEEE80211_DISCARD(ic, IEEE80211_MSG_XRATE, 2054 wh, ieee80211_mgt_subtype_name[subtype >> 2055 IEEE80211_FC0_SUBTYPE_SHIFT], 2056 "%s", "recv'd rate set invalid"); 2057 } else { 2058 IEEE80211_SEND_MGMT(ic, ni, 2059 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0); 2060 } 2061 if (allocbs) { 2062 /* 2063 * Temporary node created just to send a 2064 * response, reclaim immediately. 2065 */ 2066 ieee80211_free_node(ni); 2067 } 2068 break; 2069 2070 case IEEE80211_FC0_SUBTYPE_AUTH: { 2071 u_int16_t algo, seq, status; 2072 /* 2073 * auth frame format 2074 * [2] algorithm 2075 * [2] sequence 2076 * [2] status 2077 * [tlv*] challenge 2078 */ 2079 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 2080 algo = le16toh(*(u_int16_t *)frm); 2081 seq = le16toh(*(u_int16_t *)(frm + 2)); 2082 status = le16toh(*(u_int16_t *)(frm + 4)); 2083 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, 2084 "[%s] recv auth frame with algorithm %d seq %d\n", 2085 ether_sprintf(wh->i_addr2), algo, seq); 2086 /* 2087 * Consult the ACL policy module if setup. 2088 */ 2089 if (ic->ic_acl != NULL && 2090 !ic->ic_acl->iac_check(ic, wh->i_addr2)) { 2091 IEEE80211_DISCARD(ic, IEEE80211_MSG_ACL, 2092 wh, "auth", "%s", "disallowed by ACL"); 2093 ic->ic_stats.is_rx_acl++; 2094 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2095 IEEE80211_SEND_MGMT(ic, ni, 2096 IEEE80211_FC0_SUBTYPE_AUTH, 2097 (seq+1) | (IEEE80211_STATUS_UNSPECIFIED<<16)); 2098 } 2099 return; 2100 } 2101 if (ic->ic_flags & IEEE80211_F_COUNTERM) { 2102 IEEE80211_DISCARD(ic, 2103 IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO, 2104 wh, "auth", "%s", "TKIP countermeasures enabled"); 2105 ic->ic_stats.is_rx_auth_countermeasures++; 2106 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2107 IEEE80211_SEND_MGMT(ic, ni, 2108 IEEE80211_FC0_SUBTYPE_AUTH, 2109 IEEE80211_REASON_MIC_FAILURE); 2110 } 2111 return; 2112 } 2113 if (algo == IEEE80211_AUTH_ALG_SHARED) 2114 ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi, 2115 rstamp, seq, status); 2116 else if (algo == IEEE80211_AUTH_ALG_OPEN) 2117 ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq, 2118 status); 2119 else { 2120 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2121 wh, "auth", "unsupported alg %d", algo); 2122 ic->ic_stats.is_rx_auth_unsupported++; 2123 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2124 /* XXX not right */ 2125 IEEE80211_SEND_MGMT(ic, ni, 2126 IEEE80211_FC0_SUBTYPE_AUTH, 2127 (seq+1) | (IEEE80211_STATUS_ALG<<16)); 2128 } 2129 return; 2130 } 2131 break; 2132 } 2133 2134 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2135 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { 2136 u_int16_t capinfo, lintval; 2137 struct ieee80211_rsnparms rsn; 2138 u_int8_t reason; 2139 2140 if (ic->ic_opmode != IEEE80211_M_HOSTAP || 2141 ic->ic_state != IEEE80211_S_RUN) { 2142 ic->ic_stats.is_rx_mgtdiscard++; 2143 return; 2144 } 2145 2146 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 2147 reassoc = 1; 2148 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 2149 } else { 2150 reassoc = 0; 2151 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 2152 } 2153 /* 2154 * asreq frame format 2155 * [2] capability information 2156 * [2] listen interval 2157 * [6*] current AP address (reassoc only) 2158 * [tlv] ssid 2159 * [tlv] supported rates 2160 * [tlv] extended supported rates 2161 * [tlv] WPA or RSN 2162 */ 2163 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 2164 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 2165 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2166 wh, ieee80211_mgt_subtype_name[subtype >> 2167 IEEE80211_FC0_SUBTYPE_SHIFT], 2168 "%s", "wrong bssid"); 2169 ic->ic_stats.is_rx_assoc_bss++; 2170 return; 2171 } 2172 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 2173 lintval = le16toh(*(u_int16_t *)frm); frm += 2; 2174 if (reassoc) 2175 frm += 6; /* ignore current AP info */ 2176 ssid = rates = xrates = wpa = wme = NULL; 2177 while (frm < efrm) { 2178 switch (*frm) { 2179 case IEEE80211_ELEMID_SSID: 2180 ssid = frm; 2181 break; 2182 case IEEE80211_ELEMID_RATES: 2183 rates = frm; 2184 break; 2185 case IEEE80211_ELEMID_XRATES: 2186 xrates = frm; 2187 break; 2188 /* XXX verify only one of RSN and WPA ie's? */ 2189 case IEEE80211_ELEMID_RSN: 2190 wpa = frm; 2191 break; 2192 case IEEE80211_ELEMID_VENDOR: 2193 if (iswpaoui(frm)) 2194 wpa = frm; 2195 else if (iswmeinfo(frm)) 2196 wme = frm; 2197 /* XXX Atheros OUI support */ 2198 break; 2199 } 2200 frm += frm[1] + 2; 2201 } 2202 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2203 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 2204 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid); 2205 2206 if (ni == ic->ic_bss) { 2207 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2208 "[%s] deny %s request, sta not authenticated\n", 2209 ether_sprintf(wh->i_addr2), 2210 reassoc ? "reassoc" : "assoc"); 2211 ieee80211_send_error(ic, ni, wh->i_addr2, 2212 IEEE80211_FC0_SUBTYPE_DEAUTH, 2213 IEEE80211_REASON_ASSOC_NOT_AUTHED); 2214 ic->ic_stats.is_rx_assoc_notauth++; 2215 return; 2216 } 2217 /* assert right associstion security credentials */ 2218 if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) { 2219 IEEE80211_DPRINTF(ic, 2220 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 2221 "[%s] no WPA/RSN IE in association request\n", 2222 ether_sprintf(wh->i_addr2)); 2223 IEEE80211_SEND_MGMT(ic, ni, 2224 IEEE80211_FC0_SUBTYPE_DEAUTH, 2225 IEEE80211_REASON_RSN_REQUIRED); 2226 ieee80211_node_leave(ic, ni); 2227 /* XXX distinguish WPA/RSN? */ 2228 ic->ic_stats.is_rx_assoc_badwpaie++; 2229 return; 2230 } 2231 if (wpa != NULL) { 2232 /* 2233 * Parse WPA information element. Note that 2234 * we initialize the param block from the node 2235 * state so that information in the IE overrides 2236 * our defaults. The resulting parameters are 2237 * installed below after the association is assured. 2238 */ 2239 rsn = ni->ni_rsn; 2240 if (wpa[0] != IEEE80211_ELEMID_RSN) 2241 reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh); 2242 else 2243 reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh); 2244 if (reason != 0) { 2245 IEEE80211_SEND_MGMT(ic, ni, 2246 IEEE80211_FC0_SUBTYPE_DEAUTH, reason); 2247 ieee80211_node_leave(ic, ni); 2248 /* XXX distinguish WPA/RSN? */ 2249 ic->ic_stats.is_rx_assoc_badwpaie++; 2250 return; 2251 } 2252 IEEE80211_DPRINTF(ic, 2253 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 2254 "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n", 2255 ether_sprintf(wh->i_addr2), 2256 wpa[0] != IEEE80211_ELEMID_RSN ? "WPA" : "RSN", 2257 rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen, 2258 rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen, 2259 rsn.rsn_keymgmt, rsn.rsn_caps); 2260 } 2261 /* discard challenge after association */ 2262 if (ni->ni_challenge != NULL) { 2263 FREE(ni->ni_challenge, M_DEVBUF); 2264 ni->ni_challenge = NULL; 2265 } 2266 /* NB: 802.11 spec says to ignore station's privacy bit */ 2267 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0) { 2268 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2269 "[%s] deny %s request, capability mismatch 0x%x\n", 2270 ether_sprintf(wh->i_addr2), 2271 reassoc ? "reassoc" : "assoc", capinfo); 2272 IEEE80211_SEND_MGMT(ic, ni, resp, 2273 IEEE80211_STATUS_CAPINFO); 2274 ieee80211_node_leave(ic, ni); 2275 ic->ic_stats.is_rx_assoc_capmismatch++; 2276 return; 2277 } 2278 rate = ieee80211_setup_rates(ni, rates, xrates, 2279 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 2280 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 2281 /* 2282 * If constrained to 11g-only stations reject an 2283 * 11b-only station. We cheat a bit here by looking 2284 * at the max negotiated xmit rate and assuming anyone 2285 * with a best rate <24Mb/s is an 11b station. 2286 */ 2287 if ((rate & IEEE80211_RATE_BASIC) || 2288 ((ic->ic_flags & IEEE80211_F_PUREG) && rate < 48)) { 2289 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2290 "[%s] deny %s request, rate set mismatch\n", 2291 ether_sprintf(wh->i_addr2), 2292 reassoc ? "reassoc" : "assoc"); 2293 IEEE80211_SEND_MGMT(ic, ni, resp, 2294 IEEE80211_STATUS_BASIC_RATE); 2295 ieee80211_node_leave(ic, ni); 2296 ic->ic_stats.is_rx_assoc_norate++; 2297 return; 2298 } 2299 ni->ni_rssi = rssi; 2300 ni->ni_rstamp = rstamp; 2301 ni->ni_intval = lintval; 2302 ni->ni_capinfo = capinfo; 2303 ni->ni_chan = ic->ic_bss->ni_chan; 2304 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 2305 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 2306 if (wpa != NULL) { 2307 /* 2308 * Record WPA/RSN parameters for station, mark 2309 * node as using WPA and record information element 2310 * for applications that require it. 2311 */ 2312 ni->ni_rsn = rsn; 2313 ieee80211_saveie(&ni->ni_wpa_ie, wpa); 2314 } else if (ni->ni_wpa_ie != NULL) { 2315 /* 2316 * Flush any state from a previous association. 2317 */ 2318 FREE(ni->ni_wpa_ie, M_DEVBUF); 2319 ni->ni_wpa_ie = NULL; 2320 } 2321 if (wme != NULL) { 2322 /* 2323 * Record WME parameters for station, mark node 2324 * as capable of QoS and record information 2325 * element for applications that require it. 2326 */ 2327 ieee80211_saveie(&ni->ni_wme_ie, wme); 2328 ni->ni_flags |= IEEE80211_NODE_QOS; 2329 } else if (ni->ni_wme_ie != NULL) { 2330 /* 2331 * Flush any state from a previous association. 2332 */ 2333 FREE(ni->ni_wme_ie, M_DEVBUF); 2334 ni->ni_wme_ie = NULL; 2335 ni->ni_flags &= ~IEEE80211_NODE_QOS; 2336 } 2337 ieee80211_node_join(ic, ni, resp); 2338 break; 2339 } 2340 2341 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2342 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 2343 u_int16_t capinfo, associd; 2344 u_int16_t status; 2345 2346 if (ic->ic_opmode != IEEE80211_M_STA || 2347 ic->ic_state != IEEE80211_S_ASSOC) { 2348 ic->ic_stats.is_rx_mgtdiscard++; 2349 return; 2350 } 2351 2352 /* 2353 * asresp frame format 2354 * [2] capability information 2355 * [2] status 2356 * [2] association ID 2357 * [tlv] supported rates 2358 * [tlv] extended supported rates 2359 * [tlv] WME 2360 */ 2361 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 2362 ni = ic->ic_bss; 2363 capinfo = le16toh(*(u_int16_t *)frm); 2364 frm += 2; 2365 status = le16toh(*(u_int16_t *)frm); 2366 frm += 2; 2367 if (status != 0) { 2368 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2369 "[%s] %sassoc failed (reason %d)\n", 2370 ether_sprintf(wh->i_addr2), 2371 ISREASSOC(subtype) ? "re" : "", status); 2372 if (ni != ic->ic_bss) /* XXX never true? */ 2373 ni->ni_fails++; 2374 ic->ic_stats.is_rx_auth_fail++; /* XXX */ 2375 return; 2376 } 2377 associd = le16toh(*(u_int16_t *)frm); 2378 frm += 2; 2379 2380 rates = xrates = wpa = wme = NULL; 2381 while (frm < efrm) { 2382 switch (*frm) { 2383 case IEEE80211_ELEMID_RATES: 2384 rates = frm; 2385 break; 2386 case IEEE80211_ELEMID_XRATES: 2387 xrates = frm; 2388 break; 2389 case IEEE80211_ELEMID_VENDOR: 2390 if (iswmeoui(frm)) 2391 wme = frm; 2392 /* XXX Atheros OUI support */ 2393 break; 2394 } 2395 frm += frm[1] + 2; 2396 } 2397 2398 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2399 rate = ieee80211_setup_rates(ni, rates, xrates, 2400 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 2401 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 2402 if (rate & IEEE80211_RATE_BASIC) { 2403 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2404 "[%s] %sassoc failed (rate set mismatch)\n", 2405 ether_sprintf(wh->i_addr2), 2406 ISREASSOC(subtype) ? "re" : ""); 2407 if (ni != ic->ic_bss) /* XXX never true? */ 2408 ni->ni_fails++; 2409 ic->ic_stats.is_rx_assoc_norate++; 2410 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 2411 return; 2412 } 2413 2414 ni->ni_capinfo = capinfo; 2415 ni->ni_associd = associd; 2416 if (wme != NULL && 2417 ieee80211_parse_wmeparams(ic, wme, wh) >= 0) { 2418 ni->ni_flags |= IEEE80211_NODE_QOS; 2419 ieee80211_wme_updateparams(ic); 2420 } else 2421 ni->ni_flags &= ~IEEE80211_NODE_QOS; 2422 /* 2423 * Configure state now that we are associated. 2424 * 2425 * XXX may need different/additional driver callbacks? 2426 */ 2427 if (ic->ic_curmode == IEEE80211_MODE_11A || 2428 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { 2429 ic->ic_flags |= IEEE80211_F_SHPREAMBLE; 2430 ic->ic_flags &= ~IEEE80211_F_USEBARKER; 2431 } else { 2432 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; 2433 ic->ic_flags |= IEEE80211_F_USEBARKER; 2434 } 2435 ieee80211_set_shortslottime(ic, 2436 ic->ic_curmode == IEEE80211_MODE_11A || 2437 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); 2438 /* 2439 * Honor ERP protection. 2440 * 2441 * NB: ni_erp should zero for non-11g operation. 2442 * XXX check ic_curmode anyway? 2443 */ 2444 if (ic->ic_curmode == IEEE80211_MODE_11G && 2445 (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)) 2446 ic->ic_flags |= IEEE80211_F_USEPROT; 2447 else 2448 ic->ic_flags &= ~IEEE80211_F_USEPROT; 2449 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2450 "[%s] %sassoc success: %s preamble, %s slot time%s%s\n", 2451 ether_sprintf(wh->i_addr2), 2452 ISREASSOC(subtype) ? "re" : "", 2453 ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", 2454 ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", 2455 ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "", 2456 ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "" 2457 ); 2458 ieee80211_new_state(ic, IEEE80211_S_RUN, subtype); 2459 break; 2460 } 2461 2462 case IEEE80211_FC0_SUBTYPE_DEAUTH: { 2463 u_int16_t reason; 2464 2465 if (ic->ic_state == IEEE80211_S_SCAN) { 2466 ic->ic_stats.is_rx_mgtdiscard++; 2467 return; 2468 } 2469 /* 2470 * deauth frame format 2471 * [2] reason 2472 */ 2473 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 2474 reason = le16toh(*(u_int16_t *)frm); 2475 ic->ic_stats.is_rx_deauth++; 2476 IEEE80211_NODE_STAT(ni, rx_deauth); 2477 2478 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, 2479 "[%s] recv deauthenticate (reason %d)\n", 2480 ether_sprintf(ni->ni_macaddr), reason); 2481 switch (ic->ic_opmode) { 2482 case IEEE80211_M_STA: 2483 ieee80211_new_state(ic, IEEE80211_S_AUTH, 2484 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 2485 break; 2486 case IEEE80211_M_HOSTAP: 2487 if (ni != ic->ic_bss) 2488 ieee80211_node_leave(ic, ni); 2489 break; 2490 default: 2491 ic->ic_stats.is_rx_mgtdiscard++; 2492 break; 2493 } 2494 break; 2495 } 2496 2497 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 2498 u_int16_t reason; 2499 2500 if (ic->ic_state != IEEE80211_S_RUN && 2501 ic->ic_state != IEEE80211_S_ASSOC && 2502 ic->ic_state != IEEE80211_S_AUTH) { 2503 ic->ic_stats.is_rx_mgtdiscard++; 2504 return; 2505 } 2506 /* 2507 * disassoc frame format 2508 * [2] reason 2509 */ 2510 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 2511 reason = le16toh(*(u_int16_t *)frm); 2512 ic->ic_stats.is_rx_disassoc++; 2513 IEEE80211_NODE_STAT(ni, rx_disassoc); 2514 2515 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2516 "[%s] recv disassociate (reason %d)\n", 2517 ether_sprintf(ni->ni_macaddr), reason); 2518 switch (ic->ic_opmode) { 2519 case IEEE80211_M_STA: 2520 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 2521 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 2522 break; 2523 case IEEE80211_M_HOSTAP: 2524 if (ni != ic->ic_bss) 2525 ieee80211_node_leave(ic, ni); 2526 break; 2527 default: 2528 ic->ic_stats.is_rx_mgtdiscard++; 2529 break; 2530 } 2531 break; 2532 } 2533 default: 2534 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2535 wh, "mgt", "subtype 0x%x not handled", subtype); 2536 ic->ic_stats.is_rx_badsubtype++; 2537 break; 2538 } 2539 #undef ISREASSOC 2540 #undef ISPROBE 2541 } 2542 #undef IEEE80211_VERIFY_LENGTH 2543 #undef IEEE80211_VERIFY_ELEMENT 2544 2545 /* 2546 * Handle station power-save state change. 2547 */ 2548 static void 2549 ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) 2550 { 2551 struct ieee80211com *ic = ni->ni_ic; 2552 struct mbuf *m; 2553 2554 if (enable) { 2555 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) 2556 ic->ic_ps_sta++; 2557 ni->ni_flags |= IEEE80211_NODE_PWR_MGT; 2558 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2559 "[%s] power save mode on, %u sta's in ps mode\n", 2560 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta); 2561 return; 2562 } 2563 2564 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) 2565 ic->ic_ps_sta--; 2566 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; 2567 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2568 "[%s] power save mode off, %u sta's in ps mode\n", 2569 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta); 2570 /* XXX if no stations in ps mode, flush mc frames */ 2571 2572 /* 2573 * Flush queued unicast frames. 2574 */ 2575 if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) { 2576 if (ic->ic_set_tim != NULL) 2577 ic->ic_set_tim(ni, 0); /* just in case */ 2578 return; 2579 } 2580 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2581 "[%s] flush ps queue, %u packets queued\n", 2582 ether_sprintf(ni->ni_macaddr), IEEE80211_NODE_SAVEQ_QLEN(ni)); 2583 for (;;) { 2584 int qlen; 2585 2586 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen); 2587 if (m == NULL) 2588 break; 2589 /* 2590 * If this is the last packet, turn off the TIM bit. 2591 * If there are more packets, set the more packets bit 2592 * in the mbuf so ieee80211_encap will mark the 802.11 2593 * head to indicate more data frames will follow. 2594 */ 2595 if (qlen != 0) 2596 m->m_flags |= M_MORE_DATA; 2597 /* XXX need different driver interface */ 2598 /* XXX bypasses q max */ 2599 IF_ENQUEUE(&ic->ic_ifp->if_snd, m); 2600 } 2601 if (ic->ic_set_tim != NULL) 2602 ic->ic_set_tim(ni, 0); 2603 } 2604 2605 /* 2606 * Process a received ps-poll frame. 2607 */ 2608 static void 2609 ieee80211_recv_pspoll(struct ieee80211com *ic, 2610 struct ieee80211_node *ni, struct mbuf *m0) 2611 { 2612 struct ieee80211_frame_min *wh; 2613 struct mbuf *m; 2614 u_int16_t aid; 2615 int qlen; 2616 2617 wh = mtod(m0, struct ieee80211_frame_min *); 2618 if (ni->ni_associd == 0) { 2619 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 2620 (struct ieee80211_frame *) wh, "ps-poll", 2621 "%s", "unassociated station"); 2622 ic->ic_stats.is_ps_unassoc++; 2623 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 2624 IEEE80211_REASON_NOT_ASSOCED); 2625 return; 2626 } 2627 2628 aid = le16toh(*(u_int16_t *)wh->i_dur); 2629 if (aid != ni->ni_associd) { 2630 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 2631 (struct ieee80211_frame *) wh, "ps-poll", 2632 "aid mismatch: sta aid 0x%x poll aid 0x%x", 2633 ni->ni_associd, aid); 2634 ic->ic_stats.is_ps_badaid++; 2635 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 2636 IEEE80211_REASON_NOT_ASSOCED); 2637 return; 2638 } 2639 2640 /* Okay, take the first queued packet and put it out... */ 2641 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen); 2642 if (m == NULL) { 2643 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2644 "[%s] recv ps-poll, but queue empty\n", 2645 ether_sprintf(wh->i_addr2)); 2646 ieee80211_send_nulldata(ieee80211_ref_node(ni)); 2647 ic->ic_stats.is_ps_qempty++; /* XXX node stat */ 2648 if (ic->ic_set_tim != NULL) 2649 ic->ic_set_tim(ni, 0); /* just in case */ 2650 return; 2651 } 2652 /* 2653 * If there are more packets, set the more packets bit 2654 * in the packet dispatched to the station; otherwise 2655 * turn off the TIM bit. 2656 */ 2657 if (qlen != 0) { 2658 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2659 "[%s] recv ps-poll, send packet, %u still queued\n", 2660 ether_sprintf(ni->ni_macaddr), qlen); 2661 m->m_flags |= M_MORE_DATA; 2662 } else { 2663 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 2664 "[%s] recv ps-poll, send packet, queue empty\n", 2665 ether_sprintf(ni->ni_macaddr)); 2666 if (ic->ic_set_tim != NULL) 2667 ic->ic_set_tim(ni, 0); 2668 } 2669 m->m_flags |= M_PWR_SAV; /* bypass PS handling */ 2670 IF_ENQUEUE(&ic->ic_ifp->if_snd, m); 2671 } 2672 2673 #ifdef IEEE80211_DEBUG 2674 /* 2675 * Debugging support. 2676 */ 2677 2678 /* 2679 * Return the bssid of a frame. 2680 */ 2681 static const u_int8_t * 2682 ieee80211_getbssid(struct ieee80211com *ic, const struct ieee80211_frame *wh) 2683 { 2684 if (ic->ic_opmode == IEEE80211_M_STA) 2685 return wh->i_addr2; 2686 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS) 2687 return wh->i_addr1; 2688 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) 2689 return wh->i_addr1; 2690 return wh->i_addr3; 2691 } 2692 2693 void 2694 ieee80211_note(struct ieee80211com *ic, const char *fmt, ...) 2695 { 2696 char buf[128]; /* XXX */ 2697 va_list ap; 2698 2699 va_start(ap, fmt); 2700 vsnprintf(buf, sizeof(buf), fmt, ap); 2701 va_end(ap); 2702 2703 if_printf(ic->ic_ifp, "%s", buf); /* NB: no \n */ 2704 } 2705 2706 void 2707 ieee80211_note_frame(struct ieee80211com *ic, 2708 const struct ieee80211_frame *wh, 2709 const char *fmt, ...) 2710 { 2711 char buf[128]; /* XXX */ 2712 va_list ap; 2713 2714 va_start(ap, fmt); 2715 vsnprintf(buf, sizeof(buf), fmt, ap); 2716 va_end(ap); 2717 if_printf(ic->ic_ifp, "[%s] %s\n", 2718 ether_sprintf(ieee80211_getbssid(ic, wh)), buf); 2719 } 2720 2721 void 2722 ieee80211_note_mac(struct ieee80211com *ic, 2723 const u_int8_t mac[IEEE80211_ADDR_LEN], 2724 const char *fmt, ...) 2725 { 2726 char buf[128]; /* XXX */ 2727 va_list ap; 2728 2729 va_start(ap, fmt); 2730 vsnprintf(buf, sizeof(buf), fmt, ap); 2731 va_end(ap); 2732 if_printf(ic->ic_ifp, "[%s] %s\n", ether_sprintf(mac), buf); 2733 } 2734 2735 static void 2736 ieee80211_discard_frame(struct ieee80211com *ic, 2737 const struct ieee80211_frame *wh, 2738 const char *type, const char *fmt, ...) 2739 { 2740 va_list ap; 2741 2742 printf("[%s:%s] discard ", ic->ic_ifp->if_xname, 2743 ether_sprintf(ieee80211_getbssid(ic, wh))); 2744 if (type != NULL) 2745 printf("%s frame, ", type); 2746 else 2747 printf("frame, "); 2748 va_start(ap, fmt); 2749 vprintf(fmt, ap); 2750 va_end(ap); 2751 printf("\n"); 2752 } 2753 2754 static void 2755 ieee80211_discard_ie(struct ieee80211com *ic, 2756 const struct ieee80211_frame *wh, 2757 const char *type, const char *fmt, ...) 2758 { 2759 va_list ap; 2760 2761 printf("[%s:%s] discard ", ic->ic_ifp->if_xname, 2762 ether_sprintf(ieee80211_getbssid(ic, wh))); 2763 if (type != NULL) 2764 printf("%s information element, ", type); 2765 else 2766 printf("information element, "); 2767 va_start(ap, fmt); 2768 vprintf(fmt, ap); 2769 va_end(ap); 2770 printf("\n"); 2771 } 2772 2773 static void 2774 ieee80211_discard_mac(struct ieee80211com *ic, 2775 const u_int8_t mac[IEEE80211_ADDR_LEN], 2776 const char *type, const char *fmt, ...) 2777 { 2778 va_list ap; 2779 2780 printf("[%s:%s] discard ", ic->ic_ifp->if_xname, ether_sprintf(mac)); 2781 if (type != NULL) 2782 printf("%s frame, ", type); 2783 else 2784 printf("frame, "); 2785 va_start(ap, fmt); 2786 vprintf(fmt, ap); 2787 va_end(ap); 2788 printf("\n"); 2789 } 2790 #endif /* IEEE80211_DEBUG */ 2791